Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №2. Безусловная многомерная оптимизация1.doc
Скачиваний:
58
Добавлен:
02.05.2014
Размер:
287 Кб
Скачать
☆

Блок-схема метода Гаусса-Зейделя.

gradf1=11+2*x1*exp(x1*x1+0.21*x2*x2);

gradf2=-0.4+0.42*x2*exp(x1*x1+0.21*x2*x2);

p++; k=2*p;

grad[1]= gradf1 (x1[k],x2[k],1);

grad[2]= gradf2 (x1[k],x2[k],2); N1=N1+2;

нет да

да нет

x1=a+(b-a)/(l*l);

x2=a+(b-a)/l; N=N+2; E=0.0001

y1=11*( x1[k]-x1*grad1)-0.4* x2[k]+exp(pow((x1[k]-x1*grad1),2)+0.21*pow(x2[k],2))

y2=11* x1[k]-0.4*( x2[k]-x2*grad2)+exp(pow(x1[k],2)+0.21*pow((x2[k]-x2*grad2),2))

нет да

да нет

нет да

grad[1]= gradf1 (x1[k+1],x2[k+1],1);

grad[2]= gradf2 (x1[k+1],x2[k+1],2); N1=N1+2;

shag=0.17; m=0; N++;

Y1=11*( x1[k+1]-0*grad1)-0.4* x2[k+1]+exp(pow((x1[k+1]-0*grad1),2)+0.21*pow(x2[k+1],2))

C=(m+1)*shag; N++

Y2 =11* x1[k+1]-0.4*( x2[k+1]-C*grad2)+exp(pow(x1[k+1],2)+0.21*pow((x2[k+1]-C*grad2),2))

m=m+1; Y1=Y2

b=C

нет да

a=0

a=(m+1)*shag

да нет

x1=a+(b-a)/(l*l); l=1.618;

x2=a+(b-a)/l; N=N+2; E=0.0001

y1=11*( x1[k+1]-x1*grad1)-0.4* x2[k+1]+exp(pow((x1[k+1]-x1*grad1),2)+0.21*pow(x2[k+1],2))

y2=11* x1[k+1]-0.4*( x2[k+1]-x2*grad2)+exp(pow(x1[k+1],2)+0.21*pow((x2[k+1]-x2*grad2),2))

нет да

b=x2; x2=x1; y2=y1;

x1=a+b-x2; y1=f(x1);

a=x1; x1=x2; y1=y2;

x2=a+b-x1; y2=f(x2);

N=N++;

да нет

нет да

alfa=(a+x2)/2

alfa=(x1+b)/2

x2[k+2]=x2[k+1]-alfa*grad[2]

x1[k+2]=x1[k+1];

Z=sqrt( pow((x1[k+2]-x1[k]),2) + pow((x2[k+2]-x2[k]),2) )

да нет

minx1=x1[k+2];

minx2=x2[k+2];

miny=fx(x1[k+2],x2[k+2]);

Листинги программ.

Поиск по образцу

#include <iostream.h>

#include <stdio.h>

#include <math.h>

#include <conio.h>

long int t=0;

long double fx(long double x1,long double x2);

