极值问题

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "MatrixAlgo.h"
#include "Extremum.h"

//一维极值连分式法
void jmax1(double x[2], double eps, int k, int js[2])
{
 int i,j,m,jt;
 double xx,h1,h2,dx,y[10],b[10],z[2];
 js[0]=0;
 jt=1;
 h2=0.0;
 while (jt==1)
 {
  j=0;
  while (j<=7)
  {
   if (j<=2)
    xx=x[0]+0.01*j;
   else
    xx=h2;
   jmax1f(xx,z);
   if (fabs(z[1])<eps)
   {
    jt=0;
    j=10;
   }
   else
   {
    h1=z[1];
    h2=xx;
    if (j==0)
    {
     y[0]=h1;
     b[0]=h2;
    }
    else
    {
     y[j]=h1;
     m=0;
     i=0;
     while ((m==0)&&(i<=j-1))
     {
      if (fabs(h2-b[i])+1.0==1.0)
       m=1;
      else
       h2=(h1-y[i])/(h2-b[i]);
      i=i+1;
     }
     b[j]=h2;
     if (m!=0)
      b[j]=1.0e+35;
     h2=0.0;
     for (i=j-1; i>=0; i--)
      h2=-y[i]/(b[i+1]+h2);
     h2=h2+b[0];
    }
    j=j+1;
   }
  }
  x[0]=h2;
  js[0]=js[0]+1;
  if (js[0]==k)
   jt=0;
 }
 xx=x[0];
 jmax1f(xx,z);
 x[1]=z[0];
 if (fabs(x[0])<=1.0)
  dx=1.0e-05;
 else
  dx=fabs(x[0]*1.0e-05);
 xx=x[0]-dx;
 jmax1f(xx,z);
 h1=z[0];
 xx=x[0]+dx;
 jmax1f(xx,z);
 h2=z[0];
 js[1]=-1;
 if ((h1+h2-2.0*x[1])<=0.0)
  js[1]=1;
 return;
}


//n维极值连分式法
void jmaxn(double x[], int n, double eps, int k, int js[])
{
 int i,j,m,l,jt,il;
 double y[10],b[10],p,z,t,h1,h2,f,dx;
 js[0]=0;
 jt=1;
 h2=0.0;
 while (jt==1)
 {
  t=0.0;
  js[0]=js[0]+1;
  for (i=1; i<=n; i++)
  {
   f=jmaxnf(x,n,i);
   t=t+fabs(f);
  }
  if (t<eps)
   jt=0;
  else
  {
   for (i=0; i<=n-1; i++)
   {
    il=5;
    while (il!=0)
    {
     j=0;
     t=x[i];
     il=il-1;
     while (j<=7)
     {
      if (j<=2)
       z=t+j*0.01;
      else
       z=h2;
      x[i]=z;
      f=jmaxnf(x,n,i+1);
      if (fabs(f)+1.0==1.0)
      {
       j=10;
       il=0;
      }
      else
      {
       h1=f;
       h2=z;
       if (j==0)
       {
        y[0]=h1;
        b[0]=h2;
       }
       else
       {
        y[j]=h1;
        m=0;
        l=0;
        while ((m==0)&&(l<=j-1))
        {
         p=h2-b[l];
         if (fabs(p)+1.0==1.0)
          m=1;
         else
          h2=(h1-y[l])/p;
         l=l+1;
        }
        b[j]=h2;
        if (m!=0)
         b[j]=1.0e+35;
        h2=0.0;
        for (l=j-1; l>=0; l--)
         h2=-y[l]/(b[l+1]+h2);
        h2=h2+b[0];
       }
       j=j+1;
      }
     }
     x[i]=h2;
    }
    x[i]=z;
   }
   if (js[0]==k)
    jt=0;
  }
 }
 js[1]=1;
 f=jmaxnf(x,n,0);
 x[n]=f;
 dx=0.00001;
 t=x[0];
 x[0]=t+dx;
 h1=jmaxnf(x,n,0);
 x[0]=t-dx;
 h2=jmaxnf(x,n,0);
 x[0]=t;
 t=h1+h2-2.0*f;
 if (t>0.0)
  js[1]=-1;
 j=1;
 jt=1;
 while (jt==1)
 {
  j=j+1;
  dx=0.00001;
  jt=0;
  t=x[j-1];
  x[j-1]=t+dx;
  h2=jmaxnf(x,n,0);
  x[j-1]=t-dx;
  h1=jmaxnf(x,n,0);
  x[j-1]=t;
  t=h1+h2-2.0*f;
  if ((t*js[1]<0.0)&&(j<n))
   jt=1;
 }
 if (t*js[1]>0.0)
  js[1]=0;
 return;
}

