三分法——求解凸性函数的极值问题

本文介绍了一种使用二分法查找函数极值的方法,并提供了详细的程序模板。通过几个具体的例题展示了如何根据不同的函数调整模板以求解极值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://www.cnblogs.com/markliu/archive/2012/08/09/2630652.html     

如图,类似二分的定义Left和Right,mid = (Left + Right) / 2,midmid = (mid + Right) / 2; 如果mid靠近极值点,则Right = midmid;否则(即midmid靠近极值点),则Left = mid;


程序模版如下:

复制代码
double Calc(Type a)
{
    /* 根据题目的意思计算 */
}

void Solve(void)
{
    double Left, Right;
    double mid, midmid;
    double mid_value, midmid_value;
    Left = MIN; Right = MAX;
    while (Left + EPS < Right)
    {
        mid = (Left + Right) / 2;
        midmid = (mid + Right) / 2;
        mid_area = Calc(mid);
        midmid_area = Calc(midmid);
        // 假设求解最大极值.
        if (mid_area >= midmid_area) Right = midmid;
        else Left = mid;
    }
   printf("%.0lf\n",Calc(Left));
}
复制代码

接下来看几个例题:给出函数,其他的套模板就可以AC
hdu-4355 party all the time (2012 Multi-University Training Contest 6 )

函数为:

复制代码
double Calc(double i){
    double S=0.0;
    for(int j=0;j<n;j++){
        S+=fabs((i-p[j].x)*(i-p[j].x)*(i-p[j].x))*p[j].w;
    }
    return S;
}
复制代码

zju-3203 Light Bulb (The 6th Zhejiang Provincial Collegiate Programming Contest)

函数为:

double Calc(double x){
    return (h*D-H*x)/(D-x)+x;
}

hdu-3714 Error Curves (2010 Asia Chengdu Regional Contest )
函数为:

复制代码
double Calc(double x){
    double Max,t;
    Max=p[0].a*x*x+p[0].b*x+p[0].c;
    for(int i=1;i<n;i++){
        t=p[i].a*x*x+p[i].b*x+p[i].c;
        Max=max(t,Max);
    }
    return Max;
}
复制代码

hdu-2438 Turn the corner (2008 Asia Harbin Regional Contest Online )

函数为:

复制代码
double Calc(double a)
{
    double b,c,d;
    b=w/sin(a)+l*cos(a);
    c=l*sin(a)+w/cos(a)-x;
    d=l*sin(a)+w/cos(a);
    return c*b/d;
}
复制代码

这道题单纯的套模板会WA,我们要将分割方向倒置,midmid=(mid+l)/2;从左边取第二个中点。

复制代码
double l,r,mid,midmid,mid_area,midmid_area;
l=0.0,r=pi/2;
while(l+eps<r){
        mid=(l+r)/2;
        midmid=(mid+l)/2;
        mid_area=Calc(mid);
        midmid_area=Calc(midmid);
        if(mid_area>=midmid_area) l=midmid;
        else r=mid;
}
复制代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值