Графическое решение задач линейного программирования

Требования к функциям, выполняемым системой, программно-аппаратному и техническому обеспечению, к эргономике и технической эстетике, надежности и хранению информации. Схема взаимодействия модулей. Структурная схема программы. Наиболее вероятные ошибки.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 19.05.2014
Размер файла 541,3 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Содержание

Введение

1. Постановка задачи

1.1 Требования к функциям, выполняемым системой

1.2 Требования к программно-аппаратному обеспечению

1.3 Требования к техническому обеспечению

1.4 Требования к эргономике и технической эстетике

1.5 Требования к надежности и хранению информации

2. Основная часть

2.1 Математическая модель

2.2 Метод решения задачи

2.3 Структурная схема программы

2.4 Схема взаимодействия модулей

3. Руководство программисту

4. Руководство пользователю

4.1 Общие сведения

4.2 Работа с помощью

4.3 Наиболее вероятные ошибки

Заключение

Список использованных источников

Приложение А - Текст программы

Приложение Б - Формы программы

Аннотация

Курсовой проект на тему «Графическое решение задач линейного программирования» содержит введение, четыре главы, заключение и приложения, которые состоят из текста, формы программы и диска с программой.

Программный продукт разработан в среде программирования Borland Delphi 7. Данная программа предназначена для получения практических навыков в разработке программных средств с использованием современных алгоритмических языков программирования и информационных технологий, стандартизации основных этапов жизненного цикла программных средств, стандартизации документирования программных средств, обеспечении надежности и качества функционирования программных средств, использовании методов тестирования программного обеспечения.

Имеется удобный и понятный интерфейс для работы с программой.

Введение

Линейное программирование - это раздел математики ориентируемый на нахождении экстремума в задачах, которые описываются линейными уравнениями.

Графический способ решения задач линейного программирования целесообразно использовать для решения задач с двумя переменными, когда ограничения выражены неравенствами.

Задачи курсового проекта:

- изучить теоретический материал по теме работы;

- описать создание программного продукта по теме работы.

1. Постановка задачи

Составить математическую модель графического решения задач линейного программирования. Описать предъявляемые требования к эргономике и технической эстетики для разработанного интерфейса программы. Разработать программный продукт для графического решения задач линейного программирования.

К основным параметрам функциональных задач в постановке задачи относятся:

1)цель и назначение данной задачи состоит в том, чтобы разработать программный продукт для графического решения задач линейного программирования;

2)условия решения задачи с использованием средств вычислительной техники:

- процессор: Pentium/Celeron/AMD K5- 2400 MHz;

- монитор SVGA, поддерживающий графический режим 1024*768;

- размер ОЗУ 1024Мб;

- свободное пространство на жестком диске не менее 20 Мб;

- видео карта 512 Мб;

- клавиатура;

- мышь;

3)содержание функций обработки входной информации при решения задачи: по введенным данным будет производиться расчет задачи;

4)требование к периодичности решения задачи: данный программный продукт будет использоваться по требованию оператора;

5)ограничение по срокам и точностям выходной информации: информация предоставляется сразу после завершения процесса обработки входной информации;

6)состав и форма представления выходной информации: выходные данные выводятся на экран;

7)источники входной информации для решения задачи: данные о технических характеристиках компьютеров;

8)пользователи задачи: программный продукт рассчитан на конечного пользователя.

1.1 Требования к функциям, выполняемым системой

Разработанный программный продукт «Графическое решение задач линейного программирования» должен удовлетворять эргономическим требованиям, требованиям к программно-аппаратному окружению, а также требованиям к надежности и хранению информации.

Обладать автоматизированным сбором информации, представлять информацию в более удобном виде.

В программном продукте реализованы следующие функции:

- решение задачи;

- справка.

1.2 Требования к программно-аппаратному обеспечению

Программное обеспечение должно удовлетворять следующим требованиям:

- возможность экономично и целесообразно использовать предоставляемую память;

- включать в себя проверку целостности данных;

- при возникновении ошибок выдавать сообщения, отражающие суть ошибок, облегчающее их исправление.

Для корректной работы с программным продуктом необходимо наличие следующих минимальных конфигураций аппаратного окружения :

- операционная система Windows XP, Windows 7 Ultimate;

- Delphi 7;

- Microsoft Office 2003, 2007.

1.3 Требования к техническому обеспечению

Для работы с программным продуктом необходимо наличие следующих минимальных конфигураций аппаратного окружения:

- процессор Intel Atom N570 CPU 3.2 GHz;

- RAM - 1Gb;

- HDD - 120Gb;

- клавиатура;

- мышь;

- монитор LG G2225HQ.

1.4 Требования к эргономике и технической эстетике

Эргономика представляет собой научную дисциплину, комплексно изучающую человека в конкретных условиях его деятельности. Возникшая на стыке общественных, технических и естественных наук, она является одновременно и проектной, и научной дисциплиной.

Взаимодействие пользователей с прикладным программным обеспечением, входящим в состав системы должно осуществляться посредством визуального графического интерфейса. Интерфейс системы должен быть понятным и удобным, не должен быть перегружен графическими элементами и должен обеспечивать быстрое отображение экранных форм. Навигационные элементы должны быть выполнены в удобной для пользователя форме. Средства редактирования информации должны удовлетворять принятым соглашениям в части использования функциональных клавиш, режимов работы, поиска, использования оконной_ системы. Ввод-вывод данных системы, прием управляющих команд и отображение результатов их исполнения должны выполняться в интерактивном режиме. Интерфейс должен соответствовать современным. эргономическим требованиям и обеспечивать удобный доступ к основным функциям и операциям системы.

Интерфейс должен быть рассчитан на преимущественное использование манипулятора типа «мышь», то есть управление системой должно осуществляться с помощью набора экранных меню, кнопок, значков и т. п. элементов. Клавиатурный режим ввода должен используется главным образом при заполнении и/или редактировании текстовых и числовых полей экранных форм. Все надписи экранных форм, а также сообщения, выдаваемые пользователю (кроме системных сообщений) должны быть на русском языке.

Система должна обеспечивать корректную обработку аварийных ситуаций, вызванных неверными действиями пользователей, неверным форматом или недопустимыми значениями входных данных. В указанных

случаях система должна выдавать пользователю соответствующие сообщения, после чего возвращаться в рабочее состояние, предшествовавшее неверной (недопустимой) команде или некорректному вводу данных.

Экранные формы должны проектироваться с учетом требований унификации:

- все экранные формы пользовательского интерфейса должны быть выполнены в едином графическом дизайне, с одинаковым расположением основных элементов управления и навигации;

- для обозначения сходных операций должны использоваться сходные графические значки, кнопки и другие управляющие (навигационные) элементы. Термины, используемые для обозначения типовых операций (добавление информационной сущности, редактирование поля данных), а также последовательности действий пользователя при их выполнении, должны быть унифицированы;

- внешнее поведение сходных элементов интерфейса (реакция на наведение указателя «мыши», переключение фокуса, нажатие кнопки) должны реализовываться одинаково для однотипных элементов.

1.5 Требования к надежности и хранению информации

Надежность - это одно из важнейших свойств программного продукта, обеспечение которого даёт возможность предусмотреть различные ситуации, когда операционная система или пользователь не могут корректно работать с программой. Например, неправильный ввод (текст вместо цифр), не поддерживаемая операционная система и т.д.

Вся система должна обладать надёжностью, необходимо предусмотреть, самые неожиданные действия пользователя и если они неправильны, программа должна объяснить, как сделать то, чего хочет программа от пользователя.

Данный программный продукт характеризуется высокой степенью_ надежности хранения информации. При некорректных действиях

пользователя программа не должна производить аварийное завершение_ работы, потому что это повлечет за собой потерю данных, а_ соответствующим образом обрабатывать эти действия, не прерывая нормальный ход программы.

Помимо этого в программе предусмотрено жесткий контроль вводимой информации, для сокращения случайных ошибок пользователя.

Хранение программного продукта может осуществляться на любом магнитном или оптическом носителе информации. В нашем случае применены компакт диски CD-R/DWD-R и Flash - носители.

Следует признать, что абсолютно надежных программ не существует, так как абсолютная степень надежности не может быть теоретически доказана и, следовательно, недостижима. Описанные модели представляют теоретический подход и, как правило, имеют ограниченное применение.

