- •Кафедра автоматизированных и вычислительных систем
- •Методические указания
- •Методы поиска экстремума для функций
- •1.1. Методы одномерной оптимизации
- •Метод «золотого сечения»
- •2. Контрольное задание № 1.
- •3. Реализация метода поиска минимума функции нескольких переменных с использованием метода хука-дживса
- •3.1. Постановка задачи и алгоритм решения
- •3.2. Пример реализации алгоритма
- •4. Контрольное задание № 2.
- •5. Реализация метода поиска минимума
- •5.1. Теоретические сведения
- •5.5. Структурная схема алгоритма
- •6. Контрольное задание № 3.
- •394026 Воронеж, Московский просп., 14
3.2. Пример реализации алгоритма
Пример. Используя метод Хука – Дживса, вычислить минимум функции
F(x1, x2, x3) = (x1 – 2)2 + (x2 – 5)2 + (x3 + 2)4.
Начальная точка (4, -2, 3). Величина шага равна 1.
Пример реализации программы на языке Turbo Pascal.
const
n=3;
type
masx=array [1..n] of real;
var
x, b, y, p: masx; {массивы для точек}
i,j,fe: integer; {fe - счетчик для подсчета количества вычислений функции}
h, k , fi, fb: real; {h, k - шаг, fi - значение функции, fb - значение функции в базовой точке}
ps,bs: integer;
{признаки для указания вида исследования - в базисной точке (bs=1, ps=0) или в точке образца (bs=0, ps=1)}
EndAlg: boolean; {признак окончания подсчета минимума}
{функция, минимум которой требуется найти}
function FunZ (x: masx):real;
begin
FunZ:=sqr(x[1]-2)+sqr(x[2]-5)+sqr(x[3]+2)*sqr(x[3]+2);
fe:=fe+1;
end;
{процедура вывода на экран координат очередной найденной точки}
procedure PrintPoint;
begin
Write('Точка ');
for i:=1 to n do
begin
Write(x[i]:5:2,' ');
end;
WriteLn;
WriteLn;
end;
{процедура исследования поведения функции в окрестности базисной точки}
procedure IsslBaz;
begin
while j<=n do
begin
x[j]:=y[j]+k;
if FunZ(x)>fi then
begin
x[j]:=y[j]-k;
if FunZ(x)>fi then
x[j]:=y[j]
else
y[j]:=x[j];
end
else
y[j]:=x[j];
fi:=FunZ(x);
WriteLn('Исследующий поиск ',fi:5:2 );
PrintPoint;
j:=j+1;
end;
end;
{процедура поиска по образцу}
procedure PoiskPoObr;
begin
for i:=1 to n do
begin
p[i]:=2*y[i]-b[i];
b[i]:=y[i];
x[i]:=p[i];
y[i]:=x[i];
end;
fb:=fi;
ps:=1;
bs:=0;
fi:=FunZ(x);
WriteLn('Поиск по образцу ', fi:5:2);
PrintPoint;
j:=1;
end;
{Основная программа}
Begin
{Ввод исходных данных - координаты стартовой точки и шага}
WriteLn('Метод Хука-Дживса');
Writeln('vvod x1, x2, x3');
for i:=1 to n do
begin
WriteLn('Введите x[',i,']');
ReadLn(x[i]);
end;
WriteLn('Введите шаг');
ReadLn(h);
k:=h;
fe:=0;
for i:=1 to n do
begin
y[i]:=x[i];
p[i]:=x[i];
b[i]:=x[i];
end;
{Вычисление начального значения функции и вывод данного значения и стартовой точки на экран}
fi:=FunZ(x);
WriteLn(Начальное значение функции ',fi:5:2 );
PrintPoint;
{Установка признака исследования функции вокруг базисной точки}
ps:=0;
bs:=1;
j:=1;
fb:=fi;
EndAlg:=false;
while EndAlg=false do
begin
{Процедура исследования функции вокруг базисной точки}
IsslBaz;
{Если функция уменьшилась - проведение поиска по образцу}
if (fi<fb-0.00000001) then
PoiskPoObr
Else
{Если исследование по образцу уже проводилось вокруг шаблона Pi и уменьшение функции не было достигнуто, то следует изменить базисную точку для проведения нового исследования вокруг базовой точки (будет произведено в начале следующей итерации цикла}
if (ps=1) and (bs=0) then
begin
for i:=1 to n do
begin
p[i]:=b[i];
y[i]:=b[i];
x[i]:=b[i];
end;
bs:=1;
ps:=0;
fi:=FunZ(x);
fb:=fi;
WriteLn('Замена базисной точки ', fi:5:2);
PrintPoint;
j:=1;
end
else
{Иначе - уменьшить длину шага}
begin
k:=k/10;
WriteLn('Umenshit dlinu shaga');
WriteLn;
{Если шаг достаточно мал - установить признак окончания алгоритма}
if k<0.00000001 then EndAlg:=true;
end;
end;
{Вывод на экран результатов}
WriteLn('Минимум найден');
PrintPoint;
WriteLn('Min=', fb:5:2);
WriteLn('Кол-во вычислений = ', fe);
ReadLn;
end.
Приведенная выше программа реализует описанную процедуру. Одной или двух точек бывает недостаточно для определения начальной точки. Первая точка всегда должна выбираться осмотрительно. ЭВМ работает только с ограниченной точностью, и ошибки могут накапливаться в процессе сложных вычислений, особенно если шаг имеет "неудобную" длину.
Поэтому в строке if (fi < fb – 0.00000001) then, где выясняется вопрос об изменении базисной точки, мы избегаем уменьшения длины шага из-за накапливания ошибки введением длины шага, равной 10-8. Мы отслеживаем, где производится исследование - в базисной точке (BS = 1, PS = 0) или в точке образца (BS = 0, PS = 1). Как можно убедиться на практике, если не принимаются такие меры предосторожности, даже программа с удовлетворительной логикой будет неработоспособна.
В приведенной программе минимальная длина шага равна 10-8, но она может быть изменена (например, путем введения дополнительной переменной).
Результаты выполнения программы следующие:
– точка минимума – координаты (2, 5, -2);
– значение функции в точке минимума – 0;
– число вычислений значения функции – 64.