Это главная страница по методам
оптимизаций

Главная страница
сайта

Написать письмо
автору

Небольшая коллекция методов оптимизаций

Для студентов технических университетов. Может быть полезен преподавателям, аспирантам и инженерам.
(Серия "Математика в техническом университете" под редакцией Зарубина, Крищенко)
Содержание

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

Вообщем-то, в этом разделе не будет ничего оригинального. Нет и полного описания методов. Даны краткие описания, дающие характеристику методу, кое-какие формулы, помогающие понять смыл того или иного метода. В основном, смыл создания этой страницы состоит в том, чтобы были доступны работающие версии методов на тот случай, когда уже совсем ничего не получается. Кроме того, доступна работа, где один из таких методов работает на практике. Эта работа заключается в поиске оптимальной формы балки, к середине которой приложена нагрузка. Работу можно прочитать отсюда
С другой стороны, весьма логично было бы предположить, что каждый более или менее грамотный человек, будь то математик, экономист или студент (выделим сего брата в отдельную категорию...), вполне может "забацать" тот или иной метод самостоятельно. Так зачем нужна эта страница? Во-первых, не всегда люди бывают "более или менее грамотными", во-вторых, у всех иногда бывают проблемы даже с простыми вещами. Временами нужно что-то, что столкнет с мертвой точки в постижении того или иного объекта. В этом могут помочь уже сделанные кем-то шаги. В данном случае, написанные (или, скорее, реализованные) мной методы. Не буду лукавить, в них наверняка есть какие-либо огрехи, но, как это может показаться ни парадоксально, они, в большинстве случаев, работают.

Какие методы представлены
  1. Безусловные методы
  2. "Условные" методы или численные методы нелинейного программирования
Теперь по поводу того, каким образом будут представлены результаты. Все методы написаны в среде Delphi 6. Думаю, это более или менее оптимальный вариант, так как будет необходимо строить линии уровня функции. Какие могли быть варианты (и как показывает практика, эти варианты с успехом реализовываются).
Метод 1. В страшном сне не приснится (без обид...)
Сам метод пишется на Pascal или C/C++, его результаты записываются в текстовый файл. Файл загружается в один из математических пакетов (MatLab, MathCad), посредством которых строятся линии уровня функции, а по данным созданного файла строится траектория поиска.
Плюсы метода
Минусы метода
Не нужно заботиться о построении линий уровня Нет удобной возможности построения линий уровня в данной точке
  Довольно трудоемкий процесс отладки, т.к. нет мгновенной графической интерпретации метода, что требует значительного времени в период созидания, который превращается в рутинное программирование формул, блокируя интерес к самому методу минимизации
  Довольно изощренным способом нужно умудриться построить ломанную траектории. Снимаю шляпу перед реализаторами этого метода...
Тем не менее, таким образом сдала ДЗ по методам оптимизации почти вся моя группа. Значит, он имеет право на существование. Но право, господа ....
Метод 2. Экзотический
Прошу затаить дыхание... Итак, все (сами методы и алгоритм, рисующий линии уровня) пишется на VBA (!!!) в Excel. Результат выводится в поле диаграммы. Короче, я знаю только одного человека, который мог это придумать, и что самое удивительное, сумел реализовать несколько методов таким образом.
Плюсы метода
Минусы метода
Саму функцию и ее градиент можно легко изменять в строке формул (что полезно, если программой будет пользоваться не один человек, а вся группа) Очень неудобно выводить линии уровня
  Крайне медленная работа... Нет, вы себе представить не можете как медленно!