Типовая структура характеристик и атрибутов качества для оценивания исполняемого программного обеспечения, применяемые метрики, соответствующие виды, испытаний и методы измерений в методике представляются в таблицах.

Регистрация означает протоколирование выявляемых в процессе оценивания событий или проявлений ошибок (недостатков, нарушений требований).

Программная документация, в общем виде, должна удовлетворять следующим требованиям:

- соответствие требованиям стандартов единой системы программной документации;

- понятность документации;

- полнота документации;

- возможность освоения программного обеспечения по документации;

- возможность освоения программного обеспечения на контрольном примере;

- легкость установки и запуска программного обеспечения;

- понятность входных и выходных данных;

- наличие описания структуры функций программного обеспечения;

- соответствие функций программного обеспечения требованиям
техническому заданию;

- наличие описания функций программного обеспечения;

- отсутствие противоречий в реализации интерфейса с пользователем;

- отсутствие противоречий в диагностике системы;

- обеспечение помощи пользователю при затруднениях средствами
функции подсказки;

- достаточность документации для ввода программного обеспечения в
эксплуатации;

- правильность документации;

- приемлемость уровня технического исполнения документации;

- наличие краткой аннотации программного обеспечения;

- наличие описания решаемых задач;

- наличие описания ограничении по применению;

- наличие описания алгоритмов.

2. Основная часть

2.1 Математическая модель

Математическая модель - это математическое представление реальности.

Математическое моделирование - это процесс построения и изучения математических моделей.

Все естественные и общественные науки, использующие математический аппарат, по сути, занимаются математическим моделированием: заменяют реальный объект его математической моделью и затем изучают последнюю.

Графический способ решения ЗЛП целесообразно использовать для решения задач с двумя переменными, когда ограничения выражены системой неравенств 1:

(1)

x1 ? 0, x2 ? 0

2.2 Метод решения задачи

Алгоритм графического способа решения задач линейного программирования заключается:

1) Построить прямые уравнения, которые получаются в результате замены в ограничения знаков неравенств на знаки равенств;

2) Найти полуплоскости, определяемые каждым из ограничений задачи;

3) Определить многоугольник решений;

4) Построить вектор = (c1;c2) - вектор градиент;

5) Построить прямую F = c1x1 + c2x2 = 0, проходящую через начало координат и перпендикулярную вектору ;

6) Передвигать прямую F в направлении вектора , в результате чего либо находят точку, в которой целевая функция принимает экстремум (максимум или минимум), либо устанавливают неограниченность функции на множестве планов;

7) Определить координаты точки экстремума функции и вычислить значение целевой функции в этой точки.

Пример. Предприятие изготавливает два вида продукции - П1 и П2, которая поступает в оптовую продажу. Для производства продукции используются два вида сырья - А и В. Максимально возможные запасы сырья в сутки составляют 9 и 13 единиц соответственно. Расход сырья на единицу продукции вида П1 и вида П2 дан в таблице 1.

Таблица 1 - Расход сырья продукции

Сырье

Расход сырья

на 1 ед. продукции

Запас сырья, ед.

П1

П2

А

В

2

3

3

2

9

13

Опыт работы показал, что суточный спрос на продукцию П1 никогда не превышает спроса на продукцию П2 более чем на 1 ед. кроме того, известно, что спрос на продукцию П2 никогда не превышает 2 ед. в сутки.

Оптовые цены единицы продукции равны: 3д.е. - для П1 4 д.е. для П2.

Какое количество продукции каждого вида должно производить предприятие, чтобы доход от реализации продукции был максимальным?

Решение: Для построения математической модели остается только идентифицировать переменные и представить цель и ограничения в виде математических функций этих переменных.

Предположим, что предприятие изготовит х1 единиц продукции П1 и х2 единиц продукции П2. поскольку производство продукции П1 и П2 ограничено имеющимися в распоряжении в распоряжении предприятия сырьем каждого вида и спросом на данную продукцию, а также учитывая, что количество изготавливаемых изделий не может быть отрицательным, должна выполняться система неравенств 2:

2х1 + 3х2 9;

3х1 + 2х2 13;

х1 - х2 1; (2)

х2 2;

х1 0; х2 0.

Доход от реализации х1 единиц продукции П1 и х2 продукции П2 составит F = 3x1 + 4x2.

Таким образом, мы приходим к следующей математической задаче: среди всех неотрицательных решений данной системы линейных неравенств требуется найти такое, при котором функция F принимает максимальное значение Fmax .

Найдем решение данной задачи графическим способом.

Построим многоугольник решений. Для этого в системе координат Х10Х2 на плоскости изобразим граничные прямые L1, L2, L3, L4:

2х1 + 3х2 = 9 (L1);

3х1 + 2х2 = 13 (L2);

х1 - х2 = 1 (L3);

х2 = 2 (L4).

Для построения прямой Z = 3х1 + 4х2 = 0 строим вектор-градиент С = (3;4) и через точку 0 проводим прямую, перпендикулярную ему. Построенную прямую Z = 0 перемещаем параллельно самой себе в направление вектора С. Из рисунка 9 следует, что по отношению к многоугольнику решений опорной эта прямая становится в точке С, где функция принимает максимальное значение. Точка С лежит на пересечении прямых L1 и L3. для определения ее координат решим систему уравнений 1:

2х1 + 3х2 = 9;

х1 - х2 = 1. (1)

Оптимальный план задачи х1 = 2,4; х2 = 1,4. подставляя значения х1 и х2 в линейную функцию, получим равенство 1:

Zmax = 3 * 2,4 + 4 * 1,4 = 12,8. (1)

Полученное решение означает, что объем производства продукции П1 должен быть равен 2,4 ед., а продукции П2 - 1,4 ед. доход, получаемый в этом случае, составит: Z = 12,8 д.е. Ответ показан на рисунке 1:

Размещено на http://www.allbest.ru/

Рисунок 1 - Геометрическая интерпретация решения задач линейного программирования

2.3 Структурная схема программы

Программный продукт имеет конструкцию построения - состав и взаимосвязь программный модулей. Пример структурной схемы программы представлен на рисунке 2.

Рисунок 2 - Структурная схема программы

2.4 Схема взаимодействия модулей

Программа содержит 4 модуля. Схема взаимодействия модулей программы изображена на рисунке 3.

Рисунок 3 - Схема взаимодействия модулей

3. Руководство программисту

Данный программный продукт написан в среде визуального программирования Borland Delphi 7 и был основан на модульном программировании. В программе используются стандартные компоненты Delphi, с помощью которых осуществляется её реализация. Программа включает в себя следующие файлы:

- graph_simplex.dpr - содержит общее описание проекта;

- graph_simplex.cfg - содержит параметры и настройки компилятора;

- graph_simplex.dof - содержит параметры и настройки проекта;

- graph_simplex.res - файл ресурсов;

- graph_simplex.exe - исполнимый файл;

- файлы с расширением *.pas - файлы модулей которые содержат код программы;

- файлы с расширением *.dfm - файлы в которых находится описание окон;

- файлы с расширением *.dcu - результат преобразования текста модулей в машинные инструкции.

Все вышеперечисленные файлы необходимы для правильной организации программы. Переименование или удаление любого из файлов приведет к сбою в работе программы.

Программы включает в себя 4 модуля каждый из которых выполняют определенные функции:

MainForm - рабочая среда программы;

NewTaskForm - новая задача ;

TaskSizeForm - новая симплекс - таблица ;

AboutForm - вызов справки

Для начала работы с программой нужно запустить файл graph_simplex.exe.

Текст программы представлен в приложении А.

4. Руководство пользователю

4.1 Общие сведения

Данная программа предназначена для графического решения задач линейного программирования.

Для начала работы с программой необходимо запустить файл graph_simplex.exe.

Для запуска программы выбрать вкладку «Задача». В появившемся окне ввести информацию из задачи в новую симплекс-таблицу, после чего нажать «ОК». Далее следует выбрать выбрать критерий минимизации и максимизации, после чего на главном окне появятся графическое решение и уравнения решения данной задачи

Для получения справочной информации по программе следует после запуска программы щелкнуть по вкладке «Справка».

Работу программы можно посмотреть в приложении Б.

4.2 Работа с помощью

В программном продукте предоставлена справка, в которой написано назначение программы и информация о разработчике.

Для вызова справки нужно выбрать на панели инструментов пункт «Справка».

1) Справка «О программе» (рисунок 4).

Рисунок 4 - Справка «О программе»

