算法自学__三分法

发布时间:2024年01月18日

参考资料:

问题引入

给定一个单峰函数,如何求得极值点?

算法思想

在这里插入图片描述

对于区间 [ l , r ] [l, r] [l,r],求出两个三等分点 l s e c lsec lsec r s e c rsec rsec,然后比较这两个点的函数值 f ( l s e c ) f(lsec) f(lsec) f ( r s e c ) f(rsec) f(rsec)。如果有 f ( r s e c ) > f ( l s e c ) f(rsec)>f(lsec) f(rsec)>f(lsec),说明极值点一定在区间 [ l s e c , r ] [lsec, r] [lsec,r]内取得,因为如果答案在区间 [ l , l s e c ) [l,lsec) [l,lsec)内取得,则一定有函数 f f f在区间 [ l r e c , r ] [lrec, r] [lrec,r]内单调递减,于是有 f ( l s e c ) > f ( r s e c ) f(lsec)>f(rsec) f(lsec)>f(rsec),这与 f ( r s e c ) > f ( l s e c ) f(rsec)>f(lsec) f(rsec)>f(lsec)相矛盾。

不难发现,上述做法在每次循环中会让区间长度变为原长度的 2 / 3 2/3 2/3。我们还可以取区间中点两边附近的两个点,这样可以让在每次循环后让区间长度变为原长度的 1 / 2 1/2 1/2

代码实现

// eps = 1e-7
while(r-l>1e-6){
		double mid = (l+r)/2;
		double midl = mid-eps, midr = mid+eps;
		if(f(midr)>f(midl)) l = midl, ans = mid;
		else r = midr;
	}

循环条件最好为最大轮数

其他

在求解多项式函数的值时往往需要采用秦九韶算法。

//N为多项式的最高次,数组a[]按次数从高到低存储
double f(double x){
	double res = 0;
	for(int i=0;i<=N;i++) res = res*x + a[i];
	return res;
}
文章来源:https://blog.csdn.net/MaTF_/article/details/127067598
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。