Если вы хотите повергнуть кого-нибудь в шоковое состояние, или прослыть оригиналом, то можете воспользоваться таким способом. Когда-нибудь я выложу исходники. Автор сей идеи (Бабаскин Евгений Михайлович) вроде не возражает. Файл Excel в архиве Zip находится здесь
Итак, мы будем реализовывать все на Delphi. Но нам придется самим строить линии уровня. О возможных вариантах, какими это можно реализовать, чуть позже, а сейчас - о интерфейсе программы.
Интерфейс программы
Внешний вид программы, минимизирующей функции
Основные компоненты интерфейса: Поле вывода - Область, куда выводятся графические результаты ( линии уровня, траектория поиска, ограничения); Область управления - область справа от поля вывода, в которой пользователь может изменять параметры оптимизации (начальную точку, количество итераций перед рестартом, точность и т.д.). Не всеми параметрами можно управлять отсюда (Имейте в виду - программа писалась в течение семестра, а не на каникулах, времени на всякую ерунду не всегда хватало). Иногда некоторые параметры, как например, линейные ограничения в случаях "условной" оптимизации, придется вводить в исходном тексте, но об этом будет рассказано более подробно в соответствующем разделе; Поле отчета - таблица внизу, в которую выводится текстовая информация о параметрах итераций (текущая точка итерации, значение функции в этой точке, иногда - ее градиента, проверяемое условие останова (разность двух соседних точек или норма градиента)); Кнопки управления - в самом верху, позволяют выбрать метод оптимизации, сохранить результаты.
Область управления
-Здесь вводится количество линий уровня и точность, с которой они будут выводиться, чем больше число в поле "Точность", тем толще будут получаться линии.
-Точность, с которой будет производиться минимизация.
Мировые координаты: x0,y0 - координаты левого нижнего угла. x1,y1 - правого верхнего. Минимизация будет проводиться (если она 2D) по x: x0<x<x1; по y: y0<y<y1. Список внизу - история изменения масштаба. Об этом подробнее ниже.
Начальная точка минимизации. С этой точки стартует большинство алгоритмов
Каждая точка очередной итерации помечается маркером. Размер этого маркера можно изменять, введя новое значение в поле "радиус точки" (в пикселях). Некоторые алгоритмы могут предусматривать рестарт после определенного количество итераций, которое можно ввести в поле "Рестарт после".
Конечно, есть еще над чем поработать, но это уж вы сами, должны же и вы что-нибудь сделать. Остались только мелочи, такие как, например, управление голосом и прочая ерунда, недостойная внимания настоящего математика. В любом случае, если сотворите что-нибудь стоящее, быстренько посылайте на ящик.
 

вверх


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

function func(x,y:double):double;
var sqrt5:double;
begin
//my function
   sqrt5:=sqrt(5);
   Result:=8*x*x-4*x*y+5*y*y+8*sqrt5*(x+2*y)+64;
   //sample function
 //Result:=2*sqr(x)+2*sqr(y)-2*x*y-4*x-6*y;
   //Jonny's function
 //  Result:=11*sqr(x)+3*sqr(y)+6*x*y-2*sqrt(10)*(x-3*y)-22;
//   Result:=sqr(x)-4*x+sqr(y)-2*y;
//lena's function
//         Result:=2*sqr(x)-4*x*y+5*sqr(y)-4*sqrt(5)*(x-y)+4;
//sonya's function
//    Result:=6*sqr(x)+3*sqr(y)-4*x*y+4*sqrt5*(x+2*y)+22;
//     result:=ln(abs(x*sin(y))+abs(cos(y)));
//     Result:=cos(x)-sqr(y);
 // Result:=8*sqr(cos(x))-4*sin(x)*sin(y)+5*sqr(sin(y))+8*sqrt(5)*(sin(x)+2*cos(Y))+64;
//Функция Розенброка
 //result:=alpha*sqr(sqr(x)-y)+sqr(x-1);
//Функция Химмельблау
//result:=sqr(sqr(x)+y-11)+sqr(x+sqr(y)-7);
end;
В комментариях упоминаются функции Розенброка и Химмельблау. Это следующие неквадратичные функции:
Функция Розенброка
Функция Розенброка: alpha*sqr(sqr(x)-y)+sqr(x-1)
Функция Химмельблау
Функция Химмельблау: sqr(sqr(x)+y-11)+sqr(x+sqr(y)-7)
Думаю, без труда Вы сможете изменить этот сектор кода.
За антиградиент отвечает процедура GradientFunc в том же модуле funclevel.pas.
procedure GradientFunc(x,y:double;var grad:TWorldPoint);
//Это антиградиент!!!
var sqrt5:double;
begin
        sqrt5:=sqrt(5);
        grad.x:=-(16*x-4*y+8*sqrt5);
        grad.y:=-(-4*x+10*y+16*sqrt5);
