Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
137
Добавлен:
07.08.2013
Размер:
925.82 Кб
Скачать

10.2. Многомерный поиск минимума функций и добавленный метод внешних штрафных функций. Метод Дэвидона-Флетчера-Пауэлла.

Описание программы:

Программа реализует метод Дэвидона-Флетчера-Пауэлла. Находится минимум функций двух переменных.

В меню программы можно выбрать ход программы, а именно:

  1. Запуск тестовой (квадратичной) функции двух переменны, взятой из задания на исследование овражности функции.

  2. Запуск поиска минимума неквадратичной функции овражной структуры, овражность которой усиливается при увеличении значений переменных . (См. раздел 7)

  3. Запуск поиска минимума задачи на условный минимум квадратичной функции. Реализуется метод внешних штрафов с применение метода многомерного поиска минимума Дэвидона-Флетчера-Пауэлла.

По завершению программа выдает точку минимума и значение функции в этой точки. Все промежуточные выводы вычислений, которые помогают отследить правильность выполнения программы, изъяты, т.к. не являются обязательными.

Программа написана в среде Microsoft Visual Studio 2010.

Листинг:

#include <iostream>;

#include <math.h>;

using namespace std;

//размерность Евклидова пространства

const int n=2;

//создание нестандартных наименований типов

typedef int counters;

typedef int number_of_iteration;

typedef double step;

typedef double fine;

typedef double accuracy;

typedef double norm_gradient;

typedef double point [n];

typedef double difference_of_points [n];

typedef double gradient [n];

typedef double difference_of_grad [n];

typedef double direction [n];

typedef double matrix [n][n];

typedef double Hessian_matrix [n][n];

typedef double Determ_Hess_matr;

double phi(fine p,point x)

{

double g1=0,g2=0;

g1=2*x[0]+3*x[1]-6;

g2=2*x[0]+x[1]-4;

return (p*0.125)*( (abs(g1)+g1)*(abs(g1)+g1)+(abs(g2)+g2)*(abs(g2)+g2) );

}

double f(char var,fine p,point &x)

{

if (var=='1') return x[0]*x[0]-3*x[0]*x[1]+10*x[1]*x[1]+5*x[0]-3*x[1];

if (var=='2') return sqrt(1+2*x[0]+x[1]*x[1])+exp(x[0]*x[0]+2*x[1]*x[1])-x[0]-x[1];

if (var=='3') return x[0]*x[0]-2*x[0]-x[1]+phi(p,x);

}

double psy(char var,fine p,step s,point &x, direction &d)

{

double sum1=0,sum2=0,sum3=0;

double g1=0,g2=0;

if (var=='1')

{

sum1=d[0]*d[0]-3*d[0]*d[1]+10*d[1]*d[1];

sum2=2*x[0]*d[0]-3*x[1]*d[0]-3*x[0]*d[1]+20*x[1]*d[1]+5*d[0]-3*d[1];

sum3=x[0]*x[0]-3*x[0]*x[1]+10*x[1]*x[1]+5*x[0]-3*x[1];

return s*s*sum1+s*sum2+sum3;

}

if (var=='2')

{

sum1=sqrt( (1+2*x[0]+x[1]*x[1]) + 2*s*(d[0]+x[1]*d[1]) + s*s*(d[1]*d[1]) );

sum2=exp( (x[0]*x[0]+2*x[1]*x[1])+2*s*(x[0]*d[0]+2*x[1]*d[1])+s*s*(d[0]*d[0]+2*d[1]*d[1]) );

sum3=x[0]+x[1]+s*(d[0]+d[1]);

return sum1+sum2-sum3;

}

if (var=='3')

{

g1=2*x[0]+3*x[1]+s*(2*d[0]+3*d[1])-6;

g2=2*x[0]+x[1]+s*(2*d[0]+d[1])-4;

sum1=2*x[0]*d[0]-2*d[0]-d[1];

sum2=x[0]*x[0]-2*x[0]-x[1];

sum3=(p*0.125)*( (abs(g1)+g1)*(abs(g1)+g1)+(abs(g2)+g2)*(abs(g2)+g2) );

return ( s*s*d[0]*d[0]+s*sum1+sum2+sum3 );

}

}

double diff(char &var,fine p,counters i,counters j, point &x)

{

accuracy h=0.000000001;

point dx;

for(j=0;j<n;j++) {dx[j]=x[j];}

dx[i]=dx[i]+h;

return ((f(var,p,dx)-f(var,p,x))/h);

}

double d_diff(char &var,fine p,counters i,point &x)

{

accuracy h=0.00001;

double result=0;

double f1=0,f2=0,f3=0;

double dx[n];

counters j=0;

for(j=0;j<n;j++){dx[j]=x[j];}

dx[i]=x[i]+h; f1=f(var,p,dx);

f2=f(var,p,x);

dx[i]=x[i]-h; f3=f(var,p,dx);

result=(f1-2*f2+f3)/(h*h);

if (abs(result)<0.001) result=0;

return result;

}

double mixdiff(char &var,fine p,counters i,counters j,point &x)

