計算最短路徑的A 演算法簡介

2021-06-26 14:07:07 字數 2839 閱讀 5131

還沒仔細看,比學的要深,特意留存學習

a*演算法是到目前為止最快的一種計算最短路徑的演算法,但它一種『較優』演算法,即它一般只能找到較優解,而非最優解,但由於其高效性,使其在實時系統、人工智慧等方面應用極其廣泛。

因而我們可以發現,a*演算法成功與否的關鍵在於估價函式的正確選擇,從理論上說,乙個完全正確的估價函式是可以非常迅速地得到問題的正確解答,但一般完全正確的估價函式是得不到的,因而a*演算法不能保證它每次都得到正確解答。乙個不理想的估價函式可能會使它工作得很慢,甚至會給出錯誤的解答。

為了提高解答的正確性,我們可以適當地降低估價函式的值,從而使之進行更多的搜尋,但這是以降低它的速度為代價的,因而我們可以根據實際對解答的速度和正確性的要求而設計出不同的方案,使之更具彈性。

眾所周知,對圖的表示可以採用陣列或鍊錶,而且這些表示法也各也優缺點,陣列可以方便地實現對其中某個元素的訪問,但插入和刪除操作卻很困難,而鍊錶則利於插入和刪除,但對某個特定元素的定位卻需借助於搜尋。而a*演算法則需要快速插入和刪除所求得的最優值以及可以對當前結點以下結點的操作,因而陣列或鍊錶都顯得太通用了,用來實現a*演算法會使速度有所降低。要實現這些,可以通過二分樹、跳轉表等資料結構來實現,我採用的是簡單而高效的帶優先權的堆疊,經實驗表明,乙個1000個結點的圖,插入而且移動乙個排序的鍊錶平均需500次比較和2次移動;未排序的鍊錶平均需1000次比較和2次移動;而堆僅需10次比較和10次移動。需要指出的是,當結點數n大於10,000時,堆將不再是正確的選擇,但這足已滿足我們一般的要求。

還有一種更好的方法是hot queues,而且這種方法還可應用於dijkstra演算法以降低其複雜度。當我們移動估價函式值為f的結點時,我們插入值為f+δ(δ<=c)(若δ>=0將意味著估價函式是有效的,反之亦然),常量c為從乙個結點到相鄰結點的權的最大改變。同時我們用一些「容器」來儲存估價函式值的子集(這正如o(n)的排序演算法的思想),例如,當有10個「容器」時,堆將平均只包含1/10的估價值。因而這將比用堆更為有效。

估價函式(heuristic function)

估價函式的正確選取將直接關係到a*演算法的成功與否,而函式的確定卻與實際情形有著密切的關係。在本文中,僅對網格狀地圖的估價函式作部分討論,而在其它情形中,需要作不同的分析,但至少估價函式應為連續函式。

a.      manhattan distance

這是一種標準的估價函式,

h(a) = 10 * (abs(a.x-goal.x) + abs(a.y-goal.y))

b.      diagonal distance

如果在地圖上允許作斜線方向的運動,則mahattan distance修正為diagonal distance

h(a) = max(abs(a.x-goal.x), abs(a.y-goal.y))

估價函式的判優

一般情形下,我們只需對估價函式的值進行比較而取其大者即可,但在幾個結點的估價函式值相同的情形下,我們需要採取一定的策略來決定這幾者誰更優,從而避免對多個點的搜尋。從而如下**可實現之:

double dx1 = currentx - goalx;

double dy1 = currenty - goaly;

double dx2 = startx - goalx;

double dy2 = starty - goaly;

cross = dx1*dy2 - dx2*dy1;

if( cross<0 ) cross = -cross;

... add cross*0.001 to the heuristic ...

這段**計算始點、當前點和終點的向量積,從而可以判斷這三點是否共線(或近似共線),這樣不同點間即使有微小的差別也會被放大,從而更利於判斷。

改進的a*演算法

a.      beam search

在a*演算法中需要保留所有的結點,這將使得時間和空間的消耗都很大,而beam search方法對結點數作出限期,當結點數過多時,它會將一些不(大)可能為最優的點排除,從而降低時間和空間的要求,但需要說明的是,由於在排除結點後需對結點排序,當排序的工作量大於排除點後所節省的工作量,則該方法無意義。

b.      iterative deepening

這是一種在人工智慧中常使用的方法,它首先產生一近似值,然後對它進行修正而逐步接近最優解。這其實在一種博奕演算法的變形。

c.      dynamic weighting

這種演算法是基於這樣的考慮,即在搜尋初期以速度優先,在搜尋後期以準確度優先(這可通過對搜尋初、後期賦予不同的權值來實現)。即:

f(p) = g(p) + w(p) * h(p)

d.      bidirectional search

這種演算法從起點和終點同時應用a*演算法,直到有結點相遇。其缺點在於複雜度太大,一般僅用於複雜的圖形。

e.      hierarchical a*

這種演算法思想是將搜尋過程化,對每個簡單過程求解從而得全域性較優解。正如當我們到另一城市時,可分解為從家裡「搜尋」一條路徑至車站,再從車站「搜尋」一條路徑到另一城市,當我們從家裡出發時,需要考慮的是怎樣盡快地到達車站,而不是怎樣盡快地到另一城市。

f.      dynamic a*(d*)

這種演算法主要用於人工智慧和機械人技術。由於a*演算法一開始要求獲得全部資訊,而這在實際中有時是不可能的,而d*演算法就是在假定資訊不完整的前提下應用a*演算法,但它會隨著得到資訊的增多而不斷改進結果,這就決定了它對空間的要求相當高,因為它需要保留以前的所有獲得資訊及運算情形。

最短路徑演算法 最短路

在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?input 輸入包括多組資料。每組資料第一行是兩個整數n m n 100,m 10000 n...

最短路徑演算法

floyd演算法 012345 001 54 1108 1 2 801 3 3 1035 45 302 5413520 floyd 演算法過程描述如下 首先 以邊集 初始化,得到所有的直接連通代價 依次考慮第 k個結點,對於 中的每乙個 i j 判斷是否滿足 s i j s i k s k j 如果...

最短路徑演算法

個人覺得下面 有代表性 最短路徑演算法原始碼 vb 本人載 開發gis,遊自編的最短路徑查詢程式,速度特快,3萬節點,35000條路全部遍歷,只需1秒。現將最短路徑的思路告訴大家,希望大家在優化,並用不同語言編制,我正在學delphi,準備用delphi做成庫,本例以由拓撲關係的arc info 檔...