//不等式约束线性规划问题
int jlplq(double a[], double b[], double c[], int m, int n, double x[])
{
 int i,mn,k,j,l,*js;
 double s,z,dd,y,*p,*d;
 js=(int *)malloc(m*sizeof(int));
 p=(double *)malloc(m*m*sizeof(double));
 d=(double *)malloc(m*(m+n)*sizeof(double));
 for (i=0; i<=m-1; i++)
  js[i]=n+i;
 mn=m+n;
 s=0.0;
 while (1==1)
 {
  for (i=0; i<=m-1; i++)
   for (j=0; j<=m-1; j++)
    p[i*m+j]=a[i*mn+js[j]];
  l=brinv(p,m);
  if (l==0)
  {
   x[n]=s;
   free(js);
   free(p);
   free(d);
   return(l);
  }
  brmul(p,a,m,m,mn,d);
  for (i=0; i<=mn-1; i++)
   x[i]=0.0;
  for (i=0; i<=m-1; i++)
  {
   s=0.0;
   for (j=0; j<=m-1; j++)
    s=s+p[i*m+j]*b[j];
   x[js[i]]=s;
  }
  k=-1;
  dd=1.0e-35;
  for (j=0; j<=mn-1; j++)
  {
   z=0.0;
   for (i=0; i<=m-1; i++)
    z=z+c[js[i]]*d[i*mn+j];
   z=z-c[j];
   if (z>dd)
   {
    dd=z;
    k=j;
   }
  }
  if (k==-1)
  {
   s=0.0;
   for (j=0; j<=n-1; j++)
    s=s+c[j]*x[j];
   x[n]=s;
   free(js);
   free(p);
   free(d);
   return(1);
  }
  j=-1;
  dd=1.0e+20;
  for (i=0; i<=m-1; i++)
   if (d[i*mn+k]>=1.0e-20)
   {
    y=x[js[i]]/d[i*mn+k];
    if (y<dd)
    {
     dd=y;
     j=i;
    }
   }
  if (j==-1)
  {
   x[n]=s;
   free(js);
   free(p);
   free(d);
   return(0);
  }
  js[j]=k;
 }
}

