1. 程式人生 > >Chapter 4 Backtracking Search Algorithms

Chapter 4 Backtracking Search Algorithms

求解約束滿足問題的演算法技術主要有三種:回溯搜尋、區域性搜尋和動態規劃。本章主要研究回溯搜尋演算法。基於動態規劃[15]的演算法——有時在文獻中稱為變數消除、綜合或推理演算法——是第7章的主題。區域性或隨機搜尋演算法是第五章的主題。

約束滿足問題的求解演算法可以是完全的,也可以是不完全的。完整的,或系統的演算法,如果存在一個解決方案就保證能找到,也可以用來表明一個CSP沒有解決方案,或找到一個可證明的最優解決方案。回溯搜尋演算法和動態規劃演算法通常是完整演算法的例子。不完全或非系統的演算法,不能用來表明一個CSP沒有一個解決方案或找到一個可證明的最優解決方案。然而,這種演算法通常能夠有效地找到一個存在的解,並且可以用來找到最優解的近似。區域性或隨機搜尋演算法是不完全演算法的例子

在回溯搜尋和動態程式設計這兩類完全演算法中,回溯搜尋演算法目前在實踐中是最重要的。 動態程式設計方法的缺點是它們通常需要指數量的時間和空間,並且它們通過發現或使得可以容易地生成CSP的所有解決方案來執行不必要的工作。 但是,很少有人希望在實踐中找到CSP的所有解決方案。 相反,回溯搜尋演算法一次只能處理一個解,因此只需要多項式的空間量。

自從40多年前[30,57]的回溯演算法的第一個正式陳述以來,已經提出並評估了許多用於提高回溯搜尋演算法的效率的技術。 在本章中,我將研究一些最重要的技術,包括分支策略,約束傳播,nogood記錄,回跳,變數和值排序的啟發式,隨機化和重啟策略,以及深度搜索的替代方法。這些技術並不總是正交的,有時將兩種或兩種以上的技術合併到一個演算法中會產生乘法效果(例如將重啟和nogood記錄合併在一起),有時還會產生退化效果(例如增加約束傳播而不是向後跳躍)。

鑑於這些技術可以組合成一種演算法的多種可能方法,我還對回溯演算法進行了比較研究。這些技術的最佳組合產生了健壯的回溯演算法,這些演算法現在可以常規地解決具有實際重要性的大型硬例項。

4.1 Preliminaries

在本節中,我首先定義約束滿足問題,然後簡要回顧回溯搜尋所需的背景知識。

每個約束C是一個關係——一組tuple——在一些變數集上的關係,由vars(C)表示。集合vars(C)的大小稱為約束的濃度。一元約束是濃度1的約束,二元約束是濃度2的約束,非二元約束是濃度大於2的約束,全域性約束是可以超越變數的任意子集的約束。約束可以通過指定約束中的元組必須滿足的公式來內涵地指定,也可以通過顯式地列出約束中的元組來擴充套件。CSP的解決方案是為每個變數分配一個值,使其滿足所有約束。如果不存在解決方案,則CSP被認為是不一致的或不能滿足的。

可滿足性問題(SAT)是一個CSP,其中變數的域是布林值,約束是布林公式。我將假設約束是合取正規化,因此被寫成子句。字(A literal )是布林變數或其否定,子句(A clause )是文字的析取。例如,公式¬x1∨x2∨x3是一個子句。只有一個字的子句叫做單位子句 a unit clause;沒有文字的子句稱為空子句 the empty clause。空子句是不可滿足的。

對CSP解決方案的回溯搜尋可以看作是對搜尋樹執行深度優先遍歷。搜尋樹是在搜尋過程中生成的,它表示為了找到解決方案可能必須檢查的其他選擇。在搜尋樹中擴充套件節點的方法通常稱為分支策略,文獻中已經提出並研究了幾種替代方法(參見4.2節)。如果在演算法執行的某一點生成了節點,則回溯演算法將訪問visits該節點。約束用於檢查節點是否可能導致CSP的解決方案,以及修剪不包含解決方案的子樹。如果搜尋樹中的一個節點不能提供解決方案,那麼它就是一個死端deadend。

樸素回溯演算法(naive backtracking algorithm, BT)是所有更復雜回溯演算法的起點(見表4.1)。在BT搜尋樹中,0層的根節點是賦值的空集,j層的節點是賦值集{x1 = a1,…xj = aj}。在搜尋樹中的每個節點上,都會選擇一個未例項化的變數,該節點之外的分支由所有可能的方法組成,這些方法通過例項化變數及其域中的值來擴充套件節點。分支表示可以為該變數做出的不同選擇。在BT中,在節點上只檢查沒有未例項化變數的約束。如果約束檢查失敗(約束不滿足),則嘗試當前變數的下一個域值。如果沒有剩餘的域值,BT將回溯到最近例項化的變數。如果最後一個變數例項化後,所有約束檢查都成功,那麼就會找到解決方案。

圖4.1顯示了由樸素回溯演算法(BT)為6皇后問題生成的回溯樹的一個片段。節點上的標籤是該節點上作業集的短基。例如,標記為25的節點由賦值集{x1 = 2,x2 = 5}組成。白點表示沒有例項化變數的所有約束都得到滿足的節點(沒有一對皇后相互攻擊)。黑點表示一個或多個約束檢查失敗的節點。(陰影和虛線箭頭的原因在4.5節中解釋。)為了簡單起見,我假設了一個靜態的例項化順序,在這個順序中,變數xi總是在搜尋樹的第I級被選擇,並且值是按照順序1、…、6分配給變數的。