三分求单峰函数最值

二分可以求解单调函数最值,类比不难想到三分可以求解单峰函数。
何为单峰函数,

如果函数f(x)在区间[a, b]上只有唯一的最大值点(或最小值点)C,而在最大值点(或最小值点)C的左侧,函数单调增加(减少);在点C的右侧,函数单调减少(增加),则称这个函数为区间[a, b]上的单峰函数
如果函数f(x)在区间[a, b]上只有唯一的最大值点(或最小值点)C,而在最大值点(或最小值点)C的左侧,函数单调增加(减少);在点C的右侧,函数单调减少(增加),则称这个函数为区间[a, b]上的单峰函数.例如,图中的两个函数f(x),g(x)就是单峰函数.
如果函数f(x)在区间(a, b)上有唯一的极值点,则f(x)在区间[a, b]上是单峰函数.
若函数f(x)在区间[a, b]上是单峰函数, C是最佳点,如果在区间[a, b]上任取x1,x2,如果在试验中效果较好的点是x1,则必有C和x1在x2的同侧,若以x2为分界点,含x1点的区间范围是函数的一个存优范围.
在结构优化中所说的单峰函数常常是指图(2)中的有极小点的函数。

21
特别的,直线在有限区间内可以看为单峰函数。

LA 5009
这里是选了eps 迭代法也可以,

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn = 50000;
int a[maxn],b[maxn],c[maxn];

const double eps = 1e-12;
int n;
double F(double x)
{
	double ans = a[1]*x*x+b[1]*x+c[1];
	for(int i = 2;i <= n;i++)
		ans = max(ans,a[i]*x*x+b[i]*x+c[i]);
	return ans;
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		for(int i = 1;i <= n;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]);			
		double L = 0.0,R = 1000.0;
		while(R-L > eps){
			double m1 = L+(R-L)/3;
			double m2 = R-(R-L)/3;
			if(F(m1) < F(m2)) R = m2;
			else L = m1;			
		}
		printf("%.4lf\n",F(L));
	}
	return 0;
}

另外,最优算法是斐波那契搜索,对这种连续的函数,这是最快的。

posted @ 2017-05-31 13:23  rsqppp  阅读(703)  评论(0)    收藏  举报