A. A*演算法是什麼
A*
(A-Star)演算法是一種靜態路網中求解最短路最有效的方法。
公式表示為: f(n)=g(n)+h(n),
其中f(n) 是從初始點經由節點n到目標點的估價函數,
g(n) 是在狀態空間中從初始節點到n節點的實際代價,
h(n)是從n到目標節點最佳路徑的估計代價。
保證找到最短路徑(最優解的)條件,關鍵在於估價函數h(n)的選取:
估價值h(n)<= n到目標節點的距離實際值,這種情況下,搜索的點數多,搜索范圍大,效率低。但能得到最優解。
如果 估價值>實際值, 搜索的點數少,搜索范圍小,效率高,但不能保證得到最優解
B. 關於A*演算法和3D演算法
A*演算法是一種啟發式搜索的演算法,公式表示為: f(n)=g(n)+h(n)g(n) 是在狀態空間中從初始節點到n節點的實際代價,
h(n)是從n到目標節點最佳路徑的估計代價。3D演算法,沒看懂你說什麼意思
C. apriori演算法是什麼
Apriori演算法是第一個關聯規則挖掘演算法,也是最經典的演算法。它利用逐層搜索的迭代方法找出資料庫中項集的關系,以形成規則,其過程由連接(類矩陣運算)與剪枝(去掉那些沒必要的中間結果)組成。該演算法中項集的概念即為項的集合。包含K個項的集合為k項集。項集出現的頻率是包含項集的事務數,稱為項集的頻率。如果某項集滿足最小支持度,則稱它為頻繁項集。
演算法應用
隨著高校貧困生人數的不斷增加,學校管理部門資助工作難度也越加增大。針對這一現象,提出一種基於數據挖掘演算法的解決方法。將關聯規則的Apriori演算法應用到貧困助學體系中,並且針對經典Apriori挖掘演算法存在的不足進行改進,先將事務資料庫映射為一個布爾矩陣,用一種逐層遞增的思想來動態的分配內存進行存儲,再利用向量求"與"運算,尋找頻繁項集。
D. A*演算法怎麼驗算
驗算步驟如下:
a初值為12時,a+=a-=a*=a結果為0
步驟:
這個表達式的運算是從右向左的:
1.
a*=a:a=a*a=12*12=144
2.
a-=144:
a=a-144=144-144=0
3.
a+=0:
a=a+0=0+0=0。演算法(Algorithm)是指解題方案的准確而完整的描述,是一系列解決問題的清晰指令,演算法代表著用系統的方法描述解決問題的策略機制。也就是說,能夠對一定規范的輸入,在有限時間內獲得所要求的輸出。如果一個演算法有缺陷,或不適合於某個問題,執行這個演算法將不會解決這個問題。不同的演算法可能用不同的時間、空間或效率來完成同樣的任務。一個演算法的優劣可以用空間復雜度與時間復雜度來衡量。
演算法中的指令描述的是一個計算,當其運行時能從一個初始狀態和(可能為空的)初始輸入開始,經過一系列有限而清晰定義的狀態,最終產生輸出並停止於一個終態。一個狀態到另一個狀態的轉移不一定是確定的。隨機化演算法在內的一些演算法,包含了一些隨機輸入。
形式化演算法的概念部分源自嘗試解決希爾伯特提出的判定問題,並在其後嘗試定義有效計算性或者有效方法中成形。這些嘗試包括庫爾特·哥德爾、JacquesHerbrand和斯蒂芬·科爾·克萊尼分別於1930年、1934年和1935年提出的遞歸函數,阿隆佐·邱奇於1936年提出的λ演算,1936年EmilLeonPost的Formulation1和艾倫·圖靈1937年提出的圖靈機。即使在當前,依然常有直覺想法難以定義為形式化演算法的情況。
E. A*演算法是怎麼來的,歷史背景是啥,誰提出的A*演算法幫幫忙,謝謝!
1968年,的一篇論文,「P. E. Hart, N. J. Nilsson, and B. Raphael. A formal basis for the heuristic determination of minimum cost paths in graphs. IEEE Trans. Syst. Sci. and Cybernetics, SSC-4(2):100-107, 1968」。從此,一種精巧、高效的演算法------A*演算法橫空出世了,並在相關領域得到了廣泛的應用。
F. A*演算法應用,大家給點介紹,做課程設計
維基網路有很多的,大陸訪問不了,可以設置個香港代理。
SHA 家族
[編輯首段]維基網路,自由的網路全書
跳轉到: 導航, 搜尋
安全散列演演演算法能計算出一個數位訊息所對應到的,長度固定的字串(又稱訊息摘要)。且若輸入的訊息不同,它們對應到不同字串的機率很高;而 SHA 是FIPS所認證的五種安全雜湊演演演算法。這些演演演算法之所以稱作「安全」是基於以下兩點(根據官方標準的描述):「1)由訊息摘要反推原輸入訊息,從計算理論上來說是很困難的。2)想要找到兩組不同的訊息對應到相同的訊息摘要,從計算理論上來說也是很困難的。任何對輸入訊息的變動,都有很高的機率導致其產生的訊息摘要迥異。」
SHA 家族的五個演演演算法,分別是SHA-1, SHA-224, SHA-256, SHA-384, 和 SHA-512,由美國國家安全局 (NSA) 所設計,並由美國國家標准與技術研究院(NIST) 發布;是美國的政府標准。後四者有時並稱為SHA-2。SHA-1 在許多安全協定中廣為使用,包括 TLS 和 SSL、 PGP、SSH、S/MIME 和 IPsec,曾被視為是 MD5(更早之前被廣為使用的雜湊函數)的後繼者。但 SHA-1 的安全性如今被密碼學家嚴重質疑;雖然至今尚未出現對 SHA-2 有效的攻擊,它的演演演算法跟 SHA-1 基本上仍然相似;因此有些人開始發展其他替代的雜湊演演演算法。緣於最近對 SHA-1 的種種攻擊發表,「美國國家標准與技術研究院(NIST)開始設法經由公開競爭管道(類似高級加密標准AES的發展經過),發展一個或多個新的雜湊演演演算法。」
目錄 [隱藏]
1 SHA-0 和 SHA-1
1.1 SHA-0 的破解
1.2 SHA-1 的破解
2 SHA-2
3 SHA 所定義的長度
4 SHAd
5 應用
6 SHA-1 演演演算法
7 SHA-2 演演演算法
8 參見
9 參考資料
10 外部鏈結
[編輯] SHA-0 和 SHA-1
SHA-1 壓縮演演演算法中的一個迴圈。A, B, C, D 和 E 是這個state中的 32 位元文字;F 是會變化的非線性函數;<<<n 代表bit向左循環移動n個位置。n因操作而異。田代表molo 232之下的加法,Kt 是一個常數。最初載明的演演演算法於 1993年發布,稱做安全雜湊標准 (Secure Hash Standard),FIPS PUB 180。這個版本現在常被稱為 SHA-0。它在發布之後很快就被 NSA 撤回,並且由 1995年發布的修訂版本 FIPS PUB 180-1 (通常稱為 SHA-1) 取代。SHA-1 和 SHA-0 的演演演算法只在壓縮函數的訊息轉換部份差了一個位元的循環位移。根據 NSA 的說法,它修正了一個在原始演演演算法中會降低密碼安全性的錯誤。然而 NSA 並沒有提供任何進一步的解釋或證明該錯誤已被修正。而後 SHA-0 和 SHA-1 的弱點相繼被攻破,SHA-1 似乎是顯得比 SHA-0 有抵抗性,這多少證實了 NSA 當初修正演演演算法以增進安全性的聲明。
SHA-0 和 SHA-1 可將一個最大 264 位元的訊息,轉換成一串 160 位元的訊息摘要;其設計原理相似於 MIT 教授 Ronald L. Rivest 所設計的密碼學雜湊演演演算法 MD4 和 MD5。
[編輯] SHA-0 的破解
在 CRYPTO 98 上,兩位法國研究者提出一種對 SHA-0 的攻擊方式 (Chabaud and Joux, 1998): 在 261的計算復雜度之內,就可以發現一次碰撞(即兩個不同的訊息對應到相同的訊息摘要);這個數字小於 280 ,也就是說,其安全性不到一個理想的雜湊函數抵抗攻擊所應具備的計算復雜度。
2004年時,Biham 和 Chen 也發現了 SHA-0 的近似碰撞 — 兩個訊息可以雜湊出幾乎相同的數值;其中 162 位元中有 142 位元相同。他們也發現了 SHA-0 的完整碰撞(相對於近似碰撞),將本來需要 80 次方的復雜度降低到 62 次方。
2004年8月12日,Joux, Carribault, Lemuet 和 Jalby 宣布找到 SHA-0 演演演算法的完整碰撞的方法,這是歸納 Chabaud 和 Joux 的攻擊所完成的結果。發現一個完整碰撞只需要 251的計算復雜度。他們使用的是一台有 256 顆 Itanium2 處理器的超級電腦,約耗 80,000 CPU 工時 [1]。
2004年8月17日,在 CRYPTO 2004 的 Rump 會議上,王小雲, 馮登國 (Feng), 來學嘉 (Lai), 和於紅波 (Yu) 宣布了攻擊 MD5、SHA-0 和其他雜湊函數的初步結果。他們攻擊 SHA-0 的計算復雜度是 240,這意謂的他們的攻擊成果比 Joux 還有其他人所做的更好。請參見 MD5 安全性。2005 年二月,王小雲和殷益群、於紅波再度發表了對 SHA-0 破密的演演演算法,可在 239 的計算復雜度內就找到碰撞。
[編輯] SHA-1 的破解
鑒於 SHA-0 的破密成果,專家們建議那些計畫利用 SHA-1 實作密碼系統的人們也應重新考慮。2004 年 CRYPTO 會議結果公布之後,NIST 即宣布他們將逐漸減少使用 SHA-1,改以 SHA-2 取而代之。
2005年,Rijmen 和 Oswald 發表了對 SHA-1 較弱版本(53次的加密迴圈而非80次)的攻擊:在 280 的計算復雜度之內找到碰撞。
2005年二月,王小雲、殷益群及於紅波發表了對完整版 SHA-1 的攻擊,只需少於 269 的計算復雜度,就能找到一組碰撞。(利用暴力搜尋法找到碰撞需要 280 的計算復雜度。)
這篇論文的作者們寫道;「我們的破密分析是以對付 SHA-0 的差分攻擊、近似碰撞、多區塊碰撞技術、以及從 MD5 演演演算法中尋找碰撞的訊息更改技術為基礎。沒有這些強力的分析工具,SHA-1 就無法破解。」此外,作者還展示了一次對 58 次加密迴圈 SHA-1 的破密,在 233 個單位操作內就找到一組碰撞。完整攻擊方法的論文發表在 2005 年八月的 CRYPTO 會議中。
殷益群在一次面談中如此陳述:「大致上來說,我們找到了兩個弱點:其一是前置處理不夠復雜;其二是前 20 個迴圈中的某些數學運算會造成不可預期的安全性問題。」
2005 年八月 17 的 CRYPTO 會議尾聲中王小雲、姚期智、姚儲楓再度發表更有效率的 SHA-1 攻擊法,能在 263 個計算復雜度內找到碰撞。
在密碼學的學術理論中,任何攻擊方式,其計算復雜度若少於暴力搜尋法所需要的計算復雜度,就能被視為針對該密碼系統的一種破密法;這並不表示該破密法已經可以進入實際應用的階段。
就應用層面的考量而言,一種新的破密法出現,暗示著將來可能會出現更有效率、足以實用的改良版本。雖然這些實用的破密法版本根本還沒誕生,但確有必要發展更強的雜湊演演演算法來取代舊的演演演算法。在「碰撞」攻擊法之外,另有一種反譯攻擊法,就是由雜湊出的字串反推原本的訊息;反譯攻擊的嚴重性更在碰撞攻擊之上。 在許多會應用到密碼雜湊的情境(如用戶密碼的存放、文件的數位簽章等)中,碰撞攻擊的影響並不是很大。舉例來說,一個攻擊者可能不會只想要偽造一份一模一樣的文件,而會想改造原來的文件,再附上合法的簽章,來愚弄持有私密金鑰的驗證者。另一方面,如果可以從密文中反推未加密前的使用者密碼,攻擊者就能利用得到的密碼登入其他使用者的帳戶,而這種事在密碼系統中是不能被允許的。但若存在反譯攻擊,只要能得到指定使用者密碼雜湊過後的字串(通常存在影檔中,而且可能不會透露原密碼資訊),就有可能得到該使用者的密碼。
2006 年的 CRYPTO 會議上,Christian Rechberger 和 Christophe De Cannière 宣布他們能在容許攻擊者決定部分原訊息的條件之下,找到 SHA-1 的一個碰撞。
[編輯] SHA-2
SHA-2 的第t個加密迴圈。圖中的深藍色方塊是事先定義好的非線性函數。ABCDEFGH一開始分別是八個初始值,Kt是第t個金鑰,Wt是本區塊產生第t個word。原訊息被切成固定長度的區塊,對每一個區塊,產生n個word(n視演演演算法而定),透過重復運作迴圈n次對ABCDEFGH這八個工作區段循環加密。最後一次迴圈所產生的八段字串合起來即是此區塊對應到的雜湊字串。若原訊息包含數個區塊,則最後還要將這些區塊產生的雜湊字串加以混合才能產生最後的雜湊字串。NIST 發布了三個額外的 SHA 變體,這三個函數都將訊息對應到更長的訊息摘要。以它們的摘要長度 (以位元計算) 加在原名後面來命名:SHA-256,SHA-384 和 SHA-512。它們發布於 2001年的 FIPS PUB 180-2 草稿中,隨即通過審查和評論。包含 SHA-1 的 FIPS PUB 180-2,於 2002年以官方標准發布。2004年2月,發布了一次 FIPS PUB 180-2 的變更通知,加入了一個額外的變種 "SHA-224",這是為了符合雙金鑰 3DES 所需的金鑰長度而定義。
SHA-256 和 SHA-512 是很新的雜湊函數,前者以定義一個word為32位元,後者則定義一個word為64位元。它們分別使用了不同的偏移量,或用不同的常數,然而,實際上二者結構是相同的,只在迴圈執行的次數上有所差異。 SHA-224 以及 SHA-384 則是前述二種雜湊函數的截短版,利用不同的初始值做計算。
這些新的雜湊函數並沒有接受像 SHA-1 一樣的公眾密碼社群做詳細的檢驗,所以它們的密碼安全性還不被大家廣泛的信任。Gilbert 和 Handschuh (2003) 曾對這些新變種作過一些研究,聲稱他們沒有弱點。
[編輯] SHA 所定義的長度
下表中的中繼雜湊值(internal state)表示對每個資料區塊壓縮雜湊過後的中繼值(internal hash sum)。詳情請參見Merkle-Damgård construction。
演演演算法 輸出雜湊值長度 (bits) 中繼雜湊值長度 (bits) 資料區塊長度 (bits) 最大輸入訊息長度 (bits) 一個Word長度 (bits) 迴圈次數 使用到的運運算元 碰撞攻擊
SHA-0 160 160 512 264 − 1 32 80 +,and,or,xor,rotl 是
SHA-1 160 160 512 264 − 1 32 80 +,and,or,xor,rotl 存在263 的攻擊
SHA-256/224 256/224 256 512 264 − 1 32 64 +,and,or,xor,shr,rotr 尚未出現
SHA-512/384 512/384 512 1024 2128 − 1 64 80 +,and,or,xor,shr,rotr 尚未出現
[編輯] SHAd
SHAd 函數是一個簡單的相同 SHA 函數的重述:
SHAd-256(m)=SHA-256(SHA-256(m))。它會克服有關延伸長度攻擊的問題。
[編輯] 應用
SHA-1, SHA-224, SHA-256, SHA-384 和 SHA-512 都被需要安全雜湊演演演算法的美國聯邦政府所應用,他們也使用其他的密碼演演演算法和協定來保護敏感的未保密資料。FIPS PUB 180-1 也鼓勵私人或商業組織使用 SHA-1 加密。Fritz-chip 將很可能使用 SHA-1 雜湊函數來實現個人電腦上的數位版權管理。
首先推動安全雜湊演演演算法出版的是已合並的數位簽章標准。
SHA 雜湊函數已被做為 SHACAL 分組密碼演演演算法的基礎。
[編輯] SHA-1 演演演算法
以下是 SHA-1 演演演算法的虛擬碼:
Note: All variables are unsigned 32 bits and wrap molo 232 when calculating
Initialize variables:
h0 := 0x67452301
h1 := 0xEFCDAB89
h2 := 0x98BADCFE
h3 := 0x10325476
h4 := 0xC3D2E1F0
Pre-processing:
append the bit '1' to the message
append k bits '0', where k is the minimum number >= 0 such that the resulting message
length (in bits) is congruent to 448 (mod 512)
append length of message (before pre-processing), in bits, as 64-bit big-endian integer
Process the message in successive 512-bit chunks:
break message into 512-bit chunks
for each chunk
break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15
Extend the sixteen 32-bit words into eighty 32-bit words:
for i from 16 to 79
w[i] := (w[i-3] xor w[i-8] xor w[i-14] xor w[i-16]) leftrotate 1
Initialize hash value for this chunk:
a := h0
b := h1
c := h2
d := h3
e := h4
Main loop:
for i from 0 to 79
if 0 ≤ i ≤ 19 then
f := (b and c) or ((not b) and d)
k := 0x5A827999
else if 20 ≤ i ≤ 39
f := b xor c xor d
k := 0x6ED9EBA1
else if 40 ≤ i ≤ 59
f := (b and c) or (b and d) or (c and d)
k := 0x8F1BBCDC
else if 60 ≤ i ≤ 79
f := b xor c xor d
k := 0xCA62C1D6
temp := (a leftrotate 5) + f + e + k + w[i]
e := d
d := c
c := b leftrotate 30
b := a
a := temp
Add this chunk's hash to result so far:
h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
h4 := h4 + e
Proce the final hash value (big-endian):
digest = hash = h0 append h1 append h2 append h3 append h4
上述關於 f 運算式列於 FIPS PUB 180-1 中 , 以下替代運算式也許也能在主要迴圈裡計算 f :
(0 ≤ i ≤ 19): f := d xor (b and (c xor d)) (alternative)
(40 ≤ i ≤ 59): f := (b and c) or (d and (b or c)) (alternative 1)
(40 ≤ i ≤ 59): f := (b and c) or (d and (b xor c)) (alternative 2)
(40 ≤ i ≤ 59): f := (b and c) + (d and (b xor c)) (alternative 3)
[編輯] SHA-2 演演演算法
以下是SHA-256 演演演算法的虛擬碼。注意,64個word w[16..63]中的位元比起 SHA-1 演演演算法,混合的程度大幅提升。
Note: All variables are unsigned 32 bits and wrap molo 232 when calculating
Initialize variables
(first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19
Initialize table of round constants
(first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
k[0..63] :=
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
Pre-processing:
append the bit '1' to the message
append k bits '0', where k is the minimum number >= 0 such that the resulting message
length (in bits) is congruent to 448 (mod 512)
append length of message (before pre-processing), in bits, as 64-bit big-endian integer
Process the message in successive 512-bit chunks:
break message into 512-bit chunks
for each chunk
break chunk into sixteen 32-bit big-endian words w[0..15]
Extend the sixteen 32-bit words into sixty-four 32-bit words:
for i from 16 to 63
s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3)
s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift 10)
w[i] := w[i-16] + s0 + w[i-7] + s1
Initialize hash value for this chunk:
a := h0
b := h1
c := h2
d := h3
e := h4
f := h5
g := h6
h := h7
Main loop:
for i from 0 to 63
s0 := (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22)
maj := (a and b) xor (a and c) xor (b and c)
t2 := s0 + maj
s1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25)
ch := (e and f) xor ((not e) and g)
t1 := h + s1 + ch + k[i] + w[i]
h := g
g := f
f := e
e := d + t1
d := c
c := b
b := a
a := t1 + t2
Add this chunk's hash to result so far:
h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
h4 := h4 + e
h5 := h5 + f
h6 := h6 + g
h7 := h7 + h
Proce the final hash value (big-endian):
digest = hash = h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7
其中 ch 函數及 maj 函數可利用前述 SHA-1 的優化方式改寫。
SHA-224 和 SHA-256 基本上是相同的, 除了:
h0 到 h7 的初始值不同,以及
SHA-224 輸出時截掉 h7 的函數值。
SHA-512 和 SHA-256 的結構相同,但:
SHA-512 所有的數字都是64位元,
SHA-512 執行80次加密迴圈而非64次,
SHA-512 初始值和常數拉長成64位元,以及
二者位元的偏移量和循環位移量不同。
SHA-384 和 SHA-512 基本上是相同的,除了:
h0 到 h7 的初始值不同,以及
SHA-384 輸出時截掉 h6 和 h7 的函數值。
G. A*演算法的原理
A* (A-Star)演算法是一種靜態路網中求解最短路最有效的直接搜索方法。
注意是最有效的直接搜索演算法。之後涌現了很多預處理演算法(ALT,CH,HL等等),在線查詢效率是A*演算法的數千甚至上萬倍。
公式表示為: f(n)=g(n)+h(n),
其中 f(n) 是從初始點經由節點n到目標點的估價函數,
g(n) 是在狀態空間中從初始節點到n節點的實際代價,
h(n) 是從n到目標節點最佳路徑的估計代價。
保證找到最短路徑(最優解的)條件,關鍵在於估價函數f(n)的選取:
估價值h(n)<= n到目標節點的距離實際值,這種情況下,搜索的點數多,搜索范圍大,效率低。但能得到最優解。並且如果h(n)=d(n),即距離估計h(n)等於最短距離,那麼搜索將嚴格沿著最短路徑進行, 此時的搜索效率是最高的。
如果 估價值>實際值,搜索的點數少,搜索范圍小,效率高,但不能保證得到最優解。
H. A*演算法現實應用的實際意義
A*演算法在人工智慧中是一種典型的啟發式搜索演算法,為了說清楚A*演算法,我看還是先說說何謂啟發式演算法。
一、何謂啟發式搜索演算法
在說它之前先提提狀態空間搜索。狀態空間搜索,如果按專業點的說法就是將問題求解過程表現為從初始狀態到目標狀態尋找這個路徑的過程。通俗點說,就是在解一個問題時,找到一條解題的過程可以從求解的開始到問題的結果(好象並不通俗哦)。由於求解問題的過程中分枝有很多,主要是求解過程中求解條件的不確定性,不完備性造成的,使得求解的路徑很多這就構成了一個圖,我們說這個圖就是狀態空間。問題的求解實際上就是在這個圖中找到一條路徑可以從開始到結果。這個尋找的過程就是狀態空間搜索。
常用的狀態空間搜索有深度優先和廣度優先。廣度優先是從初始狀態一層一層向下找,直到找到目標為止。深度優先是按照一定的順序前查找完一個分支,再查找另一個分支,以至找到目標為止。這兩種演算法在數據結構書中都有描述,可以參看這些書得到更詳細的解釋。
前面說的廣度和深度優先搜索有一個很大的缺陷就是他們都是在一個給定的狀態空間中窮舉。這在狀態空間不大的情況下是很合適的演算法,可是當狀態空間十分大,且不預測的情況下就不可取了。他的效率實在太低,甚至不可完成。在這里就要用到啟發式搜索了。
啟發式搜索就是在狀態空間中的搜索對每一個搜索的位置進行評估,得到最好的位置,再從這個位置進行搜索直到目標。這樣可以省略大量無畏的搜索路徑,提到了效率。在啟發式搜索中,對位置的估價是十分重要的。採用了不同的估價可以有不同的效果。我們先看看估價是如何表示的。
啟發中的估價是用估價函數表示的,如:
f(n) = g(n) + h(n)
其中f(n)是節點n的估價函數,g(n)實在狀態空間中從初始節點到n節點的實際代價,h(n)是從n到目標節點最佳路徑的估計代價。在這里主要是h(n)體現了搜索的啟發信息,因為g(n)是已知的。如果說詳細點,g(n)代表了搜索的廣度的優先趨勢。但是當h(n)>>g(n)時,可以省略g(n),而提高效率。這些就深了,不懂也不影響啦!我們繼續看看何謂A*演算法。
二、初識A*演算法
啟發式搜索其實有很多的演算法,比如:局部擇優搜索法、最好優先搜索法等等。當然A*也是。這些演算法都使用了啟發函數,但在具體的選取最佳搜索節點時的策略不同。象局部擇優搜索法,就是在搜索的過程中選取「最佳節點」後舍棄其他的兄弟節點,父親節點,而一直得搜索下去。這種搜索的結果很明顯,由於舍棄了其他的節點,可能也把最好的節點都舍棄了,因為求解的最佳節點只是在該階段的最佳並不一定是全局的最佳。最好優先就聰明多了,他在搜索時,便沒有舍棄節點(除非該節點是死節點),在每一步的估價中都把當前的節點和以前的節點的估價值比較得到一個「最佳的節點」。這樣可以有效的防止「最佳節點」的丟失。那麼A*演算法又是一種什麼樣的演算法呢?其實A*演算法也是一種最好優先的演算法。只不過要加上一些約束條件罷了。由於在一些問題求解時,我們希望能夠求解出狀態空間搜索的最短路徑,也就是用最快的方法求解問題,A*就是干這種事情的!我們先下個定義,如果一個估價函數可以找出最短的路徑,我們稱之為可採納性。A*演算法是一個可採納的最好優先演算法。A*演算法的估價函數可表示為:
f'(n) = g'(n) + h'(n)
這里,f'(n)是估價函數,g'(n)是起點到終點的最短路徑值,h'(n)是n到目標的最斷路經的啟發值。由於這個f'(n)其實是無法預先知道的,所以我們用前面的估價函數f(n)做近似。g(n)代替g'(n),但g(n)>=g'(n)才可(大多數情況下都是滿足的,可以不用考慮),h(n)代替h'(n),但h(n)<=h'(n)才可(這一點特別的重要)。可以證明應用這樣的估價函數是可以找到最短路徑的,也就是可採納的。我們說應用這種估價函數的最好優先演算法就是A*演算法。哈!你懂了嗎?肯定沒懂!接著看!
舉一個例子,其實廣度優先演算法就是A*演算法的特例。其中g(n)是節點所在的層數,h(n)=0,這種h(n)肯定小於h'(n),所以由前述可知廣度優先演算法是一種可採納的。實際也是。當然它是一種最臭的A*演算法。
再說一個問題,就是有關h(n)啟發函數的信息性。h(n)的信息性通俗點說其實就是在估計一個節點的值時的約束條件,如果信息越多或約束條件越多則排除的節點就越多,估價函數越好或說這個演算法越好。這就是為什麼廣度優先演算法的那麼臭的原因了,誰叫它的h(n)=0,一點啟發信息都沒有。但在游戲開發中由於實時性的問題,h(n)的信息越多,它的計算量就越大,耗費的時間就越多。就應該適當的減小h(n)的信息,即減小約束條件。但演算法的准確性就差了,這里就有一個平衡的問題。