4.3 Наиболее вероятные ошибки

В процессе работы с программой появляются сообщения об ошибках, случае если не все поля заполнены.

Окно ошибки при не правильном выборе количества ограничений показано на рисунке 5:

Рисунок 5 - Окно ошибки при не правильном выборе количества ограничений

Заключение

В курсовом проекте изложен теоретический материал по теме «Графическое решение задач линейного программирования», приведен пример решения задач данным методом.

Результатом курсового проекта является программный продукт, выполненный в среде программирования Borland Delphi 7, с использованием дополнительных компонентов, и разработан по всем правилам разработки программного продукта.

Были получены и закреплены знания по дисциплине «Математические методы». Полученные знания и навыки за время выполнения курсового проекта в дальнейшем будут применяться в разработке программ.

Таким образом, цель курсового проекта достигнута, задачи выполнены.

Приложение A

Текст программы

program graph_simplex;

{$IFDEF VER240}

{$R 'theory.res' '..\docs\theory.rc'}

{$ELSE}

{$R '..\bin\theory.res'}

{$ENDIF}

uses

Forms,

NewTaskFormUnit in 'forms\NewTaskForm\NewTaskFormUnit.pas' {NewTaskForm},

MainFormUnit in 'forms\MainForm\MainFormUnit.pas' {MainForm},

TaskSizeFormUnit in 'forms\TaskSizeForm\TaskSizeFormUnit.pas' {TaskSizeForm},

AboutFormUnit in 'forms\AboutForm\AboutFormUnit.pas' {AboutForm};

{$R *.res}

begin

Application.Initialize;

{$IF CompilerVersion > 18.5}

Application.MainFormOnTaskbar := True;

{$IFEND}

Application.CreateForm(TMainForm, MainForm);

Application.Run;

end.

unit MainFormUnit;

interface

uses

Windows, Messages, SysUtils, Variants, Classes,

Graphics, Controls, Forms, Dialogs, Menus, ExtCtrls,

ActnList, StdCtrls, MSimplexMath, ComCtrls,

Math, ToolWin, ImgList, Buttons, OleCtrls, ActiveX,

MSHTML, SHDocVw;

type

TPointd = record

x: Double;

y: Double;

end;

TMainForm = class(TForm)

MainMenu: TMainMenu;

miTask: TMenuItem;

miExit: TMenuItem;

miHelp: TMenuItem;

miAbout: TMenuItem;

LeftPanel: TPanel;

PaintBox: TPaintBox;

miNewTask: TMenuItem;

N1: TMenuItem;

ActionList: TActionList;

acNewTask: TAction;

BottomPanel: TPanel;

tbScale: TTrackBar;

ScaleLabel: TLabel;

TaskRichEdit: TRichEdit;

BottomPanel2: TPanel;

cbDrawDirectFunctionDomain: TCheckBox;

cbDrawGrid: TCheckBox;

Bevel1: TBevel;

Bevel2: TBevel;

ToolBar: TToolBar;

ToolButton1: TToolButton;

ToolButton2: TToolButton;

ToolButton3: TToolButton;

cbDrawFunctionDomain: TCheckBox;

ImageList: TImageList;

bmp1: TMenuItem;

acSaveBmp: TAction;

SaveDialog: TSaveDialog;

TaskSpeedButton: TSpeedButton;

TheorySpeedButton: TSpeedButton;

TheoryPanel: TPanel;

TheoryWebBrowser: TWebBrowser;

cbDrawDirectVector: TCheckBox;

TaskTypeComboBox: TComboBox;

procedure miExitClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure FormResize(Sender: TObject);

procedure PaintBoxPaint(Sender: TObject);

procedure acNewTaskExecute(Sender: TObject);

procedure miAboutClick(Sender: TObject);

procedure tbScaleChange(Sender: TObject);

procedure cbDrawDirectFunctionDomainClick(Sender: TObject);

procedure cbDrawGridClick(Sender: TObject);

procedure cbDrawFunctionDomainClick(Sender: TObject);

procedure acSaveBmpExecute(Sender: TObject);

procedure cbDrawDirectVectorClick(Sender: TObject);

procedure TaskSpeedButtonClick(Sender: TObject);

procedure TheorySpeedButtonClick(Sender: TObject);

procedure TaskTypeComboBoxChange(Sender: TObject);

private

FM: Integer;

FTaskType: Integer;

A: TMatrix;

B: TVector;

C: TVector;

S: array of Integer;

что x1 >= 0; x2 >= 0;

FX1X2Positive: boolean;

sx, sy: Double;

FTaskSolved: Boolean;

FTaskInfinite: Boolean;

FWidthdiv2: Integer;

FHeightdiv2: Integer;

FGraphScale: Double;

FPaintBuffer: TBitMap;

FDrawTaskGraph: Boolean;

procedure DrawGraph;

procedure SolveTask;

procedure DrawFunctionDomain;

procedure DrawGrid;

function TestForInfinite(ALine1, ALine2: TVector; AMinMaxValue: Double): Boolean;

procedure DrawDirectVector;

function LineToPoint(a1, b1, c1: Double; a2, b2, c2: Double; var x,y: Double):Boolean;

function GetSignStr(Index: Integer): string;

function PointBelongsRest(x, y: Double; ARestIndex: Integer; x1x2positive: boolean): boolean;

function PointBelongsRestDomain(x, y: Double; x1x2positive: boolean): boolean;

procedure WMErasebkgnd(var Msg: TWMErasebkgnd); message WM_ERASEBKGND;

function GetGraphScale: Double;

public

property GraphScale: Double read GetGraphScale;

end;

var

MainForm: TMainForm;

implementation

{$R *.dfm}

uses

TaskSizeFormUnit, NewTaskFormUnit, AboutFormUnit;

function GetTempDirPath: string;

var

EnvStr: string;

ReturnSize: integer;

begin

SetLength(EnvStr, 256);

ReturnSize:=GetEnvironmentVariable('temp', PChar(EnvStr), 256);

SetLength(EnvStr, returnsize);

if returnsize > 0 then begin

Result:=EnvStr;

end else begin

Result:='';

end;

end;

function CheckForSlash(AString: string): string;

var

LString: string;

begin

if AString <> '' then begin

LString:=Trim(AString);

if LString[Length(LString)] <> PathDelim then begin

LString:=LString + PathDelim;

end;

Result:=LString;

end else begin

Result:='';

end;

end;

procedure WriteInRichEd(RichEd: TRichEdit; S: string; Color: TColor; ASize: Integer; Style: TFontStyles);

begin

RichEd.SelStart := Length(RichEd.Text);

RichEd.SelAttributes.Color := Color;

RichEd.SelAttributes.Style := Style;

RichEd.SelAttributes.Size := ASize;

RichEd.SelText := S;

end;

function PointInRect(APoint: TPoint; ARect: TRect): Boolean;

begin

Result := (APoint.X > ARect.Left) and (APoint.Y > ARect.Top) and (APoint.X < ARect.Right) and (APoint.Y < ARect.Bottom);

end;

function CheckForNil(AValue: Double): Double;

begin

if AValue = 0 then

begin

Result := 1;

end else

begin

Result := AValue;

end;

end;

function CheckOne(AValue: Double): string;

begin

if AValue = 1 then

begin

Result := '';

end else

begin

if AValue = - 1 then

begin

Result := '-';

end else

begin

Result := FloatToStr(AValue);

end;

end;

end;

function CheckMinusPlus(AValue: Double): string;

begin

if AValue < 0 then

begin

Result := CheckOne(AValue);

end else

begin

Result := '+' + CheckOne(AValue);

end;

end;

function TMainForm.GetSignStr(Index: Integer): string;

begin

case S[Index] of

0: Result := '=';

1: Result := '>=';

2: Result := '<=';

end;

end;

true,

function TMainForm.LineToPoint(a1, b1, c1: Double; a2, b2, c2: Double; var x,y: Double):Boolean;

var

d: Double;

dx: Double;

dy: Double;

begin

d := a1 * b2 - b1 * a2;

if d <> 0 then

begin

Result := true;

dx := -c1 * b2 + b1 * c2;

dy := -a1 * c2 + c1 * a2;

x := - dx / d;

y := - dy / d;

end else

begin

Result := false;

end;

end;

procedure TMainForm.acNewTaskExecute(Sender: TObject);

var

i: Integer;

LNewTaskForm: TNewTaskForm;