int main(){

cout<<"Metod poiska po obrazcu."<<endl;

long double **x = new long double *[2];

for(int p=0;p<5;p++)

x[p]=new long double[6];

x[1][0]=-1;

x[2][0]=0;

long double h=0.09,e=0.0001;

long double *y=new long double[6];

y[0]=fx(x[1][0],x[2][0]);

int k=0;

metka:

if (k!=1){

x[1][1]=x[1][0]-h;

x[2][1]=x[2][0]-h;

y[1]=fx(x[1][1],x[2][1]);

cout<<"x11="<<x[1][1]<<" x21="<<x[2][1]<<endl;

}

if (k!=2){

x[1][2]=x[1][0]-h;

x[2][2]=x[2][0]+h;

y[2]=fx(x[1][2],x[2][2]);

cout<<"x12="<<x[1][2]<<" x22="<<x[2][2]<<endl; }

if (k!=3){

x[1][3]=x[1][0]+h;

x[2][3]=x[2][0]+h;

y[3]=fx(x[1][3],x[2][3]);

cout<<"x13="<<x[1][3]<<" x23="<<x[2][3]<<endl; }

if (k!=4){

x[1][4]=x[1][0]+h;

x[2][4]=x[2][0]-h;

y[4]=fx(x[1][4],x[2][4]);

cout<<"x14="<<x[1][4]<<" x24="<<x[2][4]<<endl; }

k=0;

int l=1;

for(int i=1;i<5;i++) {

if(y[i]<y[l]) l=i;

}

if(y[l]<y[0]){ if(l>2) {x[1][l-2]=x[1][0];x[2][l-2]=x[2][0];y[l-2]=y[0];k=l-2;}

else {x[1][l+2]=x[1][0];x[2][l+2]=x[2][0];y[l+2]=y[0];k=l+2;}

x[1][0]=x[1][l];x[2][0]=x[2][l];y[0]=y[l];

goto metka;}

else{

h=h/2;

if(h>e){goto metka;}

else{long double minx1,minx2,minf;

minx1=x[1][0];

minx2=x[2][0];

minf=y[0];

cout<<"minx1="<<minx1<<" minx2="<<minx2<<" minf="<<minf<<endl;

cout<<"N="<<t<<endl;

getch();

return(0); }

}

}

long double fx(long double x1,long double x2){

t=t++;

long double f;

f=11*x1-0.4*x2+exp(x1*x1+0.21*x2*x2);

return(f);}

Симплекс метод

#include <iostream.h>

#include <stdio.h>

#include <math.h>

#include <conio.h>

long int t=0;

long double fx(long double x1,long double x2);

long double gradfx(long double x1,long double x2,short int r);

int i,j;

int main(){

cout<<"Metod simpleksa."<<endl;

long double **x = new long double *[2];

for(int p=1;p<3;p++)

x[p]=new long double[200];

x[1][0]=-1;

x[2][0]=0;

long double r=2.5,e=0.0001;

x[1][1]=x[1][0]+r;

x[2][1]=x[2][0];

x[1][2]=x[1][0];

x[2][2]=x[2][0]+r;

cout<<"x11="<<x[1][1]<<" x21="<<x[2][1]<<endl;

cout<<"x12="<<x[1][2]<<" x22="<<x[2][2]<<endl;

long double *y=new long double[4]; //y3=y

y[0]=fx(x[1][0],x[2][0]);

y[1]=fx(x[1][1],x[2][1]);

y[2]=fx(x[1][2],x[2][2]);

long double c1,c2,u1,u2;

int l1,l2;

metka:

l1=0,l2=0;

for(int i=0;i<3;i++) {

if(y[i]<y[l1]) l1=i;

}

for(int j=0;j<3;j++) {

if(y[j]>y[l2]) l2=j;

}

if(r>e){c1=0,c2=0;

for(int i=0;i<3;i++)

if(i!=l2) {c1+=x[1][i];c2+=x[2][i];}

c1/=2; c2/=2;

u1=2*c1-x[1][l2];

u2=2*c2-x[2][l2];

y[3]=fx(u1,u2);

//постоение нового симплекса

if(y[3]<y[l2]){x[1][l2]=u1;x[2][l2]=u2;y[l2]=y[3];

cout<<""<<x[1][l2]<<","<<x[2][l2]<<endl;}

else{ //cout<<"u1="<<u1<<" u2="<<u2<<endl;

for(int i=0;i<3;i++)

if(i!=l1){ x[1][i]=(x[1][i]+x[1][l1])/2;

x[2][i]=(x[2][i]+x[2][l1])/2;

y[i]=fx(x[1][i],x[2][i]);

cout<<""<<x[1][i]<<","<<x[2][i]<<endl;

}

r=r/2;

}

goto metka;

}

else{

long double minx1,minx2,minf;

minx1=x[1][l1];

minx2=x[2][l1];

minf=y[l1];

cout<<"minx1="<<minx1<<" minx2="<<minx2<<" minf="<<minf<<endl;

cout<<"N="<<t<<endl;

getch();

return(0);}

}

