《人工智能——一種現代方法》(第二版)【第3章 用搜索法對問題求解】小結

這章是第二部分問題求解的開篇,主講運用搜索法解決問題。然後介紹常用無信息搜索策略(BFS,DFS,IDS……),還強調了下避免重複狀態,最後提到了下使用不完全信息的搜索。

開章提到:當沒有單獨的行動可以解決問題的時候,智能體如何找到一個行動序列達到它的目標,是討論的重點。然後會描述一種基於目標的智能體,稱爲問題求解智能體。問題求解智能體通過尋找達到所希望的狀態的行動序列來決策要做什麼。從精確地定義組成“問題”和它的“解”的元素開始,並且給出一些例子來詳細介紹這些定義。

智能化智能體被認爲是能使自己的性能度量達到最大化的智能體。

基於當前的情形和智能體的性能度量的目標形式化是問題求解的第一個步驟。

我們將考慮的目標是一個世界狀態集合——正是在那些狀態中,該目標是可滿足的。智能體的任務是找出能夠使它達到目標狀態的行動序列。在能作這個之前,它需要決策所要考慮的行動和狀態的種類。而在很多的細節水平上,世界的不確定因素太多,問題的解也將包含過多的步驟。問題形式化是決策對於給定的目標需要考慮哪些行動和狀態的過程。

如果智能體不知道哪個可能的行動學列是最好的,那是因爲它對由每個行動產生的狀態瞭解得不夠多。如果智能體沒有得到額外的知識,就只能停滯不前了。這時它能做的最好決策就是隨機選擇一個行動。

一般來說,一個智能體有多個評價未知直接選項的時候,可以首先檢驗各個不同的能導致已知評價的狀態的可能行動序列,然後選擇最佳序列。尋找這樣一個序列的過程被稱爲搜索。

搜索算法把問題作爲輸入,並以行動序列的形式返回問題的解。一旦找到一個解,那麼它所建議的行動就可以付諸實施。這被稱爲執行階段。從而,我們有了一個對智能體的簡單設計,即“形式化,搜索,執行”。在把目標和待求解的問題形式化之後,智能體通過調用搜索過程對它求解。然後智能體用得到的解來引導行動,按照解的建議去作下一步事情。一旦解被執行,智能體將形式化新的目標。

這裏,我們的智能體設計假定環境是靜態的,可觀察的,確定性的,離散的。

1,靜態的,是因爲完成問題形式化和求解的時候不再注意可能發生在環境中的任何變化;2,可觀察的,瞭解初始化狀態是最簡單的;3,離散的,是爲了枚舉“可選的行動過程”的思想;4,確定性的(無二義性?)。

問題求解有兩部分,一是定義明確的問題及解;二是把問題形式化。

1,一個問題可以形式化地定義爲四個組成部分:智能體起始時的初始狀態,對智能體可採納的可能行動的描述(最常見的形式化是使用一個後繼函數,給定一個特殊狀態x,SUCCESSOR-FN(x)返回一個由有序對<action, successor>組成的集合。總之,初始狀態和它的後繼函數隱含地定義了問題的狀態空間,即是從初始狀態可以達到的所有狀態的集合。),目標測試(用來確定給定的狀態是不是目標狀態),路徑耗散函數爲每條路徑分配一個數值化的耗散值。

上述元素定義了一個問題,可以把他們集合在一起成爲單一的數據結構,作爲問題求解算法的輸入。問題的解就是從初始狀態到目標狀態的路徑。解的質量由路徑耗散函數度量,而最優解是所有解里路徑耗散值最小的解。

去除表象中的細節的過程被稱爲抽象化。除了對狀態描述抽象化之外,還要對行動本身進行抽象化。

選擇一個好的抽象化方法,涉及在保持有效性和保證抽象化的行動能夠容易完成的同時去除儘可能多的細節。如果缺乏能力去構造游泳的抽象化,智能體將會被現實世界完全淹沒。

然後提到了幾個問題實例,都是抽象出狀態,初始狀態,後繼函數,目標測試和路徑消耗。

重點是對解的搜索。該章討論的搜索技術使用顯式的搜索樹,搜索樹是由初始狀態和後繼函數共同產生的,同時也定義了狀態空間。一般來說,當同一個狀態可以從多條路徑達到時,我們會得到一個搜索圖而不是搜索樹。

