Анализ методов определения минимального, максимального значения функции при наличии ограничений

Федеральное агентство по образованию

Московский государственный открытый университет

Чебоксарский политехнический институт















Курсовой проект

по дисциплине: "Оптимальные системы автоматического управления"

на тему: "Анализ методов определения минимального, максимального значения функции при наличии ограничений"







Выполнил:

студент 5 курса,

ФУИТС, гр. И-52/06,

Терсенидис М. Г.

Проверила:

Изосимова Т. А.









Чебоксары – 2010


Задание



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



,



где a = 1, b = 0.5, c = 1, d = 0, e = 1, f = 0.333.

Дана начальная точка поиска A0(x0, y0), где x0 = 0.5, y0 = 2.5.

Найти безусловный экстремум функции f(x,y):

методом наискорейшего спуска;

методом сопряженных направлений.

Точность вычислений:







Найти условный экстремум этой же функции f(x,y) методом симплексных процедур при наличии ограничений:



1.5x + у – 3.75 ≥ 0;

0.5х + у - 3.75 ≤ 0;

x - у - 2 ≤ 0.



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



, где k = 4, T1 = 10, T2 = 5.

	
разработать модель для данного типа ОСАУ;

провести исследование ОСАУ с применением программного продукта "20-sim Pro 2.3";

снять переходные и импульсные характеристики.




Содержание



	Введение

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

	2. Нахождение экстремума функции без ограничения

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

	4. Нахождение экстремума функции при наличии ограничений

	5. Синтез оптимальной по быстродействию системы с помощью принципа максимума Понтрягина

	Заключение

	Список использованной литературы

	Приложение

функция переменная экстремум максимум


Введение



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

В настоящее время для решения оптимальных задач применяют в основном следующие методы:

методы исследования функций классического анализа;

методы, основанные на использовании неопределенных множителей Лагранжа;

вариационное исчисление;

динамическое программирование;

принцип максимума;

линейное программирование;

нелинейное программирование.

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

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

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

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




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



В данном разделе будет рассматриваться задача безусловной оптимизации, т.е. данная задача характеризуется тем, что минимум функции f: Rm  R ищется на всем пространстве: f(x)  min, x  Rm.

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

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

градиентные методы, в которых используются точные значения первых производных f (x);

методы второго порядка, в которых наряду с первыми производными используются также вторые производные функции f (x).

Методы прямого поиска

		Здесь предполагается, что f(x) непрерывна и унимодальная. Если рассматриваемые методы применяются для анализа мультимодальных функций, то приходится ограничиваться идентификацией локальных минимумов. К особенностям этих методов можно отнести:

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

не требуют явного выражения целевой функции в аналитическом виде;

может требовать более значительных затрат времени по сравнению с методами, основанными на производных.

Метод поиска по симплексу

Процедура симплексного метода базируется на регулярном симплексе. Регулярный симплекс в N-мерном пространстве представляет собой многогранник, образованный N+1 равностоящими друг от друга точками - вершинами. Так в задаче с двумя переменными симплексом является равносторонний треугольник, с тремя - тетраэдр.

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

Преимущества метода:

сравнительная простота логической структуры метода и, соответственно, программы для ЭВМ;

используется сравнительно небольшое число заранее установленных параметров;

невысокий уровень требований к ЭВМ;

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

Недостатки метода:

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

алгоритм работает достаточно медленно, т.к. полученная на предыдущих итерациях информация не используется для ускорения поиска;

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

Градиентные методы

Важность прямых методов неоспорима, т.к. в практических задачах информация о значениях целевой функции является единственно надежной информацией, которой располагает инженер. Однако, если существует и непрерывны целевая функция f(x) и ее первые производные, a также они могут быть записаны в аналитическом виде (или с достаточно высокой точностью вычислены при помощи численных методов), то целесообразно использовать методы, основанные на использовании градиента целевой функции.

Градиент функции F(x) – это вектор, составляющие которого равны частным производным функции F(x) по соответствующим переменным, т.е.







Направление вектора градиента совпадает с направлением наискорейшего возрастания функции. Вектор противоположного знака -F(x) называется антиградиентом, его направление совпадает с направлением наискорейшего убывания функции.

Матрица вторых производных 2F(x) – это симметричная квадратная матрица порядка n вторых частных производных функции F(x). Эту матрицу называют матрицей Гессе и обозначают H(x) 2F(x). Ее элемент, расположенный на пересечении i-й строки и j-го столбца, равен:







Пусть хТ=[x1, x2,…, xn] – вектор переменных. Для наличия в точке x* локального минимума (максимума) необходимо, чтобы выполнялось равенство F(x*) 0 и матрица Гессе H(x*) 2F(x*) была положительно (отрицательно) полуопределенной, т.е. xTHx 0 ( xTHx 0).

Достаточным условием существования минимума (максимума) в точке x* является положительная (отрицательная) определённость матрицы Гессе в этой точке, т.е. xTHx >0 ( xTHx<0).

Все методы основаны на итерационной процедуре, реализуемой в соответствии с формулой xk+1 = xk + k s(xk), где

xk - текущее приближение к решению x*;

		k - параметр, характеризующий длину шага;

		s(xk) - направление поиска в N - мерном пространстве управляемых переменных xi, i = 1, 2,..., N.

Способ определения k и s(xk) на каждой итерации связан с особенностями применяемого метода. Обычно выбор k осуществляется путем решения задачи минимизации f(x) в направлении s(xk). Поэтому при реализации градиентных методов необходимо использовать эффективные алгоритмы одномерной минимизации.

Простейший градиентный метод

В основе метода лежит следующая итерационная модификация формулы



xk+1 = xk +  k s(xk),

xk+1 = xk -  k  f(xk), где



 - заданный положительный коэффициент;

 f(xk) - градиент целевой функции первого порядка.

Недостатки:

необходимость выбора подходящего значения ;

медленная сходимость к точке минимума ввиду малости f(xk) в окрестности этой точки.

Метод наискорейшего спуска

Свободен от первого недостатка простейшего градиентного метода, т.к. k вычисляется путем решения задачи минимизации  f(xk) вдоль направления  f(xk) с помощью одного из методов одномерной оптимизации xk+1 = xk -  k  f(xk).

Данный метод иногда называют методом Коши.

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

Метод сопряженных направлений

Общая задача нелинейного программирования без ограничений сводится к следующему: минимизировать f(x), x En, где f(x) является целевой функцией. При решении этой задачи мы используем методы минимизации, которые приводят к стационарной точке f(x), определяемой уравнением f(x*)=0. Метод сопряженных направлений относится к методам минимизации без ограничений, использующим производные. Задача: минимизировать f(x), x En, где f(x) является целевой функцией n независимых переменных. Важной особенностью является быстрая сходимость за счет того, что при выборе направления используется матрица Гессе, которая описывает область топологии поверхности отклика. В частности, если целевая функция квадратичная, то можно получить точку минимума не более чем за количество шагов, равное размерности задачи.

Для применения метода на практике его необходимо дополнить процедурами проверки сходимости и линейной независимости системы направлений. Методы второго порядка

Метод Ньютона

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



xk+1 = xk - 2 f(xk-1)  f(xk).



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



xk+1 = xk - k 2 f(xk-1)  f(xk), где



k - параметр, выбираемый таким образом, чтобы f(xk+1)  min.



2. Нахождение экстремума функции без ограничения



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

Определение exst. Функция f(x) заданная на интервале (а, в) имеет в точке x* max(min), если эту точку можно окружить таким интервалом (x*-ε, x*+ε), содержащимся в интервале (а, в), что для всех ее точек х, принадлежащих интервалу (x*-ε, x*+ε), выполняется неравенство:



f(x) ≤ f(x*) → для max

f(x) ≥ f(x*) → для min


Это определение не накладывает никаких ограничений на класс функций f(x), что, конечно, очень ценно.

Если ограничится для функций f(x), достаточно распространенным, но все же более узким классом гладких функций (под гладкими функциями мы будем понимать такие функции, которые непрерывны вместе со своими производными на интервале изменения аргумента), то можно воспользоваться теоремой Ферма, которая дает необходимые условия существования exst.

Теорема Ферма. Пусть функция f(x) определена в некотором интервале (а, в) и в точке "с" этого интервала принимает наибольшее (наименьшее) значение. Если существует в этой точке двухсторонняя конечная производная , то существования необходимо exst .

Примечание. Двухсторонняя производная характеризуется свойством  иными словами, речь идет о том, что в точке "с" производная в пределе одна и та же при подходе к точке "с" слева и справа, т.е. f(x) – гладкая функция.