long double fx(long double x1,long double x2){

t++;

long double f;

f=11*x1-0.4*x2+exp(x1*x1+0.21*x2*x2);

return(f);}

Градиентный метод с дроблением шага

#include <iostream.h>

#include <stdio.h>

#include <math.h>

long int t=0,a=0;

long double fx(long double x1,long double x2);

long double gradfx(long double x1,long double x2,short int r);

int main(){

cout<<"gradientnii metod s drobleniem shaga."<<endl;

long double *x1=new long double [562];

long double *x2=new long double [562];

x1[0]=-1;

x2[0]=0;

long double alfa=0.39,e=0.0001,delta=0.1;

long double minx1,minx2,minf;

int k=0;

long double *grad = new long double [5];

long double D,y,z1;

grad[1]=gradfx(x1[0],x2[0],1);

grad[2]=gradfx(x1[0],x2[0],2);

D=pow(grad[1],2)+pow(grad[2],2);

metka2:

y=fx(x1[k],x2[k]);

metka:

z1=fx(x1[k]-alfa*grad[1],x2[k]-alfa*grad[2]);

if((z1-y)>-(alfa*delta*D)) {alfa=alfa/2; goto metka; }

else{

x1[k+1]=x1[k]-alfa*grad[1];

x2[k+1]=x2[k]-alfa*grad[2];

grad[1]=gradfx(x1[k+1],x2[k+1],1);

grad[2]=gradfx(x1[k+1],x2[k+1],2);

D=pow(grad[1],2)+pow(grad[2],2);}

if(sqrt(D)>e) { k++; goto metka2; }

else{

minx1=x1[k+1];

minx2=x2[k+1];

minf=fx(minx1,minx2);}

cout<<"minx1="<<minx1<<" minx2="<<minx2<<" minf="<<minf<<endl;

cout<<"N="<<t+a<<endl;

cout<<"k="<<k<<endl;

return(0);

}

long double fx(long double x1,long double x2){

a++; long double f;

f=11*x1-0.4*x2+exp(x1*x1+0.21*x2*x2);

return(f);}

long double gradfx(long double x1,long double x2,short int r){

::t++;

long double gradf;

if (r==1)

gradf=11+2*x1*exp(x1*x1+0.21*x2*x2);

if (r==2)

gradf=-0.4+0.42*x2*exp(x1*x1+0.21*x2*x2);

return(gradf);

}

Метод Гаусса-Зейделя

#include <iostream.h>

#include <stdio.h>

#include <math.h>

#include <conio.h>

int COUNT_F,COUNT_GRAD;

double function( double x1, double x2);

double proiz( double x1, double x2,short int r);

double odn_alg( double X1, double X2,short int s);

double __function(const double X1,const double X2, double alfa, double grad1, double grad2,short int v);

void ab(double &a,double &b,const double X1,const double X2,double grad1,double grad2,short int u);

int main(){

double x1[1000];

double x2[1000];

int p=-1,k;

x1[0]=-1;

x2[0]=0;

double grad[3]; double e=0.0001;double alfa;

cout<<"Metod Gayssa-Zeidela"<<endl;

do{

p++; k=2*p;

grad[1]=proiz(x1[k],x2[k],1);

alfa=odn_alg(x1[k],x2[k],1);

x1[k+1]=x1[k]-alfa*grad[1];

x2[k+1]=x2[k];

cout<<"x11="<<x1[k+1]<<" x21="<<x2[k+1]<<endl;

grad[2]=proiz(x1[k+1],x2[k+1],2);

alfa=odn_alg(x1[k+1],x2[k+1],2);

x2[k+2]=x2[k+1]-alfa*grad[2];

x1[k+2]=x1[k+1];

cout<<"x12="<<x1[k+2]<<" x22="<<x2[k+2]<<endl;

}while( sqrt( pow((x1[k+2]-x1[k]),2) + pow((x2[k+2]-x2[k]),2) ) > e);

double minx1,minx2,miny;

minx1=x1[k+2];

minx2=x2[k+2];

miny=function(x1[k+2],x2[k+2]);

printf("~x=(%f,%f),~y=%f,iterations=%i,func=%i,grad=%i\n",x1[k+2],x2[k+2],miny,k,COUNT_F-1,COUNT_GRAD);

getch();

return(0);

}