LTaskSizeForm: TTaskSizeForm;

begin

LTaskSizeForm := TTaskSizeForm.Create(nil);

try

if LTaskSizeForm.ShowModal = mrOk then

begin

LNewTaskForm := TNewTaskForm.Create(nil);

try

LNewTaskForm.N := 2;

FM := LTaskSizeForm.M;

LNewTaskForm.M := LTaskSizeForm.M;

if LNewTaskForm.ShowModal = mrOk then

begin

TaskTypeComboBox.Enabled := true;

FTaskType := LNewTaskForm.cbTaskType.ItemIndex;

TaskTypeComboBox.ItemIndex := LNewTaskForm.cbTaskType.ItemIndex;

SetLength(S, FM);

for i := 0 to FM - 1 do

begin

S[i] := LNewTaskForm.Sign[i];

end;

A := LNewTaskForm.NMatrix;

B := LNewTaskForm.Vectorb;

C := LNewTaskForm.Vectorc;

SolveTask;

FDrawTaskGraph := true;

Repaint;

end;

finally

LNewTaskForm.Free;

end;

end;

finally

LTaskSizeForm.Free;

end;

end;

procedure TMainForm.acSaveBmpExecute(Sender: TObject);

begin

if SaveDialog.Execute then

begin

FPaintBuffer.SaveToFile(SaveDialog.FileName);

end;

end;

procedure TMainForm.cbDrawDirectFunctionDomainClick(Sender: TObject);

begin

Repaint;

end;

procedure TMainForm.cbDrawDirectVectorClick(Sender: TObject);

begin

Repaint;

end;

procedure TMainForm.cbDrawFunctionDomainClick(Sender: TObject);

begin

Repaint;

end;

procedure TMainForm.cbDrawGridClick(Sender: TObject);

begin

Repaint;

end;

// Процедура рисования направляющего вектора

procedure TMainForm.DrawDirectVector;

var

x, y: Double;

x1, y1: Double;

x2, y2: Double;

x3, y3: Double;

xp, yp: Double;

LAlpha: Double;

xp1, yp1: Double;

begin

if (C[0] = 0) and (C[1] = 0) then

begin

Exit;

end;

x := C[0];

y := C[1];

if x <> 0 then x1 := x / sqrt(sqr(x) + sqr(y));

if y <> 0 then y1 := y / sqrt(sqr(x) + sqr(y));

x := x1;

y := y1;

if FWidthdiv2 < FHeightdiv2 then

begin

xp := FWidthdiv2 + (x * FWidthdiv2);

yp := FHeightdiv2 + ( - y * FWidthdiv2);

end else

begin

xp := FWidthdiv2 + (x * FHeightdiv2);

yp := FHeightdiv2 + ( - y * FHeightdiv2);

end;

// Рисуем линию

FPaintBuffer.Canvas.Pen.Width := 2;

FPaintBuffer.Canvas.Pen.Color := clRed;

FPaintBuffer.Canvas.Font.Color := clRed;

FPaintBuffer.Canvas.MoveTo(FWidthdiv2, FHeightdiv2);

FPaintBuffer.Canvas.LineTo(Round(xp), Round(yp));

// Рисуем стрелки

xp1 := - 1 * x * 20;

yp1 := y * 20;

LAlpha := 15 * pi / 180;

x := xp1 * Cos(LAlpha) - yp1 * Sin(LAlpha);

y := xp1 * Sin(LAlpha) + yp1 * Cos(LAlpha);

x2 := xp + x;

y2 := yp + y;

FPaintBuffer.Canvas.MoveTo(Round(xp), Round(yp));

FPaintBuffer.Canvas.LineTo(Round(x2), Round(y2));

x3 := x2;

y3 := y2;

LAlpha := - 15 * pi / 180;

x := xp1 * Cos(LAlpha) - yp1 * Sin(LAlpha);

y := xp1 * Sin(LAlpha) + yp1 * Cos(LAlpha);

x2 := xp + x;

y2 := yp + y;

FPaintBuffer.Canvas.MoveTo(Round(xp), Round(yp));

FPaintBuffer.Canvas.LineTo(Round(x2), Round(y2));

FPaintBuffer.Canvas.MoveTo(Round(x2), Round(y2));

FPaintBuffer.Canvas.LineTo(Round(x3), Round(y3));

end;

procedure TMainForm.DrawFunctionDomain;

var

j: Integer;

x, y: Double;

LAlpha: Double;

x1, y1: Double;

x2, y2: Double;

x3, y3: Double;

p1, p2: TPoint;

LAngle: Double;

OfsX, OfsY: Double;

LPointIndex: Integer;

LSegmentLength: Double;

LDomainDirection: Integer;

LPoints: array[1..4] of TPointd;

begin

P1(x1; y1) Рё P2(x2; y2)

x = (x1 + x2) / 2; y = (y1 + y2) / 2;

{P1P2}.

(l,m): l(x-x0)+m(y-y0)=0.

for j := 0 to FM - 1 do

begin

if (A[j, 0] = 0) and (A[j, 1] = 0) then

begin

Continue;

end;

// 0 - '=';

// 1 - '>=';

// 2 - '<=';

if S[j] <> 0 then

begin

LPointIndex := 1;

if A[j, 1] <> 0 then

begin

x := FWidthdiv2 / GraphScale;

y := (B[j] - (A[j, 0] * x)) / A[j, 1];

if Abs(y) <= (FHeightdiv2 / GraphScale) then

begin

LPoints[LPointIndex].x := x;

LPoints[LPointIndex].y := y;

LPointIndex := LPointIndex + 1;

end;

end;

if A[j, 1] <> 0 then

begin

x := - FWidthdiv2 / GraphScale;

y := (B[j] - (A[j, 0] * x)) / A[j, 1];

if Abs(y) <= (FHeightdiv2 / GraphScale) then

begin

LPoints[LPointIndex].x := x;

LPoints[LPointIndex].y := y;

LPointIndex := LPointIndex + 1;

end;

end;

if A[j, 0] <> 0 then

begin

y := FHeightdiv2 / GraphScale;

x := (B[j] - (A[j, 1] * y)) / A[j, 0];

if Abs(x) <= (FWidthdiv2 / GraphScale) then

begin

LPoints[LPointIndex].x := x;

LPoints[LPointIndex].y := y;

LPointIndex := LPointIndex + 1;

end;

end;

if A[j, 0] <> 0 then

begin

y := - FHeightdiv2 / GraphScale;

x := (B[j] - (A[j, 1] * y)) / A[j, 0];

if Abs(x) <= (FWidthdiv2 / GraphScale) then

begin

LPoints[LPointIndex].x := x;

LPoints[LPointIndex].y := y;

end;

end;

x1 := LPoints[1].x;

y1 := LPoints[1].y;

x2 := LPoints[2].x;

y2 := LPoints[2].y;

if A[j, 0] <> 0 then

begin

x := x1 + 0.25;

y := ((x - x1) / A[j, 0]) * A[j, 1] + y1;

end else

begin

y := y1 + 0.25;

x := ((y - y1) / A[j, 1]) * A[j, 0] + x1;

end;

case S[j] of

1: begin // 1 - '>=';

if ((A[j, 0] * x) + (A[j, 1] * y)) >= B[j] then

begin

LDomainDirection := 1;

end else

begin

LDomainDirection := - 1;

end;

end;

2: begin // 2 - '<=';

if ((A[j, 0] * x) + (A[j, 1] * y)) <= B[j] then

begin

LDomainDirection := 1;

end else

begin

LDomainDirection := - 1;

end;

end;

end;

FPaintBuffer.Canvas.Pen.Width := 1;

FPaintBuffer.Canvas.Pen.Color := clBlue;

FPaintBuffer.Canvas.Pen.Style := psSolid;

if x1 > x2 then

begin

x3 := x2;

y3 := y2;

x2 := x1;

y2 := y1;

x1 := x3;

y1 := y3;

end;

OfsX := x1 * GraphScale;

OfsY := y1 * GraphScale;

LSegmentLength := Sqrt(Sqr(y2 - y1) + Sqr(x2 - x1));

if cbDrawFunctionDomain.Checked then

begin

LAlpha := 0;

while True do

begin

x3 := OfsX + (x2 - x1) * LAlpha;

y3 := OfsY + (y2 - y1) * LAlpha;

LAlpha := LAlpha + 7 / LSegmentLength;

if A[j, 0] <> 0 then