*В случае  имеет место min, а при  → max. Наконец, если при х=х0 , то использование 2-ой производной не помогает и нужно воспользоваться, например, определением exst.

При решении задачи I необходимые условия exst (т.е. теорема Ферма) используется очень часто.

Если уравнение exst  имеет вещественные корни, то точки, соответствующие этим корням, являются подозрительными на exst (но не обязательно самыми экстремумами, ибо имеем дело с необходимыми, а не с необходимыми и достаточными условиями). Так, например, в точке перегиба Хп имеет место , однако, как известно, это не экстремум.








Заметим ещё, что:

из необходимых условий нельзя сказать, какой вид экстремума найден max или min: для определения этого нужны дополнительные исследования;

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

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

Метод наискорейшего спуска

Метод наискорейшего спуска является градиентным методом с переменным шагом. На каждой итерации величина шага k выбирается из условия минимума функции f(x) в направлении спуска, т.е.



.



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



 ()=f (x(k)-f (x(k)))



Воспользуемся для этого методом золотого сечения.

Алгоритм метода наискорейшего спуска состоит в следующем.

Задаются координаты начальной точки x(0).

В точке x(k), k = 0, 1, 2, …, вычисляется значение градиентаf (x(k)).

Определяется величина шага k путем одномерной минимизации по  функции



 ()=f (x(k)-f (x(k))).



Определяются координаты точки x(k):



xi(k+1)= xi(k)-kfi (x(k)), i=1, …, n.



Проверяется условие останова итерационного процесса:



||f (x(k+1))|| .



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








Рис. 2.1. Блок схема метода наискорейшего спуска.



Реализация метода в программе:

Метод наискорейшего спуска.




Рис. 2.2. Реализация метода наискорейшего спуска.



Вывод: В нашем случае метод сошёлся за 7 итераций. Точка А7 (0,6641; -1,3313) является точкой экстремума. Метод сопряженных направлений. Для квадратичных функций можно создать градиентный метод, при котором время сходимости будет конечным и равно числу переменных n.

Назовем некоторое направление  и  сопряженными по отношению к некоторой положительно определенной матрице Гесса H, если выполняется:



 Если ,



Тогда  т.е. . Значит при единичной H, сопряженное направление означает их перпендикуляр. В общем же случае H неединичная. В общем случае сопряженность - это применение матрицы Гесса к вектору  - означает поворот этого вектора на некоторый угол  и его растяжение или сжатие.







А теперь вектору  вектор  ортогонален т. е. сопряженность это не ортогональность векторов  и , а ортогональность повернутого вектора  т.е.  и .

			

			

			

			


Рис. 2.3. Блок-схема метода сопряженных направлений.



Реализация метода в программе: Метод сопряженных направлений.





Рис. 2.4. Реализация метода сопряженных направлений.




Рис. 2.5. График метода сопряженных направлений.



Вывод: Точка А3 (0,6666; -1,3333), была найдена за 3 итерации и является точкой экстремума.



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



		Напомним, что общая задача условной оптимизации выглядит так

		f(x)  min, x 

		где  — собственное подмножество Rm. Подкласс задач с ограничениями типа равенств выделяется тем, что множество  задается ограничениями вида

		

		fi(x) = 0, где fi: Rm R (i = 1, …, k).

		

		
Таким образом, = {x  Rm: fi(x) = 0, i = 1, …, k}.

		Нам будет удобно писать у функции f индекс "0". Таким образом, задача оптимизации с ограничениями типа равенств записывается в виде

		

		f0(x)  min, (3.1)

		fi(x) = 0, i = 1, …, k. (3.2)

		

		Если обозначить теперь через f функцию на Rm со значениями в Rk, координатная запись которой имеет вид f(x) = (f1(x), …, fk(x)), то (3.1)–(3.2) можно также записать в виде

		

		f0(x)  min, f(x) = .

		

		Геометрически задача с ограничениями типа равенств — это задача о поиске наинизшей точки графика функции f0 над многообразием  (см. рис. 3.1).

		

		

		Рис. 3.1.

		
Точки, удовлетворяющие всем ограничениям (т. е. точки множества ), обычно называют допустимыми. Допустимая точка x* называется условным минимумом функции f0 при ограничениях fi(x) = 0, i = 1, ..., k (или решением задачи (3.1)–(3.2)), если при всех допустимых точках x f0(x*)  f0(x). (3.3)

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

