苏州吴中甪直最新招聘:最优法与黄金分割

来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 16:33:33

优选法应用在我国从70年代初,华罗庚先生最初研究推广并大量应用。对编程领域某些解决问题的方法有所帮助。其实数学上的很多方法可以解决一个程序时间和空间最优复杂度的问题。希望对大家有用……
优选法,是以数学原理(即中国的古代黄金分割)为指导,用最可能少的试验次数,尽快找到生产和科学实验中最优方案的一种科学试验的方法。例如:在现代体育实践的科学实验中,怎样选取最合适的配方、配比;寻找最好的操作和工艺条件;找出产品的最合理的设计参数,使产品的质量最好,产量最多,或在一定条件下使成本最低,消耗原料最少,生产周期最短等。把这种最合适、最好、最合理的方案,一般总称为最优;把选取最合适的配方、配比,寻找最好的操作和工艺条件,给出产品最合理的设计参数,叫做优选。也就是根据问题的性质在一定条件下选取最优方案。最简单的最优化问题是极值问题,这样问题用微分学的知识即可解决。
  实际工作中的优选问题 ,即最优化问题,大体上有两类:

           一类是求函数的极值;如果目标函数有明显的表达式,一般可用微分法、变分法、极大值原理或动态规划等分析方法求解(间接选优)。

           另一类是求泛函的极值。如果目标函数的表达式过于复杂或根本没有明显的表达式,则可用数值方法或试验最优化等直接方法求解(直接选优)。
 
        优选法的优点:用较少的试验次数和外在条件,缩短时间和空间的消费、提高质量,达到解决问题的最经济的方法。

优选法基本步骤
  1)选定优化判据(试验指标),确定影响因素,优选数据是用来判断优选程度的依据。
  2)优化判据与影响因素直接的关系称为目标函数。
  3)优化计算。优化(选)试验方法一般分为两类: 

                         分析法:同步试验法 ;黑箱法:循序试验法

优选法的分类
  优选法分为单因素方法和多因素方法两类。单因素方法有平分法、0.618法(黄金分割法)、分数法、分批试验法等;多因素方法很多.但在理论上都不完备.主要有降维法、爬山法、单纯形调优胜。随机试验法、试验设计法等。优选法已在体育领域得到广泛应用。
  1.单因素优选法
如果在试验时,只考虑一个对目标影响最大的因素,其它因素尽量保持不变,则称为单因素问题。这个概念太复杂 了,通俗一点,把解决问题的结果看做方案的函数,当可供选择的方案分布在一条直线上时,其结果可看作一个单变量函数,此时的最优化问题为单因素优化问题。一般步骤:
  (1)首先应估计包含最优点的试验范围,如果用a表示下限,b表示上限,试验范围为[a,b];
  (2)然后将试验结果和因素取值的关系写成数学表达式,不能写出表达式时,就要确定评定结果好坏的方法。

一般可采用对分法、黄金分割法及牛顿一元函数求根的切线法与割线法等方法解决.也可用最小二乘法解决。

 

当多种方案是在一个平面上更高维数的空间中连续分布时,叫做二因素或多因索优化问题,此时可采用牛顿方法或梯度方法求解。若选择方案的分布是离散的,则可采用单纯形等方法解决。
  

      2.多因素优选法
  多因素问题:首先对各个因素进行分析,找出主要因素,略去次要因素,划“多”为“少”,以利于解决问题。

 

 

 

黄金分割法(又称0.618法)是用来求单峰函数的max(或min)的算法。这是一种搜索法,不需要利用函数的导数值。

所用到的 0.618 是黄金分割比的近似值。
黄金分割比  = (sqrt(5)-1)/2 ~=  0.61803398874989484820... 又等于 斐波那契数列的 a(n)/a(n+1), n->∞

下边是我检索到的一些范例程序,没有经过调试,有兴趣自己研究一下。

