Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №34 / MO_Lab3 / MO_Lab3
.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) {};
Vector Move (Vector Direction, double Alpha)
{
double xx1 = x1 + Direction.x1*Alpha;
double xx2 = x2 + Direction.x2*Alpha;
return Vector(xx1, xx2);
}
};
double mod (double x)
{
return (x > 0) ? x : -x;
}
// Заданная функция
double F (Vector X)
{
return -12*X.x2+4*X.x1*X.x1+4*X.x2*X.x2-4*X.x1*X.x2;
}
// Градиент в точке Х
Vector Grad (Vector X)
{
Vector g (8*X.x1 - 4*X.x2, -12 + 8*X.x2 - 4*X.x1);
return g;
}
// Производная в точке Х по направлению Р
double dF_dA (Vector X, Vector p)
{
Vector g = Grad(X);
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));
if (dF_dA (x, p) > 0) {p.x1 = -p.x1; p.x2 = -p.x2;}
while (dF_dA (x.Move(p, Alpha), p) * dF_dA (x.Move(p, 2*Alpha), p) > 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.Move(p, z),p) > 0) b = z;
else a = z;
}
return z;
}
double Davidon (double a, double b, Vector x, Vector p)
{
double z, w, g, min;
bool done = false;
// f'(a) = dF_dA (x.Move(p, a), p)
// f'(b) = dF_dA (x.Move(p, b), p)
// f (a) = F (x, p, a)
// f (b) = F (x, p, b)
while (!done)
{
z = dF_dA (x.Move(p, a), p) + dF_dA (x.Move(p, b), p) + 3 * ((F_A (x, p, a) - F_A (x, p, b))/b);
w = sqrt (z*z - dF_dA (x.Move(p, a), p) * dF_dA (x.Move(p, b), p));
g = (z - dF_dA (x.Move(p, a), p) + w) / (dF_dA (x.Move(p, b), p) - dF_dA (x.Move(p, a), p) + 2*w);
min = a + g * (b - a);
done = (mod(dF_dA (x.Move(p, min), p)) < Eps) || (min == a) || (min == b);
if (!done)
{
if (dF_dA (x.Move(p, min), p) > 0) b = min;
else a = min;
}
}
return min;
}
void main (void)
{
Vector StartPoint (-0.5, 1),
Direction (1, 0);
double a = 0, b = 0;
Swann4 (&a, &b, StartPoint, Direction);
printf ("Swann : a = %f, b = %f\n\n", a, b);
double min1 = Bolcano(a, b, StartPoint, Direction);
printf ("Bolcano min : %f (%f, %f)\n\n", min1,
StartPoint.x1 + min1*Direction.x1, StartPoint.x2 + min1*Direction.x2);
double min2 = Davidon(a, b, StartPoint, Direction);
printf ("Davidon min : %f (%f, %f)\n\n", min2,
StartPoint.x1 + min2*Direction.x1, StartPoint.x2 + min2*Direction.x2);
printf ("Real min : (0.500000, 1.000000)");
getch();
}