//sample gradient
   // 	grad.x:=-(4*x-2*y-4);
    //    grad.y:=-(4*y-2*x-6);
//Jonny's functions gradient
 //  	grad.x:=-(22*x+6*y-2*sqrt(10));
//        grad.y:=-(6*y+6*x+6*sqrt(10));
//тестоввая функция
//   Result:=sqr(x)-4*x+sqR(y)-2*y;
//     grad.x:=-(2*x-4);
//     grad.y:=-(2*y-2);
//Функция Розенброка
//      grad.x:=-(alpha*4*(sqr(x)-y)*x+2*x-2);
//       grad.y:=-(-alpha*2*(sqr(x)-y));
//Функция Химмельблау
//	grad.x:=-(4*(sqr(x)+y-11)*x+2*(x+sqr(y)-7));
//        grad.y:=-(2*(sqr(x)+y-11)+4*(x+sqr(y)-7)*y);
//
//        grad.x:=-(12*x-4*y+4*sqrt5);
//        grad.y:=-(6*y-4*x+4*sqrt5*2);
{        grad.x:=-16*cos(x)*sin(x)-4*cos(x)*sin(y)+8*sqrt5*cos(x);
        grad.y:=-4*sin(x)*cos(y)+10*sin(y)*cos(y)-16*sqrt5*sin(y);}
end;
Она возвращает результат в виде структуры TWorldPoint, которая описана в начале модуля funclevel.pas и имеет естественный вид:
type
   TWorldPoint=record   {saves a point in world coord}
        x,y:double;
   end;
 

вверх

Кроме того, обратите внимание на процедуры, осуществляющие перевод из экранных координат в мировые и наоборот: World2Screen, Screen2World (будем их сокращенно называть w2s и s2w). Экранные координаты хранятся в виде аналогичной TWorldPoint структуры:

type
   TScreenPoint=record   {saves a point in screen coord}
        x,y:integer;
   end;

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

Этот переход можно записать в матричном виде:
Переход из мировых координат в экранные

где
Коэффициент M11

Коэффициент M22

offsetx=PbOut.Canvas.ClipRect.Left-M11*x0
offsety=PbOut.Canvas.ClipRect.Buttom-M22*y0
Таким образом, представим саму процедуру перевода из мировых координат в экранные:

procedure World2Screen(Area:TDoubleRect;Window:TRect;world:TWorldPoint;var screen:TScreenPoint);
var M11,M22:double;
begin
with Screen do
begin
    M11:=(Window.Right-Window.Left)/(Area.rx-Area.lx);
    M22:=-(Window.Top-Window.Bottom)/(Area.ry-Area.ly);
    x:=trunc(M11*world.x+Window.Left-M11*Area.lx);
    y:=window.Bottom-trunc(M22*world.y-M22*Area.ly);
end;
end;

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

procedure Screen2World(Area:TDoubleRect;Window:TRect;screen:TScreenPoint;var world:TWorldPoint);
var M11,M22:double;
begin
    M11:=(Window.Right-Window.Left)/(Area.rx-Area.lx);
    M22:=-(Window.Top-Window.Bottom)/(Area.ry-Area.ly);
    World.x:=(screen.x-(Window.Left-M11*Area.lx))/M11;
    World.y:=(Window.Bottom-screen.y+M22*Area.ly)/M22;
end;
Эти две весьма полезные функции нам пригодятся в дальнейшем, для визуализации траектории поиска минимума.
 

вверх

Дихотомия
Многие методы многомерной оптимизации требуют в своем алгоритме применения одномерной минимизации какой-либо одномерной вспомогательной функции, например, для реализации исчерпывающего спуска в удачно выбранном направлении, или вдоль базисных векторов, как это происходит в методе покоординатного циклического спуска. Минимизировать одномерную функцию можно несколькими способами. В моей программе применяется метод деления отрезка пополам или ДИХОТОМИИ. Для начала давайте разберемся как им пользоваться, а потом выясним, как вообще он работает.
За дихотомию отвечает модуль dichotomy.pas. В нем объявлены две глобальные переменные xk и uk типа TWorldPoint. Они нужны для минимизации часто встречающейся функции вида:
(*)
psi(cappa)=f(xk+cappa*uk),
которая является скалярной функцией скалярного аргумента k (каппа).
Дихотомия осуществляется функцией MakeDichotomy, возвращающей точку, в которой фукнция достигает минимума. Она имеет следующий синтаксис:

