三分搜索

目录

一、概念

二、算法过程

三、代码


转自:https://blog.csdn.net/u011787119/article/details/44598871

https://www.cnblogs.com/ECJTUACM-873284962/p/6536414.html

一、概念

在二分查找的基础上,在右区间(或左区间)再进行一次二分,这样的查找算法称为三分查找,也就是三分法。

三分查找通常用来迅速确定最值。

二分查找所面向的搜索序列的要求是:具有单调性(不一定严格单调);没有单调性的序列不是使用二分查找。

与二分查找不同的是,三分法所面向的搜索序列的要求是:序列为一个凸性函数。通俗来讲,就是该序列必须有一个最大值(或最小值),在最大值(最小值)的左侧序列,必须满足不严格单调递增(递减),右侧序列必须满足不严格单调递减(递增)。如下图,表示一个有最大值的凸性函数:

 

二、算法过程

如图所示,已知左右端点L、R,要求找到某点的位置。

思路:通过不断缩小 [L,R] 的范围,无限逼近白点。

做法:先取 [L,R] 的中点 midl,再取 [mid,R] 的中点 midr,通过比较 f(midl) 与 f(midr) 的大小来缩小范围。

         当最后 L=R-1 时,再比较下这两个点的值,我们就找到了答案。

1、当 f(midl) > f(midr) 的时候,我们可以断定 mmid 一定在白点的右边。

反证法:假设 mmid 在白点的左边,则 mid 也一定在白点的左边,又由 f(midl) > f(midr) 可推出 midl < midr,与已知矛盾,故假设不成立。

所以,此时可以将 R = midr 来缩小范围。

2、当 f(midl) < f(midr) 的时候,我们可以断定 mid 一定在白点的左边。

反证法:假设 midl 在白点的右边,则 midr 也一定在白点的右边,又由 f(midl) < f(midr) 可推出 midl > midr,与已知矛盾,故假设不成立。

同理,此时可以将 L = midl 来缩小范围。

三、代码

double f(double x)
{
    // 计算函数值,即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(f(midl) >= f(midr)) right = midr;
        else left = midl;
    }
    return left;
}

猜你喜欢

转载自blog.csdn.net/qq_39826163/article/details/83829785