Скачиваний:
6
Добавлен:
01.05.2014
Размер:
84.48 Кб
Скачать

Санкт-Петербургский государственный

электротехнический университет «ЛЭТИ»

кафедра ВТ

Лабораторная работа №4

Исследование градиентных методов

Выполнили: студенты гр. 3372

Варакин Д.

Манакова М.

Проверил:

Санкт-Петербург,

2005 г.

Цель работы:

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

Вариант:

Вар. 3: функция f(x1, x2) = 8x12 + 4x1x2 + 5x22, начальная точка x = (10; 10).

Описание метода:

Овражный метод:

Начальный этап.

  1. Взять 2 близкие точки (x1 и y1), отстоящие друг от друга на расстояние E < 10^(-3) по одной из координат.

  2. Задать точность, счетчик числа итераций.

Основной этап

Шаг 1.

Выполнить 2 параллельных шага Коши на дно оврага (по направлению антиградиента в одной из точек). Получить x2 = A1*p1, y2 = A2*p1;

Шаг 2.

Вычислить направление ускорения d = x2 – y2. Продвинуться в x3 = x2 + A3*d

Шаг 3.

Если выполняется КОП (||d|| < E), то оставновиться и принять x* = x3.

Иначе обозначить x1 = x3 и вернуться к шагу 1.

Спецификация основных переменных и функций:

Имя

Тип

Входные данные

Вых. данные

Описание

Eps

double

-

-

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

a, b

double

-

-

Значения промежуточных инетрвалов.

F()

-

Vector x

double Func(x)

Заданная функция.

Grad()

-

Vector

Vector

Градиент в данной точке.

dF_dA

-

Vector x, p

double

Производная в точке х по направлению р

F_A

-

Vector x, p, double Alpha

double

Значение одномерной функции со смещением Alpha от точки х в направлении р.

Swann4()

-

double *a, *b

double *a, *b

Реализация алгоритма Свенна-4.

Bolcano

-

double a, b, …

double x

Реализует алгоритм Больцано.

OvragMetod

-

Vector X1

Vector

Реализует овражный метод.

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

#include "stdio.h"

#include "conio.h"

#include "math.h"

#define min(a,b) (((a) < (b)) ? (a) : (b))

#define max(a,b) (((a) > (b)) ? (a) : (b))

#define Eps 0.001

class Vector

{

public:

double x1;

double x2;

Vector (double a, double b) {x1 = a; x2 = b;}

Vector (void) {};

};

double mod (double x)

{

return (x > 0) ? x : -x;

}

// Заданная функция

double F (Vector X)

{

return 8 * X.x1 * X.x1 + 4 * X.x1 * X.x2 + 5 * X.x2 * X.x2;

}

// Градиент в точке Х

Vector Grad (Vector X)

{

Vector g (16*X.x1 + 4*X.x2, 4*X.x1 + 10*X.x2);

return g;

}

// Производная в точке Х по направлению Р

double dF_dA (Vector X, Vector p, double Alpha)

{

Vector t (X.x1 + Alpha * p.x1, X.x2 + Alpha * p.x2);

Vector g = Grad(t);

return g.x1*p.x1 + g.x2*p.x2;

}

// Значение одномерной функции от Alpha по направлению р из точки х

double F_A (Vector x, Vector p, double Alpha)

{

Vector Z (x.x1 + Alpha*p.x1, x.x2 + Alpha*p.x2);

return F(Z);

}

// Метод Свенна-4

void Swann4 (double *a, double *b, Vector x, Vector p)

{

double Alpha = 0.001;// * mod(F(x));

printf ("F:Swann4: Alpha = %f\n", Alpha);

if (dF_dA (x, p, Alpha) > 0) {p.x1 = -p.x1; p.x2 = -p.x2;}

while (dF_dA (x, p, Alpha) * dF_dA (x, p, 2*Alpha) > 0) Alpha *= 2;

*a = min(Alpha/2, 2*Alpha);

*b = max(Alpha/2, 2*Alpha);

}

double Bolcano (double a, double b, Vector x, Vector p)

{

double z = 0;

while ((b-a) > Eps)

{

z = (a + b) / 2;

if (dF_dA(x, p, z) > 0) b = z;

else a = z;

}

return z;

}

// Овражный метод

Vector OvragMetod (Vector X1)

{

// Начальный этап

double Eps1 = 0.001; // Приближение

double Eps2 = 0.001; // Точность

double a, b; // Для метода Свенна

Vector X1m (X1.x1 + Eps1, X1.x2);

Vector X1r (X1.x1, X1.x2);

Vector d, X3 (X1.x1, X1.x2);

Vector stop;

double Alpha;

// Основной этап

do

{

X1r.x1 = X3.x1; X1r.x2 = X3.x2;

X1m.x1 = X3.x1 + Eps1; X1m.x2 = X3.x2;

Vector grad = Grad(X1r);

grad.x1 *= -1; grad.x2 *= -1;

Vector Direction (grad.x1, grad.x2); // Направление антиградиента

Swann4 (&a, &b, X1r, Direction);

Alpha = Davidon(a, b, X1r, Direction);

Vector X2r (X1r.x1 + Alpha*Direction.x1, X1r.x2 + Alpha*Direction.x2);

Vector X2m (X1m.x1 + Alpha*Direction.x1, X1m.x2 + Alpha*Direction.x2);

d.x1 = X2r.x1 - X2m.x1; d.x2 = X2r.x2 - X2m.x2; // Направление ускорения

Swann4 (&a, &b, X2r, d);

Alpha = Davidon (a, b, X2r, d);

X3.x1 = X2r.x1 + Alpha*d.x1; X3.x2 = X2r.x2 + Alpha*d.x2;

stop = Grad(X3);

}

while (sqrt(stop.x1*stop.x1 + stop.x2*stop.x2) > Eps2);

return X3;

}

void main (void)

{

Vector StartPoint (10, 10);

Vector min = OvragMetod (StartPoint);

printf ("Minimum: (%f, %f)\n", min.x1, min.x2);

getch();

}

Примеры выполнения программы:

Точность

Результаты

Eps = 10-4

Minimum: (-0.000018, -0.000001)

Real: (0, 0)

Eps = 10-3

Minimum: (-0.000214, -0.000033)

Real: (0, 0)

Eps = 10-2

Minimum: (-0.001358, -0.000148)

Real: (0, 0)

Ответы на контрольные вопросы:

  1. Представить первую итерацию решения задачи Вашего варианта задания.

X1r = (10.000000, 10.000000)

X1m = (10.001000, 10.000000)

grad = (200.000000, 140.000000)

new grad = (-200.000000, -140.000000)

Direct = (-200.000000, -140.000000)

Swann4 = (0.016000, 0.064000)

Davidon = 0.055750

X2r = (-1.150000, 2.195000)

X2m = (-1.149000, 2.195000)

d = (-0.001000, 0.000000)

F:Swann4: Alpha = 0.001000

Swann4_2 = (262.144000, 1048.576000)

Alpha = 262.144750

X3 = (-1.412145, 2.195000)

sqrt = 21.367537

  1. Сравнить методы М4 – М7 с точки зрения организации поиска.

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

  1. Аналитическим методом найти минимум функции y(x) = (x2 – – x1)2 + (1 – x1)2.

Минимум = (1, 1)

  1. Аналитическим методом найти точку экстремума функции y(x1х2x3) = x12 + 2x22 + 5x32 – 2x1x2 – 4x2x3 – 2x3.

Экстремум (минимум) = (0, 0)

Выводы:

Мы разработали программу, реализующую процедуры минимизации функции многих переменных.