begin

x := x3 + 2 * LDomainDirection;

y := ((x - x3) / A[j, 0]) * A[j, 1] + y3;

end else

begin

y := y3 + 2 * LDomainDirection;

x := ((y - y3) / A[j, 1]) * A[j, 0] + x3;

end;

p1.X := FWidthdiv2 + Round(x3);

p1.Y := FHeightdiv2 + Round(- y3);

p2.X := FWidthdiv2 + Round(x);

p2.Y := FHeightdiv2 + Round(- y);

if (PointBelongsRestDomain(x / GraphScale, y / GraphScale, FX1X2Positive)) or

(PointBelongsRest(x / GraphScale, y / GraphScale, j, FX1X2Positive) and (not FTaskSolved) and (not FTaskInfinite)) then

begin

if FPaintBuffer.Canvas.Pixels[p2.X, p2.Y] <> clMoneyGreen then

begin

FPaintBuffer.Canvas.Brush.Color := clMoneyGreen;

FPaintBuffer.Canvas.Brush.Style := bsSolid;

FPaintBuffer.Canvas.FloodFill(p2.X, p2.Y, clWhite, fsSurface);

end;

end;

if y2 < y1 then

begin

if (p2.X > FPaintBuffer.Width) or (p2.Y > FPaintBuffer.Height) then

begin

Break;

end;

end else

begin

if (p2.X > FPaintBuffer.Width) or (p2.Y < 0) then

begin

Break;

end;

end;

end;

end;

if cbDrawDirectFunctionDomain.Checked then

begin

LAlpha := 0;

while True do

begin

x3 := OfsX + (x2 - x1) * LAlpha;

y3 := OfsY + (y2 - y1) * LAlpha;

LAlpha := LAlpha + 7 / LSegmentLength;

if A[j, 0] <> 0 then

begin

LAngle := ArcTan(A[j, 1] / A[j, 0]) * 180 / pi;

if Abs(LAngle) <= 45 then

begin

if LAngle < 0 then x := x3 + 10 * - LDomainDirection else x := x3 + 10 * LDomainDirection;

y := ((x - x3) / A[j, 0]) * A[j, 1] + y3;

end else

begin

if LAngle < 0 then y := y3 + 10 * - LDomainDirection else y := y3 + 10 * LDomainDirection;

x := ((y - y3) / A[j, 1]) * A[j, 0] + x3;

end;

end else

begin

y := y3 + 10 * LDomainDirection;

x := ((y - y3) / A[j, 1]) * A[j, 0] + x3;

end;

p1.X := FWidthdiv2 + Round(x3);

p1.Y := FHeightdiv2 + Round(- y3);

p2.X := FWidthdiv2 + Round(x);

p2.Y := FHeightdiv2 + Round(- y);

FPaintBuffer.Canvas.MoveTo(p1.X, p1.Y);

FPaintBuffer.Canvas.LineTo(p2.X, p2.Y);

if y2 < y1 then

begin

if (p2.X > FPaintBuffer.Width) or (p2.Y > FPaintBuffer.Height) then

begin

Break;

end;

end else

begin

if (p2.X > FPaintBuffer.Width) or (p2.Y < 0) then

begin

Break;

end;

end;

end;

end;

end;

end;

end;

procedure TMainForm.DrawGraph;

var

MaxX: Double;

MaxY: Double;

x, y: Double;

x1, y1: Double;

x2, y2: Double;

i, j: Integer;

MaxValue1: Double;

MaxValue2: Double;

LPointIndex: Integer;

LPoints: array[1..4] of TPointd;

begin

if FDrawTaskGraph then

begin

// Р'ычисляем масштаб графика

MaxX := 0;

MaxY := 0;

for i := 0 to FM - 1 do

begin

if (A[i, 0] = 0) and (A[i, 1] = 0) then

begin

Continue;

end;

if A[i, 0] <> 0 then

begin

x := B[i] / A[i, 0];

end else

begin

x := 0;

end;

if A[i, 1] <> 0 then

begin

y := B[i] / A[i, 1];

end else

begin

y := 0;

end;

if Abs(x) > MaxX then

begin

MaxX := Abs(x);

end;

if Abs(y) > MaxY then

begin

MaxY := Abs(y);

end;

end;

if MaxX <> 0 then

begin

MaxValue1 := (FWidthdiv2 div 2) / MaxX;

end else

begin

MaxValue1 := 1.7e308;

end;

if MaxY <> 0 then

begin

MaxValue2 := (FHeightdiv2 div 2) / MaxY;

end else

begin

MaxValue2 := 1.7e308;

end;

if MaxValue1 < MaxValue2 then

begin

FGraphScale := MaxValue1;

end else

begin

FGraphScale := MaxValue2;

end;

if FGraphScale >= 1000 then

begin

FGraphScale := (FWidthdiv2 div 2) / 3;

end;

end else

begin

FGraphScale := 50;

end;

// Рисуем сетку

DrawGrid;

// Рисуем ось координат

FPaintBuffer.Canvas.Pen.Width := 3;

FPaintBuffer.Canvas.Pen.Color := clBlack;

FPaintBuffer.Canvas.Font.Color := clBlack;

FPaintBuffer.Canvas.Font.Style := [fsBold];

FPaintBuffer.Canvas.MoveTo(FWidthdiv2, FPaintBuffer.Height);

FPaintBuffer.Canvas.LineTo(FWidthdiv2, 0);

FPaintBuffer.Canvas.LineTo(FWidthdiv2 - 5, 10);

FPaintBuffer.Canvas.LineTo(FWidthdiv2 + 5, 10);

FPaintBuffer.Canvas.LineTo(FWidthdiv2, 0);

FPaintBuffer.Canvas.TextOut(FWidthdiv2 + 15, 2, 'x2');

FPaintBuffer.Canvas.MoveTo(0, FHeightdiv2);

FPaintBuffer.Canvas.LineTo(FPaintBuffer.Width, FHeightdiv2);

FPaintBuffer.Canvas.LineTo(FPaintBuffer.Width - 10, FHeightdiv2 - 5);

FPaintBuffer.Canvas.LineTo(FPaintBuffer.Width - 10, FHeightdiv2 + 5);

FPaintBuffer.Canvas.LineTo(FPaintBuffer.Width, FHeightdiv2);

FPaintBuffer.Canvas.TextOut(FPaintBuffer.Width - 20, FHeightdiv2 - 25, 'x1');

FPaintBuffer.Canvas.Font.Style := [];

if FDrawTaskGraph then

begin

// Рисуем прямые ограничений

for j := 0 to FM - 1 do

begin

if (A[j, 0] = 0) and (A[j, 1] = 0) then

begin

Continue;

end;

LPointIndex := 1;

if A[j, 1] <> 0 then

begin

x := FWidthdiv2 / GraphScale;

y := (B[j] - (A[j, 0] * x)) / A[j, 1];

if Abs(y) <= (FHeightdiv2 / GraphScale) then

begin

LPoints[LPointIndex].x := x;

LPoints[LPointIndex].y := y;

LPointIndex := LPointIndex + 1;

end;

end;

if A[j, 1] <> 0 then

begin

x := - FWidthdiv2 / GraphScale;

y := (B[j] - (A[j, 0] * x)) / A[j, 1];

if Abs(y) <= (FHeightdiv2 / GraphScale) then

begin

LPoints[LPointIndex].x := x;

LPoints[LPointIndex].y := y;

LPointIndex := LPointIndex + 1;

end;

end;

if A[j, 0] <> 0 then

begin

y := FHeightdiv2 / GraphScale;

x := (B[j] - (A[j, 1] * y)) / A[j, 0];

if Abs(x) <= (FWidthdiv2 / GraphScale) then

begin

LPoints[LPointIndex].x := x;

LPoints[LPointIndex].y := y;

LPointIndex := LPointIndex + 1;

end;

end;

if A[j, 0] <> 0 then

begin

y := - FHeightdiv2 / GraphScale;

x := (B[j] - (A[j, 1] * y)) / A[j, 0];

if Abs(x) <= (FWidthdiv2 / GraphScale) then

begin

LPoints[LPointIndex].x := x;

LPoints[LPointIndex].y := y;

end;

end;

x1 := LPoints[1].x;

y1 := LPoints[1].y;

x2 := LPoints[2].x;

y2 := LPoints[2].y;

FPaintBuffer.Canvas.Pen.Width := 2;