搜索的基本做法是:先追隨一個選擇,把其它的暫且放在一邊,等到以後萬一發現第一個選擇不能通向問題的解的時候再考慮。而對要被擴展的狀態的選擇是由搜索策略決定的。

見圖3.7中一般的生成搜索樹算法的非形式化描述。(循環是否有節點,根據不同策略選擇一個節點進行判斷,判斷節點是否爲目標節點,是結束,否繼續拓展增加)

節點的表示有很多方式,不過我們假設節點是一個包含五個元素的數據結構:

STATE:狀態空間中與該節點相對應的節點;

PARENT-NODE:搜索樹中產生該節點的節點(即父節點);

ACTION:由父節點產生該節點所用的行動;

PATH-COST:從初始狀態到到達該節點的路徑消耗,傳統上記爲g(n),路徑由父指針表示;

DEPTH:從初始狀態到達該節點所經路徑上的步數。

記住節點和狀態的差別是很重要的。節點是用來表示搜索樹的記錄型數據結構。狀態對應於世界的格局。

已經生成出來但還未被擴展的節點集合被稱爲邊緣。邊緣的每個元素都是葉節點,即在搜索樹中沒有後繼的節點。因此可以更加形式化一般的樹搜索算法。見圖3.9。從FRINGE中取節點,判斷是否目標,不是擴展所有後繼節點加入FRINGE中。循環。


度量問題求解的性能,問題求解算法的輸出不是失敗就是解。(當然除掉一些陷入無限循環而永遠不會返回輸出的)通過一下四種途徑來評價一個算法的性能。

1,完備性:當問題有解時,這個算法是否能夠保證找到一個解?

2,最優性:這個搜索策略是否能找到最優解?

3,時間複雜性:找到一個解需要花費多長時間?

4,空間複雜性:在執行搜索的過程中需要多少內存?

時間和空間的複雜度往往要與問題難度的某種度量一起考慮。在AI領域,狀態空間圖是由初始狀態和後繼函數隱含地表示的,經常是無限的,它的複雜度根據下列三個值來表達。

b,分支因子,或者說是任何節點的後繼的最大個數;

d,最淺的目標節點的深度;

m,狀態空間中任何路徑的最大深度。

時間複雜度常常根據搜索過程中產生的節點數目來度量,而空間複雜度則根據在內存中存儲的最大節點數來度量。

在評價一個搜索算法的有效性的時候,可以只考慮搜索耗散——它通常取決於時間複雜度,不過也可以包括內存的使用情況——或者我們可以使用總耗散,它把找到的解的搜索耗散和路徑耗散結合起來。(解耗散,舉例說明,書中的例子是到Bucharest城市,這裏搜索耗散就是找到解的時間,而解耗散就是汽車到達B城市的時間,需要考慮公里數加上車速等因素)


無信息的搜索策略介紹了廣度優先,代價一致,深度優先,深度有限,迭代深入深度優先,雙向這六種。那三個名字聽起來有點陌生的策略只是對廣度和深度優先的改進優化。

廣度優先搜索是簡單的搜索策略,首先先擴展根節點,接着擴展根節點的所有後繼,然後再擴展它們的後繼,以此類推。一般來講,在下一層的任何節點擴展之前搜索樹上本層深度的所有節點都已經擴展過。(用FIFO實現上面的FRINGE集合即可實現)(維基百科上面的:廣度優先搜索算法(Breadth-First-Search),又譯作寬度優先搜索,或橫向優先搜索,簡稱BFS,是一種圖形搜索算法。簡單的說,BFS是從根節點開始,沿着樹的寬度遍歷樹的節點。如果所有節點均被訪問,則算法中止。廣度優先搜索的實現一般採用open-closed表。)

複雜度方面,維基百科給出的是O(b^d),而該書給出的是O(b^(d+1))。這個差異應該是對d的定義不同。維基上面對於樹的介紹如下http://zh.wikipedia.org/wiki/%E6%A0%91_(%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84),其中其深度定義d是層次的。而該書中的d定義爲到根節點的距離,即是兩者定義上就相差1了。至於這個d+1怎麼來的的問題,按照本書上面提到的“時間複雜度常常根據搜索過程中產生的節點數目來度量,而空間複雜度則根據在內存中存儲的最大節點數來度量。”來衡量的話,給出d+1的結論是OK的。這個b^(d+1)指數是由目標節點所在層的節點擴展出來的未被擴展的節點數量產生的。

