一致代價搜尋 關於搜尋演算法的一些總結

2021-10-12 17:12:49 字數 3089 閱讀 6100

搜尋演算法在路徑規劃、行為決策、語句識別、語義分析等多個領域都發揮著非常重要的作用,以下是我本週對搜尋演算法的一些簡單總結:

2. 廣度優先搜尋,這個也是一種無資訊搜尋,也是只知道起點和終點然後讓機器去搜尋,與深度搜尋不同的是它每次拓展的是邊緣空間節點中最淺的那個節點,都是同乙個深度的話就拓展最左邊的那個節點,若是借用下圖來說明的話,就是假如我們需要從s到g,首先將s進行拓展,發現只有def三個節點,def的深度都是相同的,於是我們拓展最左邊的d節點,發現它的子節點中沒有終點,於是我們將它的子節點納入邊緣空間集合中,這時邊緣空間集合中的節點為bceep五個節點,但是e和p是最淺的,於是我們又拓展e節點,發現它的節點中同樣沒有終點,於是又將它的子節點納入邊緣集合中間中,此時邊緣集合空間中的節點為bcehrp六個節點,這裡面p的深度是最淺的,於是我們又拓展p....依次類推,這種方法的有點是只要終點存在,機器就一定能夠找到終點,也就是具備完備性,缺點就是若是運氣不太好,可能邊緣空間集合中所包含的節點數量會非常多,會非常占用記憶體,而且也不具備最優性。

3. 迭代深入搜尋,就是同時結合深度優先於廣度優先的有點吧,某種意義上我是這麼覺得的,就是我們預先設定乙個探索的層數,然後在這個層數以內採用深度優先演算法,當在這個層數裡面都沒有找到終點的話,然後就對這個層數進行拓展,允許進行更深一層的探索,這樣的話即保留了深度優先演算法的對記憶體的很少的占用的優勢,又一定能夠找到那個解(終點)如果這個解存在的話。這種方法的話有一點小小的缺點就是可能會造成一定的浪費冗餘,因為拓展之後的那一層並不是簡單的只需要探索那一層,這種演算法仍然會將前面的重新再採用深度優先演算法重新算一遍,但是所幸的是一般在深度不太深的初始的那些節點都不太多,大多數節點都是在底層,所以即使對上層的那些節點進行重複的探索,浪費也不是特別嚴重。

4. 代價敏感搜尋,就是找到最少的代價的那條路徑然後進行搜尋。代價函式是人為確定的。

5. 代價一致搜尋,其實是代價敏感搜尋的一種實現,它會將之前的走過的路徑的代價進行乙個累加,然後尋找其代價最低的路徑。具體過程如下圖所示

6.貪婪搜尋,這是一種啟發式搜尋,就是已經知道了一部分資訊,不需要讓機器進行所有方向上的探索,就比如我要從a城市到d城市,所有城市的距離我們是已知的,中間還有bc兩個城市,a可以到b也可以到c,但是bc兩個城市到d城市的距離是不一樣的,這種演算法就是只尋找離終點最近的節點,就是如果b離d更近,那麼久拓展b。這種演算法有一定的弊端,就是這種演算法只考慮了後半段的距離而沒有考慮前面的距離,還是這個例子,假如a到b是50公里,a到c是30公里,然後b到d是40公里,c到d是50公里,這個演算法的話,只會選擇離終點d最近的路徑,即a-b-d這樣的路徑,這樣走下來是90公里,但是如果a-c-d的話只要走80公里,顯然這種演算法不能滿足最優性。

那麼問題來了,a*演算法顯然與g(n)和h(n)兩個函式有關,那如果說這兩個函式設定得不太好或者不合適得話,a*還會滿足最優性嗎?或者說我們要找出乙個怎樣的h與g才能使得a*演算法能夠滿足最優性等要求?

