
Добавил:
Medi
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
// 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 лаб. метод Полака Рибьера + Лекции МО + перевод ГА