function MakeDichotomy(a,b,eps,prec:double;func:T1DFunction):double;

где a,b - обозначают границы отрезка, на котором ищется минимум функции, eps- точность минимизации, func - переменная процедурного типа, ссылающаяся на функцию, минимизация которой должна быть осуществлена. Описывается она так:
type T1DFunction=function(x:double):double;
Для минимизации функции вида (*) объявлена функция:
function Pseudo1D(x:double):double;
begin
     Result:=Func(xk.x+x*uk.x,xk.y+x*uk.y);
end;

Таким образом, для минимизации функции вида (*) в контексте некоторого метода нужно поступить следующим образом:
var curx, grad:TWorldPoint;
    func:T1DFunction;
    cappa:double;
// дальнейшие объявления и операторы
func:=@Pseudo1D;
GradientFunc(curx.x,curx.y,grad);//будем спускаться в направлении антиградиента
xk:=curx;
uk:=grad;		//собственно,направление антиградиента
cappa:=MakeDichotomy(0,1,eps/100,eps/100,func);{eps:double - аргумент функции,
					реализующей тот или иной метод.
					Обратите внимание, что точность 
					дихотомии должна быть значительно 
					выше требуемой от метода точности}
 

вверх

Суть метода дихотомии
Рассмотрим следующую процедуру, называемую процедурой исключения отрезка, которая нам пригодится в поиске минимума унимодальной(т.е. имеющей одну точку экстремума на рассматриваемом отрезке) скалярной функции. На отрезке [a,b] выберем две несовпадающие между собой точки c,d так, чтобы выполнялись неравенства a<c<d<b. Далее, если f(c)<f(d), то, т.к. функция унимодальная, заключаем, что точка минимума лежит внутри отрезка [a,d], а отрезок [d,b] вообще можно исключить. Если же f(c)>=f(d), то, наоборот, в дальнейшем рассматриваем только отрезок [c,b].
Выбрасываем отрезок [d,b]
Выбрасываем отрезок [a,c]
На первой итерации (k=1) на отрезке [ak,bk]=(k=1)=[a,b] длиной lk=(k=1)=l выбираем две точки следующим образом:
где p - достаточно мало >0. Выполним в этих точках процедуру исключения отрезка и если длина получившегося отрезка [aj,bj] (j=k+1) больше заданного числа eps, то переходим к следующей итерации.
Заметим, наконец, что вместо дихотомии можно использовать любой другой метод одномерной минимизации, например, метод Фибоначчи, Золотого сечения, метод Ньютона и др. Отличительной особенностью этих методов является то, что писать их Вам придется самим.
Модуль dichotomy.pas

Линии уровня
Думаю, многие сталкивались с проблемой построения линий уровня функции. Как оказалось, эта проблема не так проста как кажется. В процессе ее обдумывания у нас родилось несколько методов ее решения. Но, так получилось, что я реализовал самый простецкий метод. Однако следует заметить, что, несмотря на высокую плату за простоту, реализованный метод не является привередливым ни к функции, ни к ее линиям уровня. Иными словами, он не требует замкнутости линий уровня, ему все равно сколько раз дифференцируема функция (если вообще дифференцируема), но при этом довольно долго и неуклюже работает.
Суть этого простейшего алгоритма в следующем. Имеем графическое окно размером Width x Height, а также область изменения функции [x0,x1]x[y0,y1]. Любым способом выясняем минимум и максимум целевой функции на том множестве. (Исторически сложилось так, что в моем методе применяется "лобовой" прямой перебор с шагом 1e-2. Это можно понять, т.к. изначально отрисовка линий уровня писалась в то время, когда ни один из методов не был реализован. Ну, а потом, понятно, руки не дошли. Однако, с точки зрения рационализма, следует применить один из методов. Я бы отдал предпочтение, в случае квадратичной функции, либо ДФП-методу, либо методу Розенброка). Делим отрезок [min,max] на N частей, где N - число линий уровня. В итоге имеем множество точек L={y0,y1,...yk},k=N-1 - значений функции, для которых будем рисовать линии уровня. Далее, сканируем наше окно с шагом 1 пиксель, с помощью отображения Screen2World получаем точку с мировыми координатами, соответствующую точке с экранными, вычисляем значение целевой функции и если оно с некоторой точностью соответствует одному из значений, принадлежащему множеству L, то помечаем текущий пиксель цветом, отличным от цвета фона.
Посмотреть результаты работы такого алгоритма в зависимости от точности и количества линий уровня (Функция Химмельблау) можно Здесь.