如上圖所示,如果採用a*演算法,那麼顯然會走sag的路線,但是這個很明顯並不是最有的路徑,那麼到底**出了問題?答案就是h的設定出了問題,啟發函式h其實在我看來就是類似於乙個約束條件,告訴機器不需要全方位的去探索,而是約束著機器往終點的那個方向去探索。這個約束條件在什麼時候會失效呢?就是當啟發函式h大於實際耗散時,啟發函式失效。這個很好理解,就比如說我從s到g的實際最短距離是50公里,你設定個80的啟發函式,就是告訴計算機從s到g距離至少有80公里,顯然對演算法的幫助沒有任何優化,而當只有我啟發函式小於實際耗散時,才能對演算法有優化效果,就比如設定個30,那麼就告訴計算機s到g的距離至少有30公里,那麼小於30公里的那些路徑統統可以不用考慮了。

8. 關於啟發函式的尋找,我們已經知道乙個啟發函式設定的好壞直接影響搜尋演算法的最優性與否。啟發函式永遠不是唯一的,最好的啟發函式當然是和實際耗散相等,但是隨便一設定就是實際值的話這種概率還是蠻小的,這裡不討論,下面介紹一種常用的尋找啟發函式的方法,即由鬆弛問題得到啟發函式,這種方法得出的啟發函式通常都是能用的,只不過具體對演算法有多大的優化那就還是要看具體怎麼設定了。這種方法說起來其實很簡單,就是我們將目標鬆弛化,然後得到啟發函式值。就比如說從a到b實際距離是50公里,這50公里可能是因為道路的曲折、然後障礙物之類的一些影響,導致從a到b需要50公里,但是如果我們將這個問題鬆弛化,就是完全忽略道路的曲折,還有路上的障礙物等等一系列因素,那麼得到a到b的直線距離可能就是30公里,那麼這個30公里就可以用來做啟發函式,也就是說告訴計算機這麼乙個約束條件,a到b至少有30公里,小於這個值的路徑一律不予考慮,因為這已經是最寬鬆的條件了。

再比如說這個數碼遊戲,正常情況下每一步都只有那麼少數的幾個數字能夠移動,且不可能斜著移動,也不能覆蓋。如果我們將這些規則都忽略,也就是說將這個問題鬆弛化,得出從起始位置到最終位置需要8步,那麼設定這個8步為啟發函式的話顯然就是正確的,因為至少需要8步這是顯然的。這種將問題進行鬆弛化然後再取啟發函式的方法就是非常常用的方法,可能具體優化程度取決於鬆弛程度,但是得到的啟發函式正常情況下時一定能用的。

以上就是我對搜尋演算法的一些總結與理解。

小白 關於DFS深度優先搜尋演算法的一些問題

本人小白,這是該賬號的第一篇文章,開場白到此。最近在看 啊哈 演算法 這本書,在第4章中介紹了dfs演算法 dfs演算法框架如下 void dfs int step 判斷邊界 for int i 0 i n i 迴圈嘗試每種可能 book i 1 嘗試下一步dfs step 1 book i 0 r...

關於搜尋,我的一些看法

目前的搜尋大體分通用搜尋和垂直搜尋。兩者差別在於資訊 通用的範圍很廣,所以資料量一般都是海量。垂直的資訊 比較單一,所以資料量相對而言就小。技術角度而言,通用主要關注資料量,偏重架構設計,而垂直著重搜尋的ui。如何設計好乙個架構,我覺得自己還在摸索,所以不多說,感興趣的可以看看google的 垂直搜...

一些搜尋總結

我們在bfs時,要從起點,搜遍整顆搜尋樹,然後找到終點,整個過程大概是乙個如下的結構 我比較懶,所以圖非常簡陋。最上面的節點表示起點,最下面的點表示終點。我們正常的bfs是從起點一路向下搜到終點,這樣要擴充套件不少的狀態,耗費不少的時間。這樣我們想我們其實可以從起點和終點同時開始搜,起點和終點同時向...