1. 程式人生 > >搜尋_常見搜尋演算法概述

搜尋_常見搜尋演算法概述

常見搜尋演算法概述

注意:

     DFS(包括各種DFS變形)和BFS(包括各種BFS變形)均可建立起演算法中訪問的結點與解空間樹中結點的對映關係, 以這種對映關係為基礎可以證明這兩種所有演算法及其變形的諸多重要性質.

     搜尋的過程實際是遍歷解空間樹的過程, 搜尋的內容可分為, 搜尋所有可行解, 搜尋一個可行解, 搜尋一個最優的可行解, 搜尋所有狀態的最優解, 搜尋目標狀態的最優解.

約定:

     (1)對於解空間樹, 設L為解空間樹中從根到結點A的路徑, A對應狀態a且代價最小, 那麼L上所有結點均對應某個狀態的最小代價

     (2)下面討論中涉及到的所有結點和狀態均指從解空間樹根結點可達的結點和狀態.

1.深搜(DFS)     

1.1常規DFS

性質:

     (1)還原性(還原現場, 資料修改操作和資料還原操作成對出現)

     (2)子集性(如果當前訪問的結點為解空間樹中的結點, 那麼下次遞迴或回溯到的結點仍為解空間樹中的結點)

     (3)唯一性(程式棧(或稱之為遞迴呼叫鏈)的每個狀態至多出現一次, 可據此證明程式必在有限時間內終止)

     (4)完全覆蓋性質(程式將訪問所有有必要訪問的結點, 比如包含最優解的結點)

     (5)兩次遞迴呼叫相同,要求當前遞迴程式棧相同且進行該次遞迴呼叫時全域性變數的值和函式引數均相同

1.2雙向DFS

     主要優點: 減小搜尋樹規模

1.3 迭代加深DFS

     適用場景: 目標結點位於解空間樹較淺層的情況

1.4 IDA*

     特點:基於迭代加深DFS的A*演算法 

2.廣搜(BFS)    

2.1常規BFS

性質:

     (1)使用先進先出佇列, 可用於求解最小步數

     (2)邊權值(每次擴充套件結點的代價)均為1

     (3)佇列滿足兩段性和單調性

2.2用於權值為正數的先進先出佇列BFS

性質:

     (1)程式必在有限時間內終止

     證明: 根據解空間樹中不同狀態的個數為有限個, 每次對結點擴充套件時新入佇列的狀態的代價值小於該狀態之前更新得到的代價值, 且代價值非負即可證明之.

     (2)演算法結束後所有狀態的代價值被更新為其最小值

     證明: 假設狀態a的代價值未被更新為其最小值, 設L為解空間樹中從根到結點A的路徑, A對應狀態a且使得a的代價最小, 如果a的代價未被更新為其最小值, 則其前驅結點的代價也未被更新為其最小值, 使用數學歸納法可以推出路徑L上的所有結點(包括根節點)的代價值均不會被更新為對應代價的最小值, 這顯然與路徑L上根節點對應狀態的代價值被更新為其最小值矛盾, 因此假設不成立, 結論得證.

2.3用於權值為正數的優先佇列BFS

