Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторные работы / Nelder_Midt / Unit1
.cpp//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include <math.h>
#include <conio.h>
#define N 3
#pragma argsused
float f(float x[]);
void mid (int n, float x0[N], float eps_max);
void lgh (int n, float F[], int *l, int *g, int *h);
void center (int n, int h, float X[], float xcp[], float d[]);
void eps(int n, float X[], float F[], float *epsx, float *epsf);
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
int n=3;
float eps_max=1e-4;
static float x0[3]={-0.5,1,0.5};
mid (n,x0,eps_max);
getch();
return 0;
}
//---------------------------------------------------------------------------
//Многомерный поиск минимума целевой функции Нелдера Мида
void mid (int n, float x0[N], float eps_max)
{
float epsx,epsf,epsx_max, epsf_max;
float X[N*(N+1)];
float F[N+1];
int P[N+1];
int p;
int M;
int l,g,h;
float *xm, fm, xr[N], fr, *xc, fc;
float alfa,beta,gamma;
float xcp[N], d[N];
float x[N];
int i,j;
if(n<=1)
{
printf("Odnomerniy poisk ne poddergivaetsya!!!\n");
exit(1);
}
else if (N<n)
{
printf("Makroopredelenie N dolgno bit ne menshe %d\n",n);
exit(1);
}
xm=x; xc=x; epsx_max=eps_max; epsf_max=eps_max;
M=1.65*n+0.05*n*n;
alfa=1; beta=0.5; gamma=2;
for(j=0; j<=n; j++)
{
for(i=0; i<n; i++)
{
if(j==0)
X[i+n*j]=x0[i];
else if(i==j-1)
X[i+n*j]=x0[i]+1;
else
X[i+n*j]=x0[i];
}
F[j]=f(&X[0+n*j]);
P[j]=0;
}
p=0;
do
{
lgh(n,F,&l,&g,&h);
center(n,h,X,xcp,d);
for(j=0; j<=n; j++)
if(P[i]>M)
h=j;
else
P[j]++;
if(h==p)
h=g;
p=h;
P[h]=0;
for(i=0; i<n; i++)
xm[i]=xcp[i]+alfa*d[i];
fm=f(xm);
if (fm<F[l])
{
for(i=0; i<n; i++)
xr[i]=xcp[i]+gamma*d[i];
fr=f(xr);
if (fr<F[l])
{
for(i=0;i<n;i++)
X[i+n*h]=xr[i];
F[h]=fr;
}
else
{
for(i=0; i<n; i++)
X[i+n*h]=xm[i];
F[h]=fm;
}
}
else if (fm<F[g])
{
for (i=0;i<n;i++)
X[i+n*h]=xm[i];
F[h]=fm;
}
else
{
if(fm<F[h])
{
for (i=0;i<n; i++)
xc[i]=xcp[i]+beta*d[i];
fc=f(xc);
}
else
{
for (i=0;i<n; i++)
xc[i]=xcp[i]+beta*d[i];
fc=f(xc);
}
if (fc<F[h])
{
for (i=0; i<n; i++)
X[i+n*h]=xc[i];
F[h]=fc;
}
else
{
for(j=0; j<=n; j++)
{
for(i=0;i<n;i++)
X[i+n*j]=(X[i+n*j]+X[i+n*l])/2;
P[j]=0;
}
}
}
eps(n,X,F,&epsx, &epsf);
}
while (epsx>=epsx_max || epsf>=epsf_max);
printf("Optimalnie parametri:\n");
for(i=0; i<n; i++)
printf("x[%d]=%f\n",i,X[i+n*l]);
printf("Minimum celevoy funkcii:%f\n",F[l]);
}
//LGH/////////////////////////////////////////////////////////////
void lgh(int n, float F[], int *l, int *g, int *h)
{
int j;
if(F[0]<F[1])
{*l=0; *h=1;}
else
{*l=1; *h=0;}
if (F[2]<F[*l])
{*g=*l; *l=2;}
else if(F[2]>F[*h])
{*g=*h; *h=2;}
else
*g=2;
for(j=3; j<=n; j++)
if (F[j]>F[*h])
{*g=*h; *h=j;}
else if (F[j]<F[*l])
*l=j;
else if (F[j]>F[*g])
*g=j;
}
///////////////////////////////////////////////////////////////////////////
///Ceneter/////////////////////////////////////////////////////////////////
void center (int n, int h, float X[], float xcp[], float d[])
{
int i,j ;
for(i=0; i<n; i++)
xcp[i]=0;
for (j=0; j<=n; j++)
if(j==h)
continue;
else
for(i=0; i<n; i++)
xcp[i]+=X[i+n*j];
for(i=0; i<n; i++)
{
xcp[i]/=n ;
d[i]=xcp[i]-X[i+n*h];
}
}
//EPS/////////////////////////////////////////////////////////////////////////
void eps(int n, float X[], float F[], float *epsx, float *epsf)
{
int i,j;
float tmp;
*epsx=0; *epsf=0; tmp=0;
for(j=0; j<=n; j++)
{
for(i=0; i<n; i++)
tmp+=(X[i+n*j]-X[i+n*0])*(X[i+n*j]-X[i+n*0]);
*epsx+=sqrt(tmp);
*epsf+=fabs(F[j]-F[0]);
tmp=0;
}
}
//F///////////////////////////////////////////////////////////////////////////
float f(float x[])
{
return (x[0]-x[1]+x[2])*(x[0]-x[1]+x[2])+(-x[0]+x[1]+x[2])*(-x[0]+x[1]+x[2])+(x[0]+x[1]-x[2])*(x[0]+x[1]-x[2]);
}