Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
2
Добавлен:
01.05.2014
Размер:
3.2 Кб
Скачать
#include <iostream.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>

int i=1;
// структура для вектора
struct vect {
			double x; //координата х
			double y; //координата у
			double z; //координата z
			double norm() {return sqrt(x*x+y*y+z*z);} //норма вектора
			 };

vect x0={2,-2,-2};
vect nol={0,0,0};
vect xe={4,-3, -0.5};
#define min(a,b) (((a)>(b))?(b):(a))// функция для определения минимума
#define max(a,b) (((a)<(b))?(b):(a))//функция для определения максимума

// возвращаем значение функции у от вектора х
double y(vect &x)
{
	return 3*(x.x-4)*(x.x-4)+5*(x.y+3)*(x.y+3)+7*(2*x.z+1)*(2*x.z+1);
}


// заданная функция
double y(double x, double y, double z)
{
	return 3*(x-4)*(x-4)+5*(y+3)*(y+3)+7*(2*z+1)*(2*z+1);
}

//считаем длину вектора
double Length(vect &x1, vect &x2)
{

	return sqrt((x1.x-x2.x)*(x1.x-x2.x)+(x1.y-x2.y)*(x1.y-x2.y)+(x1.z-x2.z)*(x1.z-x2.z));
}


//считаем производную
double dy(double a, vect &p,double e=0.001)
{
	return (y( x0.x+p.x*(a+e), x0.y+p.y*(a+e), x0.z+p.z*(a+e) )-y( x0.x+p.x*a, x0.y+p.y*a, x0.z+p.z*a))/(p.norm()*e);
}

// двигаемся вдоль прямой по направлению
inline double y(double a, vect &p)
{
return y(x0.x+p.x*a,x0.y+p.y*a,x0.z+p.z*a);
}

inline vect antiGrad(vect &point,double e=0.000001)
{
	vect px; px.x=point.x+e; px.y=point.y;   px.z=point.z;
	vect py; py.x=point.x;   py.y=point.y+e; py.z=point.z;
	vect pz; pz.x=point.x;   pz.y=point.y;   pz.z=point.z+e;
	vect res;
	res.x=-(y(px)-y(point))/e;
	res.y=-(y(py)-y(point))/e;
	res.z=-(y(pz)-y(point))/e;
	return res;
}

// метод Свенна 4
double Swann4( vect &p)
{
	double dy1=dy(0, p);// берем производную в начальной точке
	if(dy1>0)//меняем направление
	{
		p.x=-p.x;
		p.y=-p.y;
		p.z=-p.z;
		dy1=-dy1;
	}
	double a=min(2, fabs(2*(y(x0)-dy1)/dy1));
	int i=1;
	while(dy(a, p)*dy1>0)// пока производная не поменяла знак
	{
		i++;
		a*=2;// удваиваем шаг
	};
	getch();
	return a;
}


vect Dixot(vect &p)
{
	double w,q,x1=0;
	double e=0.0001;//погрешность
	double a=Swann4(p);// находим начальный шаг методом Свенна
	// устанавливаем интервал [a,b]
	double b=max(a,a/2);
			 a=min(a,a/2);
	int i=1;
	do{ w=(a+b-e)/2;
		 q=(a+b+e)/2;
		//сокращаем текущий интервал локализации
		 if( y(w, p) < y(q, p))
			b=q;
		 else
			a=w;
		 i++;

	  }while( i <= 12 );
	x1 = (a+b)/2;
		vect res1;
	res1.x=x0.x+p.x*x1;
	res1.y=x0.y+p.y*x1;
	res1.z=x0.z+p.z*x1;
	printf("\nRESULT: x= [%f, %f, %f]",res1.x,res1.y, res1.z);
	return res1;
}




//Циклический покоординатный спуск
void CPS( vect &x1, double e2=0.0001 )
{
	vect x2, res;
	vect a, p;
	printf("\nЦиклический покоординатный спуск:\n");
		p.x = 1;
		p.y = 0;
		p.z = 0;
		x2=Dixot(p);
		res.x = x2.x;
		p.x = 0;
		p.y = 1;
		p.z = 0;
		x2=Dixot(p);
		res.y = x2.y;
		p.x = 0;
		p.y = 0;
		p.z = 1;
		x2=Dixot(p);
		res.z = x2.z;
		p = antiGrad( res );
		printf( "\nNORMA GRADIENTA: %f", p.norm() );
		printf("\nTo4nuj minimym:   [%f  %f  %f] ",xe.x, xe.y, xe.z );
		printf("\nMinimum:          [%f  %f  %f]", res.x, res.y, res.z );

}

void main()
{

	clrscr();
	CPS(x0);
	getch();

}
Соседние файлы в папке Лабораторная работа №42