另外要提到的完備性和最優性。完備性很容易理解,如果最淺的目標節點處於一個有限的深度d。不過,最淺的目標節點不一定就是最優的目標節點。這個要注意,必須要有“路徑耗散是節點深度的非遞減函數”的前提才能成立。


代價一致搜索,其實就是一個貪心搜索,取代擴展深度最淺的節點,代價一致搜索擴展的是路徑消耗最低的節點n。如果所有單步耗散都相等的話,這種算法就和廣度優先搜索算法是一樣的。不過,這樣在擴展到一個具有能返回到同一狀態的零耗散行動的節點時就會陷入無限循環(例如NoOp行動,即無操作行動)。

完備性方面,如果每一步的耗散都大於等於某個小的正值常數r。這個條件可以有效地保證最優性。因爲這意味着路徑的耗散總是增加的。即是最開始擴展到的節點一定耗散不大於後面擴展到的節點。

複雜度方面,由於代價一致搜索是由路徑的耗散引導而不是深度,所以不能簡單地使用b和d來刻畫。替代地,用C*表示最優解的耗散值,並且假設每個行動的耗散至少爲r。那麼這個算法最壞情況下的時間和空間複雜度爲O(b^ceil(C*/r)),要比b^d大得多。當單步消耗都相等的時候,兩者相等。


深度優先搜索,總是擴展搜索樹的當前邊緣中最深的節點。其對內存的需求很少。只需要存儲一條從根節點到葉節點的路徑,以及該路徑每個節點的所有未被擴展的兄弟節點即可。(一旦一個節點被擴展,當它的所有後代都被完全搜索過後這個節點就可以從內存中刪除。)

因此,DFS只需要存儲bm+1個節點。其另一種變形稱爲回溯搜索,所用的內存空間更少。在回溯搜索中,每次只產生一個後繼節點而不是所有的後繼節點:每個被部分擴展的節點要記住下一個要生成的節點是哪個。用這種方法,內存只需要O(m)而不是O(bm)。其還推動了另一個節省內存(和節省時間)的技巧:通過直接修改當前的狀態描述而不是先對它進行復制來生成後繼節點的思想。

完備性方面,是不能保證的。因爲如果所左子樹深度沒限制又不包含目標節點,那麼DFS永遠不會停止。另外,最優也明顯不能保證。時間複雜度方面,搜索O(b^m)數量級節點。


下面還介紹了兩個對DFS優化的搜索策略。

深度有限搜索,這個,在DFS的基礎上面預先設定了一個深度限制l。搜索過程和DFS一樣,只是深度爲l的節點被當作沒有後繼的節點對待。雖然這種方法解決了無窮路徑的問題,但是如果我們選擇的l<d的話,這會導致不完備性。

實際上,對狀態空間的研究,我們會發現狀態空間的直徑,從而用來限制DFS,可以得到優化。


迭代深入深度優先搜索,簡稱爲迭代深入搜索,是一個用來尋找最合適的深度限制的通用策略。它的做法是不斷地增大深度限制,直到找到目標節點。空間需求明顯和DFS一樣,也爲O(bd)。雖然深度較低的節點多次重複,但是總的來說,還是不算多。也只是到達O(b^d),比BFS快。

一般來講,當搜索空間很大而且解的深度未知的時候,迭代深入搜索是一個首選的無信息搜索方法。


最後介紹的雙向搜索,同時運行兩個搜索,一個從初始狀態空間向前搜索,另一個從目標狀態先後搜索。其思想是b^(d/2)+b^(d/2)要比b^d小得多。(通過哈希表檢測一個節點是否屬於另一顆搜索樹只需要固定的時間)時間複雜度爲O(b^(d/2))……最困難的地方是,目標測試只給出對可能很大的目標狀態集合的一個隱性描述——象棋中的將死。


避免重複狀態是很重要的,一般用closed表和open表。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章