性質:

     (1)演算法必定在有限時間內終止

     證明: 根據解空間樹中不同狀態的個數為有限個, 每個狀態只在第一次出佇列時被擴充套件, 且每次擴充套件時加入佇列中的新元素(之前未出過佇列)個數為有限個即可證明之.

     (2)出佇列的元素對應的代價值非遞減

     證明: 根據每次擴充套件時新加入佇列的結點(之前未出過佇列)的代價均大於被擴充套件結點即可證明之.

     (3)每個狀態至少出(入)佇列1次

     證明: 假設狀態a在演算法執行過程中未進入過佇列, 設L為解空間樹中從根到結點A的路徑, A對應狀態a且使得a的代價最小, 如果a未入過佇列, 則其前驅結點對應狀態b也未入過佇列(如果b入佇列, 那麼在b第一次出佇列時必定將a入佇列), 使用數學歸納法可以推出路徑L上的所有結點(包括根節點)均不會入佇列, 這顯然與路徑L上根節點對應狀態入佇列矛盾, 因此假設不成立, 結論得證.

     (4)每個狀態第一次出佇列對應代價值為該狀態的最小代價值

     證明: 假設存在某個狀態a第一次出佇列時對應的代價值並非其最小代價, 設L為解空間樹中從根到結點A的路徑, A對應狀態a且使得a的代價最小, 根據假設, 在a第一次出佇列之前, 路徑L上A的前驅結點對應的狀態b的代價不會被更新為其最小值(如果b對應代價被更新為最小值, 那麼在狀態b第一次出佇列時將把狀態a的最小代價加入佇列), 使用數學歸納法可以推出路徑L上所有結點對應代價均不會被更新為其最小值, 這顯然與根結點對應狀態的代價被更新為其最小值矛盾矛盾, 故假設不成立, 結論得證.

     (5)如果每個狀態不論是否為第一次出佇列均會被擴充套件, 且擴充套件時不進行任何剪枝, 那麼狀態a第k次出佇列時對應狀態a的第k小的代價.

     證明: 根據結論(2)狀態a第k次出佇列時對應的代價值b不小於狀態a的第k小 代 價t, 假設b > t, 那麼必有a的某個第c(c <= k)小代價對應的結點p在a第k次出佇列之前未入佇列, 設從根到p的路徑為L, 顯然L上所有結點的代價均小於t, 故代價為t的結點出佇列之前, 路徑L上所有的結點均應該入(出)佇列.

2.4雙向BFS

性質:

     (1)適用於起始狀態的目標狀態明確的搜尋過程, 可減小解空間樹的規模

     (2)每次對當前隊首結點進行擴充套件時檢查新加入的結點是否同時存在於起始狀態和目標狀態已經搜尋到的結點集中

     (3)如果某次迭代之前兩個佇列中的某個為空, 且之前未發現兩棵搜尋樹中的公共結點, 那麼必有以起始狀態為根的搜尋樹與以目標狀態為根的搜尋樹的交集(狀態的集合)為空

     (4)如果在將一個方向上某個第k層結點(根為第0層)v入佇列時發現在v進入過另一個方向上的佇列, 且另一個方向已經擴充套件m層(不包括根), 那麼整體解空間樹中從起始狀態到目標狀態的最短路徑上邊的個數為k + m.

2.5雙端佇列BFS

性質:

     (1)適用於邊權值為0或1(可同時存在)的解空間樹

     (2)每次擴充套件當前隊首結點a時, 設a對應代價為f(a), 從a擴充套件至其子結點b的代價為z(z等於0或1), 如果f(a) + z小於當前b對應狀態最後一次更新後的代價值, 那麼如果z為0則將b入隊頭, 如果z為1則將b入隊尾.

     (3)演算法可能多次更新同一狀態的代價, 演算法結束後所有狀態的代價值被更新為對應狀態的最小代價值

2.6 A*

性質:

     (1)帶估價函式的優先佇列BFS

     (2)目標狀態第k次出佇列對應的代價為目標狀態的第k小代價

     證明: 先證明k = 1時結論成立, 當k = 1時也即目標狀態第一次出佇列, 假設目標狀態第一次出佇列時的代價值t大於目標狀態的最小代價m, 設結點A對應目標狀態的最小代價m, L為從根到A的一條路徑, 則路徑L上所有結點的實際代價與估價函式值之和小於t, 因此在代價值為t 的結點出佇列之前路徑L上的所有結點均已經(入)出佇列.   這顯然與目標狀態第一次出佇列的代價值為t矛盾. 假設k = i, i >= 1時上述結論成立, 當k = i + 1時, 假設目標狀態第i + 1次出佇列對應的實際代價值d大於目標狀態的第i + 1小代價, 使用類似的方法,設結點e對應目標狀態的第i + 1小代價q, 為從根到e的一條路徑, 則路徑上所有結點在代價值為d的結點出佇列之前均已經(入)出佇列, 這與假設的目標狀態第i + 1次出佇列對應的實際代價值d大於q矛盾, 因此假設不成立, 結論得證.