圖搜索的通用算法


這里提出一個通用的圖搜索算法,它允許各種 用戶—偏愛啟發式的或盲目的,進行定制。我把這個算法叫做圖搜索(GRAPHSEARCH)。

下面是(第一個版本)它的定義。

GRAPHSEACH
1) 生成一個僅包含開始節點n0的搜索樹Tr。把n0放在一個稱為OPEN的有序列表中。
2) 生成一個初始值為空的列表CLOSED。
3) 如果OPEN為空,則失敗並退出。
4) 選出OPEN中的第一個節點,並將它從OPEN中移出,放入CLOSED中。稱該節點為n。
5) 如果n是目標節點,順着Tr中的弧從n回溯到n0找到一條路徑,獲得解決方案,則成功退
出(弧在第6步產生)。
6) 擴展節點n,生成n的后繼節點集M。通過在Tr中建立從n到M中每個成員的弧生成n的后繼。
7) 按照任意的模式或啟發式方式對列表OPEN重新排序。
8) 返回步驟3 。

這個算法可用來執行最優搜索、廣度優先搜索或深度優先搜索。

變化1.廣度搜索和深度搜索

這兩種搜索都是盲目搜索,運氣不好就會遍歷整個解空間....

對於上述的通用算法第7部進行修改即可完成這兩種搜索,即改變排序的方式。

1.在廣度優先搜索中,新節點只要放在OPEN的尾部即可(先進先出, FIFO),節點不用重排。

   這就是隊列....

2.在深度優先搜索中,新節點放在OPEN的開始(后進先出,LIFO)。

   這就是棧,棧的地方都可以使用遞歸實現....


變化2.啟發式搜索算法

下面是其基本思想:
1) 假定有一個啟發式(評估)函數ˆf ,可以幫助確定下一個要擴展的最優節點,
我們采用一個約定,即ˆf的值小表示找到了好的節點。
這個函數基於指定問題域的信息,它是狀態描述的一個實數值函數。
2) 下一個要擴展的節點n是ˆf(n)值最小的節點(假定節點擴展產生一個節點的所有后

繼)。

3) 當下一個要擴展的節點是目標節點時過程終止。

1.A*算法

 A*搜尋算法,俗稱A星算法,作為啟發式搜索算法中的一種,這是一種在圖形平面上,有多個節點的路徑,求出最低通過成本的算法。常用於游戲中的NPC的移動計算,或線上游戲的BOT的移動計算上。該算法像Dijkstra算法一樣,可以找到一條最短路徑;也像BFS一樣,進行啟發式的搜索。     A*算法最為核心的部分,就在於它的一個估值函數的設計上:         f(n)=g(n)+h(n)     其中f(n)是每個可能試探點的估值,它有兩部分組成:     一部分,為g(n),它表示從起始搜索點到當前點的代價(通常用某結點在搜索樹中的深度來表示)。     另一部分,即h(n),它表示啟發式搜索中最為重要的一部分,即當前結點到目標結點的估值,     h(n)設計的好壞,直接影響着具有此種啟發式函數的啟發式算法的是否能稱為A*算法。    一種具有f(n)=g(n)+h(n)策略的啟發式算法能成為A*算法的充分條件是:       1、搜索樹上存在着從起始點到終了點的最優路徑。       2、問題域是有限的。       3、所有結點的子結點的搜索代價值>0。       4、h(n)=<h*(n) (h*(n)為實際問題的代價值)。     當此四個條件都滿足時,一個具有f(n)=g(n)+h(n)策略的啟發式算法能成為A*算法,並一定能找到最優解。     對於一個搜索問題,顯然,條件1,2,3都是很容易滿足的,而條件4: h(n)<=h*(n)是需要精心設計的,由於h*(n)顯然是無法知道的,所以,一個滿足條件4的啟發策略h(n)就來的難能可貴了。

    不過,對於圖的最優路徑搜索和八數碼問題,有些相關策略h(n)不僅很好理解,而且已經在理論上證明是滿足條件4的,從而為這個算法的推廣起到了決定性的作用。

    且h(n)距離h*(n)的呈度不能過大,否則h(n)就沒有過強的區分能力,算法效率並不會很高。對一個好的h(n)的評價是:h(n)在h*(n)的下界之下,並且盡量接近h*(n)。


 先舉一個小小的例子:即求V0->V5的路徑,V0->V5的過程中,可以經由V1,V2,V3,V4各點達到目的點V5。下面的問題,即是求此起始頂點V0->途徑任意頂點V1、V2、V3、V4->目標頂點V5的最短路徑。

//是的,圖片是引用rickone 的。            通過上圖,我們可以看出::A*算法最為核心的過程,就在每次選擇下一個當前搜索點時,是從所有已探知的但未搜索過點中(可能是不同層,亦可不在同一條支路上),選取f值最小的結點進行展開。       而所有“已探知的但未搜索過點”可以通過一個按f值升序的隊列(即優先隊列)進行排列。

      這樣,在整體的搜索過程中,只要按照類似廣度優先的算法框架,從優先隊列中彈出隊首元素(f值),對其可能子結點計算g、h和f值,直到優先隊列為空(無解)或找到終止點為止。

 A*算法與廣度、深度優先和Dijkstra 算法的聯系就在於:當g(n)=0時,該算法類似於DFS,當h(n)=0時,該算法類似於BFS。且同時,如果h(n)為0,只需求出g(n),即求出起點到任意頂點n的最短路徑,則轉化為單源最短路徑問題,即Dijkstra算法。這一點,可以通過上面的A*搜索樹的具體過程中將h(n)設為0或將g(n)設為0而得到。


2.單源最短路徑

上邊的A*算法可以求得最短路徑,計算的過程只求出g(n),即求出起點到任意頂點n的最短路徑,則轉化為單源最短路徑問題,即Dijkstra算法。第7部排序使用升序。


上述算法的性能比較,見下文,這個文章寫的很好。
http://blog.csdn.net/v_JULY_v/article/details/6238029








注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com