//求n维极值的单形调优法
int jjsim(int n, double d, double u, double v, double x[], double eps, int k, double xx[], double f[])
{
 int r,g,i,j,l,kk;
 double nn,fe,fr,fl,fg,ft,ff;
 double *xt,*xf,*xe;
 xt=(double *)malloc(n*sizeof(double));
 xf=(double *)malloc(n*sizeof(double));
 xe=(double *)malloc(n*sizeof(double));
 kk=0;
 nn=1.0*n;
 fr=sqrt(nn+1.0);
 fl=d*(fr-1.0)/(1.414*nn);
 fg=d*(fr+nn-1.0)/(1.414*nn);
 for(i=0; i<=n-1; i++)
  for(j=0; j<=n; j++)
   xx[i*(n+1)+j]=0.0;
 for(i=1; i<=n; i++)
  for(j=0; j<=n-1; j++)
   xx[j*(n+1)+i]=fl;
 for(i=1; i<=n; i++)
  xx[(i-1)*(n+1)+i]=fg;
 for(i=0; i<=n; i++)
 {
  for(j=0; j<=n-1; j++)
  {
   xt[j]=xx[j*(n+1)+i];
  }
  f[i]=jjsimf(xt,n);
 }
 ft=1.0+eps;
 while ((kk<k)&&(ft>eps))
 {
  kk=kk+1;
  fr=f[0];
  fl=f[0];
  r=0;
  l=0;
  for (i=1; i<=n; i++)
  {
   if (f[i]>fr)
   {
    r=i;
    fr=f[i];
   }
   if (f[i]<fl)
   {
    l=i;
    fl=f[i];
   }
  }
  g=0;
  fg=f[0];
  j=0;
  if (r==0)
  {
   g=1;
   fg=f[1];
   j=1;
  }
  for (i=j+1; i<=n; i++)
   if ((i!=r)&&(f[i]>fg))
   {
    g=i;
    fg=f[i];
   }
  for (j=0; j<=n-1; j++)
  {
   xf[j]=0.0;
   for (i=0; i<=n; i++)
    if (i!=r)
     xf[j]=xf[j]+xx[j*(n+1)+i]/nn;
   xt[j]=2.0*xf[j]-xx[j*(n+1)+r];
  }
  ft=jjsimf(xt,n);
  if (ft<f[l])
  {
   for (j=0; j<=n-1; j++)
    xf[j]=(1.0+u)*xt[j]-u*xf[j];
   ff=jjsimf(xf,n);
   if (ff<f[l])
   {
    for (j=0; j<=n-1; j++)
     xx[j*(n+1)+r]=xf[j];
    f[r]=ff;
   }
   else
   {
    for (j=0; j<=n-1; j++)
     xx[j*(n+1)+r]=xt[j];
    f[r]=ft;
   }
  }
  else
  {
   if (ft<=f[g])
   {
    for (j=0; j<=n-1; j++)
     xx[j*(n+1)+r]=xt[j];
    f[r]=ft;
   }
   else
   {
    if (ft<=f[r])
    {
     for (j=0; j<=n-1; j++)
      xx[j*(n+1)+r]=xt[j];
     f[r]=ft;
    }
    for (j=0; j<=n-1; j++)
     xf[j]=v*xx[j*(n+1)+r]+(1.0-v)*xf[j];
    ff=jjsimf(xf,n);
    if (ff>f[r])
     for (i=0; i<=n; i++)
     {
      for (j=0; j<=n-1; j++)
      {
       xx[j*(n+1)+i]=(xx[j*(n+1)+i]+xx[j*(n+1)+l])/2.0;
       x[j]=xx[j*(n+1)+i];
       xe[j]=x[j];
      }
      fe=jjsimf(xe,n);
      f[i]=fe;
     }
    else
    {
     for (j=0; j<=n-1; j++)
      xx[j*(n+1)+r]=xf[j];
     f[r]=ff;
    }
   }
  }
  ff=0.0;
  ft=0.0;
  for (i=0; i<=n; i++)
  {
   ff=ff+f[i]/(1.0+nn);
   ft=ft+f[i]*f[i];
  }
  ft=(ft-(1.0+n)*ff*ff)/nn;
 }
 for (j=0; j<=n-1; j++)
 {
  x[j]=0.0;
  for (i=0; i<=n; i++)
   x[j]=x[j]+xx[j*(n+1)+i]/(1.0+nn);
  xe[j]=x[j];
 }
 fe=jjsimf(xe,n);
 x[n]=fe;
 free(xt);
 free(xf);
 free(xe);
 return(kk);
}

