1. 程式人生 > >三分搜尋

三分搜尋

目錄

一、概念

二、演算法過程

三、程式碼


轉自: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;
}