三分法求解问题

来源:互联网 发布:linux 释放端口占用 编辑:程序博客网 时间:2024/05/23 05:07

    当需要求某凸性或凹形函数的极值,通过函数本身表达式并不容易求解时,就可以用三分法不断逼近求解。


类似二分的定义LeftRightmid = (Left + Right) / 2,midmid = (mid + Right) / 2;

如果mid靠近极值点,则Right = midmid

否则(midmid靠近极值点),则Left = mid;

这样就一定确定极值所在的区域

例题:zoj 3203 Light Bulb

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
double H,h,d;
double solve(double x)
{
double z=1.0*(h*d-H*x)/(H-h);
return 1.0*x+1.0*z*h/(x+z);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lf%lf%lf",&H,&h,&d);
double low=0;
double up=1.0*(1.0*h/H*d);
while(fabs(low-up)>1e-9)
{
double mid=1.0*(low+up)/2;
double midmid=1.0*(mid+up)/2;
if(solve(mid)<=solve(midmid))
{
low=mid;
}
else up=midmid;
}

printf("%.3lf\n",1.0*solve(low));
}
return 0;
}
分析可知:人的影子的变化趋势是先变大后变小,符合三分法的要求。自己完整的分析思路:

          然后就确定横坐标x为人到墙壁的距离(人影的地上部分),又因为人影长度为在地上部分加上墙上部分,现在需要求解墙上部分(y)

如图


由tan(θ)=y/z=h/(x+z)=H/(D+z),求出z再带入用x表示y就行了。

然后确定low,up,这就没什么可说的了。

原创粉丝点击