{

accuracy h=0.00001;

double result=0;

double f1=0,f2=0,f3=0,f4=0;

double dx[n];

counters k=0;

for(k=0;k<n;k++) {dx[k]=x[k];}

f1=f(var,p,x);

dx[i]=dx[i]-h; f2=f(var,p,dx);

dx[j]=dx[j]-h; f4=f(var,p,dx);

dx[i]=dx[i]+h; f3=f(var,p,dx);

result=(f1-f2-f3+f4)/(h*h);

if (abs(result)<0.001) result=0;

return result;

}

void Hessian(char &var,fine p,point &x,Hessian_matrix &H,Determ_Hess_matr &dH)

{

counters i=0,j=0;

dH=0;

cout<<endl<<"Матрица Гесса: "<<endl;

for(i=0;i<n;i++)

{

for(j=0;j<n;j++)

{

H[i][j]=mixdiff(var,p,i,j,x);

H[i][i]=d_diff(var,p,i,x);

cout<<" "<<H[i][j];

}

cout<<endl;

}

dH=H[0][0]*H[1][1]-H[0][1]*H[1][0];

cout<<"Определитель матрицы Гесса: "<<dH<<endl;

}

void step_0(char &var,counters i, counters j, accuracy &eps, point &x, matrix &D)

{

cout<<endl<<"Список: "<<endl<<endl;

cout<<"1.Тестовая функция "<<endl;

cout<<"2.Неквадратичная (основная) функция "<<endl;

cout<<"3.Условная минимизация.Метод внешних штрафных функций"<<endl;

repeat:

cout<<endl<<"Пункт: ";

cin>>var;

if ((var=='1')||(var=='2')||(var=='3')) {;}

else {cout<<endl<<"Выберете пункт из списка!"<<endl; goto repeat;}

cout<<endl<<"Задайте точность:\t";

cin>>eps;

cout<<endl<<"Ввод начальной точки Х в "<<n<<"-мерном Евклидовом";

cout<<endl<<"пространстве, при k=0(можно в строчку, разделяя пробелами)";

cout<<endl;

for (i=0;i<n;i++) { cin>>x[i]; if (i==n-1) {break;} }

//присвоение вида D=Е (при k=0)

for (i=0;i<n;i++) {for (j=0;j<n;j++) {D[i][j]=0; D[i][i]=1;}}

}

void step_1(counters i, counters j, gradient &g, direction &d, matrix &D)

{

for(i=0;i<n;i++){d[i]=0;}

for(i=0;i<n;i++){ for(j=0;j<n;j++){ d[i]=d[i]+D[i][j]*g[j]; } }

for(i=0;i<n;i++){ d[i]=-d[i]; }

cout<<"Направление{ d(x)=-D*f'(x) }: "<<endl;

for(i=0;i<n;i++){cout<<d[i]<<endl;}

}

void step_2(char &var,fine p,step &s,point &x,direction &d)

{

double a=-1000, b=1000;

double const1=0.381966, const2=0.618033;

double alfa=0, bett=0;

double F1=0,F2=0;

double eps=0.000000001;

alfa=a+const1*(b-a);

bett=a+const2*(b-a);

while(const2*(b-a)>=eps)

{

F1=psy(var,p,alfa,x,d);

F2=psy(var,p,bett,x,d);

if (F1>F2)

{

a=alfa;

alfa=bett;

bett=a+const2*(b-a);

}

else

{

b=bett;

bett=alfa;

alfa=a+const1*(b-a);

}

};

F1=psy(var,p,alfa,x,d);

F2=psy(var,p,bett,x,d);

if (F1>F2) s=bett;

else s=alfa;

cout<<"Шаг S: "<<s<<""<<endl;

}

void step_3(char &var,fine p,difference_of_points &U,difference_of_grad &V,step s,point &x,direction &d)

{

counters i=0,j=0,k=1;

gradient g;

for(i=0;i<n;i++) {U[i]=-x[i];}

for (i=0;i<n;i++){g[i]=diff(var,p,i,j,x); if (abs(g[i])<0.0001) g[i]=0;}

for(i=0;i<n;i++) {V[i]=-g[i];}

for(i=0;i<n;i++) {x[i]=x[i]+s*d[i];}

for(i=0;i<n;i++) {U[i]=U[i]+x[i];}

for (i=0;i<n;i++){g[i]=diff(var,p,i,j,x); if (abs(g[i])<0.0001) g[i]=0;}

for(i=0;i<n;i++) {V[i]=V[i]+g[i];}

for(i=0;i<n;i++) {cout<<x[i]<<endl;}

cout<<endl<<"Разность точек U: "<<endl;

for(i=0;i<n;i++) {cout<<U[i]<<endl;}

cout<<endl<<"Разность градиентов V: "<<endl;

for(i=0;i<n;i++) {cout<<V[i]<<endl;}k++;

}

void step_4(counters i,norm_gradient &norm,gradient &g)

{

norm=0;

for (i=0;i<n;i++) {norm=norm+g[i]*g[i];}

norm=sqrt(norm);

}

void step_5(difference_of_points U,difference_of_grad V,matrix &D)

