1. 程式人生 > >Dijkstra演算法和A*演算法總結

Dijkstra演算法和A*演算法總結

   Dijkstra演算法和A*演算法都是最短路徑問題的常用演算法,下面就對這兩種演算法的特點進行一下比較:

  1. Dijkstra演算法計算源點到其他所有點的最短路徑長度,A*關注點到點的最短路徑(包括具體路徑)。
  2. Dijkstra演算法建立在較為抽象的圖論層面,A*演算法可以更輕鬆地用在諸如遊戲地圖尋路中。
  3. Dijkstra演算法的實質是廣度優先搜尋,是一種發散式的搜尋,所以空間複雜度和時間複雜度都比較高。對路徑上的當前點,A*演算法不但記錄其到源點的代價,還計算當前點到目標點的期望代價,是一種啟發式演算法,也可以認為是一種深度優先的演算法。
  4. 由第一點,當目標點很多時,A*演算法會帶入大量重複資料和複雜的估價函式,所以如果不要求獲得具體路徑而只比較路徑長度時,Dijkstra演算法會成為更好的選擇。



啟發函式的性質

那麼能不能綜合上面Dijkstra演算法得到最優解和貪心演算法速度快的特點,有更好的辦法呢? 
注意一下這個地方,Dijkstra演算法是適用於任何圖演算法找最短距離均可的,但是用到啟發式演算法的話,大部分情況下會是一個方格圖,因為只有方格圖才能比較好的估算從當前點到終點的距離】 
那麼我們可以先定義一個估算函式 

f(n)=g(n)+h(n)
其中g(n)表示起點到當前點n實際走的代價,h(n)表示當前點n到終點的估算代價。 
所以上面兩個合起來就是其走當前點到終點的總代價函式f(n)
h(n)這個估計函式不同的估計情況,結果也不會相同。
  1. 先考慮極端情況, 如果h
    (n)=0
    的情況下,只有g(n)起作用,那麼A*演算法就是Dijkstra演算法。
  2. 如果h(n)始終小於等於實際n點到終點的距離,那麼必然能夠保證A*演算法找的解就是最優解。而且h(n)越小,則A*擴充套件的節點也就越多,A*演算法執行的也就越慢。
  3. 如果h(n)始終都等於實際n點到終點的距離,那麼A*演算法只會嚴格走從起點到終點的最短路徑。雖然這種情況一般不可能發生,當然一些特殊情況下會發生【比如沒有障礙物的情況】。
  4. 如果h(n)有時候大於實際n點到終點的距離,那麼不能保證A*演算法能夠找到最短路徑
  5. 另外一種極端情況,就是如果只有h(n)發揮作用,則A*演算法就相當於貪心演算法。