Vb代码
  1. Const k2 = 0.618033988749895  
  2.   
  3.  Const k1 = 1 - k2   
  4.   
  5. Function M618(ByVal a#, ByVal b#, r#, L%, Nr%) As Double ' [a,b]-区间,r-精度,L=1求峰,L=0求谷  
  6.   
  7.  Dim u#, v#, tu#, tv#   
  8.   
  9.     If a > b Then   
  10.   
  11.       Text2.Text = a:   
  12.   
  13.       Text1.Text = b   
  14.   
  15.     a = Val(Text1.Text):  
  16.   
  17.     b = Val(Text2.Text)   
  18.   
  19. End If '开始计算   
  20.   
  21.     u = a + k1 * (b - a)   
  22.   
  23.     v = a + b - u  
  24.   
  25.     tu = ff(u)  
  26.   
  27.     tv = ff(v)  
  28.   
  29.     Nr = 0 '   
  30.   
  31. Do Until Abs(u - v) < r Or Nr > 70  
  32.   
  33.  If tu < tv Xor L = 0 Then '判断函数值的大小   
  34.   
  35.    a = u u = v:   
  36.   
  37.    tu = tv 'u 点不再计算,要求K2要严格等于黄金分割比   
  38.   
  39.     v = a + k2 * (b - a) '求出新的v  
  40.   
  41.     tv = ff(v) Else b = v v = u:   
  42.   
  43.     tv = tu u = a + k1 * (b - a)   
  44.   
  45.     tu = ff(u) End If   
  46.   
  47.     Nr = Nr + 1 Loop   
  48.   
  49.     M618 = (u + v) / 2  
  50.   
  51.  End Function  

  

 

黄金分割法求解 一元二次函数f(x)=x2+2x+1

C代码
  1. #include "math.h"   
  2.   
  3. #include "stdio.h"   
  4.   
  5. #define f(x) x*x+2*x+1 //函数功能是用黄金分割法实现求一元函数 的最优解   
  6.   
  7. double hj(double *a,double *b,double e,int *n)   
  8.   
  9. {   
  10.   
  11. double x1,x2,s;  
  12.   
  13.  if(fabs(*b-*a)<=e) s=f((*b+*a)/2);  
  14.   
  15.  else { x1=*a+0.382*(*b-*a); x2=*a+0.618*(*b-*a);  
  16.   
  17.  if(f(x1)>f(x2)) *a=x1; else *b=x2;   
  18.   
  19. *n=*n+1; s=hj(a,b,e,n);   
  20.   
  21. }   
  22.   
  23. return s;   
  24.   
  25. }   
  26.   
  27. main() {  
  28.   
  29.  double s,a,b,e; int n=0;   
  30.   
  31.  scanf("%lf %lf %lf",&a,&b,&e); // 输入区间[a,b]和精度e的值   
  32.   
  33.  s=hj(&a,&b,e,&n); //调用hj函数,其中n代表迭代次数   
  34.   
  35.  printf("a=%lf,b=%lf,s=%lf,n=%d\n",a,b,s,n);   
  36.   
  37. }   
  38.   
  39. 运行时:输入:0.6 0.5 0.1 输出结果为: 0.6 0.5 0.1 a=0.600000,b=0.500000,s=2.402500,n=0  

 

 

 

 

0.618算法优化子程序,程序包含4个C文件mhjfgf.c、funct.c、jtf.c、hjfgf.c

C代码
  1. //mhjfgf.c代码如下:  
  2. #include "hjfgf.c"  
  3. main()  
  4. {double xx[1],a[1],b[1],ff;  
  5. double s[]={1},x0[]={0};  
  6. jtf(x0,0.1,s,1,a,b);  
  7. ff=gold(a,b,0.00001,1,xx);  
  8. printf("\nx[0]=%f,,ff=%f",xx[0],ff);  
  9. getch();  
  10. }  
  11.   
  12.   
  13. //funct.c代码如下:  
  14. #include "stdio.h"  
  15. #include "stdlib.h"  
  16. #include "math.h"  
  17. double objf(double x[])  
  18. {double ff;  
  19. ff=8*pow(x[0],3)-2*x[0]*x[0]-7*x[0]+3;  
  20. return(ff);  
  21. }  
  22.   
  23.   
  24. //jtf.c代码如下:  
  25. #include "funct.c"  
  26. void jtf(double x0[],double h0,double s[],int n,double a[],double b[])  
  27. {int i;  
  28. double *x[3],h,f1,f2,f3;  
  29. for(i=0;i<3;i++)  
  30.   x[i]=(double *)malloc(n*sizeof(double));  
  31.   h=h0;  
  32. for(i=0;i
  33.   *(x[0]+i)=x0[i];  
  34. f1=objf(x[0]);  
  35. for(i=0;i
  36.   *(x[1]+i)=*(x[0]+i)+h*s[i];  
  37.   f2=objf(x[1]);  
  38. if(f2>=f1)  
  39.   {h=-h0;  
  40.     for(i=0;i
  41.     *(x[2]+i)=*(x[0]+i);  
  42.    f3=f1;  
  43.     for(i=0;i
  44.     {*(x[0]+i)=*(x[1]+i);  
  45.      *(x[1]+i)=*(x[2]+i);  
  46.     }  
  47.    f1=f2;  
  48.    f2=f3;  
  49.    }  
  50.    for(;;)  
  51.    {h=2*h;  
  52.      for(i=0;i
  53.      *(x[2]+i)=*(x[1]+i)+h*s[i];  
  54.    f3=objf(x[2]);  
  55.    if(f2
  56.    else  
  57.     { for(i=0;i
  58.        {*(x[0]+i)=*(x[1]+i);  
  59.         *(x[1]+i)=*(x[2]+i);  
  60.        }  
  61.       f1=f2;  
  62.       f2=f3;  
  63.     }  
  64.    }  
  65.    if(h<0)  
  66.     for(i=0;i
  67.     {a[i]=*(x[2]+i);  
  68.      b[i]=*(x[0]+i);  
  69.     }  
  70.    else  
  71.     for(i=0;i
  72.     {a[i]=*(x[0]+i);  
  73.      b[i]=*(x[2]+i);  
  74.      }  
  75.    for(i=0;i<3;i++)  
  76.    free(x[i]);  
  77. }  
  78.   
  79.   
  80. //hjfgf.c代码如下:  
  81. #include "jtf.c"  
  82. double gold(double a[],double b[],double eps,int n,double xx[])  
  83. {int i;  
  84. double f1,f2,*x[2],ff,q,w;  
  85. for(i=0;i<2;i++)  
  86.   x[i]=(double *)malloc(n*sizeof(double));  
  87. for(i=0;i
  88.   {*(x[0]+i)=a[i]+0.618*(b[i]-a[i]);  
  89.    *(x[1]+i)=a[i]+0.382*(b[i]-a[i]);  
  90.   }  
  91.   f1=objf(x[0]);  
  92.   f2=objf(x[1]);  
  93.   do  
  94.    {if(f1>f2)  
  95.      {for(i=0;i
  96.       {b[i]=*(x[0]+i);  
  97.        *(x[0]+i)=*(x[1]+i);  
  98.        }  
  99.      f1=f2;  
  100.      for(i=0;i
  101.       *(x[1]+i)=a[i]+0.382*(b[i]-a[i]);  
  102.      f2=objf(x[1]);  
  103.      }  
  104.     else  
  105.      { for(i=0;i
  106.        {a[i]=*(x[1]+i);  
  107.        *(x[1]+i)=*(x[0]+i);}  
  108.      f2=f1;  
  109.     for(i=0;i
  110.      *(x[0]+i)=a[i]+0.618*(b[i]-a[i]);  
  111.     f1=objf(x[0]);  
  112.      }  
  113.   q=0;  
  114.   for(i=0;i
  115.    q=q+(b[i]-a[i])*(b[i]-a[i]);  
  116.   w=sqrt(q);  
  117.   }while(w>eps);  
  118.   for(i=0;i
  119.    xx[i]=0.5*(a[i]+b[i]);  
  120.   ff=objf(xx);  
  121.   for(i=0;i<2;i++)  
  122.   free(x[i]);  
  123.   return(ff);  
  124. }