{ counters i=0, j=0;

point l,m;

double A1=0,B1=0;

matrix A, B;

for(i=0;i<n;i++) { m[i]=0; l[i]=0; }

for(i=0;i<n;i++) { A1=A1+U[i]*V[i]; }

for(i=0;i<n;i++) { for(j=0;j<n;j++) { A[i][j]=(U[i]*U[j])/A1; } }

for(i=0;i<n;i++) { for(j=0;j<n;j++) { m[i]=m[i]+D[i][j]*V[j]; } }

for(i=0;i<n;i++) { B1=B1+V[i]*m[i]; }

for(i=0;i<n;i++) { for(j=0;j<n;j++) { l[i]=l[i]+V[j]*D[j][i]; } }

for(i=0;i<n;i++) { for(j=0;j<n;j++) { B[i][j]=((-1)*(m[i]*l[j]))/B1; } }

for(i=0;i<n;i++) { for(j=0;j<n;j++) { D[i][j]=D[i][j]+A[i][j]+B[i][j]; } }

cout<<endl<<"Матрица A: "<<endl;

for(i=0;i<n;i++)

{for(j=0;j<n;j++){cout<<" "<<A[i][j]<<" ";}cout<<endl;}

cout<<endl<<"Матрица В: "<<endl;

for(i=0;i<n;i++)

{for(j=0;j<n;j++){cout<<" "<<B[i][j]<<" ";}cout<<endl;}

cout<<endl<<"Матрица D (k=k+1): "<<endl;

for(i=0;i<n;i++)

{for(j=0;j<n;j++){cout<<" "<<D[i][j]<<" ";}cout<<endl;}

}

void main()

{

//Включаем вывод русских символов в консоль

setlocale(LC_ALL,"Russian");

char var;

counters i=0, j=0;

number_of_iteration k=0;

double c=5;

step s=0;

fine p=0.1;

accuracy eps=0;

accuracy fine_eps;

norm_gradient norm=0;

point x;

difference_of_points U;

gradient g;

difference_of_grad V;

direction d;

matrix D;

Hessian_matrix H;

Determ_Hess_matr dH;

step_0(var,i,j,eps,x,D);

if (var=='3')

{

cout<<endl<<"Точность метода штрафных функций: ";

cin>>fine_eps;

}

cout<<endl;

Hessian(var,p,x,H,dH);

if (dH<=0)

{

cout<<endl<<”Функций в данной области не имеет минимума: ”<<endl;

goto end;

}

cout<<endl<<"Градиент при k="<<k<<": "<<endl;

for (i=0;i<n;i++)

{

g[i]=diff(var,p,i,j,x);

if (abs(g[i])<0.0001) g[i]=0;

cout<<g[i]<<endl;

}

step_4(i,norm,g);

cout<<endl<<"Норма градиента при k="<<k<<": "<<norm<<endl;

//Реализация метода внешних штрафных функций(3 пункт)

switch (var)

{case '3': while (phi(p,x)>=fine_eps)

{

do

{

cout<<endl; for (i=0;i<20;i++) cout<<"|||";

cout<<endl<<"Итерация: "<<k<<endl<<endl;

step_1(i,j,g,d,D);

step_2(var,p,s,x,d);

cout<<endl<<"Следующая точка при k="<<k+1<<": "<<endl;

step_3(var,p,U,V,s,x,d);

cout<<endl<<"Градиент: "<<endl;

for (i=0;i<n;i++)

{

g[i]=diff(var,p,i,j,x);

if (abs(g[i])<0.0001) g[i]=0;

cout<<g[i]<<endl;

}

step_4(i,norm,g);

cout<<endl<<"Норма градиента: "<<norm<<endl;

step_5(U,V,D);

k++;

}

while (norm>eps);

p=c*p;

for (i=0;i<n;i++)

{

g[i]=diff(var,p,i,j,x);

if (abs(g[i])<0.0001) g[i]=0;

}

step_4(i,norm,g);

} break;

default: while (norm>eps)

{

cout<<endl; for (i=0;i<20;i++) cout<<"|||";

cout<<endl<<"Итерация: "<<k<<endl<<endl;

step_1(i,j,g,d,D);

step_2(var,p,s,x,d);

cout<<endl<<"Следующая точка при k="<<k+1<<": "<<endl;

step_3(var,p,U,V,s,x,d);

cout<<endl<<"Градиент: "<<endl;

for (i=0;i<n;i++)

{

g[i]=diff(var,p,i,j,x);

if (abs(g[i])<0.0001) g[i]=0;

cout<<g[i]<<endl;

}

step_4(i,norm,g);

cout<<endl<<"Норма градиента: "<<norm<<endl;

step_5(U,V,D);

k++;

}break;

}

cout<<endl; for (i=0;i<20;i++) cout<<"|||";

cout<<endl<<endl<<"Конец вычислений: "<<endl;

cout<<endl<<"Точка минимума при k="<<k<<": "<<endl;

for(i=0;i<n;i++) {cout<<x[i]<<endl;}

cout<<endl<<"Значение функции k="<<k<<": "<<endl;

cout<<f(var,p,x)<<endl;

end:;

}

Соседние файлы в папке курсовая docx40