Правило множителей Лагранжа

		Описываемый ниже необходимый признак локального условного минимума был сформулирован Лагранжем. Определим F: Rm  Rk+1, положив F(x) = (f0(x), f1(x), ..., fk(x)). Заданная на Rm×Rk+1 скалярная функция Лагранжа M по определению принимает значения в R и задается равенством

		

		M(x, ) = (, F(x)) =  i fi(x) (x  Rm,  Rk+1).

		

		Координаты вектора , т. е. числа k называются множителями Лагранжа или двойственными переменными. Оказывается, имеет место следующая теорема, часто именуемая правилом множителей Лагранжа:

		Теорема. Пусть F  C1 и x* — локальный условный минимум функции f0 при ограничениях fi(x) = 0 (i = 1, ..., k). Тогда найдется ненулевой вектор * такой, что x* является стационарной точкой функции x M(x, *):

		

		Mx(x, *)|x=x*=*i f i(x*)= .

		

		Правило множителей Лагранжа доставляет необходимое условие локального условного минимума и поэтому позволяет искать точки, "подозрительные" на экстремум. В самом деле, для нахождения точки (x*, *)  Rm+k+1, т. е. для нахождения m + k + 1 неизвестных, мы имеем m + k уравнений

		

		f(x) = , Mx(x, )= .

		

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

		Регулярные точки

		Допустимая точка x задачи (3.1)–(3.2) называется регулярной, если векторы {f i(x)}ki=1линейно независимы. Оказывается, что если x* — регулярная точка минимума, то в векторе * можно считать *0 ненулевым, а поскольку множители Лагранжа определяются с точностью до множителя, можно считать, что *0 = 1. Чтобы сформулировать это утверждение более точно, введем следующие обозначения. Пусть   Rk, а функция Лагранжа в регулярном случае определяется равенством

		

		L(x, 

		

		Очевидно, L(x, 

		Теорема (правило множителей Лагранжа в регулярном случае)

		Пусть F  C1, а x* — регулярное локальное решение задачи (3.1)–(3.2). Тогда найдется ненулевой вектор *  Rk такой, что

		

		L

		

		
Одно достаточное условие локального минимума

		Говорят, что линейный оператор A положительно определен на подпространстве E, если (Ax, x) > 0 при всех x  E. Касательным подпространством к многообразию  в точке y называется множество Ty = {x  Rm: (f (y), x) = 0, i = 1, ..., k}. Касательной гиперплоскостью к многообразию  в точке y называется множество

		

		y = {x  Rm: fi(y) + (f (y), xy) = 0, i = 1, ..., k}.

		

		Теорема (достаточное условие минимума)

		Пусть F  C2, а x* — регулярная стационарная точка функции Лагранжа, т. е., в частности, L(x*, *) =  при некотором ненулевом *  Rk. Тогда, если Lxx(x*, *)положительно определен на Tx*, то точка x* является локальным решением задачи (3.1)–(3.2).

Методы решения задач с ограничениями типа равенств

		Мы будем рассматривать ниже только регулярный случай. Один из естественных подходов к решению задач типа (3.1)–(3.2) основывается на необходимом условии экстремума — правиле множителей Лагранжа. Если бы можно было утверждать, что решению x* задачи (3.1)–(3.2) соответствует экстремум (x*, *) функции Лагранжа L, то к функции L можно было бы применять разработанные методы решения безусловных задач. Однако, так утверждать нельзя. В самом деле, если в точке x ограничения не выполняются, то за счет выбора  функцию L (поскольку по  она линейна) можно сделать как сколь угодно большой положительной, так и сколь угодно большой отрицательной. Поэтому естественно искать решение x* как первые m координат стационарной точки функции Лагранжа, например, методом Ньютона, мы приходим к методу Ньютона решения задач с ограничениями типа равенств — это просто метод Ньютона решения уравнения L(x, ) =  (в регулярном случае):

		
L(xn, n) + L(xn, n)(xn+1  xn, 

		

		в "координатной" форме

		

		L

		

		

		Остается подставить в эти уравнения явные выражения производных функции Лагранжа (учитывая, в частности, что L(xn,n) = ):

		

		f 0(xn)+ [f (xn)]*n + (f 0(xn)+ nif i(xn)) (xn+1  xn) + [f (xn)]*(n+1  n) = ,

		f(xn) + f (xn)(xn+1  xn) = 

		

		и мы получаем m+k линейных уравнений для нахождения m+k неизвестных (xn+1, n+1).

		Описанный метод обладает всеми достоинствами и всеми недостатками метода Ньютона решения безусловных задач, в частности, он лишь локально сходится и требует большого объема вычислений. Поэтому попытаемся модифицировать градиентный метод, приспособив его к решению условной задачи (3.1)–(3.2). Поскольку, как сказано выше, точка (x*, *) - это седловая точка функции Лагранжа, то естественно пытаться с помощью градиентного метода минимизировать ее по x, одновременно максимизируя ее по :

		

		xn+1 = xn  

		

		или, что то же xn+1 = xn  (xn).

		Можно доказать, что этот метод (его обычно называют методом Эрроу — Гурвица) при естественных ограничениях на гладкость и при условии положительной определенности оператора Lxx(x*,*) локально линейно сходится.

		Описанные методы относятся к разряду двойственных методов, поскольку в итерационном процессе участвуют как прямые (x), так и двойственные () переменные.

		Можно строить также прямые методы решения условных задач. Например, реализовать идею о том, что следующее приближение градиентного метода. Приближение xn+1 ищется как минимум функции x  (f 0(xn),x  xn) + ||x  xn||2 на касательной гиперплоскости xn. Здесь "штрафной член" ||x  xn||2 позволяет "минимизировать" линейную функцию x  (f 0(xn),x  xn). Таким образом, мы приходим к прямому методу

		

		xn+1 = argmin [(f 0(xn),x  xn) + ||x  xn||2], (3.4)

		fi(xn) + (f i(xn),x  xn) = 0, i = 1, ..., k. (3.5)

		

		Ограничения (3.5) в этом методе — это, очевидно, линеаризации ограничений (3.2) в точке xn: минимум ищется на касательной гиперплоскости xn.

		Один из распространенных методов решения задач с ограничениями, с которым мы еще столкнемся — так называемый метод штрафов. Он позволяет сводить задачу с ограничениями к задаче без ограничений и суть его заключается в наказании за невыполнение ограничений. Именно, вместо минимизации функции f0 с ограничениями (3.2) минимизируется функция fs(x) = f0(x) + s||f(x)||2 без ограничений, в которой s — положительный параметр.

		Теперь рассмотрим постановку задач с ограничениями типа неравенств gj(x)  0, j = 1, ..., l (3.6).

		


		Рис. 3.2.

		

		Определяются допустимые точки, локальный и глобальный, строгий и нестрогий минимумы. Так же мы будем использовать обозначения f и g для функций из Rm в Rk и Rl, соответственно, определяемые координатами fi и gj. Поэтому задачу (3.1)- (3.3), (3.6) можно записывать в виде

		

		f(x) = , g(x) 

		

		(напомним, что неравенство g(x)  означает покоординатные неравенства).

		

		f0(x)  min, f(x) = , g(x) 

		

		Через J(x) будет обозначаться множество индексов так называемых активных ограничений: J(x) = {j  {1, ..., l}: gj(x) = 0} — это номера ограничений, которые в данной точке существенны.

		Теорема (обобщенное правило множителей Лагранжа)

		Пусть f0, f, g  C1, а x* — локальное решение задачи f0(x)  min, f(x) = , g(x)  Тогда найдутся такие *0  R,  Rk,  Rl, не равные одновременно нулю, такие, что *j  0 при j  J(x*) и

		

		*0 f 0(x*)+ *i f i(x*)+*j gj(x*) = . (3.7)

		

		Регулярный случай

		Так же, как и в случае ограничений-равенств, в случае общей задачи нелинейной оптимизации, необходимый признак, информативен только в случае, если  0. В этой ситуации можно разделить (3.7) на *0 и, следовательно, считать его равным единице. Это позволяет ввести функцию Лагранжа L: Rm×Rk×Rk  R (в регулярном случае) равенством

		

		(x,  = f0(x) + (, f(x)) + (, g(x)).

		

		Условие регулярности в случае общей задачи выглядит сложнее. Именно, допустимая точка x называется регулярной, если векторы f 1(x),..., f k(x) линейно независимы и для некоторого ненулевого вектора

		

		hRm (f i(x),h) = 0 при i = 1, ..., k и (gj(x),h) < 0 при j  J(x).

			

			Геометрически, эти условия означают, что, во-первых, вектор h является касательным к многообразию, выделяемому ограничениями-равенствами (т. е. ортогонален всем градиентам f i(x)), и, во-вторых, он образует с градиентами gj(x) активных ограничений (указывающими, очевидно, вовне множества ) тупой угол.

			


		Рис. 3.3.

		

Методы возможных направлений

		Эти методы основываются на следующем простом понятии. Вектор (направление) z в допустимой точке x назовем возможным для задачи (3.1), (3.3), если малое перемещение в этом направлении уменьшает значение функции f0 и не выводит из множества допустимых точек, т. е. если при достаточно малых s точка xs = x + sz допустима и f(xs) < f(x). Если теперь на каждом шаге сдвигаться в возможном направлении на достаточно малое расстояние, то мы очевидно получим релаксационную последовательность, которая во многих случаях будет сходиться к решению задачи. Методы этого типа называются методами возможных направлений.

Методы проекции градиента

		Проекцией Px точки x  Rm на множество  Rm называется любая ближайшая к x точка множества :

		

		||x  Px||  ||x  y|| при всех y 

		

		
В тех случаях, когда проекцию точки на множество допустимых точек задачи (3.1), (3.3) найти достаточно легко (например, когда  — линейное подпространство, полупространство, шар, Rm и т. д.) используют метод проекции градиента:

		

		xn+1 = P(xn  nf 0(xn))

		

		(см. рис. 3.4), являющийся прямым обобщением градиентного метода.

		

		

		Рис. 3.4.

		

		Можно доказать, например, что если функция f0  C1 сильно выпукла и f  удовлетворяет условию Липшица, а множество  замкнуто и ограничено, то метод проекции градиента сходится со скоростью геометрической прогрессии.

Методы линеаризации

		Суть этих методов, как следует из названия, состоит в линеаризации минимизируемой функции и ограничений в очередной точке xn строящейся релаксационной последовательности и объявлении следующим значением xn+1 решения получающейся линейной задачи, т. е. задачи

		
(f 0(xn),x  xn)  min, (3.8)

		gi(xn) + (gi(xn),x  xn)  0, i = 1, ..., l. (3.9)

		

		Чтобы эта (линейная) задача была разрешима либо добавляют штраф в минимизируемую функцию, заменяя (3.8), например, задачей

		

		(f 0(xn), x xn) + ||x  xn||2  min,

		

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

		

		xi  xni n  0, xi + xni n  0 (i = 1, ..., m).



Методы штрафов

		Основная идея здесь заключается в переходе от задачи (3.1), (3.3) к задаче безусловной оптимизации, в которой "наказывается" либо удаление от множества  допустимых точек (внешний штраф), либо приближение изнутри множества  к его границе (внутренний штраф). Различают методы внешних штрафов и внутренних штрафов. При методе внешних штрафов задачу решают тем или иным методом решения безусловных задач, увеличивая на каждом шаге штраф s. Как и в случае задач с ограничениями-равенствами, основным недостатком метода штрафов является рост числа обусловленности s. На несколько другой идее основываются так называемые методы внутренних штрафов или барьеров. Образно его можно описать так: у границы множества  возводятся барьеры, не позволяющие приближаться к его границе.

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

Симплекс - метод

Симплекс-метод – один из наиболее эффективных методов численного решения задач ЛП. Суть понятия "симплекс" заключается в следующем. Для тела в k-мерном пространстве симплексом называется множество, состоящее из k+1 вершин этого тела. Так, при k = 2, т.е. на плоскости, симплексом будут вершины треугольника; при k = 3 симплексом являются вершины четырехгранника, например тетраэдра, и т.д. Такое название методу дано по той причине, что в его основе лежит последовательный перебор вершин ОДЗП с целью определения координат той вершины, в которой функция цели имеет экстремальное значение.

Решение задачи с помощью симплекс-метода разбивается на два основных этапа. На первом этапе находят одно из решений, удовлетворяющее системе ограничений. Системы, в которых переменных больше, чем ограничений N > m, называются неопределенными. Они приводятся к определенным системам (N = m) путем приравнивания к нулю N-m каких-либо переменных.

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

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

В системе из m уравнений с N неизвестными общее число базисных решений при N > m определяется числом сочетаний








Базисное решение, в котором все xi ≥ 0, i = [1,m], называется допустимым базисным решением. Таким образом, первый этап завершается нахождением допустимого базисного решения, хотя бы и неудачного.

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

базисные переменные и функция цели выражаются через небазисные переменные;

по определенному правилу выбирается та из небазисных переменных, изменение значения которой способно улучшить значение F(x) , и она вводится в базис;

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

базисные переменные и функция цели выражаются через новые небазисные переменные, и повторяются операции 2 и 3.

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

		

4. Нахождение экстремума функции при наличии ограничений



Метод симплексных процедур

Симплексом в пространстве n-измерений называют выпуклый многогранник, имеющий n+1 вершин, не лежащих в подпространстве размерности, меньшей n.

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

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

		

		


		Рис. 4.1. Блок-схема метода симплексных процедур.



Реализация метода в программе:






		Рис. 4.2. Реализация метода симплексных процедур.



		

		Рис. 4.3. График метода симплексных процедур.



Вывод: Минимальное значение функция принимает в точке А2 (2.3, 0.3). F(2.3, 0.3) = 7,003.

		


5. Синтез оптимальной по быстродействию системы с помощью принципа максимума Понтрягина



Синтез системы

Критерий управления, как отмечалось ранее, в этом случае







Мера ошибки в критерии H =1, а верхний предел T неизвестен. Начальная Х(0) = Х0 и конечная Х(T) = ХT точки закреплены.

Запишем функцию Гамильтона и условия трансверсальности:





 (T) и  (0)-произвольны.



Согласно принципу максимума Понтрягина, стратегия управления состоит в минимизации функции Гамильтона относительно u. Минимум Г будет тогда, когда  min по и или  min по и

Отсюда



 (5.2)



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

По изложенной методике определим оптимальное управление , которое произвольное начальное состояние (х10, x20) переводит в начало координат за минимальное время Т.

Представим объект  (5.1) в виде уравнения состояния (нормальная форма)



	 (5.3)



В рассматриваемом примере матрица , вектор . Образуем матрицу .

Матрица G — невырожденная, поэтому система (3) будет нормальной. Характеристические числа матрицы A  = 0,  = -2, это числа вещественные, поэтому система (3) удовлетворяет условиям теоремы об n-интервалах. Оптимальное управление u*(t) является кусочно-постоянным и имеет не более двух интервалов постоянства.

Таким образом, управляющие последовательности в зависимости от начального состояния будут: {+ 1}, {-1},{+1,-1}, {-1, + 1}.

Обозначим u* = ∆=±1 и найдем общее решение системы при и* = ∆.



















Обозначим  – множество начальных состояний, которые переводятся в начало координат управляющей последовательностью и* = {+1}, – множество начальных состояний, которые переводятся в начало координат управляющей последовательностью и* = {-1}. Эти множества описываются уравнениями







Если принять  то множество  запишется в виде







Закон управления



 (5.4)



Линия  представляет собой линию переключения.

Введем функцию , характеризующую расстояние от текущего положения фазовой точки (x1,x2) до линии переключения:


 (5.5)



Когда фазовая точка окажется на линии переключения, то правая часть уравнения (5) будет равна нулю ( = 0) и управляющее устройство должно произвести переключение знака управления на противоположный. Пока фазовая точка находится над линией переключения,  > 0 и управление должно быть отрицательным и (t) = -U. Когда фазовая точка находится под линией переключения,  < 0 и управление должно быть положительным и (t) = +U. Таким образом, в зависимости от знака должен выбираться и знак управления:







Все изложенное позволяет записать алгоритм оптимального по быстродействию регулятора для объекта (1):







		=0, если , х2

		

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

		

		

		Рис. 5.1. Структурная схема системы


Моделирование объекта

		По алгоритму решения

		

		

		,

		

		полученному ранее, составим структурные схемы для построения переходной и импульсной характеристик системы, реализующие закон управления для объекта , где k = 1, T1 = 10, T2 = 8.

		

		

		Рис. 5.2. Структурная схема модели ОСАУ для переходной характеристики

		

		

		Рис. 5.3. Вводимые параметры

		


		Рис. 5.4. График переходной характеристики

		

		tp = 31.6 c.

		

		

		Рис. 5.5. Структурная схема модели ОСАУ для импульсной характеристики

		

		


		Рис. 5.6. Вводимые параметры

		

		

		Рис. 5.7. График импульсной характеристики

		

		tp = 19,6 c.

		


Заключение



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

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

		Метод "Симплексных процедур" является лучшим выбором, при нахождении экстремумов нелинейной функции, в условиях ограничений типа неравенств. Его достоинство – не сложность подсчетов и точность, подкреплённая теоремой Лагранжа. Минус – много вычислений.

		На языке программирования высшего уровня Delphi реализованы алгоритмы вышеназванных методов.

С помощью принципа максимума Понтрягина был выполнен синтез оптимальной по быстродействию системы для объекта , также была разработана модель ОСАУ для данного объекта. С применением программного продукта "20-sim Pro 2.3" было проведено исследование и сняты переходная характеристика (tp = 31.6 c) и импульсная характеристика (tp = 19,6 c). Метод показал прекрасные показатели регулирования.




Список использованной литературы



Акулич И. Л. Математическое программирование в примерах и задачах. – М: Высшая школа, 1986.

Болтянский В. Г. Математические методы оптимального управления. – М: Наука, 1969.

Иванов В. А., Фалдин Н. В. Теория оптимальных систем автоматического управления. – М: Наука, 1981.

Чураков Е. П. Оптимальные адаптивные системы. – М: Энергоатомиздат, 1987.

Пупков К.А., Егупов Н.Д., Методы классической и современной теории автоматического управления: Учебник в 5-и тт.; 2-е изд., - М.: Издательство МГТУ им. Н.Э. Баумана, 2004. - 742 с.

Гудвин Г. К., Гребе С. Ф., Сальгадо М. Э., Проектирование систем управления: Издательство Бином. Лаборатория знаний, 2004. 911 c.




Приложение



unit all_methods;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ExtCtrls, DB, IBDatabase, Grids, DBGrids, DBCtrls, Mask,

ADODB, ComCtrls;

type

Vector = array[1..3] of Double;

Matrix = array[1..3] of Vector;

Mass = array[1..10] of Double;

TFMain = class(TForm)

EX: TEdit;

EY: TEdit;

EZ: TEdit;

LX: TLabel;

LY: TLabel;

LZ: TLabel;

BGauss: TButton;

EK: TEdit;

LK: TLabel;

MIter: TListBox;

LFxy: TLabel;

Label2: TLabel;

BClear: TButton;

BSpusk: TButton;

Label11: TLabel;

RBMin: TRadioButton;

RBMax: TRadioButton;

Label13: TLabel;

Label14: TLabel;

EXb: TEdit;

EYb: TEdit;

EU: TEdit;

Label15: TLabel;

GBIn: TGroupBox;

GBOut: TGroupBox;

GBControl: TGroupBox;

BExit: TButton;

BSopr: TButton;

DBGMain: TDBGrid;

DSMain: TDataSource;

EA: TDBEdit;

DBNavigator1: TDBNavigator;

DataSetMain: TADODataSet;

Conn: TADOConnection;

EB: TDBEdit;

EC: TDBEdit;

ED: TDBEdit;

EE: TDBEdit;

EF: TDBEdit;

EX0: TDBEdit;

EY0: TDBEdit;

Im: TImage;

Label18: TLabel;

Label3: TLabel;

Label4: TLabel;

Label5: TLabel;

Label6: TLabel;

Label7: TLabel;

Label8: TLabel;

Label9: TLabel;

RBx: TRadioButton;

RBy: TRadioButton;

Label10: TLabel;

ESkor: TEdit;

Label19: TLabel;

BSimplex: TButton;

GBConstr: TGroupBox;

LC1: TLabel;

LC3: TLabel;

LC2: TLabel;

EVar: TDBEdit;

GridBox: TGroupBox;

GrapfBox: TGroupBox;

LC10: TLabel;

LC20: TLabel;

LC30: TLabel;

LC40: TLabel;

LC4: TLabel;

Q: TADOQuery;

SaveZnak: TButton;

BStop: TButton;

procedure BGaussClick(Sender: TObject);

procedure BSpuskClick(Sender: TObject);

procedure BExitClick(Sender: TObject);

procedure BSoprClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure EVarChange(Sender: TObject);

procedure BSimplexClick(Sender: TObject);

procedure LC10Click(Sender: TObject);

procedure LC20Click(Sender: TObject);

procedure LC30Click(Sender: TObject);

procedure LC40Click(Sender: TObject);

procedure GaussSystem(N:Integer);

procedure Zapoln();

procedure ZnakConstrain();

procedure SaveZnakClick(Sender: TObject);

procedure Clear();

procedure BClearClick(Sender: TObject);

procedure BStopClick(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

FMain: TFMain;

xr, yr: Word; // координаты центра окружности

dr: byte;

a, b, c, d, e, f:Double; //

Am : array[1..4,1..2] of Double;

Bm : array[1..4] of Double;

Fm : Mass;

Xm, Ym : array[1..10] of Double;

znak1, znak2, znak3, znak4, nomer:Integer;

_BoolStop:Boolean;

implementation

{$R *.dfm}

Function fz(x, y, a, b, c, d, e, f : Double) : Double;

begin

Result := a*x*x+2*b*x*y+c*y*y+2*d*x+2*e*y+f;

end;

//---------------------------------------------

Function xi(y, b, d, a : Double) : Double;

begin

Result := -(b*y+d)/a;

end;

//---------------------------------------------

Function yi(x, b, e, c : Double) : Double;

begin

Result := -(b*x+e)/c;

end;

//---------------------------------------------

Function dx(x, y, b, d, a : Double) : Double;

begin

Result := 2*a*x+2*b*y+2*d;

end;

//---------------------------------------------

Function dy(x, y, b, e, c : Double) : Double;

begin

Result := 2*b*x+2*c*y+2*e;

end;

procedure Delay(dwMilliseconds: Longint);

var

iStart, iStop: DWORD;

begin

iStart := GetTickCount;

repeat

iStop := GetTickCount;

Application.ProcessMessages;

until (iStop - iStart) >= dwMilliseconds;

end;

procedure Ris;

Var ImW, ImH, sm, sm2, k, sm3, sm4, step :Integer;

begin

with FMain do

try

ImW:=Im.Width;

ImH:=Im.Height;

Im.Canvas.Pen.Width:=1;

Im.Canvas.Pen.Color := clBlack;

Im.Canvas.MoveTo(10,Round(ImH/2));

Im.Canvas.LineTo(ImW-10,Round(ImH/2));

Im.Canvas.MoveTo(Round(ImW/2),10);

Im.Canvas.LineTo(Round(ImW/2),ImH-10);

step:=20;

// вправо

sm:=Round(ImW/2)+step;

sm2:=Round(ImH/2)-step;

sm3:=Round(ImW/2)-step;

sm4:=Round(ImH/2)+step;

for k := 1 to 15 do

begin

Im.Canvas.MoveTo(sm,Round(ImH/2)+5);

Im.Canvas.LineTo(sm,Round(ImH/2)-5);

sm:=sm+step;

// вверх

Im.Canvas.MoveTo(Round(ImW/2)+5,sm2);

Im.Canvas.LineTo(Round(ImW/2)-5,sm2);

sm2:=sm2-step;

// влево

Im.Canvas.MoveTo(sm3,Round(ImH/2)+5);

Im.Canvas.LineTo(sm3,Round(ImH/2)-5);

sm3:=sm3-step;

// Вниз

Im.Canvas.MoveTo(Round(ImW/2)+5,sm4);

Im.Canvas.LineTo(Round(ImW/2)-5,sm4);

sm4:=sm4+step;

end;

Im.Canvas.TextOut(Round(ImW/2)+18,Round(ImH/2)+7,'1');

Im.Canvas.TextOut(Round(ImW/2)-11,Round(ImH/2)-27,'1');

Im.Canvas.TextOut(Round(ImW)-12,Round(ImH/2)+7,'X');

Im.Canvas.TextOut(Round(ImW/2)-11,7,'Y');

except

ShowMessage('error');

end;

end;

procedure TFMain.Clear();

begin

with FMain do

begin

Im.Canvas.Brush.Color := ClWhite;

Im.Canvas.FillRect(Canvas.ClipRect);

Ris;

MIter.Clear;

EU.Text:='';

EX.Text:='';

EY.Text:='';

EZ.Text:='';

EK.Text:='';

EXb.Text:='';

EYb.Text:='';

end;

end;

//---------------------------------------------

procedure TFMain.BClearClick(Sender: TObject);

begin

Clear();

end;

procedure TFMain.BExitClick(Sender: TObject);

begin

Close();

end;

procedure TFMain.BGaussClick(Sender: TObject);

var k, i, ostatok:Integer;

x0, y0, z0, x, y, z, _bez:Double; //a, b, c, d, e, f,

begin

if (RBx.Checked = false) and (RBy.Checked = false) then RBx.Checked := true;

try

if Miter.Count > 0 then MIter.Clear;

EU.Enabled := false;

k:=0;

Zapoln();

_bez:=(b*d-e*a)/(a*c-b*b);

EYb.Text:=floattostr(_bez);

EXb.Text:=floattostr(-(b*_bez+d)/a);

//-------------------------------

x:=StrToFloat(EX0.Text);

y:=StrToFloat(EY0.Text);

//z:=fz(x,y,a,b,c,d,e,f);

if RBx.Checked then ostatok := 1

else ostatok := 0;

for i := 1 to 1000 do

Begin

k:=i-1;

//-------------------Вывод-----------------------------------

MIter.Items.Add('---------------------');

MIter.Items.Add('k='+inttostr(k)+' | '+

'x'+inttostr(k)+'='+floattostr(x)+' | '+

'y'+inttostr(k)+'='+floattostr(y)+' | '+

'F(x,y)='+floattostr(z));

x0:=x;

y0:=y;

z0:=fz(x0,y0,a,b,c,d,e,f);

//------------------------------------------------------------

if (i mod 2) = ostatok then

Begin

x:=x0; //xi(y0,b,d,e);

y:=-(b*x0+e)/c;//yi(x0,b,e,c);

End

else

Begin

x:=-(b*y0+d)/a; //xi(y0,b,d,e);

y:=y0; //yi(x0,b,e,c);

End;

z:=fz(x,y,a,b,c,d,e,f);

//------------------------------------------------------------

if ((abs(x-x0)<0.01)and (abs(y-y0)<0.01) and (abs(z-z0)<0.01)) then break;

End;

EX.Text:=floattostr(x);

EY.Text:=floattostr(y);

EZ.Text:=floattostr(z);

EK.Text:=inttostr(k+1);

except

ShowMessage('Не удалось найти экстремум, попробуйте другой метод.');

end;

end;

procedure TFMain.BSpuskClick(Sender: TObject);

var k, i:Integer;

x0, y0, z0, x, y, z, Fx, Fy, M, _bez:Double; // a, b, c, d, e, f,

H : array[1..2,1..2] of Double;

begin

if (RBMin.Checked = false) and (RBMax.Checked = false) then RBMin.Checked := true;

if Miter.Count > 0 then MIter.Clear;

EU.Enabled := true;

k:=0;

Zapoln();

//-------------------------------

_bez:=(b*d-e*a)/(a*c-b*b);

EYb.Text:=floattostr(_bez);

EXb.Text:=floattostr(-(b*_bez+d)/a);

//-------------------------------

MIter.Items.Add('---------------------');

x:=StrToFloat(EX0.Text);

y:=StrToFloat(EY0.Text);

z:=fz(x,y,a,b,c,d,e,f);

MIter.Items.Add('k='+inttostr(k)+' '+

'x'+inttostr(k)+'='+floattostr(x)+' '+

'y'+inttostr(k)+'='+floattostr(y)+' '+

'F(x,y)='+floattostr(z));

H[1,1]:=2*a;

H[1,2]:=2*b;

H[2,1]:=2*b;

H[2,2]:=2*c;

for i := 1 to 1000 do

Begin

k:=k+1;

MIter.Items.Add('---------------------');

x0:=x;

y0:=y;

z0:=fz(x0,y0,a,b,c,d,e,f);

Fx:=dx(x0, y0, b, d, a);

Fy:=dy(x0, y0, b, e, c);

M:=(Fx*Fx + Fy*Fy)/(Fx*(H[1,1]*Fx+H[1,2]*Fy) + Fy*(H[2,1]*Fx+H[2,2]*Fy));

if RBMin.Checked then

begin

x:=x0-M*Fx;

y:=y0-M*Fy;

end

else if RBMax.Checked then

Begin

x:=x0+M*Fx;

y:=y0+M*Fy;

End;

z:=fz(x,y,a,b,c,d,e,f);

MIter.Items.Add('k='+inttostr(k)+' | '+

'x'+inttostr(k)+'='+floattostr(x)+' | '+

'y'+inttostr(k)+'='+floattostr(y)+' | '+

'F(x,y)='+floattostr(z)+' | '+

'u'+inttostr(k-1)+'='+floattostr(M));

if ((abs(x-x0)<0.01)and (abs(y-y0)<0.01) and (abs(z-z0)<0.01)) then break;

End;

EX.Text:=floattostr(x);

EY.Text:=floattostr(y);

EZ.Text:=floattostr(z);

EK.Text:=inttostr(k);

EU.Text:=floattostr(M);

end;

procedure TFMain.BStopClick(Sender: TObject);

begin

_BoolStop:=true;

end;

Function Znak(chislo : Double; Stroka:String) : String;

begin

if (chislo > 0) then

if (chislo <> 1) then Result:='+'+FloatToStr(chislo)+Stroka

else Result:='+'+Stroka

else if (chislo < 0) then

if (chislo <> -1) then Result:=FloatToStr(chislo)+Stroka

else Result:='-'+Stroka

else Result:='';

end;

Function ZnakN(chislo : Double; Stroka:String) : String;

begin

if (chislo > 0) then

if chislo <> 1 then Result:=FloatToStr(chislo)+Stroka

else Result:=Stroka

else if (chislo < 0) then

if (chislo <> -1) then Result:=FloatToStr(chislo)+Stroka

else Result:='-'+Stroka

else Result:='';

end;

Function ZnakKon(chislo : Double) : String;

begin

if (chislo > 0) then Result:='+'+FloatToStr(chislo)

else if chislo = 0 then Result:=''

else Result:=FloatToStr(chislo);

end;

procedure TFMain.Zapoln();

begin

with FMain do

begin

a:=DBGMain.Fields[1].AsFloat;

b:=DBGMain.Fields[2].AsFloat;

c:=DBGMain.Fields[3].AsFloat;

d:=DBGMain.Fields[4].AsFloat;

e:=DBGMain.Fields[5].AsFloat;

f:=DBGMain.Fields[6].AsFloat;

Am[1,1]:=DBGMain.Fields[9].AsFloat;

Am[1,2]:=DBGMain.Fields[10].AsFloat;

Bm[1]:=DBGMain.Fields[11].AsFloat;

Am[2,1]:=DBGMain.Fields[12].AsFloat;

Am[2,2]:=DBGMain.Fields[13].AsFloat;

Bm[2]:=DBGMain.Fields[14].AsFloat;

Am[3,1]:=DBGMain.Fields[15].AsFloat;

Am[3,2]:=DBGMain.Fields[16].AsFloat;

Bm[3]:=DBGMain.Fields[17].AsFloat;

Am[4,1]:=DBGMain.Fields[18].AsFloat;

Am[4,2]:=DBGMain.Fields[19].AsFloat;

Bm[4]:=DBGMain.Fields[20].AsFloat;

end;

end;

procedure TFMain.ZnakConstrain();

begin

with FMain do

begin

nomer:=StrToInt(EVar.Text);

Q.Close;

Q.SQL.Text:='select znak1, znak2, znak3, znak4 from Znaki where № = '+IntToStr(nomer);

Q.Open;

znak1:=Q.Fields.Fields[0].AsInteger;

znak2:=Q.Fields.Fields[1].AsInteger;

znak3:=Q.Fields.Fields[2].AsInteger;

znak4:=Q.Fields.Fields[3].AsInteger;

if znak1 = 0 then LC10.Caption:=Chr(8804)+' 0' // Chr(8805)

else LC10.Caption:=Chr(8805)+' 0';

if znak2 = 0 then LC20.Caption:=Chr(8804)+' 0'

else LC20.Caption:=Chr(8805)+' 0';

if znak3 = 0 then LC30.Caption:=Chr(8804)+' 0'

else LC30.Caption:=Chr(8805)+' 0';

if znak4 = 0 then LC40.Caption:=Chr(8804)+' 0'

else LC40.Caption:=Chr(8805)+' 0';

end;

end;

procedure TFMain.EVarChange(Sender: TObject);

begin

with FMain do

begin

Zapoln();

//-----------------------------------------------------------------------------------------------------//

with LFxy do

begin

Caption:='F(x,y)=';

Caption:=Caption+ZnakN(a,'x'+Chr(178));

Caption:=Caption+Znak(2*b,'xy');

Caption:=Caption+Znak(c,'y'+Chr(178));

Caption:=Caption+Znak(2*d,'x');

Caption:=Caption+Znak(2*e,'y');

Caption:=Caption+ZnakKon(f);

end;

//-----------------------------------------------------------------------------------------------------//

LC1.Caption:=ZnakN(Am[1,1],'x')+Znak(Am[1,2],'y')+ZnakKon(Bm[1]);

LC2.Caption:=ZnakN(Am[2,1],'x')+Znak(Am[2,2],'y')+ZnakKon(Bm[2]);

LC3.Caption:=ZnakN(Am[3,1],'x')+Znak(Am[3,2],'y')+ZnakKon(Bm[3]);

LC4.Caption:=ZnakN(Am[4,1],'x')+Znak(Am[4,2],'y')+ZnakKon(Bm[4]);

ZnakConstrain();

end;

end;

procedure TFMain.FormCreate(Sender: TObject);

var FileName, ConStr:String;

begin

FileName:='variants.mdb';//EFileName.Text; //

try

Conn.Connected:= false;

Conn.ConnectionString :=

'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source='+getCurrentDir+'\'+FileName+';'+

'Mode=Share Deny None;Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";'+

'Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;'+

'Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;'+

'Jet OLEDB:Encrypt Database=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False';

Conn.Connected:= true;

Conn.Open;

DBGMain.DataSource:=DSMain;

DataSetMain.Active:= false;

DataSetMain.CommandText :='select * from Варианты order by №';

DataSetMain.Active:= true;

DataSetMain.Open;

except

ShowMessage('Не удалось подключиться к базе вариантов. Вложите базу "variants.mdb" с вариантами в папку с программой.');

end;

//--------------------------------------------------------------------

ZnakConstrain();

//--------------------------------------------------------------------

Ris;

end;

Function Znak0(str : String) : String;

begin

if str = Chr(8804)+' 0' then Result:= Chr(8805)+' 0'

else Result:= Chr(8804)+' 0';

end;

Function ZnakUpdate(str : String) : Integer;

begin

if str = Chr(8804)+' 0' then Result:= 0

else Result:= 1;

end;

procedure TFMain.LC10Click(Sender: TObject);

begin

LC10.Caption:=Znak0(LC10.Caption);

end;

procedure TFMain.LC20Click(Sender: TObject);

begin

LC20.Caption:=Znak0(LC20.Caption);

end;

procedure TFMain.LC30Click(Sender: TObject);

begin

LC30.Caption:=Znak0(LC30.Caption);

end;

procedure TFMain.LC40Click(Sender: TObject);

begin

LC40.Caption:=Znak0(LC40.Caption);

end;

procedure TFMain.SaveZnakClick(Sender: TObject);

Var zi:Integer;

begin

with FMain do

try

nomer:=StrToInt(EVar.Text);

znak1:=ZnakUpdate(LC10.Caption);

znak2:=ZnakUpdate(LC20.Caption);

znak3:=ZnakUpdate(LC30.Caption);

znak4:=ZnakUpdate(LC40.Caption);

Q.Close;

Q.SQL.Text:='update Znaki set znak1='+IntToStr(znak1)

+', znak2='+IntToStr(znak2)

+', znak3='+IntToStr(znak3)

+', znak4='+IntToStr(znak4)

+' where №='+IntToStr(nomer);

Q.ExecSQL;

ShowMessage('Знаки успешно сохранены.');

except

ShowMessage('Не сохранить записать знаки.');

end;

end;

function RoundEx(chislo: double): double;

begin

RoundEx := (Round(chislo*1000))/1000;

end;

Function ZnakConst(str1, str2, str3 : String; X, Y :Double) : Integer;

Var zn1, zn2, zn3:Integer;

begin

zn1:=0; zn2:=0; zn3:=0;

if ((str1 = Chr(8804)+' 0') and (RoundEx(Am[1,1]*X+Am[1,2]*Y+Bm[1]) <= 0)) or

((str1 = Chr(8805)+' 0') and (RoundEx(Am[1,1]*X+Am[1,2]*Y+Bm[1]) >= 0)) then zn1:=1;

if ((str2 = Chr(8804)+' 0') and (RoundEx(Am[2,1]*X+Am[2,2]*Y+Bm[2]) <= 0)) or

((str2 = Chr(8805)+' 0') and (RoundEx(Am[2,1]*X+Am[2,2]*Y+Bm[2]) >= 0)) then zn2:=1;

if ((str3 = Chr(8804)+' 0') and (RoundEx(Am[3,1]*X+Am[3,2]*Y+Bm[3]) <= 0)) or

((str3 = Chr(8805)+' 0') and (RoundEx(Am[3,1]*X+Am[3,2]*Y+Bm[3]) >= 0)) then zn3:=1;

Result:=zn1+zn2+zn3;

end;

function FindMin(a:Mass):Double;

var

i,temp:integer;

begin

temp:=1;

for i := 1 to 10 do

if (a[i]<a[temp]) and (a[i]<>0) then

temp:=i;

Result:=a[temp]

end;

procedure TFMain.GaussSystem(N:Integer);

var g: Matrix;

bg, xv: Vector;

h: Double;

i,j,k,ns,gi, gN, Fn, ImW, ImH, ms:integer;

str:String;

begin

ms:=StrToInt(ESkor.Text);

ImW:=Im.Width;

ImH:=Im.Height;

//Ввод данных

//Размерность системы

ns := 3;

Zapoln();

MIter.Items.Add(' ');

MIter.Items.Add('------------------------------------ м. Множителей лагранжа: ------------------------------------');

if N=3 then begin gN:=3;Fn:=3; end

else gN:=4;Fn:=6;

for gi := 1 to gN do

begin

if _BoolStop = true then break;

//Коэффициенты

g[1,1]:= 2*a;

g[1,2]:= 2*b;

g[1,3]:= Am[gi,1];

g[2,1]:= 2*b;

g[2,2]:= 2*c;

g[2,3]:= Am[gi,2];

g[3,1]:= Am[gi,1];

g[3,2]:= Am[gi,2];

g[3,3]:= 0;

//Правая часть уравнения

bg[1]:= -2*d;

bg[2]:= -2*e;

bg[3]:= -Bm[gi];

//Прямой ход - исключение переменных

for i:=1 to ns-1 do

for j:=i+1 to ns do

begin

g[j,i]:=-g[j,i]/g[i,i];

for k:=i+1 to ns do

g[j,k]:=g[j,k]+g[j,i]*g[i,k];

bg[j]:=bg[j]+g[j,i]*bg[i];

end;

xv[ns]:=bg[ns]/g[ns,ns];

//Обратный ход - нахождение корней

for i:=ns-1 downto 1 do

begin

h:=bg[i];

for j:=i+1 to ns do h:=h-xv[j]*g[i,j];

xv[i]:=h/g[i,i];

end;

Xm[Fn+gi]:= xv[1];

Ym[Fn+gi]:= xv[2];

//-------------Рисование точек-----------------------------//

xr:=Round(ImW/2)+Round(Xm[Fn+gi]*20);;

yr:=Round(ImH/2)-Round(Ym[Fn+gi]*20);

Im.Canvas.Pen.Width:=2;

FMain.Im.Canvas.Pen.Color := clBlue;

FMain.Im.Canvas.Ellipse(xr-3, yr-3, xr + 3, yr + 3);

Im.Canvas.TextOut(xr+10,yr-10,'L'+inttostr(gi));

Delay(ms);

//Вывод результата

if ZnakConst(LC10.Caption, LC20.Caption, LC30.Caption, xv[1], xv[2]) = 3 then

begin

str:=' - Входит в область определения';

Fm[Fn+gi]:=fz(xv[1],xv[2],a,b,c,d,e,f);

end

else

begin

str:=' - Не входит в область определения';

Fm[Fn+gi]:=9999;

end;

MIter.Items.Add('x'+IntToStr(gi)+ '='+FloatToStr(xv[1])+' | y'+IntToStr(gi)+'='+FloatToStr(xv[2])+' | F(x,y)='+FloatToStr(fz(xv[1],xv[2],a,b,c,d,e,f)) + str);

end;

end;

procedure TFMain.BSimplexClick(Sender: TObject);

Var si, ssi, N, ImW, ImH, ms, yris, xris, NL:Integer; X, Y : array[1..10] of Double;

xg, yg, kg, bg, Xp, Yp:Double;

begin

_BoolStop:=False;

Clear();

ms:=StrToInt(ESkor.Text);

ImW:=Im.Width;

ImH:=Im.Height;

Zapoln();

if (LC4.Caption = '0') or (LC4.Caption = '') then

try

Begin

N:=3;

NL:=3;

for si := 2 to N do

begin

Ym[si-1]:=(Am[si,1]*Bm[1]-Am[1,1]*Bm[si])/(Am[si,2]*Am[1,1]-Am[si,1]*Am[1,2]);

Xm[si-1]:=(Bm[si]*Am[1,2]-Bm[1]*Am[si,2])/(Am[1,1]*Am[si,2]-Am[si,1]*Am[1,2]);//(-Bm[1]-Am[1,2]*Ym[si-1])/Am[1,1];

end;

for si := 3 to N do

begin

Ym[si]:=(Am[si,1]*Bm[2]-Am[2,1]*Bm[si])/(Am[si,2]*Am[2,1]-Am[si,1]*Am[2,2]);

Xm[si]:=(Bm[si]*Am[2,2]-Bm[2]*Am[si,2])/(Am[2,1]*Am[si,2]-Am[si,1]*Am[2,2]);//(-Bm[2]-Am[2,2]*Ym[si])/Am[2,1];

end;

End;

except

ShowMessage('А-юй!');

end

else

Begin

N:=6;

NL:=4;

for si := 2 to N-2 do

begin

Ym[si-1]:=(Am[si,1]*Bm[1]-Am[1,1]*Bm[si])/(Am[si,2]*Am[1,1]-Am[si,1]*Am[1,2]);

Xm[si-1]:=(Bm[si]*Am[1,2]-Bm[1]*Am[si,2])/(Am[1,1]*Am[si,2]-Am[si,1]*Am[1,2]);//(-Bm[1]-Am[1,2]*Ym[si-1])/Am[1,1];

end;

for si := 3 to N-2 do

begin

Ym[si+1]:=(Am[si,1]*Bm[2]-Am[2,1]*Bm[si])/(Am[si,2]*Am[2,1]-Am[si,1]*Am[2,2]);

Xm[si+1]:=(Bm[si]*Am[2,2]-Bm[2]*Am[si,2])/(Am[2,1]*Am[si,2]-Am[si,1]*Am[2,2]);//(-Bm[2]-Am[2,2]*Ym[si-1])/Am[2,1];

end;

Ym[6]:=(Am[4,1]*Bm[3]-Am[3,1]*Bm[4])/(Am[4,2]*Am[3,1]-Am[4,1]*Am[3,2]);

Xm[6]:=(Bm[4]*Am[3,2]-Bm[3]*Am[4,2])/(Am[3,1]*Am[4,2]-Am[4,1]*Am[3,2]);//(-Bm[3]-Am[3,2]*Ym[6])/Am[3,1];

End;

//----------------------------------------------------------------------------------------------

MIter.Items.Add('------------------------------------ Граничные точки области определения: ------------------------------------');

for si := 1 to NL do

begin

if _BoolStop = true then break;

//-------------Рисование прямых-----------------------------//

FMain.Im.Canvas.Pen.Color := clMaroon;

Im.Canvas.Pen.Width:=1;

if Am[si,2] = 0 then

if Bm[si] = 0 then

begin

xris:=Round(ImW/2);

yris:=Round(ImH/2-100);

Im.Canvas.MoveTo(xris,yris);

yris:=Round(ImH/2+100);

Im.Canvas.LineTo(xris,yris);

end

else

begin

xris:=Round(ImW/2-Bm[si]*20);

yris:=Round(ImH/2-100);

Im.Canvas.MoveTo(xris,yris);

yris:=Round(ImH/2+100);

Im.Canvas.LineTo(xris,yris);

end

else if Am[si,1] = 0 then

if Bm[si] = 0 then

begin

yris:=Round(ImH/2);

xris:=Round(ImW/2+100);

Im.Canvas.MoveTo(xris,yris);

xris:=Round(ImW/2)-100;

Im.Canvas.LineTo(xris,yris);

end

else

begin

yris:=Round(ImH/2+Bm[si]*20);

xris:=Round(ImW/2+100);

Im.Canvas.MoveTo(xris,yris);

xris:=Round(ImW/2)-100;

Im.Canvas.LineTo(xris,yris);

end

else

begin

kg:=-Am[si,1]/Am[si,2];

bg:=-Bm[si]/Am[si,2];

xris:=Round(ImW/2+200);

yris:=(Round(ImH/2)-Round((kg*10+bg)*20));

Im.Canvas.MoveTo(xris,yris);

xris:=Round(ImW/2)-100;

yris:=(Round(ImH/2)-Round((kg*(-5)+bg)*20));

Im.Canvas.LineTo(xris,yris);

end;

Delay(ms);

end;

//----------------------------------------------------------//

for si := 1 to N do

begin

if _BoolStop = true then break;

Fm[si]:=fz(Xm[si],Ym[si],a,b,c,d,e,f);

//-------------Рисование точек-----------------------------//

xr:=Round(ImW/2)+Round(Xm[si]*20);

yr:=Round(ImH/2)-Round(Ym[si]*20);

Im.Canvas.Pen.Width:=2;

FMain.Im.Canvas.Pen.Color := clRed;

FMain.Im.Canvas.Ellipse(xr-3, yr-3, xr + 3, yr + 3);

Im.Canvas.TextOut(xr+10,yr-10,'A'+inttostr(si));

Delay(ms);

//------------------------------------------------------//

MIter.Items.Add('x'+inttostr(si)+'='+floattostr(Xm[si])+' | y'+inttostr(si)+'='+floattostr(Ym[si])+' | F(x,y)='+FloatToStr(Fm[si]));

end;

//------------------ Обвести область-----------------------------------------------------------

for si := 1 to N do

begin

for ssi:=si to N do

begin

if _BoolStop = true then break;

Xp:=Xm[ssi]; Yp:=Ym[ssi];

if (ZnakConst(LC10.Caption, LC20.Caption, LC30.Caption, Xp, Yp) = 3)

and (ZnakConst(LC10.Caption, LC20.Caption, LC30.Caption, Xm[si], Ym[si]) = 3)

and (ZnakConst(LC10.Caption, LC20.Caption, LC30.Caption, (Xm[si]+Xp)/2, (Ym[si]+Yp)/2) = 3) then

begin

xr:=Round(ImW/2)+Round(Xp*20);

yr:=Round(ImH/2)-Round(Yp*20);

Im.Canvas.Pen.Width:=2;

FMain.Im.Canvas.Pen.Color := clRed;

Im.Canvas.MoveTo(xr,yr);

xr:=Round(ImW/2)+Round(Xm[si]*20);

yr:=Round(ImH/2)-Round(Ym[si]*20);

Im.Canvas.LineTo(xr,yr);

Xp:=Xm[si]; Yp:=Ym[si];

Delay(ms);

end;

end;

end;

//----------------------------------------------------------------------------------------------

GaussSystem(N);

for si := 1 to 10 do

begin

if _BoolStop = true then break;

if FindMin(Fm) = Fm[si] then

begin

MIter.Items.Add(' ');

MIter.Items.Add('Ответ: F(x,y)='+FloatToStr(Fm[si])+' x='+FloatToStr(Xm[si])+' y='+FloatToStr(Ym[si]));

end;

end;

end;

procedure TFMain.BSoprClick(Sender: TObject);

var k, i, ImW, ImH, r, yris, xris, ms:Integer;

x0, y0, z0, x, y, z, Fx, Fy, M, _bez, xg, yg, kg,bg:Double;

H : array[1..2,1..2] of Double;

S, S0, sp : array[1..2] of Double;

begin

_BoolStop:=False;

Clear();

if (RBMin.Checked = false) and (RBMax.Checked = false) then RBMin.Checked := true;

if Miter.Count > 0 then MIter.Clear;

EU.Enabled := true;

ms:=StrToInt(ESkor.Text);

ImW:=Im.Width;

ImH:=Im.Height;

k:=0;

Zapoln();

//-------------------------------

_bez:=(b*d-e*a)/(a*c-b*b);

EYb.Text:=floattostr(_bez);

EXb.Text:=floattostr(-(b*_bez+d)/a);

Im.Canvas.Pen.Color:=clred;

Im.Canvas.Pen.Width:=2;

xr :=Round(ImW/2)+Round(StrToFloat(EXb.Text)*20);

yr :=Round(ImH/2)-Round(StrToFloat(EYb.Text)*20);

FMain.Im.Canvas.Pen.Color := clBlue;

FMain.Im.Canvas.Ellipse(xr-4, yr-4, xr + 4, yr + 4);

Delay(ms);

Im.Canvas.TextOut(xr+10,yr-10,'Aб');

Delay(ms);

//----------------------------------------------------------------------------

MIter.Items.Add('---------------------');

x:=StrToFloat(EX0.Text);

y:=StrToFloat(EY0.Text);

z:=fz(x,y,a,b,c,d,e,f);

//----------------------------------------------------------------------------

MIter.Items.Add('k='+inttostr(k)+' | '+

'x'+inttostr(k)+'='+floattostr(x)+' | '+

'y'+inttostr(k)+'='+floattostr(y)+' | '+

'F(x,y)='+floattostr(z));

//----------------------------------------------------------------------------

xr:=Round(ImW/2)+Round(StrToFloat(EX0.Text)*20);;

yr:=Round(ImH/2)-Round(StrToFloat(EY0.Text)*20);

FMain.Im.Canvas.Pen.Color := clRed;

FMain.Im.Canvas.Ellipse(xr-2, yr-2, xr + 2, yr + 2);

Delay(ms);

Im.Canvas.TextOut(xr-16,yr-10,'Ao');

Delay(ms);

// Гессиан

H[1,1]:=2*a;

H[1,2]:=2*b;

H[2,1]:=2*b;

H[2,2]:=2*c;

// Направление

S[1]:=1;

S[2]:=1;

// Цикл рассчета метода

for i := 1 to 1000 do

Begin

if _BoolStop = true then break;

k:=k+1;

MIter.Items.Add('---------------------');

x0:=x;

y0:=y;

z0:=fz(x0,y0,a,b,c,d,e,f);

Fx:=dx(x0, y0, b, d, a);

Fy:=dy(x0, y0, b, e, c);

S0[1]:=S[1];

S0[2]:=S[2];

// Находим u

M:=(Fx*S0[1] + Fy*S0[2])/(S0[1]*(H[1,1]*S0[1]+H[1,2]*S0[2]) + S0[2]*(H[2,1]*S0[1]+H[2,2]*S0[2]));

sp[1]:=H[1,1]*S0[1]+H[1,2]*S0[2];

sp[2]:=H[2,1]*S0[1]+H[2,2]*S0[2];

S[1]:=sp[2];

S[2]:=-sp[1];

if RBMin.Checked then

begin

x:=x0-M*S0[1];

y:=y0-M*S0[2];

end

else if RBMax.Checked then

Begin

x:=x0+M*S0[1];

y:=y0+M*S0[2];

End;

MIter.Items.Add('S'+inttostr(k-1)+'('+floattostr(S0[1])+','+floattostr(S0[2])+')');

z:=fz(x,y,a,b,c,d,e,f);

//------------------ Вывод на экран ---------------------------------------

MIter.Items.Add('k='+inttostr(k)+' | '+

'x'+inttostr(k)+'='+floattostr(x)+' | '+

'y'+inttostr(k)+'='+floattostr(y)+' | '+

'F(x,y)='+floattostr(z)+' | '+

'u'+inttostr(k-1)+'='+floattostr(M));

// условие выхода из цикла

if ((abs(x-x0)<0.01)and (abs(y-y0)<0.01) and (abs(z-z0)<0.01)) then break;

// Промежуточные точки

xr:=Round(ImW/2)+Round(x*20);;

yr:=Round(ImH/2)-Round(y*20);

Im.Canvas.Pen.Width:=2;

FMain.Im.Canvas.Pen.Color := clOlive;

FMain.Im.Canvas.Ellipse(xr-2, yr-2, xr + 2, yr + 2);

Delay(ms);

// Уравнение прямой и рисование направления

xg:=x+S0[1];

yg:=y+S0[2];

kg:=(yg-y)/(xg-x);

bg:=yg-kg*xg;

FMain.Im.Canvas.Pen.Color := clBlack;

Im.Canvas.Pen.Width:=1;

yris:=(Round(ImH/2)-Round((kg*5+bg)*20));

Im.Canvas.MoveTo(Round(ImW/2+100),yris);

yris:=(Round(ImH/2)-Round((kg*(-5)+bg)*20));

Im.Canvas.LineTo(Round(ImW/2)-100,yris);

Delay(ms);

End;

EX.Text:=floattostr(x);

EY.Text:=floattostr(y);

EZ.Text:=floattostr(z);

EK.Text:=inttostr(k);

EU.Text:=floattostr(M);

end;

end.