【算法學習筆記十二】回溯法(一)

回溯是一種有組織的詳盡搜索,它通常避免搜索所有的可能性。它通常適用於需要檢查大量但有限數量的解決方案的問題。

 3着色問題

3着色問題:給出一個無向圖G=(V,E),需要用三種顏色之一爲V中的每個頂點着色,三種顏色分別爲1,2和3,使得沒有兩個鄰接的頂點有同樣的顏色。我們把這樣的着色稱爲合法的;否則,如果兩個鄰接的頂點有同一種顏色就是非法的。一種着色可以用n元,組(c1, c2, .,cn)來表示,使ci∈{1,2,3}。例如, (1,2,2,3,1)表示一個有5個頂點的圖的着色。一個n個頂點的圖共有3^n種可能的着色(合法的和非法的) ,所有可能的着色的集合可以用一棵完全的三叉樹來表示,稱爲搜索樹。在這棵樹中,從根到葉節點的每一條路徑代表一種着色指派。下圖顯示了有三個頂點的圖的這樣一棵樹。

如果沒有兩個鄰接的着色頂點有同樣的顏色,圖的一個不完全着色稱爲部分解。

回溯法通過每次一個節點地生成基底樹來工作。如果從根到當前節點的路徑對應於一個合法着色,過程就終止(除非期望找到不止一種的着色)。如果這條路徑的長度小於n,並且相應的着色是部分的,那麼就生成現節點的一個子節點,並將它標記爲現節點。另一方面,如果對應的路徑不是部分的,那麼現節點標識爲死節點並生成對應於另一種顏色的新節點。如果所有三種顏色都已經試過且沒有成功,搜索就回溯到父節點,它的顏色被改變,依次類推。

    3-COLORREC
    Input:無向圖G=(V,E)
    Output: G的頂點的3着色 c[1..n]其中每個c[j]爲1, 2 或 3
        1. for k←1 to n
        2.     c[k]←0
        3. end for
        4. flag←false
        5. graphcolor(1)
        6. if flag then output c
        7. else output “no solution”

    Procedure graphcolor(k)
        1. for color=1 to 3
        2.     c[k]←color
        3.     if c 爲合法着色 then set flag←true and exit
        4.     else if c 是部分的 then graphcolor(k+1)
        5. end for

最壞的時間複雜度爲O(n3^n),是一個指數型時間算法。

N皇后問題

如何在nxn的國際象棋棋盤上安排n個皇后,使得沒有兩個皇后能互相攻擊?如果兩個皇后處在同一行、同一列或同一條對角線上,則她們能互相攻擊。以4皇后爲例,可推廣到n皇后問題,最壞時間複雜度爲O(n^n)

    4-QUEENS
    Input: 空
    Output:對應於4皇后問題的解的向量 x[1..4] 
        1. for k←1 to 4
        2.     x[k]←0      {沒有皇后放置在棋盤上}
        3. end for
        4. flag←false
        5. k←1
        6. while k≥1
        7.     while x[k]≤3
        8.         x[k]←x[k]+1
        9.         if x 爲合法着色 then set flag←true and 且從兩個while循環推出
      10.          else if x i是部分解 then k←k+1      {前進}
      11.     end while
      12.     x[k]←0
      13.     k←k-1      {回溯}
      14. end while
      15. if flag then output x
      16. else output “no solution”
4皇后回溯過程

 

一般回溯方法

在回溯法中,解向量中每個xi都屬於一個有限的線序集Xi,因此,回溯算法按詞典序考慮笛卡兒積X1\times X2\times ...\times Xn中的元素。算法最初從空向量開始,然後選擇X1中最小的元素作爲x1,如果(x1)是一個部分解,算法通過從X2中選擇最小的元素作爲x2繼續,如果(x1,x2)是一個部分解,那麼就包括X3中最小的元素,否則x2被置爲X2中的下一個元素。一般地,假定算法已經檢測到部分解爲(x1, x2, ..,xj ),它然後再去考慮向量v=(x1,, ...xj,x(j+1)),我們有下面的情況。

(1)如果v表示問題的最後解,算法記錄下它作爲一個解,在僅希望獲得一個解時終止,或者繼續去找出其他解。

(2) (向前步驟)。如果v表示一個部分解,算法通過選擇集合X(j+2)中的最小元素向前。

