
- •1.Одномерная оптимизация. Метод «золотого сечения»
- •2. Условная нелинейная оптимизация. Применение теоремы Джона-Куна-Таккера
- •3.Линейное программирование. Симплекс-метод.
- •4.Исследование множества на выпуклость
- •5.Исследование функции на выпуклость
- •6.Исследование функции на овражность
- •7. Безусловная оптимизация неквадратичной функции овражной структуры. Метод Дэвидона-Флетчера-Пауэлла
- •8. Сведение задачи условной оптимизации к безусловной задаче оптимизации.
- •8.1. Метод внешних штрафных функций
- •8.2. Метод возможных направлений Зойтендейка
- •9.Вывод
- •10.Список литературы
- •11.Приложения
- •10.1. Одномерный поиск. Метод «золотого сечения».
- •10.2. Многомерный поиск минимума функций и добавленный метод внешних штрафных функций. Метод Дэвидона-Флетчера-Пауэлла.
10.2. Многомерный поиск минимума функций и добавленный метод внешних штрафных функций. Метод Дэвидона-Флетчера-Пауэлла.
Описание программы:
Программа реализует метод Дэвидона-Флетчера-Пауэлла. Находится минимум функций двух переменных.
В меню программы можно выбрать ход программы, а именно:
Запуск тестовой (квадратичной) функции двух переменны, взятой из задания на исследование овражности функции.
Запуск поиска минимума неквадратичной функции овражной структуры, овражность которой усиливается при увеличении значений переменных
. (См. раздел 7)
Запуск поиска минимума задачи на условный минимум квадратичной функции. Реализуется метод внешних штрафов с применение метода многомерного поиска минимума Дэвидона-Флетчера-Пауэлла.
По завершению программа выдает точку минимума и значение функции в этой точки. Все промежуточные выводы вычислений, которые помогают отследить правильность выполнения программы, изъяты, т.к. не являются обязательными.
Программа написана в среде 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:;
}