成功—失败法和0.618法结合求出局部极小值的C语言实现

来源:互联网 发布:数据库索引的认识 编辑:程序博客网 时间:2024/06/11 11:53
 

要求:

编程实现:1.成功失败法找到存在局部极小值的区间[a,b]             

                  2.在该区间内用0.618法找到局部极小值点,精确度为0.01

                 测试函数为:函数f(x)=x^4+x^3-x^2+1;

 

成功失败法找到区间[a,b]:

     1.取x,步长l>0,令k=0,若f(x+l)<=f(x),转3.否则,令l=-l,转2;

      首先选取点x,和步长l,判断f(x+l)是否小于等于f(x),若是,则证明现在朝着函数值下降的方向移动,若不是,证明现在朝着函数值上升的方向移动,这样不能找到局部极小值,所以改变移动方向,令l=-l;

     2.若f(x+l)<=f(x),转3,否则,转4.

     判断f(x+l)是否小于等于f(x),若是,则证明现在朝着函数值下降的方向移动,转3继续沿此方向移动,否则,证明已经找到一个区间,在该区间内存在局部极小值,转4,找到该区间。

     3.更新x,l和k的值,令x=x+l,l=l*2,k=k+1,转2.

     若现在朝着函数值下降的方向移动,则继续向此方向移动,更新x的值,令x=x+1,步长变为原来的2倍,l=l*2,转2继续判断。

     4.若k=0,则令a=x+l,b=x-l。若k>0,则令a = x-l/2,b = x+l;

     若k=0,则说明x已经在含极小值点的区间内了,即在第一步确定过x之后,不管朝着l方向走还是-l方向走,得到的函数值都比x点处的函数值大,此时便找到存在局部极小值的区间[x+l,x-l].若k>0,说明找到该区间时,至少朝着同一个方向走了两次,及l至少更新了一次,所以此时找到的区间为[x-l/2,x+l](或者{[x+l,x-l/2])

    找到存在一个局部极小值的区间之后,在该区间内用0.618黄金分割法求出该区间内的局部极小值

0.618法找到局部极小值:

    1.取n=a+0.618*(b-a),m=a+(b-n)。令r=f(m),g=f(n)。

     第一步从区间[a,b]内找出符合0.618比例的两个点m,n,求出其函数值。

    2.若r>g,转3,否则,转4.

    判断m和n两点处的函数值大小。

    3.令a=m,m=n,r=g,n=b-(m-a),g=f(n) 转5

    如果m点的函数值大于n点的函数值,则在区间[a,m]不可能存在极小值点,故丢掉[a,m]部分,令原来的m点为新的a点,原来的n点为新的m点,根据0.618的比例找出新的n点,同时函数值r和g的值也相应的更新。

    4.令b=n,n=m,g=r,m=a+(b-n),r=f(m),转5

    如果m点的函数值小于n点的函数值,则在区间[n,b]内不可能存在极小值点,故丢掉[n,b]部分,令原来的n点为新的b点,原来的m点为新的n点,根据0.618的比例找出新的m点,同时相应的更新r和g的函数值。

    5.若|b-a|<0.01,则找到局部极小值点(a+b)/2。否则,转2,进行继续循环直到满足所需的精度值,找到局部极小值点。

程序实现:

#include <stdio.h>#include <stdlib.h>#include <math.h>double f(double x){double y;y = pow(x,4)+pow(x,3)-pow(x,2)+1;return y;}int main () {double x=0,l=0.5;double a,b,c;double m,n,r,g;int k = 0;if(f(x+l)<=f(x)){    x=x+l;    l=l*2;        k=k+1;}    elsel=-l;while(1){if(f(x+l)<=f(x)){x=x+l;l=l*2;k=k+1;}else{break;}}if(k == 0){a = x+l;    b = x-l;}else{a = x-l/2;b = x+l;}if(a>b){c=a;a=b;b=c;}//成功失败法完成,找到区间[a,b],[a,b]区间内存在局部极小值//0.618法n = a+0.618*(b-a);m = a+(b-n);r=f(m);g=f(n);do{if(r>g){a=m;m=n;r=g;n=b-(m-a);g=f(n);}else{b=n;n=m;g=r;m=a+(b-n);r=f(m);}}while(abs(b-a)>=0.01);printf("局部极小值为:%f\n",(a+b)/2);system("pause");return 0;}


 

 

 

0 0
原创粉丝点击