
Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №43 / MO_Lab4 / MO_Lab4
.cpp#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;
return (X.x2-X.x1)*(X.x2-X.x1) + (1-X.x1)*(1-X.x1);
}
// Градиент в точке Х
Vector Grad (Vector X)
{
//Vector g (16*X.x1 + 4*X.x2, 4*X.x1 + 10*X.x2);
Vector g (4*X.x1-2*X.x2-2, 2*X.x2-2*X.x1);
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)
{
//printf ("F:Swann4: dF_dA = %f, %f; alpha = %f\n", dF_dA (x, p, Alpha), dF_dA (x, p, 2*Alpha), Alpha);
Alpha *= 2;
//getch ();
}
*a = min(Alpha/2, 2*Alpha);
*b = max(Alpha/2, 2*Alpha);
}
double Davidon (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;
}
double Davidon1 (double a, double b, Vector x, Vector p)
{
double z, w, g, min;
bool done = false;
// f'(a) = dF_dA (x, p, a)
// f'(b) = dF_dA (x, p, b)
// f (a) = F (x, p, a)
// f (b) = F (x, p, b)
while (!done)
{
z = dF_dA (x, p, a) + dF_dA (x, p, b) + 3 * ((F_A (x, p, a) - F_A (x, p, b))/b);
w = sqrt (z*z - dF_dA (x, p, a) * dF_dA (x, p, b));
g = (z - dF_dA (x, p, a) + w) / (dF_dA (x, p, b) - dF_dA (x, p, a) + 2*w);
min = a + g * (b - a);
done = (mod(dF_dA (x, p, min)) < Eps) || (min == a) || (min == b);
if (!done)
{
if (dF_dA (x, p, min) > 0) b = min;
else a = min;
}
}
return min;
}
// Овражный метод
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;
// Основной этап
printf ("X1r = (%f, %f)\n", X1r.x1, X1r.x2);
printf ("X1m = (%f, %f)\n", X1m.x1, X1m.x2);
do
{
X1r.x1 = X3.x1; X1r.x2 = X3.x2;
X1m.x1 = X3.x1 + Eps1; X1m.x2 = X3.x2;
Vector grad = Grad(X1r);
printf ("grad = (%f, %f)\n", grad.x1, grad.x2);
grad.x1 *= -1; grad.x2 *= -1;
printf ("new grad = (%f, %f)\n", grad.x1, grad.x2);
Vector Direction (grad.x1, grad.x2); // Направление антиградиента
printf ("Direct = (%f, %f)\n", Direction.x1, Direction.x2);
Swann4 (&a, &b, X1r, Direction);
printf ("Swann4 = (%f, %f)\n", a, b);
Alpha = Davidon(a, b, X1r, Direction);
printf ("Davidon = %f\n", Alpha);
Vector X2r (X1r.x1 + Alpha*Direction.x1, X1r.x2 + Alpha*Direction.x2);
printf ("X2r = (%f, %f)\n", X2r.x1, X2r.x2);
Vector X2m (X1m.x1 + Alpha*Direction.x1, X1m.x2 + Alpha*Direction.x2);
printf ("X2m = (%f, %f)\n", X2m.x1, X2m.x2);
d.x1 = X2r.x1 - X2m.x1; d.x2 = X2r.x2 - X2m.x2; // Направление ускорения
printf ("d = (%f, %f)\n", d.x1, d.x2);
Swann4 (&a, &b, X2r, d);
printf ("Swann4_2 = (%f, %f)\n", a, b);
Alpha = Davidon (a, b, X2r, d);
printf ("Alpha = %f\n", Alpha);
X3.x1 = X2r.x1 + Alpha*d.x1; X3.x2 = X2r.x2 + Alpha*d.x2;
printf ("X3 = (%f, %f)\n", X3.x1, X3.x2);
stop = Grad(X3);
printf ("sqrt = %f\n\n\n", sqrt(stop.x1*stop.x1 + stop.x2*stop.x2));
//getch ();
}
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();
}
Соседние файлы в папке MO_Lab4