(3)如果v既不是最終的解,也不是部分解,則有兩種子情況。

    (a)如果從集合X(j+1)中還有其他的元素可選擇,算法將x(j+1)置爲X(j+1)中的下一個元素。

    (b) (回溯步驟)。如果從集合X(j+1)中沒有更多的元素可選擇,算法通過將 xj置爲Xj中的下一個元素回溯;如果從集合Xj中仍然沒有其他的元素可以選擇,算法通過將xj(j-1)置爲X(j-1)中的下一個元素回溯,依次類推。

    BACKTRACKREC(遞歸)
    Input:集合 X1,...,Xn的清楚的或者隱含的描述
    Output:解向量v=(x1,...xi), 0≤i≤n
        1. v←()
        2. flag←false
        3. advance(1)
        4. if flag then output v
        5. else output “no solution”
    
    Procedure advance(k)
        1. for each x∈Xk
        2.     xk←x; append xk to v
        3.     if v 爲最終解 then set flag←true and exit
        4.     else if v 是部分解 then advance(k+1)
        5. end for
    BACKTRACKITER(迭代)
    Input: Explicit or implicit description of the sets X1,...,Xn
    Output: A solution vector v=(x1,...xi), 0≤i≤n
        1. v←()
        2. flag←false
        3. k←1
        4. while k≥1
        5.     while Xk 沒有被窮舉
        6.         xk←Xk中的下一個元素; append xk to v
        7.         if v 爲最終解 then set flag←true and exit from the two while loops
        8.         else if v is partial then k←k+1      {前進}
        9.     end while
      10.     重置Xk 使得下一個元素排在第一位
      11.     k←k-1      {回溯}
      12. end while
      13. if flag then output v
      14. else output “no solution”

分支限界法

分支限界法 是一種有組織的窮舉算法,主要用於求解最優化問題

解空間樹的動態搜索

首先確定一個合理的限界函數,並根據限界函數確定目標函數的界[down, up] 。

按照廣度優先策略遍歷問題的解空間樹,在分支結點上,依次搜索該結點的所有子結點,分別估算這些子結點的目標函數的可能取值,如果某子結點的目標函數可能取得的值超出目標函數的界,則將其丟棄,因爲從這個結點生成的解不會比目前已經得到的解更好;否則,將其加入待處理結點表(表PT)中。

依次從表PT中選取使目標函數的值取得極值的結點成爲當前擴展結點,重複上述過程,直到找到最優解。

隨着這個遍歷過程的不斷深入,表PT中所估算的目標函數的界越來越接近問題的最優解。

當搜索到一個葉子結點時:

–i) 如果該結點的目標函數值是表PT中的極值(對於最小化問題,是極小值;對於最大化問題,是極大值),則該葉子結點對應的解就是問題的最優解;

–ii) 否則,根據這個葉子結點調整目標函數的界(對於最小化問題,調整上界;對於最大化問題,調整下界),依次考察表PT中的結點,將超出目標函數界的結點丟棄,然後從表PT中選取使目標函數取得極值的結點繼續進行擴展。

0/1揹包問題

假設有4個物品,其重量分別爲(4, 7, 5, 3),價值分別爲(40, 42, 25, 12),揹包容量W=10。首先,將給定物品按單位重量價值從大到小排序,結果如下:

物品 重量(w) 價值(v) 價值/重量(v/w)
1 4 40 10
2 7 42 6
3 5 25 5
4 3 12 4

求得近似解爲(1, 0, 0, 0),獲得的價值爲40,這可以作爲0/1揹包問題的下界。

考慮最好情況,揹包中裝入的全部是第1個物品且可以將揹包裝滿,則可以得到一個非常簡單的上界的計算方法:ub=W×(v1/w1)=10×10=100。

目標函數的界:[40, 100]。

限界函數爲:ub=v+(W-w)\times (v_{i+1}/w_{i+1}) (v表示已放入揹包的物品,i表示前i個物品處理完) 

搜索過程:

(1)在根結點1,沒有將任何物品裝入揹包,因此,揹包的重量和獲得的價值均爲0,根據限界函數計算結點1的目標函數值爲10×10=100;