double function( double x1, double x2){

double f;

f=11*x1-0.4*x2+exp(x1*x1+0.21*x2*x2);

COUNT_F++;

return(f);}

double proiz( double x1, double x2,short int r){

COUNT_GRAD++;

double gradf;

if (r==1)

gradf=11+2*x1*exp(x1*x1+0.21*x2*x2);

if (r==2)

gradf=-0.4+0.42*x2*exp(x1*x1+0.21*x2*x2);

return(gradf);

}

double __function(const double X1,const double X2, double alfa, double grad1, double grad2,short int v)

{

COUNT_F++;

double rezt;

if(v==1)

rezt=11*(X1-alfa*grad1)-0.4*X2+exp(pow((X1-alfa*grad1),2)+0.21*pow(X2,2));

if(v==2)

rezt=11*X1-0.4*(X2-alfa*grad2)+exp(pow(X1,2)+0.21*pow((X2-alfa*grad2),2));

return(rezt);

}

inline double odn_alg( double X1, double X2,short int s){ //МЗС

double const l=(1+sqrt(5))/2;

double a,b,x1,x2,y1,y2,minx,z,E=0.0001;

double *grad=new double[3];

if(s==1)

{

ab(a,b,X1,X2,grad[1],grad[2],1);

x1=a+(b-a)/(l*l);

x2=a+(b-a)/l;

y1=__function(X1,X2,x1,grad[1],grad[2],1);

y2=__function(X1,X2,x2,grad[1],grad[2],1);

metka: {

if (y1<=y2) {

b=x2; x2=x1; y2=y1; x1=a+b-x2;

y1=__function(X1,X2,x1,grad[1],grad[2],1);}

else {

a=x1; x1=x2; y1=y2; x2=a+b-x1;

y2=__function(X1,X2,x2,grad[1],grad[2],1);}

}

z=(b-a)/(2*l);

if(z>E)

{ goto metka;}

else if(y1<y2)

{minx=(a+x2)/2;}

else

{minx=(x1+b)/2;}

}

else

{

ab(a,b,X1,X2,grad[1],grad[2],2);

x1=a+(b-a)/(l*l);

x2=a+(b-a)/l;

y1=__function(X1,X2,x1,grad[1],grad[2],2);

y2=__function(X1,X2,x2,grad[1],grad[2],2);

met: {

if (y1<=y2) {

b=x2; x2=x1; y2=y1; x1=a+b-x2;

y1=__function(X1,X2,x1,grad[1],grad[2],2);}

else {

a=x1; x1=x2; y1=y2; x2=a+b-x1;

y2=__function(X1,X2,x2,grad[1],grad[2],2);}

}

z=(b-a)/(2*l);

if(z>E)

{ goto met;}

else if(y1<y2)

{minx=(a+x2)/2;}

else

{minx=(x1+b)/2;}

}

return(minx);}

void ab(double &a,double &b,const double X1,const double X2,double grad1,double grad2,short int u)

{

double m=0,C,Y1,Y2;

double *grad=new double[3];

grad[1]=proiz(X1,X2,1);

grad[2]=proiz(X1,X2,2);

if(u==1)

{

long double shag=0.019;

Y1=__function(X1,X2,0,grad[1],grad[2],1);

metka2:

C=(m+1)*shag;

Y2=__function(X1,X2,C,grad[1],grad[2],1);

if(Y2<Y1) { m=m+1; Y1=Y2; goto metka2;}

else { b=C; }

if(m==0) {a=0;}

else {a=(m+1)*shag; }

}

else //u=2

{long double shag=0.17;

Y1=__function(X1,X2,0,grad[1],grad[2],2);

met2:

C=(m+1)*shag;

Y2=__function(X1,X2,C,grad[1],grad[2],2);

if(Y2<Y1) { m=m+1; Y1=Y2; goto met2;}

else { b=C; }

if(m==0) {a=0;}

else {a=(m+1)*shag; }

}

return;

}