Какие еще способы построений линий уровня можно предложить?
Евгений Михайлович Бабаскин предложил следующий вариант. Известно, что вектор градиента перпендикулярен линиям уровня функции двух переменных. Поэтому, если двигаться маленькими шагами вдоль перпендикуляра к градиенту, то с некоторой погрешностью можно описать одну из линий уровня. Недостатком такого метода является то, что довольно трудно будет описать все линии, соответствующие одному значению уровня. Попытки реализовать такой метод можно лицезреть в модуле funclevel.pas в процедуре GradientLevels.
Еще один метод заключается в численном решении уравнения F(xk,y,zn)=0 в точках xk - которые генерируются для каждого уровня zn. Впоследствии, точки (xk,yk) соединяются линиями.
Алгоритм построения линий уровня здесь
 

вверх

Методы оптимизации

Градиентного спуска с дроблением шага
Этот метод использует информацию о градиенте, а точнее, о антиградиенте функции. Напомним, что направление вектора градиента совпадает с направлением наибольшего возрастания функции, поэтому вектор антиградиента задает направление наибольшего убывания.
Исходные тексты смотрите здесь
Приведем алгоритм этого метода.
Поскольку этот алгоритм является итеративным, то все действия достаточно описать для k- го шага. Для нулевого шага начальными данными являются начальная точка и вектор антиградиента в этой точке. Итак.
  1. В точке вычисляем антиградиент антиградиент, который и определяет направление спуска на каждом шаге. Если вдруг окажется, что модуль антиградиента равен нулю (или меньше заданного числа-точности), то, значит, мы в искомой точке минимума! Инициализируем некоторую переменную заранее выбранным значением величины шага .
  2. Пока не выполняется неравенство

    уменьшаем значение величины шага в заданное количество раз: , где , а также изменяем к-ую точку (она используется в неравенстве, записанном выше)
  3. Увеличиваем k на единицу и возвращаемся в пункт 1.

Данный метод часто плохо работает на "сложных", овражных функциях. Достаточно неплохо на квадратичных. Но все-таки является одним из самых медленных, на мой взгляд. (Однако, отмечу, что все приведенные методы работают на квадратичных функциях практически одинаковое время. Разница возникает на таких функциях как Розенброка или Химмельблау.)
 

вверх

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

вверх

Сопряженных направлений
Этот метод мало чем отличается от предыдущих двух. Единственное отличие, которое, собственно, и определяет данный метод, заключается в том, что исчерпывающий спуск осуществляется по так называемым сопряженным направлениям, которые и строятся в данном методе. Вектор, сонаправленный таковым направлениям мы будем обозначать . Напомним, что два вектора v, p называются сопряженными относительно некоторой симметрической матрицы Q (иногда про такие векторы говорят, что они Q-ортогональны), если верно равенство: . Первоначально, сам метод разрабатывается для квадратичной функции, т.е. функции вида , получается некоторое соотношение, содержащее матрицу Q. Для обобщения метода на случай произвольной функции эта матрица определенным образом из этого выражения исключается (мы же не ставим перед собой цель разместить исчерпывающее руководство по методам оптимизаций!) и получается выражение, которое определяет на каждом шаге направление спуска
,
,
где .
На первом шаге принимаем s1=ag1.
После выбора направления спуска, все остальные шаги аналогичны предыдущим методам. Единственное, что иногда осуществляется рестарт алгоритма, т.е. через определенное количество шагов полагают . Это делается для того, чтобы избежать накопления ошибок алгоритма и уменьшить вероятность построения линейно-зависимых направлений спуска.
Исходные тексты метода доступны здесь
 