(2)在結點2,將物品1裝入揹包,因此,揹包的重量爲4,獲得的價值爲40,目標函數值爲40 + (10-4)×6=76,將結點2加入待處理結點表PT中;在結點3,沒有將物品1裝入揹包,因此,揹包的重量和獲得的價值仍爲0,目標函數值爲10×6=60,將結點3加入表PT中;

(3)在表PT中選取目標函數值取得極大的結點2優先進行搜索;

(4)在結點4,將物品2裝入揹包,因此,揹包的重量爲11,不滿足約束條件,將結點4丟棄;在結點5,沒有將物品2裝入揹包,因此,揹包的重量和獲得的價值與結點2相同,目標函數值爲40 + (10-4)×5=70,將結點5加入表PT中;

(5)在表PT中選取目標函數值取得極大的結點5優先進行搜索;

(6)在結點6,將物品3裝入揹包,因此,揹包的重量爲9,獲得的價值爲65,目標函數值爲65 + (10-9)×4=69,將結點6加入表PT中;在結點7,沒有將物品3裝入揹包,因此,揹包的重量和獲得的價值與結點5相同,目標函數值爲40 + (10-4)×4=64,將結點6加入表PT中;

(7)在表PT中選取目標函數值取得極大的結點6優先進行搜索;

(8)在結點8,將物品4裝入揹包,因此,揹包的重量爲12,不滿足約束條件,將結點8丟棄;在結點9,沒有將物品4裝入揹包,因此,揹包的重量和獲得的價值與結點6相同,目標函數值爲65;

(9)由於結點9是葉子結點,同時結點9的目標函數值是表PT中的極大值,所以,結點9對應的解即是問題的最優解,搜索結束。

分支界限法的設計思想

假設求解最大化問題,解向量爲X=(x1, x2, …, xn),其中,xi的取值範圍爲某個有窮集合Si,|Si|=ri(1≤in)。

在使用分支限界法搜索問題的解空間樹時,首先根據限界函數估算目標函數的界[down, up],然後從根結點出發,擴展根結點的r1個子結點,從而構成分量x1的r1種可能的取值方式。對這r1個子結點分別估算可能取得的目標函數值bound(x1),其含義是以該子結點爲根的子樹所可能取得的目標函數值不大於bound(x1),也就是部分解應滿足:

bound(x1)≥bound(x1, x2)≥ … ≥bound(x1, x2, …, xk)≥ … ≥bound(x1, x2, …, xn)

若某子結點的目標函數值超出目標函數的界,則將該子結點丟棄;否則,將該子結點保存在待處理結點表PT中。從表PT中選取使目標函數取得極大值的結點作爲下一次擴展的根結點,重複上述過程,當到達一個葉子結點時,就得到了一個可行解X=(x1, x2, …, xn)及其目標函數值bound(x1, x2, …, xn)。

如果bound(x1, x2, …, xn)是表PT中目標函數值最大的結點,則bound(x1, x2, …, xn)就是所求問題的最大值,(x1, x2, …, xn)就是問題的最優解;

如果bound(x1, x2, …, xn)不是表PT中目標函數值最大的結點,說明還存在某個部分解對應的結點,其上界大於bound(x1, x2, …, xn)。於是,用bound(x1, x2, …, xn)調整目標函數的下界,即令down=bound(x1, x2, …, xn),並將表PT中超出目標函數下界down的結點刪除,然後選取目標函數值取得極大值的結點作爲下一次擴展的根結點,繼續搜索,直到某個葉子結點的目標函數值在表PT中最大。

分支限界法求解最大化問題的一般過程:

1.根據限界函數確定目標函數的界[down, up];

2.將待處理結點表PT初始化爲空;

3.對根結點的每個子結點x執行下列操作

      3.1 估算結點x的目標函數值value;

      3.2 若(value>=down),則將結點x加入表PT中;

4.循環直到某個葉子結點的目標函數值在表PT中最大

      4.1  i=表PT中值最大的結點;

      4.2 對結點i的每個子結點x執行下列操作

           4.2.1 估算結點x的目標函數值value;

           4.2.2 若(value>=down),則將結點x加入表PT中;

           4.2.3 若(結點x是葉子結點且結點x的value值在表PT中最大),

                    則將結點x對應的解輸出,算法結束;

           4.2.4 若(結點x是葉子結點但結點x的value值在表PT中不是最大),

                    則令down=value,並且將表PT中所有小於value的結點刪除;

回溯法(二)

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章