FPaintBuffer.Canvas.MoveTo(FWidthdiv2 + Round(x1 * GraphScale), FHeightdiv2 + Round(- y1 * GraphScale));

FPaintBuffer.Canvas.LineTo(FWidthdiv2 + Round(x2 * GraphScale), FHeightdiv2 + Round(- y2 * GraphScale));

FPaintBuffer.Canvas.Font.Color := clRed;

FPaintBuffer.Canvas.Font.Style := [fsBold];

FPaintBuffer.Canvas.Brush.Style := bsClear;

if A[j, 1] <> 0 then

begin

x1 := 0;

y1 := (B[j] - (A[j, 0] * x1)) / A[j, 1];

FPaintBuffer.Canvas.Ellipse((FWidthdiv2 + Round(x1 * GraphScale)) - 3, FHeightdiv2 + Round(- y1 * GraphScale) - 3, (FWidthdiv2 + Round(x1 * GraphScale)) + 3, FHeightdiv2 + Round(- y1 * GraphScale) + 3);

FPaintBuffer.Canvas.TextOut((FWidthdiv2 + Round(x1 * GraphScale)) - 20, FHeightdiv2 + Round(- y1 * GraphScale), Chr(Ord('A') + j) + '1');

end;

if A[j, 0] <> 0 then

begin

y2 := 0;

x2 := (B[j] - (A[j, 1] * y2)) / A[j, 0];

FPaintBuffer.Canvas.Ellipse((FWidthdiv2 + Round(x2 * GraphScale)) - 3, FHeightdiv2 + Round(- y2 * GraphScale) - 3, (FWidthdiv2 + Round(x2 * GraphScale)) + 3, FHeightdiv2 + Round(- y2 * GraphScale) + 3);

FPaintBuffer.Canvas.TextOut((FWidthdiv2 + Round(x2 * GraphScale)) - 3, FHeightdiv2 + Round(- y2 * GraphScale) - 20, Chr(Ord('A') + j) + '2');

end;

end;

DrawFunctionDomain;

if cbDrawDirectVector.Checked then

begin

DrawDirectVector;

end;

if (FTaskSolved) and (cbDrawDirectVector.Checked) and ((C[0] <> 0) or (C[1] <> 0)) then

begin

if C[1] <> 0 then

begin

x1 := - Round(FWidthdiv2 / GraphScale);

if C[1] <> 0 then y1 := (- C[0] * (x1 - sx)) / C[1] + sy;

x2 := Round(FWidthdiv2 / GraphScale);

if C[1] <> 0 then y2 := (- C[0] * (x2 - sx)) / C[1] + sy;

end else

begin

y1 := - Round(FHeightdiv2 / GraphScale);

if C[0] <> 0 then x1 := (- C[1] * (y1 - sy)) / C[0] + sx;

y2 := Round(FHeightdiv2 / GraphScale);

if C[0] <> 0 then x2 := (- C[1] * (y2 - sy)) / C[0] + sx;

end;

FPaintBuffer.Canvas.Pen.Width := 2;

FPaintBuffer.Canvas.Pen.Color := clRed;

FPaintBuffer.Canvas.MoveTo(FWidthdiv2 + Round(x1 * GraphScale), FHeightdiv2 + Round(- y1 * GraphScale));

FPaintBuffer.Canvas.LineTo(FWidthdiv2 + Round(x2 * GraphScale), FHeightdiv2 + Round(- y2 * GraphScale));

end;

FPaintBuffer.Canvas.Pen.Color := clGreen;

FPaintBuffer.Canvas.Brush.Color := clGreen;

FPaintBuffer.Canvas.Ellipse((FWidthdiv2 + Round(sx * GraphScale)) - 3, FHeightdiv2 + Round(- sy * GraphScale) - 3, (FWidthdiv2 + Round(sx * GraphScale)) + 3, FHeightdiv2 + Round(- sy * GraphScale) + 3);

end;

end;

procedure TMainForm.DrawGrid;

var

i: Integer;

LGridStep: Double;

LGridCount: Integer;

LScaleFactor: Double;

begin

for i := 1 to 30 do

begin

LGridStep := GraphScale * i;

if ((LGridStep >= 25) and (LGridStep <= 30)) or (LGridStep > 30) then

begin

Break;

end;

end;

LScaleFactor := LGridStep / GraphScale;

if FHeightdiv2 > FWidthdiv2 then

begin

LGridCount := Round(FHeightdiv2 / LGridStep);

end else

begin

LGridCount := Round(FWidthdiv2 / LGridStep);

end;

FPaintBuffer.Canvas.Font.Color := clBlack;

FPaintBuffer.Canvas.Pen.Color := clBlue;

FPaintBuffer.Canvas.Pen.Style := psDot;

FPaintBuffer.Canvas.Pen.Width := 1;

if cbDrawGrid.Checked then

begin

for i := 1 to LGridCount do

begin

// Горизонтальные линии

FPaintBuffer.Canvas.MoveTo(0, FHeightdiv2 - Round(LGridStep) * i);

FPaintBuffer.Canvas.LineTo(FPaintBuffer.Width, FHeightdiv2 - Round(LGridStep) * i);

FPaintBuffer.Canvas.MoveTo(0, FHeightdiv2 + Round(LGridStep) * i);

FPaintBuffer.Canvas.LineTo(FPaintBuffer.Width, FHeightdiv2 + Round(LGridStep) * i);

// Р'ертикальные линии

FPaintBuffer.Canvas.MoveTo(FWidthdiv2 - Round(LGridStep) * i, 0);

FPaintBuffer.Canvas.LineTo(FWidthdiv2 - Round(LGridStep) * i, FPaintBuffer.Height);

FPaintBuffer.Canvas.MoveTo(FWidthdiv2 + Round(LGridStep) * i, 0);

FPaintBuffer.Canvas.LineTo(FWidthdiv2 + Round(LGridStep) * i, FPaintBuffer.Height);

end;

end;

for i := 1 to LGridCount do

begin

FPaintBuffer.Canvas.TextOut(FWidthdiv2 - Round(LGridStep) * i, FHeightdiv2, IntToStr(Round(- i * LScaleFactor)));

FPaintBuffer.Canvas.TextOut(FWidthdiv2 + Round(LGridStep) * i, FHeightdiv2, IntToStr(Round(i * LScaleFactor)));

FPaintBuffer.Canvas.TextOut(FWidthdiv2 + 5, FHeightdiv2 - Round(LGridStep) * i, IntToStr(Round(i * LScaleFactor)));

FPaintBuffer.Canvas.TextOut(FWidthdiv2 + 5, FHeightdiv2 + Round(LGridStep) * i, IntToStr(Round(- i * LScaleFactor)));

end;

end;

procedure TMainForm.FormCreate(Sender: TObject);

begin

FPaintBuffer := TBitMap.Create;

FDrawTaskGraph := false;

FTaskInfinite := false;

FX1X2Positive := true;

end;

procedure TMainForm.WMErasebkgnd(var Msg: TWMErasebkgnd);

begin

end;

procedure TMainForm.miAboutClick(Sender: TObject);

var

LAboutForm: TAboutForm;

begin

LAboutForm := TAboutForm.Create(nil);

try

LAboutForm.ShowModal;

finally

LAboutForm.Free;

end;

end;

procedure TMainForm.miExitClick(Sender: TObject);

begin

Close;

end;

procedure TMainForm.PaintBoxPaint(Sender: TObject);

begin

FPaintBuffer.Canvas.Pen.Color := clWhite;

FPaintBuffer.Canvas.Brush.Color := clWhite;

FPaintBuffer.Canvas.Rectangle(0, 0, FPaintBuffer.Width, FPaintBuffer.Height);

DrawGraph;

PaintBox.Canvas.Draw(0, 0, FPaintBuffer);

end;

function TMainForm.PointBelongsRest(x, y: Double; ARestIndex: Integer; x1x2positive: boolean): boolean;

begin

if (x1x2positive) and ((x < 0) or (y < 0)) then

begin

Result := False;

Exit;

end;

Result := True;

case S[ARestIndex] of

0: begin // 1 - '=';

if not (((A[ARestIndex, 0] * x) + (A[ARestIndex, 1] * y)) = B[ARestIndex]) then

begin

Result := False;

end;

end;

1: begin // 1 - '>=';

if not (((A[ARestIndex, 0] * x) + (A[ARestIndex, 1] * y)) >= B[ARestIndex]) then