вверх

Давидона-Флетчера-Ривса (ДФП-метод)
Это так называемый квазиньютоновский метод. На каждом шаге поиске следующая точка определяется выражением , но направление спуска определяется следующим образом
.

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

вверх

Метод циклического покоординатного спуска
Это самый простой из представленных здесь методов прямого поиска. Напомним, что под таковыми подразумевают методы, не использующие информацию о градиенте функции или об ее матрице Гессе. Данный метод просто последовательно проводит одномерную оптимизацию по каждой координате функции. Так, если функция f=f(x,y), то на каждом шаге этого метода сначала функция минимизируется в направлении оси x, а потом - оси y.
Поиск точки минимума определяется рекуррентным соотношением . Здесь определяется из решения задачи одномерной оптимизации , где ej - вектора стандартного базиса в Rn.
Отметим, что данный алгоритм эффективен в тех случаях, когда целевая функция является сепарабельной, т.е. может быть представлена в виде суммы функций, зависящих только от одной координаты.
С исходными текстами метода можно ознакомиться здесь.
 

вверх

Метод Хука-Дживса
Этот метод относится также к семейству методов прямого поиска, т.е. использующих такие алгоритмы, для которых не требуется информация о градиенте функции или ее матрицы Гессе. В отличие от вышеизложенного метода циклического покоординатного спуска, используется более хитрый подход, согласно которому, направление спуска выбирается путем исследования окрестности точки, найденной на предыдущем шаге поиска. Процесс выбора такового направления называют исследующим поиском. Результирующее направление на k-ой итерации представляет собой вектор xk-xk-1. На рисунке ниже показан пример исследующего поиска.
.

На этапе исследования вводятся обычно параметры: b - вектор перемещений, a - ускоряющий множитель и коэффициент дробления, на который делятся координаты вектора b в том случае, если в результате исследующего поиска алгоритм не смог сдвинуться из предыдущей точки. (более подробно механизмы исследований см. исходник метода).
Исходные тексты методы можно стащить отсюда.
Кроме того доступны исходники действительно многомерного метода Хука-Дживса, т.е. в котором нет ограничений на размерность оптимизации (все остальные процедуры "заточены" под 2D). Ими можно восторгаться здесь.
 

вверх

Методы Розенброка и Пауэлла
Эти методы похожи между собой и похожи на метод Хука-Дживса. Отличия состоят в том, что на каждом шаге строится ортонормированный базис и относительно этого базиса выбирается новое направление спуска (это метода Розенброка). В методе Пауэлла просто применяется другой алгоритм построения системы векторов. Объяснять тонкости, как мне видится, не имеет смысла, проще взглянуть на исходники методов.
Исходные тексты: Розенброка, Пауэлла.
 

вверх

Метод Нелдера-Мида
Этот метод использует геометрическую конфигурацию, которая называется симплекс. Симплекс - это выпуклый многогранник с числом вершин, равным n+1, где n - размерность пространства. Поиск с помощью симплекса заключается в том, что значения функции вычисляются в вершинах этой самой фигуры, выбирается самое худшее из них и вершина, соответствующая этому значение заменяется по определенному правилу на другую, образуя тем самым новый симплекс. Такую процедуру повторяют, пока не будет достигнута требуемая точность. Среди методов деформации исходного симплекса (которая происходит после отбрасывания наихудшей вершины и последующем поиске новой подходящей вершины) встречается: отражение вершины (вершина просто отражается относительно одной из сторон симплекса), редукция (симплекс сохраняет свою форму, но размеры его уменьшаются), растяжение, сжатие. Кроме того, очень важно то, как пронумерованы вершины. Для удобства важно. Нумерацию называют правильной, если вершине с меньшим номером соответствует меньшее значение функции. Иными словами, чем меньше номер, тем меньше значение.
Исходные тексты этого метода находятся здесь.
 

вверх

Написать письмо Написать письмо по поводу этой статьи
Мещанинов Николай © 2004.

Hosted by uCoz