目錄
- 1.回溯算法
1.1 回溯算法簡介
1.2 一般回溯方法 - 2.收費公路重建問題(通過考慮最大值策略,對可能性空間Xi進行了大幅度裁剪)
2.1 問題描述
2.2 一個例子
2.3 收費公路重建算法
2.4 算法分析 - 3.博弈
3.1 問題描述
3.2 極小極大策略
3.3 極小極大策略用于更復雜的游戲——西洋跳棋、國際象棋
3.4 α-β裁剪 - 4.三著色問題
4.1 問題描述
4.2 問題求解 - 5.八皇后問題
5.1 問題描述
5.2 考慮4皇后問題的解法 - 6.哈密爾頓回路問題
6.1 問題描述
6.2 問題求解
1.回溯算法
1.1 回溯算法簡介
- 像大多數NP難問題一樣,通過窮盡搜索數量巨大但有限多個可能性,可以獲得一個解。而且,事實上對于所有這些問題都不存在用窮盡搜索之外的方法來解決問題。所以產生了開發系統化的搜索技術的需要,并且希望能夠將搜索空間減少到盡可能小。
- 回溯法就是一種組織搜索的一般技術。回溯法可以被描述為有組織的窮舉搜索,它常常可以避免搜索所有的可能性。
一般適用于求解那些有潛在的大量解,但有限個數的解已經檢查過的問題。
1.2 一般回溯方法
1)一般回溯方法概念
一般回溯方法應用到一類搜索問題中,這類問題的解由滿足事先定義好的某個約束的向量(x1, x2, ..., xi)組成。這里i是0到n之間的某個整數,其中n是一個取決于問題闡述的常量。
1-1) 對于一些問題,i是固定不變的
例如三著色和八皇后問題
1-2) 另一些問題中,i對于不同的解可能有所不同(可轉換為統一的長度)
- 考慮定義如下的PARTITON問題中的一個變型。給定一個n個整數的集合X={x1, x2, ..., xn}和整數y,找出和等于y的X的子集Y。比如說,如果X = {10, 20, 30, 40, 50, 60}和y = 60,則有三種不同的解,它們分別是{10, 20, 30}, {20,40}和{60}。設計一個回溯算法求解并不困難。
這個問題可以用另一種方法明確表達,使得解釋一種明顯的長度為n的布爾向量,于是上面的三個解可以用布爾變量表示為{1, 1, 1, 0, 0, 0}, {0, 1, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 1}。
2)一般回溯方法的描述
- 解向量中每個xi都屬于一個有限的線序集Xi
- 回溯法按詞典序考慮笛卡爾積X1 × X2 × ... × Xn 。
(開始)算法最初從空向量開始,然后選擇X1中最小的元素作為x1,如果(x1)是一個部分解,算法通過從X2中選擇最小的元素作為x2繼續,如果(x1, x2)是一個部分解,那么就包括X3中最小的元素,否則x2被置為X2重的下一個元素。
(一般情況)假定算法已經檢測到為(x1, x2, ..., xj),它然后考慮向量v = (x1, x2, ..., xj, xj + 1),有以下情況:
1.如果v表示問題的最后解,算法記錄下它作為一個解,在僅希望獲得一個解時終止,或者繼續去找出其他解。
2.(向前步驟)。如果v表示一個部分解,算法通過選擇集合Xj+2中的最小元素向前。
3.如果v既不是最終解,也不是部分解,則有兩種子情況
3-1.如果從集合Xj+1中還有其他的元素可選擇,算法將xj + 1置為Xj+1中的下一個元素。
3-2.(回溯步驟)。如果從集合Xj+1中沒有更多的元素可選擇,算法通過將xj置為Xj中的下一個元素回溯;如果從集合Xj中仍然沒有其他的元素可以選擇,算法通過將xj-1置為Xj-1中的下一個元素回溯,依次類推。
3)(獲得一個解)回溯算法的偽代碼描述
- 通常如果需要使用回溯法來搜索一個問題的解,可以使用這兩個原型算法之一作為框架,圍繞它設計出專門為具體問題而裁剪出的算法來。
1)遞歸形式
2)迭代形式
2.收費公路重建問題(通過考慮最大值策略,對可能性空間Xi進行了大幅度裁剪)
2.1 問題描述
根據N(N-1)/2個形如|xi - xj|(i≠j)的距離,重新構造這N個點集。
在物理學和分子生物學中都有應用。
重建問題沒有人能夠給出一個算法保證在多項式時間內完成計算。在最壞情形下可能要花費指數時間。
2.2 一個例子
D是距離集合,并設|D| = N(N-1)/2。
D = {1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 6, 7, 8, 10}
可知N = 6.
- step1.(x1 = 0,x6 = 10)算法開始置x1 = 0。顯然x6 = 10。
從D中刪除x6 - x1 = 10。
- step2.(x5 = 8)剩下的距離中最大是8,要么x2 = 2,要么x5 = 8。由對稱性,斷定這種選擇是不重要的,可置x5 = 8。
從D中刪除x5 - x1 = 8 和 x6 - x5 = 2。
- step3.(x4 = 7或x2 = 3)剩下距離中最大的是7,要么x4 = 7,要么x2 = 3(特別注意:已經排除了x2 = 1,如果選定x2 = 1,則|x6 - x1| = 9 > 7)。
step3-1.考慮x4 = 7。從D刪除x4 - x1 = 7 , x5 - x4 = 1和 x6 - x4 = 3。
step3-2.考慮x2 = 3。從D刪除x2 - x1 = 3 , x5 - x2 = 5和 x6 - x2 = 7。
- step4.首先考慮step3-1的情況,此時x4 = 7。剩下距離中最大的距離是6,要么x3 = 6,要么x2 =4。
step4-1.考慮x3 = 6。那么x4 - x3 1,不可能,因為1不再屬于D。繼續搜索。
step4-2.考慮x2 = 4。那么x2 - x0 = 4,x5 - x2 = 4,這也不可以,因為4在D中只出現一次。
回溯考慮step3-2的情況。此時x2 = 3。剩下距離中最大的距離是6,要么x3 = 6,要么x2 =4。
step4-3.考慮x3 = 4。不可能,該選擇有兩個4,而D中只有一個。
step4-4.考慮x4 = 6。唯一剩下的選擇是x3 = 5。正好可以。
2.3 收費公路重建算法
算法的核心思路:
- 驅動代碼,首先確定無爭議的x1,xN和xN-1
- 回溯步驟:以遞歸方式實現。傳遞同樣的參數以及界Left和Right,xLeft,...,xRight是視圖放置的點的x坐標。
2.4 算法分析
可以將D作為平衡二叉查找樹保存(代碼需要修改)。如果從未回溯,那么最多有O(N2)涉及到對D(平衡二叉查找樹)的查找和刪除操作。因此,在沒有回溯的情況下,運行時間為O(N2logN)。
3.博弈
3.1 問題描述
- 考慮計算機用來進行戰略游戲的策略,如西洋跳棋和國際象棋。以簡單得多的三連游戲棋(tic-tac-toe)來進行表述。
-
三連棋的游戲規則:
兩人輪流在一有九格方盤上劃加字或圓圈,誰先把三個同一記號排成橫線、直線、斜線,即是勝者。
tic-tac-toe
3.2 極小極大策略
- (賦值)更一般的策略是使用一個賦值函數來給一個位置的“好壞”定值。能使計算機獲勝的位置+1;平局得0;使計算機輸棋的位置-1.
- (終端位置)通過考察盤面能夠確定這局輸贏的位置叫做終端位置。
- (極小極大策略)如果一個位置不是終端位置,那么該位置的值通過遞歸地假設雙方最優棋步而確定。下棋的一方(人)試圖使這個位置的值極小化,而另一方(計算機)卻要使它的值極大。
FindCompMove計算機選擇具有最大值的一步行棋。
FindHumanMove行棋人在此基礎上找出具有最小值的一步行棋。 - (后繼位置)位置P的后繼位置是通過從P走一步棋可以達到的任何位置Ps。
如果當在某個位置P計算機要走棋,那么它遞歸地求出所有的后繼位置的值。計算機選擇具有最大值的一步行棋,這就是P的值。
為了得到任意后繼位置Ps的值,要遞歸地算出Ps的所有后繼位置的值,然后選取其中最小的值。這個最小值代表行棋人一方最贊成的應招。
(draw在英語表示和棋)
- 第1行和第4行直接給和棋、贏棋賦值;其他情況,則該位置是非終端位置。
- Value應該包括所有可能后繼位置的最大值,這就是5-13行的事情
回溯在于第8行的Place(Board, i, Comp)和第10行Unplace(Board, i)。 - FindHumanMove遞歸調用FindCompMove。如果下棋人對一步棋的應招給計算機留下比計算機前面最佳棋步所得到的位置更好的位置,那么Value和BestMove將被更新。
3.3 極小極大策略用于更復雜的游戲——西洋跳棋、國際象棋
- (遞歸深度、求值函數)搜索到終端節點的全部棋步不可行,達到某個深度(層)之后只能停止搜索。遞歸停止出的結點則成為終端結點。這些終端結點的值由一個估計位置的值的函數計算出來了。
求值函數對于成功是至關重要的,因為計算機的行棋選步是基于將這個函數極大化。最好的計算機下棋程序的求值函數驚人的復雜。 - (置換表)如果已經計算過,那么一個位置在第二次出現時就不必再重新計算,將這些值存儲在散列表中。
3.4 α-β裁剪
3.4.1 博弈樹(game tree)
-
博弈樹:假象的棋局中用來給某些某個假設的位置求值的一些遞歸調用的跡。
- 上圖中幾乎有一半的終端節點沒有被檢驗。以下兩個裁剪將證明計算它們的值將不改變樹根的值。
3.4.2 α裁剪
- 如圖所示,D不需要求值。
-
實現α裁剪的方法,FindCompMove將它的嘗試性的極大值α傳遞給FindHumanMove。如果FindHumanMove的嘗試性的極小值低于這個值,那么FindHumanMove立即返回。
α裁剪
3.4.3 β裁剪
- 如果所示,C不用求值。
-
實現β裁剪的方法,FindHumanMove將它的嘗試性的極小值β傳遞給FindCompMove。如果FFindCompMove的嘗試性的極大值大于這個值,那么FindCompMove立即返回。
β裁剪
β裁剪
4.三著色問題
4.1 問題描述
- 給出一個無向圖G = (V, E),需要用三種顏色之一為V中的每個頂點著色,三種顏色分別為1, 2, 3,使得沒有兩個鄰接的頂點有同樣的顏色。
- 一種著色可用n元組(c1, c2, ..., cn)來表示,使ci ∈ {1, 2, 3},1 ≤ i ≤ n。
- 一個n個頂點圖共有3n種可能的著色(合法的和非法的),所有可能的著色的集合可以用一棵完全的三叉樹表示,稱為搜索樹。在這棵樹中,從根到葉節點的每一條路徑代表一種著色指派。(跟n個元素的全排列類似,只不過只有兩種可能,大于和小于的決策樹,參見排序算法總結)
三結點的三著色搜索樹
4.2 問題求解
回溯法的基本特征:
- 結點是用深度優先搜索的方法生成
- 不需要存儲整棵搜索樹,只需要存儲根到當前活動結點的路徑
4.2.1 遞歸算法(假設頂點集合是{1, 2, ..., n})
-
回溯由graphcolor(k)中的for循環體現。
4.2.3 迭代算法
- 內層while循環實現前進(生成新結點)
-
外層while循環實現回溯的過程
4.2.4 時間復雜度
最壞情況下生成了O(3n)個結點,對于每個結點,都需要O(n)的時間來檢查。因此,最壞情況為O(n3n)。
5.八皇后問題
5.1 問題描述
- 8皇后問題:如何在8 × 8的國際象棋棋盤上安排8個皇后,使得沒有兩個皇后能相互攻擊?如果兩個皇后處在同一行、同一列或同一條對角線上,則她們能互相攻擊。
- n皇后問題:如何在n × n的國際象棋棋盤上安排n個皇后,使得沒有兩個皇后能相互攻擊? n ≥ 1。
5.2 考慮4皇后問題的解法
5.2.1 解空間——搜索空間
- (沒有兩個皇后在同一行)每行上有4個位置,就有44種可能的布局,每種可能的布局可以用一個4分量的向量x = {x1, x2, x3, x4}描述。
- (沒有兩個皇后在同一行和同一列)搜索空間由44減少到4!。
5.2.2 回溯法求解
- 算法嘗試生成并以深度優先方式搜索一棵完全四叉有根樹
樹根對應于沒有放置皇后的情況;
第一層的結點對應于皇后的第一行的可能放置情況;
第二層的結點對應于皇后在第二行的可能放置情況;
依此類推。 - 合法——表示一個不互相攻擊的4個皇后的放置
部分——表示一個不互相攻擊的少于4個皇后的放置 - xi與xj相互攻擊
同一列——xi = xj
同一對角線——xi - xj = i -j 或 j - i
6.哈密爾頓回路問題
6.1 問題描述
- 尋找無向圖G=(V, E)中的哈密頓回路。
- 設無向圖G=(V, E),v1v2...vn是G的一條通路,若G中每個頂點在該通路中出現且僅出現一次,則稱該通路為哈密頓通路。若v1=vn,則稱該通路為哈密爾頓回路。
6.2 問題求解
- 假定G=(V, E)的頂點集為V={0,1,...,n-1}。
- 按照回路中頂點的順序,用n元向量X=(x0, x1, ..., xn-1)來表示回路中的頂點編號,其中xi ∈{0, 1, ..., n-1}。
-
用布爾數組c[n][n]來表示圖的鄰接矩陣,如果頂點i和j相鄰接,則c[i][j]為真。則哈密頓回路滿足如下約束:
回溯法步驟:
- step1.把頂點0作為回路中第一個頂點,搜索與頂點0相鄰接的編號最小的頂點,作為它的后續頂點
- step2.假定在搜索過程中已經生成了通路l = x0x1...xi-1
尋找與xi-1相鄰接的并且不屬于l的編號最小的頂點。如果搜索成功,就把這個頂點作為通路中的頂點xi,然后繼續搜索下一個頂點。 - step3.如果不成功,就把l中的xi-1刪除,從xi-1的頂點編號加1的位置開始,繼續搜索與xi-2相鄰接的并且不屬于l的編號最小的頂點
- step4.當搜索到l中的頂點xn-1時,如果xn-1與x0相鄰接,則所生成的回路就是一條哈密頓回路;
否則,把l中的xn-1刪除,繼續回溯。最后,如果在回溯過程中,l中只剩下一個頂點x0,則表明圖中不存在哈密頓回路。(如果圖中存在一個哈密頓回路,那么從任何一個頂點出發都能找到一個,如果回溯到只有一個頂點,則表明x0與其相鄰接的頂點的所有可能性都常識過了,都不能形成哈密頓回路,因此必然不存在。)