函数极值问题求解 您所在的位置:网站首页 openmp实现找最大值 函数极值问题求解

函数极值问题求解

2023-08-19 21:43| 来源: 网络整理| 查看: 265

对于一个简单函数来说,例如在这里插入图片描述 ,它的图像存在最大值和最小值,那么给定一个区间我们可以利用以下几种方法进行求解。(0 return 49*pow(x,6)+36*pow(x,5)+6*pow(x,2)+16*x-y; }

二分法求解,设置left为左边界,right为右边界,则解一定位于left和right之间,当左右边界之间的差值小于某一精确度时,就认为找到了解。具体操作如下,首先判断左右边界差值作为循环条件,接着每次循环找到左右边界的中间值,一旦该点导数值小于0,说明该点的右侧存在正确解,则将左边界设置为该点,反之将右边界缩进,左右边界通过循环不断的向正确解缩进。满足某一精确度后即可输出结果。(注意这里的函数是比较常规简单的单调函数)

double left=0.0,right=100.0; int count=0; double preci=1e-6;//设置精确度 while(right-left>preci) //若超时,在保证精度的情况下,可以改成count++ left=mid; } else { right = mid; } } 方法2:牛顿二次迭代

同样是对常规函数求解,只是牛顿二次迭代可以更快的求得结果,即便结果有些许相差,但是在经过100次以上的迭代后,答案已经很精确了。对于二次迭代,需要对函数进行二次求导,得到一次求导后各点的斜率。

double fddx(double x) { return 294*pow(x,5)+180*pow(x,4)+12*x+16; }

首先设置一个边界值,对于该边界值一阶导数的值进行判断,判断是否接近0点,或者在进行两百次循环后退出。接下来,从右边界进行缩进,对于该点进行二阶求导,在该点做一条函数切线,与x轴相交的点相比于原边界值一定更接近正确解。具体写法如下,求一阶导的函数值,该函数值除以斜率(也就是该点二阶导的值)即为缩进的x距离,在原有边界上减去该值,即向正确解缩进。

double preci=1e-8;//设置精确度 double ans=100; int count=0; while(fdx(ans,y)>preci&&count++ //TODO 计算函数 } double l=0,r=100; int count=0; double eps=1e-6;//设置精确度 while(r-l>eps) { double mid =(l+r)/2.0; double midr = (mid+r)/2.0;//这里取的是右半区间,也可以取左半区间 if(cal(mid)>cal(midr)) //判断方法,若所求峰值为最大,则mid大于其他 { r=midr; } else { l= mid; } } 方法4:模拟退火算法(适用于区间内多个峰值求最值)

在对于复杂函数进行求解时,以上三种方法,只能求得局部最优的解。利用模拟退火算法才可以得到全局最优解。 具体原理很复杂还不太理解,代码实现如下

#include #include #include #include #include #include #include #include #include #include #include //srand,rand,RAND_MAX #include //time using namespace std; typedef long long ll; int num,mark,m,n,t,maxlen,start,end; #define sc(n) scanf("%d",&n) double fx(double x,double y) { return 7*pow(x,7)+6*pow(x,6)+2*pow(x,3)+8*pow(x,2)-y*x; } double randouble() { return (rand()%10001)/10000.0;//得到小数随机数技巧 } int main() { srand((unsigned int)time(NULL));//初始化伪随机数生成器 double y; scanf("%lf",&y); double preci=1e-8; double t=100;//火的温度 double delta=0.98;//降温系数,降温系数与代码的时间复杂度相关,同时会影响解的精确度 double x=randouble()*100.0; int count=10; double ans=999999999; while(t>preci) { for(int k=1;k double newfx=fx(xnew,y); double detay=newfx-nowfx; if(detay double p=pow(exp(1),-(detay)/t); if(randouble()


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有