搜尋_優先佇列BFS_A*_演算法分析
1, 優先佇列BFS
下面是優先佇列BFS虛擬碼:
//在解空間G上以s為源結點執行優先佇列BFS
Priority_BFS(G, s)
建立初始僅包含結點s且以s的權重(代價)s.w為關鍵字的最小堆Q
while Q非空
結點u = Q.top()
Q.pop()
for(解空間G中所有未入過佇列的u的鄰接結點v)
Q.push(v)
結論1: 在演算法Priority_BFS每次執行第5行時, 如果接下來的第7行if條件成立, 那麼Q的堆頂也即結點u對應狀態g的代價最小, 注意: 對於任意從源結點s出發, 且終點為e的路徑L, 如果e具有其對應狀態的最小代價, 那麼L上所有結點都具有其對應狀態的最小代價.
證明: 設執行第5時接下來的第7行if條件成立, 滿足Q的堆頂結點u對應的狀態為a, 代價為w, 設解空間G中從源結點s達到狀態a的最小代價為, 並取解空間中任意一個對應狀態a且代價為的結點為b. 且a到b的一條包含節點數最少的路徑為R = (為的前驅結點, ).
設狀態為所有滿足w > 且R包含結點數最少的a型別狀態, 也即當a取時路徑R中除終點外的所有結點對應的狀態均滿足結論1, 那麼R中任意結點的代價(Q中對應關鍵字)均小於w, 根據結點u為狀態a第一次出佇列Q, 那麼必有在u出佇列之前, 結點b未入佇列Q, 對於R上b的前驅結點
2, A*
A*演算法為每個結點u對應的狀態a設立一個估價函式f, 滿足f(a)不大於從從狀態a轉移至目標狀態T的最小代價, 下面是A*演算法的虛擬碼:
//在解空間G上以s為源結點, T為目標狀態執行A*_BFS, 返回目標狀態T的最小代價
A*_BFS(G, s, T)
建立初始僅包含結點s且以s的權重(代價)s.w與s的估價函式s.f之和為關鍵字的最小堆Q
while Q非空
結點u = Q.top()
if u對應狀態為T
return u.w
Q.pop()
for(解空間G中所有滿足未入過佇列Q的u的鄰接結點v)
Q.push(v)
結論2: 演算法A*_BFS(G, s, T)返回解空間G中從源結點s到目標狀態T的最小代價, 注意: 解空間中所有以s為起點的路徑滿足路徑上所有b的前驅結點a使得a.w <= b.w(w對應結點的當前代價, 通常解空間樹中第i層結點的w屬性值為i)成立
證明: 假設演算法A*_BFS(G, s, T)返回的並非解空間G中從源結點s到目標狀態T的最小代價, 設非解空間G中從源結點s到目標狀態T的最小代價為g, 設G中結點e滿足: e對應狀態為T且e.w = g, 則e.f = 0, 設R為從源結點s到e的一條路徑, 則R所有結點對應的當前代價和估價函式值之和均不超過e.w, 設最後一次執行第5行時對應Q的堆頂結點u為k, 顯然在k成為堆頂之前, 結點e不能入佇列Q, 否則在e成為堆頂之前k不能成為堆頂, 這與k為所有對應狀態T的結點中第一個成為堆頂矛盾, 類似於結論1的證明過程, 使用數學歸納法易推出, 在k成為堆頂之前R上的所有結點均不能入佇列Q, 則源結點s在k成為堆頂之前不能入佇列Q, 這顯然是不可能的, 因此假設不成立, 結論2得證.