二分查找模版(最大值,最小值,浮点数的二分)与三分搜索模版

最大化最小值(二分值最小越小越容易满足条件,求最大值)

区间长度为1时的写法:
解的范围为 [lb,rb][lb,rb]

// 计算区间为[lb, rb]
while( rb > lb )  // 区间长度为1时终止循环
{
    // 防止溢出
    int m = lb + (rb - lb + 1) / 2;    // 由于是区间长度为1时终止循环,所以要加1
    if( ok(m) ) lb = m;
    else rb = m - 1;
}
// 跳出循环时 lb == rb
区间长度为2时的写法:
解的范围为  [lb,rb)[lb,rb)
while( rb - lb > 1 )  // 区间长度为2时终止循环
{
    // 防止溢出
    int m = lb + (rb - lb) / 2;    // 由于是区间长度为2时终止循环,所以不用加1(不会死循环)
    if( ok(m) ) lb = m;
    else rb = m;
}
// 跳出循环时 lb + 1 == rb
// 答案为 lb

最小化最大值(二分值越大越容易满足条件,求最小值)

区间长度为1时的写法:
解的范围为 [lb,rb][lb,rb]

while( rb > lb )
{
    // 防止溢出
    int m = lb + (rb - lb) / 2;     // 这里虽然区间长度为1,但不需要加1(不会死循环)
    if( ok(m) ) rb = m;
    else lb = m + 1;
}
// 跳出循环时 lb == rb
区间长度为2时的写法:
解的范围为  (lb,rb](lb,rb]
while( rb - lb > 1 )
{
    // 防止溢出
    int m = lb + (rb - lb) / 2;
    if( ok(m) ) rb = m;
    else lb = m;
}
// 跳出循环时 lb + 1 == rb
// 答案为 rb

浮点数的二分,100次循环可以达到2^-100(约为10^-30)的精度范围

以最大化最小值为例(即小于该数的解均满足条件)

for( int i = 0; i < 100; ++ i )
{
    double m = (lb + rb) / 2;
    if(check(m)) lb=m;
     else rb=m;
}
// 跳出循环时 lb 与 rb 近似相等,所以都可作为答案

三分搜索:https://blog.csdn.net/u011787119/article/details/44598871

double solve(double parameter)
{
    // 计算函数值,即f(x)
}

double trisection_search(double left, double right)
{
    // 三分搜索,找到最优解(求函数最大值下的自变量值)
    double midl, midr;
    while (right-left > 1e-7)
    {
        midl = (left + right) / 2;
        midr = (midl + right) / 2;
        // 如果是求最小值的话这里判<=即可
        if(solve(midl) >= solve(midr)) right = midr;
        else left = midl;
    }
    return left;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值