begin

Result := False;

end;

end;

2: begin // 2 - '<=';

if not (((A[ARestIndex, 0] * x) + (A[ARestIndex, 1] * y)) <= B[ARestIndex]) then

begin

Result := False;

end;

end;

end;

end;

function TMainForm.PointBelongsRestDomain(x, y: Double; x1x2positive: boolean): boolean;

var

i: Integer;

begin

if (x1x2positive) and ((x < 0) or (y < 0)) then

begin

Result := False;

Exit;

end;

Result := True;

for i := 0 to FM - 1 do

begin

case S[i] of

0: begin // 1 - '=';

if not (((A[i, 0] * x) + (A[i, 1] * y)) = B[i]) then

begin

Result := False;

end;

end;

1: begin // 1 - '>=';

if not (((A[i, 0] * x) + (A[i, 1] * y)) >= B[i]) then

begin

Result := False;

end;

end;

2: begin // 2 - '<=';

if not (((A[i, 0] * x) + (A[i, 1] * y)) <= B[i]) then

begin

Result := False;

end;

end;

end;

end;

end;

// Процедура решения задачи

procedure TMainForm.SolveTask;

var

x, y: Double;

i, j: Integer;

LLine1: TVector;

LLine2: TVector;

LMinMaxValue: Double;

procedure GetLine(ALine1: TVector; Andex: Integer);

begin

ALine1[0] := A[Andex, 0];

ALine1[1] := A[Andex, 1];

ALine1[2] := B[Andex];

end;

begin

TaskRichEdit.Clear;

WriteInRichEd(TaskRichEdit, 'Уравнения ограничений: ', clNavy, 12, [fsBold]);

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('');

for i := 0 to FM - 1 do

begin

if A[i, 0] <> 0 then

begin

WriteInRichEd(TaskRichEdit, CheckOne(A[i, 0]), clNavy, 12, []);

WriteInRichEd(TaskRichEdit, 'x1', clBlack, 12, []);

if A[i, 1] <> 0 then

begin

WriteInRichEd(TaskRichEdit, CheckMinusPlus(A[i, 1]), clNavy, 12, []);

WriteInRichEd(TaskRichEdit, 'x2', clBlack, 12, []);

end;

end else

begin

if A[i, 1] <> 0 then

begin

WriteInRichEd(TaskRichEdit, CheckOne(A[i, 1]), clNavy, 12, []);

WriteInRichEd(TaskRichEdit, 'x2', clBlack, 12, []);

end;

end;

WriteInRichEd(TaskRichEdit, GetSignStr(i), clNavy, 12, []);

WriteInRichEd(TaskRichEdit, FloatToStr(B[i]), clNavy, 12, []);

if (A[i, 0] <> 0) and (A[i, 1] <> 0) then

begin

WriteInRichEd(TaskRichEdit, ' (' + Chr(Ord('A') + i) + '1', clRed, 8, [fsBold]);

WriteInRichEd(TaskRichEdit, Chr(Ord('A') + i) + '2)', clRed, 8, [fsBold]);

end else

begin

if (A[i, 0] <> 0) then

begin

WriteInRichEd(TaskRichEdit, ' (' + Chr(Ord('A') + i) + '2)', clRed, 8, [fsBold]);

end;

if (A[i, 1] <> 0) then

begin

WriteInRichEd(TaskRichEdit, ' (' + Chr(Ord('A') + i) + '1)', clRed, 8, [fsBold]);

end;

end;

TaskRichEdit.Lines.Add('');

end;

TaskRichEdit.Lines.Add('');

WriteInRichEd(TaskRichEdit, 'x1>=', clBlack, 12, []);

WriteInRichEd(TaskRichEdit, '0', clNavy, 12, []);

WriteInRichEd(TaskRichEdit, '; x2>=', clBlack, 12, []);

WriteInRichEd(TaskRichEdit, '0', clNavy, 12, []);

WriteInRichEd(TaskRichEdit, ';', clBlack, 12, []);

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('');

WriteInRichEd(TaskRichEdit, 'Целевая функция: ', clNavy, 12, [fsBold]);

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('');

if C[0] <> 0 then

begin

WriteInRichEd(TaskRichEdit, CheckOne(C[0]), clNavy, 12, []);

WriteInRichEd(TaskRichEdit, 'x1', clBlack, 12, []);

if C[1] <> 0 then

begin

WriteInRichEd(TaskRichEdit, CheckMinusPlus(C[1]), clNavy, 12, []);

WriteInRichEd(TaskRichEdit, 'x2', clBlack, 12, []);

end;

end else

begin

if C[1] <> 0 then

begin

WriteInRichEd(TaskRichEdit, CheckOne(C[1]), clNavy, 12, []);

WriteInRichEd(TaskRichEdit, 'x2', clBlack, 12, []);

end;

end;

if FTaskType = 0 then

begin

WriteInRichEd(TaskRichEdit, '->Max', clBlack, 12, []);

end else

begin

WriteInRichEd(TaskRichEdit, '->Min', clBlack, 12, []);

end;

// Находим решение задачи

FTaskSolved := false;

LMinMaxValue := 1.7e308;

case FTaskType of

0: LMinMaxValue := -1.7e308;

1: LMinMaxValue := 1.7e308;

end;

SetLength(LLine1, 3);

SetLength(LLine2, 3);

for i := 0 to FM - 1 do

begin

for j := 0 to FM - 1 do

begin

if i <> j then

begin

if LineToPoint(A[i, 0], A[i, 1], B[i], A[j, 0], A[j, 1], B[j], x, y) then

begin

if PointBelongsRestDomain(x, y, FX1X2Positive) then

begin

// ShowMessage(FloatToStr(LMinMaxValue) + ' : ' + FloatToStr(x * C[0] + y * C[1]));

if ((LMinMaxValue < (x * C[0] + y * C[1])) and (FTaskType = 0)) or

((LMinMaxValue > (x * C[0] + y * C[1])) and (FTaskType = 1)) then

begin

sx := x;

sy := y;

FTaskSolved := true;

LMinMaxValue := x * C[0] + y * C[1];

GetLine(LLine1, i);

GetLine(LLine2, j);

end;

end;

end;

end;

end;

for j := 0 to FM - 1 do

begin

x := 0;

if A[j, 1] <> 0 then

begin

y := B[j] / CheckForNil(A[j, 1]);

if PointBelongsRestDomain(x, y, FX1X2Positive) then

begin

if ((LMinMaxValue < (x * C[0] + y * C[1])) and (FTaskType = 0)) or

((LMinMaxValue > (x * C[0] + y * C[1])) and (FTaskType = 1)) then

begin

sx := x;

sy := y;

FTaskSolved := true;

LMinMaxValue := x * C[0] + y * C[1];

GetLine(LLine1, j);

LLine2[0] := 1;

LLine2[1] := 0;

LLine2[2] := 0;

end;

end;

end;

x := B[j] / CheckForNil(A[j, 0]);

y := 0;

if A[j, 0] <> 0 then

begin

if PointBelongsRestDomain(x, y, FX1X2Positive) then

begin

if ((LMinMaxValue < (x * C[0] + y * C[1])) and (FTaskType = 0)) or

((LMinMaxValue > (x * C[0] + y * C[1])) and (FTaskType = 1)) then

begin

sx := x;

sy := y;

FTaskSolved := true;

LMinMaxValue := x * C[0] + y * C[1];

GetLine(LLine1, j);

LLine2[0] := 0;

LLine2[1] := 1;

LLine2[2] := 0;

end;

end;

end;

end;

end;

x := 0;

y := 0;

if PointBelongsRestDomain(x, y, FX1X2Positive) then

begin

if ((LMinMaxValue < (x * C[0] + y * C[1])) and (FTaskType = 0)) or

((LMinMaxValue > (x * C[0] + y * C[1])) and (FTaskType = 1)) then

begin

sx := x;

sy := y;

FTaskSolved := true;

LMinMaxValue := x * C[0] + y * C[1];

LLine1[0] := 1;

LLine1[1] := 0;

LLine1[2] := 0;

LLine2[0] := 0;

LLine2[1] := 1;

LLine2[2] := 0;

end;

end;

FTaskInfinite := TestForInfinite(LLine1, LLine2, LMinMaxValue);

Finalize(LLine2);

Finalize(LLine1);

if (C[0] = 0) and (C[1] = 0) then

