Скачиваний:
7
Добавлен:
03.06.2014
Размер:
2.64 Кб
Скачать
// bn.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"

#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <math.h>
using namespace std;
double icount =1;
double icountz=1;
double x0[2] = {0,3}, p[2];


double f(double x1, double x2) {
	return 1000*(x2-x1*x1*x1)*(x2-x1*x1*x1) + (1-x1)*(1-x1);
}

double y (double alfa) {
	return f (x0[0]+p[0]*alfa,x0[1]+p[1]*alfa);
}
double norm (double x[2])  {
	return sqrt(x[0]*x[0] + x[1]*x[1]);
}


void swann( double x, double& a, double& b, double h = 0.0001) {
	int k;

	if( y(x) < y(x+h) )
		h *= -1;
			
	for( k=0; y(x+h) < y(x); k++ ) {
		h *= 2;
		x += h;
	}
			
	if(h>0)
	{
		a=x-h;
	b=x+h;
	}
	else
	{
		a=x+h;
		b=x-h;
	
	}

	if( icount )
		icount = k;
}

double three_point_search( double a, double b, double eps = 0.0001, int* icount = NULL ) {
	double L, x_m = (a + b)/2, x_1, x_2;
	int k;
			
	for( k=0; abs(b - a) > eps; k++ ) {
		L = abs(b - a);

		x_1 = a + L/4;
		x_2 = b - L/4;


		if( y(x_1) < y(x_m) ) {
			b = x_m;
			x_m = x_1;
		}
		else if( y(x_m) <= y(x_1) && y(x_m) <= y(x_2) ) { 
			a = x_1;
			b = x_2;
		}
		else { 
			a = x_m;
			x_m = x_2;
		}
	}
	if( icountz )
		icountz = k;
	return x_m;
}


void VecCopy ( double dst[2], double src[2])  {
	dst[0] = src [0];
	dst[1] = src [1];
}

double dif (double x[2], int nom, double h = 0.0001)  {
	if (nom == 0)  { 
		return ( f(x[0] + h, x[1]) - f(x[0] - h, x[1]))/(2*h);
	}	
	else  
		return ( f(x[0], x[1] + h) - f( x[0], x[1] - h))/(2*h);
}



	

double polaka_ribera (void) {
	int k = 1;
	double g [2];
	double glast [2], beta, betaz ;
	while (1) {
		g[0] = dif(x0,0);
		g[1] = dif(x0,1);
		if (k%2) {
			VecCopy ( p, g);
		}
		else {
		beta = g[1]*(g[1]-g[0])/(glast[0]*glast[0]);
		betaz = g[1]*(g[1]-g[0])/(glast[1]*glast[1]);
		p[0] = - g[0] - beta*p[0];
		p[1] = - g[1] - betaz*p[1];
		}
		
		VecCopy (glast,g);

		double a, b;
		swann( 0,a, b ); //работаем с одномерным пространством
		double alpha = three_point_search( a, b ); //работаем с одномерным пространством

		x0[0] = x0[0] + p[0]*alpha; //получаем векторные значения
		x0[1] = x0[1] + p[1]*alpha;
		

		if (abs(norm(g)) < 0.0001)
			return alpha;

	}
}
	

int main (void) {

	double alpha = polaka_ribera();
	 cout << "Minimum function" ; cout << endl;
	 cout << (x0[0] + p[0]*alpha) ; cout << endl;

	
cout << (x0[1] + p[1]*alpha); cout << endl;
	 cout <<"Kol-vo Iteracii methoda trehtochechnogo poiska:" << icount; cout << endl;

	getch();
	
	return 0;
}
Соседние файлы в папке р 1-5, 2 вар.; 7 лаб. метод Полака Рибьера + Лекции МО + перевод ГА