1. 程式人生 > >搜索算法總結

搜索算法總結

沒有 tro 相加 是你 個數 格子 另一個 問題 位置

IDDFS

思路:某些問題搜索時可能會存在搜索很深卻得不到最優解的情況。設置一個深度約束,當搜索深度達到約束值卻還沒找到可行解時結束搜索。如果我們在一個深度約束下沒有搜索到答案,那麽答案一定在更深的位置,把約束深度調整到更深,直到搜索到答案為止。 對當前的情況通過一個樂觀估計函數進行預估,如果發現即使在最好的情況下搜索到當前的最深深度限制也沒辦法得到答案,就及時剪枝。


Bidirectional BFS

雙向 BFS 就是用兩個隊列,一個隊列保存從起點開始向後搜索的狀態,另一個保存從終點開始向前搜索的狀態,每個狀態包含到達該狀態的步數,兩邊相交時答案相加。

交替逐層擴展優化:由於兩端擴展節點個數可能差別很大,所以每次選擇節點個數少的隊列進行擴展。


定義一個估價函數 \(f(x)\),則 \(f(x)=g(x)+h(x)\)。其中,\(f(x)\) 指我們估計答案的價值,而 \(g(x)\) 是實際值,\(h(x)\) 是我們的預測。

在 DFS 上加入一個判斷:當 \(g(x)+h(x)\) 劣於較優解時剪枝。

(以下源自 Link 技術分享圖片

A* 算法步驟為:

  • 把起始格添加到開啟列表。
  • 重復如下的工作:
    • 尋找開啟列表中 \(f\) 值最低的格子。我們稱它為當前格。
    • 把它切換到關閉列表。
    • 對相鄰的格中的每一個?
      • 如果它不可通過或者已經在關閉列表中,略過它。反之如下。
      • 如果它不在開啟列表中,把它添加進去。把當前格作為這一格的父節點。記錄這一格的 \(f\)
        \(g\)\(h\) 值。
      • 如果它已經在開啟列表中,用 \(g\) 值為參考檢查新的路徑是否更好。更低的 \(g\) 值意味著更好的路徑。如果是這樣,就把這一格的父節點改成當前格,並且重新計算這一格的 \(g\)\(f\) 值。如果你保持你的開啟列表按 \(f\) 值排序,改變之後你可能需要重新對開啟列表排序。
    • 停止,當你
      • 把目標格添加進了關閉列表,這時候路徑被找到,或者
      • 沒有找到目標格,開啟列表已經空了。這時候,路徑不存在。
  • 保存路徑。從目標格開始,沿著每一格的父節點移動直到回到起始格。這就是你的路徑。

搜索算法總結