begin

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('-------------------------');

WriteInRichEd(TaskRichEdit, 'Целевая функция не задана!', clMaroon, 12, [fsBold]);

end else

begin

if FTaskSolved then

begin

if FTaskInfinite then

begin

FTaskSolved := false;

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('-------------------------');

WriteInRichEd(TaskRichEdit, .', clMaroon, 12, [fsBold]);

end else

begin

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('-------------------------');

WriteInRichEd(TaskRichEdit', clNavy, 12, [fsBold]);

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('');

if FTaskType = 0 then

begin

WriteInRichEd(TaskRichEdit, 'Целевая функция достигает своего максимального значения в точке:', clNavy, 10, [fsBold]);

end else

begin

WriteInRichEd(TaskRichEdit, 'Целевая функция достигает своего минимального значения в точке:', clNavy, 10, [fsBold]);

end;

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('');

WriteInRichEd(TaskRichEdit, 'x1', clBlack, 12, []);

WriteInRichEd(TaskRichEdit, '=' + FloatToStr(sx), clNavy, 12, []);

TaskRichEdit.Lines.Add('');

WriteInRichEd(TaskRichEdit, 'x2', clBlack, 12, []);

WriteInRichEd(TaskRichEdit, '=' + FloatToStr(sy), clNavy, 12, []);

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('');

WriteInRichEd(TaskRichEdit, 'Р--начение целевой функции:', clNavy, 10, [fsBold]);

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('');

WriteInRichEd(TaskRichEdit, 'f(x1, x2) = ', clBlack, 12, []);

WriteInRichEd(TaskRichEdit, FloatToStr(LMinMaxValue), clNavy, 12, []);

end;

end else

begin

TaskRichEdit.Lines.Add('');

TaskRichEdit.Lines.Add('-------------------------');

WriteInRichEd(TaskRichEdit, 'Р--адача РЅРµ имеет допустимого решения! Рў.Рє. ее ограничения несовместны.', clMaroon, 12, [fsBold]);

end;

end;

end;

procedure TMainForm.TaskSpeedButtonClick(Sender: TObject);

begin

TheoryPanel.Visible := False;

PaintBox.Visible := True;

FPaintBuffer.Width := PaintBox.Width;

FPaintBuffer.Height := PaintBox.Height;

FWidthdiv2 := FPaintBuffer.Width div 2;

FHeightdiv2 := FPaintBuffer.Height div 2;

Repaint;

end;

procedure TMainForm.TaskTypeComboBoxChange(Sender: TObject);

begin

if FTaskType <> TaskTypeComboBox.ItemIndex then

begin

FTaskType := TaskTypeComboBox.ItemIndex;

SolveTask;

Repaint;

end;

end;

function TMainForm.TestForInfinite(ALine1, ALine2: TVector; AMinMaxValue: Double): Boolean;

var

x, y: Double;

i, j: Integer;

x1, y1: Double;

x2, y2: Double;

LAlpha1: Double;

LAlpha2: Double;

LLines: array[0..1] of TVector;

begin

Result := False;

LLines[0] := ALine1;

LLines[1] := ALine2;

for j := 0 to 1 do

begin

if (LLines[j][0] <> 0) or (LLines[j][1] <> 0) then

begin

// ALine1[0]*x + ALine1[1]*y = ALine1[2]

if LLines[j][1] <> 0 then

begin

x1 := - 1;

y1 := (LLines[j][2] - LLines[j][0] * x1) / LLines[j][1];

x2 := 1;

y2 := (LLines[j][2] - LLines[j][0] * x2) / LLines[j][1];

end else

begin

y1 := - 1;

x1 := (LLines[j][2] - LLines[j][1] * y1) / LLines[j][0];

y2 := 1;

x2 := (LLines[j][2] - LLines[j][1] * y2) / LLines[j][0];

end;

end;

LAlpha1 := 0;

LAlpha2 := 0;

for i := 0 to 1000 do

begin

x := x1 + (x2 - x1) * LAlpha1;

y := y1 + (y2 - y1) * LAlpha1;

LAlpha1 := LAlpha1 + 10;

if PointBelongsRestDomain(x, y, FX1X2Positive) then

begin

if FTaskType = 0 then

begin

Result := (x * C[0] + y * C[1]) >= AMinMaxValue;

end else begin

Result := (x * C[0] + y * C[1]) <= AMinMaxValue;

end;

if Result then

begin

Exit;

end;

end;

x := x1 + (x2 - x1) * LAlpha2;

y := y1 + (y2 - y1) * LAlpha2;

LAlpha2 := LAlpha2 - 10;

if PointBelongsRestDomain(x, y, FX1X2Positive) then

begin

if FTaskType = 0 then

begin

Result := (x * C[0] + y * C[1]) >= AMinMaxValue;

end else begin

Result := (x * C[0] + y * C[1]) <= AMinMaxValue;

end;

if Result then

begin

Exit;

end;

end;

end;

end;

end;

procedure TMainForm.TheorySpeedButtonClick(Sender: TObject);

var

LTempDirPath: string;

LResourceStream: TResourceStream;

begin

PaintBox.Visible := False;

TheoryPanel.Visible := True;

LResourceStream := TResourceStream.Create(HInstance, 'THEORY', RT_RCDATA);

try

LTempDirPath := CheckForSlash(GetTempDirPath);

LResourceStream.SaveToFile(LTempDirPath + 'theory.mht');

TheoryWebBrowser.Navigate(LTempDirPath + 'theory.mht');


Подобные документы

  • Требования к функциям, выполняемым системой, к программно-аппаратному и техническому обеспечению, к надежности и хранению информации. Схема взаимодействия модулей. Структурная схема программы. Руководство пользователю и программисту, вероятные ошибки.

    курсовая работа [423,1 K], добавлен 24.03.2014

  • Структура взаимодействия входной и выходной информации. Требования к программно-аппаратному окружению, к эргономике и технической эстетике интерфейса пользователя. Эскиз и спецификация типовых объектов управления графического интерфейса, тестирование.

    курсовая работа [2,0 M], добавлен 16.02.2016

  • Проектирование программы для предприятия ООО "Чудо свечи" в среде программирования Borland Delphi. Произведение расчета системы методом аддитивной оптимизации. Требования к функциям, выполняемым системой, к программному и аппаратному обеспечению.

    курсовая работа [2,8 M], добавлен 27.02.2015

  • Особенности задач линейного программирования. Симплексный метод решения задач линейного программирования. Обоснование выбора языка, инструментария программирования, перечень идентификаторов и блок-схема алгоритма. Логическая схема работы программы.

    дипломная работа [2,4 M], добавлен 13.08.2011

  • Структура взаимодействия входной, выходной информации. Требования к программно-аппаратному окружению, эргономике. Эскиз, спецификация типовых объектов управления графического интерфейса. Руководство системного программиста, настройка и проверка программы.

    курсовая работа [2,6 M], добавлен 02.09.2013

  • Практические навыки моделирования задач линейного программирования и их решения графическим и симплекс-методом с использованием прикладной программы SIMC. Моделирование транспортных задач и их решение методом потенциалов с помощью программы TRAN2.

    контрольная работа [199,8 K], добавлен 15.06.2009

  • Сущность линейного программирования. Математическая формулировка задачи ЛП и алгоритм ее решения с помощью симплекс-метода. Разработка программы для планирования производства с целью обеспечения максимальной прибыли: блок-схема, листинг, результаты.

    курсовая работа [88,9 K], добавлен 11.02.2011

  • Требования к функциям и задачам, выполняемым системой "Подбор кредита ОАО "Россельхозбанк". Проектирование архитектуры программного продукта. Структурная схема программного продукта. Описание компонент программного обеспечения. План менеджмента проекта.

    курсовая работа [684,0 K], добавлен 03.05.2015

  • Постановка задачи нелинейного программирования. Определение стационарных точек и их типа. Построение линий уровней, трехмерного графика целевой функции и ограничения. Графическое и аналитическое решение задачи. Руководство пользователя и схема алгоритма.

    курсовая работа [2,5 M], добавлен 17.12.2012

  • Требования к разрабатываемой программе и к выполняемым ею функциям. Алгоритмы взаимодействия с реестром, поиска, открытия, чтения и удаления ключа. Запросы к исходным кодам и языкам программирования. Проведение экономических расчетов и охрана труда.

    дипломная работа [6,5 M], добавлен 10.10.2011

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.