人工智慧導論學習筆記
參考文獻:
部分截圖來自學校老師的教學PPT
https://zhuanlan.zhihu.com/p/61895500
https://zhuanlan.zhihu.com/p/64368643
https://zhuanlan.zhihu.com/p/148256240
https://zhuanlan.zhihu.com/p/272652797
https://blog.csdn.net/qq_45902301/article/details/125055544
https://blog.csdn.net/wangyong1034/article/details/105017736
https://blog.csdn.net/xing565244161/article/details/47253211
一、State Spaces and Search Problems 狀態空間和搜尋問題
為了建立一個理性計劃agent,我們需要一種方法來對agent存在的環境進行數學表達。為此,我們必須正式表達一個搜尋問題(search problem)——給定agent的當前狀態(state)(它在環境中的配置),我們如何儘可能最好地達到一個滿足目標的新狀態?講一個問題公式化需要四個前提:
- 狀態空間state space:在給定世界中所有可能的狀態
- 後繼函式successor function:包含一個狀態和一個操作,並計算執行該操作的代價(cost)和執行操作後世界的後繼狀態
- 起始狀態start state:agent最初存在時當前世界的狀態
- 目標測試函式goal test:一個函式,輸入一個狀態並決定它是否是一個目標狀態
搜尋問題
o
狀態空間的大小
狀態空間的定義
以下截圖不完整,想看完整版的去看參考文獻。
二、深度優先搜尋(DFS)
完備(整)性、最優性、時間複雜度
若走到葉子節點,便會退回上一節點,遍歷上一節點的其他相鄰節點(2 ->3-> 4)。
這樣一直重複,直到找到最終目標節點。
如你所見到的一樣,這樣的搜尋方法像一根貪婪的蚯蚓,喜歡往深的地方鑽,所以就自然而然的叫做深度優先演算法了。
三、廣度(寬度)優先搜尋(BFS)
對於深度優先演算法,強迫症就很不爽了,並表示:“為什麼不幹乾淨淨,一層 一層地從start節點搜尋下去呢,就像病毒感染一樣,這樣才像正常的搜尋的樣子嘛!”於是便有了BFS演算法。廣度優先演算法便如其名字,它是以廣度為優先的,一層一層搜尋下去的。
BFS總是先訪問完同一層的結點,然後才繼續訪問下一層結點,它最有用的性質是可以遍歷一次就生成中心結點到所遍歷結點的最短路徑,這一點在求無權圖的最短路徑時非常有用。
還是以圖的方式來演示,下圖中start為搜尋的初始節點,end為目標節點:
我們先把start節點的相關節點遍歷一次
接下來把第一步遍歷過的節點當成start節點,重複第一步
一直重複一二步,這樣便是一個放射樣式的搜尋方法,直到找到end節點
可以看出,這樣放射性的尋找方式,能找到從start到end的最短路徑(因為每次只走一步,且把所有的可能都走了,誰先到end說明這就是最短路)。
從實現的角度上,在廣度優先遍歷的過程中,我們需要用到佇列:
1. 首先擴充套件最淺的節點
2. 將後繼節點放入佇列的末尾(FIFO)
BFS是從根節點(起始節點)開始,按層進行搜尋,也就是按層來擴充套件節點。所謂按層擴充套件,就是前一層的節點擴充套件完畢後才進行下一層節點的擴充套件,直到得到目標節點為止。
四、一致代價搜尋(UCS)
以下練習作為延伸理解
輸入初始城市
Arad
輸入目的城市
Bucharest
處理城市節點:Arad 父節點:None 路徑損失為:0
孩子節點:Zerind 路徑損失為:75
新增孩子到優先佇列
孩子節點:Sibiu 路徑損失為:140
新增孩子到優先佇列
孩子節點:Timisoara 路徑損失為:118
新增孩子到優先佇列
處理城市節點:Zerind 父節點:Arad 路徑損失為:75
孩子節點:Oradea 路徑損失為:146
新增孩子到優先佇列
孩子節點:Arad 路徑損失為:150
處理城市節點:Timisoara 父節點:Arad 路徑損失為:118
孩子節點:Arad 路徑損失為:236
孩子節點:Lugoj 路徑損失為:229
新增孩子到優先佇列
處理城市節點:Sibiu 父節點:Arad 路徑損失為:140
孩子節點:Oradea 路徑損失為:291
孩子節點:Arad 路徑損失為:280
孩子節點:Fagaras 路徑損失為:239
新增孩子到優先佇列
孩子節點:Rimnicu Vilcea 路徑損失為:220
新增孩子到優先佇列
處理城市節點:Oradea 父節點:Zerind 路徑損失為:146
孩子節點:Zerind 路徑損失為:217
孩子節點:Sibiu 路徑損失為:297
處理城市節點:Rimnicu Vilcea 父節點:Sibiu 路徑損失為:220
孩子節點:Sibiu 路徑損失為:300
孩子節點:Craiova 路徑損失為:366
新增孩子到優先佇列
孩子節點:Pitesti 路徑損失為:317
新增孩子到優先佇列
處理城市節點:Lugoj 父節點:Timisoara 路徑損失為:229
孩子節點:Timisoara 路徑損失為:340
孩子節點:Mehadia 路徑損失為:299
新增孩子到優先佇列
處理城市節點:Fagaras 父節點:Sibiu 路徑損失為:239
孩子節點:Sibiu 路徑損失為:338
孩子節點:Bucharest 路徑損失為:450
新增孩子到優先佇列
處理城市節點:Mehadia 父節點:Lugoj 路徑損失為:299
孩子節點:Lugoj 路徑損失為:369
孩子節點:Drobeta 路徑損失為:374
新增孩子到優先佇列
處理城市節點:Pitesti 父節點:Rimnicu Vilcea 路徑損失為:317
孩子節點:Rimnicu Vilcea 路徑損失為:414
孩子節點:Craiova 路徑損失為:455
孩子節點:Bucharest 路徑損失為:418
替換狀態: Bucharest 舊的損失:450 新的損失:418
處理城市節點:Craiova 父節點:Rimnicu Vilcea 路徑損失為:366
孩子節點:Drobeta 路徑損失為:486
孩子節點:Rimnicu Vilcea 路徑損失為:512
孩子節點:Pitesti 路徑損失為:504
處理城市節點:Drobeta 父節點:Mehadia 路徑損失為:374
孩子節點:Mehadia 路徑損失為:449
孩子節點:Craiova 路徑損失為:494
處理城市節點:Bucharest 父節點:Pitesti 路徑損失為:418
目的地已經找到了
從城市: Arad 到城市 Bucharest 查詢成功
Arad->Sibiu->Rimnicu Vilcea->Pitesti->Bucharest
五、啟發式搜尋
六、貪婪最佳優先搜尋(GBS)
七、A*演算法
啟發式搜尋通常是鬆弛問題
1.啟發函式的特性
2.啟發函式是一致(可採納的)的條件
3.A*的可採納、一致性、最優性、完備性和缺點
A*搜尋與一致代價搜尋類似,
除了A*使用g+h而不是g。
A*搜尋既是完備的也是最優的。
4.啟發函式在A*的作用
(1)一種極端情況,如果h(n)是0,則只有g(n)起作用,此時A* 演算法演變成Dijkstra演算法,就能保證找到最短路徑。
(2)如果h(n)總是比從n移動到目標的代價小(或相等),那麼A* 保證能找到一條最短路徑。h(n)越小,A* 需要擴充套件的點越多,執行速度越慢。
(3)如果h(n)正好等於從n移動到目標的代價,那麼A* 將只遵循最佳路徑而不會擴充套件到其他任何結點,能夠執行地很快。儘管這不可能在所有情況下發生,但你仍可以在某些特殊情況下讓h(n)正好等於實際代價值。只要所給的資訊完善,A* 將執行得很完美。
(4)如果h(n)比從n移動到目標的代價高,則A* 不能保證找到一條最短路徑,但它可以執行得更快。
所以h(n)的選擇成了一個有趣的情況,它取決於我們想要A* 演算法中獲得什麼 結果。h(n)合適的時候,我們會非常快速地得到最短路徑。如果h(n)估計的代價太低,我們仍會得到最短路徑,但執行速度會減慢。如果估計的代價太高,我們就放棄最短路徑,但A* 將執行得更快。
八、曼哈頓距離和歐幾里得距離
歐幾里得距離就是上面的綠線,即歐氏距離
九、約束滿足問題
十、約束圖 Constraint Graphs
我們來介紹第二個CSP的例子:地圖著色問題。這類問題是指,我們要用一些給定的顏色來給地圖上色,並且相鄰區域的的顏色必須不同。
約束滿足問題常用約束圖來表示,其中節點代表變數,邊則代表變數之間的約束。有許多種不停的約束,每一種的解決方式也都不同:
- 一元約束:CSP中一元約束包括一個單變數。它們不在約束圖中表示,而只是在必要時用來給它們約束的變數的域進行剪枝。
- 二元約束:二元約束包含兩個變數。它們在約束圖中表示為傳統圖的邊。
- 多元約束:在CSP圖中,包含三個或更多變數的約束也能用邊來表示,它們看起來只是有一點點非常規。
我們來看一下澳大利亞地圖的染色:
這個問題中的約束就是相鄰區域顏色不能相同。於是,透過在每兩個相鄰的區域之間畫一條邊,我們能得到澳大利亞地圖染色問題的約束圖:
約束圖的價值在於能幫助我們提取CSP的結構的有效資訊。透過分析CSP的圖,我們能確定關於它的一下資訊,比如其連線/約束是稀疏還是緊密,或者它是否是樹狀的。在我們詳細討論求解約束滿足問題時我們會深挖這些問題。
十一、約束滿足問題求解 回溯搜尋
約束滿足問題的傳統解法是使用一種叫做回溯搜尋(Backtracking search)的演算法。回溯搜尋是對專門針對約束滿足問題的DFS的最最佳化,主要改善了兩個法則:
- 規定變數的順序,並按照這個順序選擇變數的賦值。因為賦值是可以互換的(例如,令WA=Red,NT=Green 等價於 令NT=Green,WA=Red),這是有效的。
- 在給變數選擇賦值時,只選擇不與已經分配了的值衝突的賦值。如果不存在這樣的值,回溯並返回前一個變數,並改變其賦值。
迭代回溯過程的虛擬碼如下:
為了讓這個過程更直觀,我們來看一下分別用深度優先搜尋和回溯搜尋解決地圖染色問題的區域性搜尋樹:
注意DFS在意識到問題之前已經把所有部分都塗成了紅色,即便如此,也沒有往正確的方向做出多少改變。另一方面,回溯搜尋在一個值沒有違背任何約束時將其賦值給一個變數,這樣能明顯減少回溯的次數。雖然回溯搜尋相比較深度優先搜尋的霸王硬上弓要有了很大的改進,我們仍然可透過過濾、變數/值的排序和結構上的探索進一步提高速度。
回溯 = DFS + 變數排序 + 失敗(不相容)回溯
十二、過濾Filtering
1、前向檢驗
2、弧相容
弧相容就是值域被刪除的點要檢查其所有相鄰點的值域有無違反約束
十三、前向搜尋額外補充
前向檢測是一種深度優先搜尋策略,它是回溯法的一種擴充套件。它採用了“向前看”的策略,即對一個變數進行賦值時,修改約束條件下相關變數的值域。其過程如下:
-
選擇一個變數。
-
遍歷變數值域。
-
根據變數的賦值,調整相關變數的值域空間。若不會導致DWO(Domain Wipe Out)則往下遞迴。
-
若有解則結束。否則恢復相關變數的值域空間,並回到步驟2。
-
該區域性狀態無解(對於步驟1選擇變數,可使用啟發式搜尋最佳化。如MRV啟發式,優先選擇值域空間小的變數。)
十四、排序 MRV LCV
我們已經提到過,在解決CSP問題時,我們對涉及到的變數和值都進行排序。在實踐中,使用兩個基本原則——最小剩餘值(minimum remaining values)和最少約束值(least constraining value)來“動態”地計算下一個變數和相應的值,通常要高效得多:
- 最小剩餘值Minimum Remaining Values (MRV):當選擇下一個要賦值的變數時,用MRV策略能選擇有效剩餘值最少的未賦值變數(即約束最多的變數)。這很直觀,因為受到約束最多的變數也最容易耗盡所有可能的值,並且如果沒有賦值的話最終會回溯,所以最好儘早賦值。
- 最少約束值Least Constraining Value (LCV):同理,當選擇下一個要賦值的值時,一個好的策略就是選擇從剩餘未分配值的域中淘汰掉最少值的那一個。要注意的是,這要求更多的計算(比方說,對每個值重新執行弧相容/前向檢測或是其他過濾方法來找到其LCV),但是取決於用途,仍然能獲得更快的速度。
十五、Minimax
前言
十六、α-β剪枝
十七、Expectimax
十八、馬爾可夫決策過程
T就是機率函式,在下面的例子中就是0.5或者1,表示狀態s採取a行動後得到狀態s'的機率
R就是狀態s採取a行動後得到狀態s'的獎勵,在下面的例子中獎勵有1,2,-10
十九、有限界和折扣 Finite Horizons and Discounting
二十、馬爾可夫性 Markovianess
二十一、馬爾可夫決策過程求解
二十二、貝爾曼方程
二十三、值迭代
上面的V1(warm),+的位置寫錯了,注意了。
以V1(cool)為例
二十四、策略提取
二十五、策略迭代
這個例子說明了值迭代真正的力量:只用兩次迭代,我們就能得到賽車MDP的最優策略!這比在同一個MDP上進行值迭代要強多了,值迭代在進行這兩次更新之後還要好多次迭代才能收斂。
二十六、值迭代、策略評估、策略提取、策略迭代總結
將值迭代、策略評估、策略提取、策略迭代進行一個歸納總結:
1.值迭代
先從貝爾曼方程開始,
在值迭代的第k輪,
跟上面那個總結一樣,值迭代用於計算狀態的最優值。
總結就是:
值迭代的做題步驟:
1.設初值為0
2.重複求最優值操作直至收斂(按題目要求來,不一定要求到收斂,有些簡單的題可以很快收斂)
3.收斂就是V*保持不變了
2.策略評估
3.策略提取
策略提取的背後的思想非常簡單:如果你處於一種狀態s,你應該採取會產生最大期望效益的行動a。
其實就是:最優值對應的行動a就是要提取的策略
4.策略迭代
總結:
策略迭代的做題步驟:
1.定義一個初始策略
2.對所有狀態進行策略評估,評估次數不限,一般收斂了就停止評估了。(評估次數由題目來定)
3.用策略評估的值進行策略提取,提取次數不限,一般收斂了就停止提取了。(提取次數由題目來定)
4.策略改進,其實就是將收斂的策略評估的策略作為最優策略