Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
1
Добавлен:
01.05.2014
Размер:
3 Кб
Скачать
#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();
}
Соседние файлы в папке MO_Lab3
  • #
    01.05.20143 Кб1MO_Lab3.cpp
  • #
    01.05.201427.65 Кб1MO_Lab3.ncb
  • #
    01.05.2014903 б1MO_Lab3.sln
  • #
    01.05.20148.19 Кб1MO_Lab3.suo
  • #
    01.05.20143.38 Кб1MO_Lab3.vcproj