//求约束条件下n维极值的复形调忧法
int jcplx(int n, int m, double a[], double b[], double alpha, double eps, double x[], double xx[], int k)
{
 int r,g,i,j,it,kt,jt,kk;
 double fj,fr,fg,z,rr,*c,*d,*w,*xt,*xf;
 c=(double *)malloc(m*sizeof(double));
 d=(double *)malloc(m*sizeof(double));
 w=(double *)malloc(m*sizeof(double));
 xt=(double *)malloc(n*sizeof(double));
 xf=(double *)malloc(n*sizeof(double));
 rr=0.0;
 for (i=0; i<=n-1; i++)
  xx[i*n*2]=x[i];
 xx[n*n*2]=jcplxf(x,n);
 for (j=1; j<=2*n-1; j++)
 {
  for (i=0; i<=n-1; i++)
  {
   xx[i*n*2+j]=a[i]+(b[i]-a[i])*rn(&rr);
   x[i]=xx[i*n*2+j];
  }
  it=1;
  while (it==1)
  {
   it=0;
   r=0;
   g=0;
   while ((r<n)&&(g==0))
   {
    if ((a[r]<=x[r])&&(b[r]>=x[r]))
     r=r+1;
    else
     g=1;
   }
   if (g==0)
   {
    jcplxs(n,m,x,c,d,w);
    r=0;
    while ((r<m)&&(g==0))
    {
     if ((c[r]<=w[r])&&(d[r]>=w[r]))
      r=r+1;
     else
      g=1;
    }
   }
   if (g!=0)
   {
    for (r=0; r<=n-1; r++)
    {
     z=0.0;
     for (g=0; g<=j-1; g++)
      z=z+xx[r*n*2+g]/(1.0*j);
     xx[r*n*2+j]=(xx[r*n*2+j]+z)/2.0;
     x[r]=xx[r*n*2+j];
    }
    it=1;
   }
   else xx[n*n*2+j]=jcplxf(x,n);
  }
 }
 kk=1;
 it=1;
 while (it==1)
 {
  it=0;
  fr=xx[n*n*2];
  r=0;
  for (i=1; i<=2*n-1; i++)
   if (xx[n*n*2+i]>fr)
   {
    r=i;
    fr=xx[n*n*2+i];
   }
  g=0;
  j=0;
  fg=xx[n*n*2];
  if (r==0)
  {
   g=1;
   j=1;
   fg=xx[n*n*2+1];
  }
  for (i=j+1; i<=2*n-1; i++)
   if (i!=r)
    if (xx[n*n*2+i]>fg)
    {
     g=i;
     fg=xx[n*n*2+i];
    }
  for (i=0; i<=n-1; i++)
  {
   xf[i]=0.0;
   for (j=0; j<=2*n-1; j++)
    if (j!=r)
     xf[i]=xf[i]+xx[i*n*2+j]/(2.0*n-1.0);
   xt[i]=(1.0+alpha)*xf[i]-alpha*xx[i*n*2+r];
  }
  jt=1;
  while (jt==1)
  {
   jt=0;
   z=jcplxf(xt,n);
   while (z>fg)
   {
    for (i=0; i<=n-1; i++)
     xt[i]=(xt[i]+xf[i])/2.0;
    z=jcplxf(xt,n);
   }
   j=0;
   for (i=0; i<=n-1; i++)
   {
    if (a[i]>xt[i])
    {
     xt[i]=xt[i]+0.000001;
     j=1;
    }
    if (b[i]<xt[i])
    {
     xt[i]=xt[i]-0.000001;
     j=1;
    }
   }
   if (j!=0) jt=1;
   else
   {
    jcplxs(n,m,xt,c,d,w);
    j=0;
    kt=1;
    while ((kt==1)&&(j<m))
    {
     if ((c[j]<=w[j])&&(d[j]>=w[j]))
      j=j+1;
     else
      kt=0;
    }
    if (j<m)
    {
     for (i=0; i<=n-1; i++)
      xt[i]=(xt[i]+xf[i])/2.0;
     jt=1;
    }
   }
  }
  for (i=0; i<=n-1; i++)
   xx[i*n*2+r]=xt[i];
  xx[n*n*2+r]=z;
  fr=0.0;
  fg=0.0;
  for (j=0; j<=2*n-1; j++)
  {
   fj=xx[n*n*2+j];
   fr=fr+fj/(2.0*n);
   fg=fg+fj*fj;
  }
  fr=(fg-2.0*n*fr*fr)/(2.0*n-1.0);
  if (fr>=eps)
  {
   kk=kk+1;
   if (kk<k)
    it=1;
  }
 }
 for (i=0; i<=n-1; i++)
 {
  x[i]=0.0;
  for (j=0; j<=2*n-1; j++)
   x[i]=x[i]+xx[i*n*2+j]/(2.0*n);
 }
 z=jcplxf(x,n);
 x[n]=z;
 free(c);
 free(d);
 free(w);
 free(xt);
 free(xf);
 return(kk);
}

double rn(double *rr)
{
 int m;
 double y,s,u,v;
 s=65536.0;
 u=2053.0;
 v=13849.0;
 *rr=u*(*rr)+v;
 m=*rr/s;
 *rr=*rr-m*s;
 y=*rr/s;
 return(y);
}

                                    ----根据《C语言常用算法程序集》整理

<投票>

 

你可能感兴趣的:(极值问题)