把這幾天學的搜尋做乙個初步總結。
一、 深度優先搜尋(dfs):從起點出發,走過的點要做標記,發現有沒走過的點,就隨意挑乙個往前走,走不動了就回退。不能走已經走過的點(需要判重)。
舉幾個栗子:
1.判斷從v出發是否能走到終點:
booldfs(v)
return
false
;}
判斷從v出發是否能走到終點時,返回值有意義。
因為有回溯的過程,所以會把k出發能走到的點都走一遍。
2.判斷從v出發是否能走到終點,如果能,要記錄路徑。
booldfs(v)
if( v 為舊點)
return
false
;將v標記為舊點;
path[depth]=v;
++depth;
對和v相鄰的每個節點u
--depth;
return
false
;}
--depth的過程就是回溯的過程。
3.在圖中尋找最優(步數最少路徑)
voiddfs(v)
return;}
if( v 為舊點) return
;if( depth >= minsteps ) return ; //
最優性剪枝
將v標記為舊點;
path[depth]=v;
++depth;
對和v相鄰的每個節點u
--depth;
將v恢復為新點
}
求最優路時,要把走過的不同的路保留下來。
為什麼將v恢復為新點:為了之後的兄弟可能會繞回v。
找最優路時返回值無意義。
圖的儲存方式對遍歷v的相鄰節點u過程的影響:
鄰接矩陣遍歷:o(n²)
鄰接表遍歷:o(n+e)
稀疏圖用鄰接表儲存效率更高。
剪枝:最優性剪枝,可行性剪枝。(待更新)
二、 廣度優先搜尋(bfs):依層次順序,從小到大擴充套件節點。把層次低的點全部擴充套件出來後,才會擴充套件層次高的點。擴充套件時,不能擴充套件已經走過的節點(要判重)。
廣搜最優解一般是求操作步驟最少,注意判重(可以用set來判重)。
三、雙向廣搜(dbfs):待更新。
四、a*演算法在bfs演算法中,若對每個狀態n都設定估價函式f(n)=g(n)+h(n),並且每次從open表中選節點進行擴充套件時,都選取f值最小的節點,則該搜尋演算法為啟發式搜尋演算法,又稱a演算法。
g(n) : 從起始狀態到當前狀態n的代價
h(n) : 從當前狀態n到目標狀態的估計代價
廣搜可以看作:f(n)=g(n)(無h(n)這項),a*的關鍵是如何設計估計函式h(n),如何對估計函式做限制,確保能找到最優解。
由於是有根據地去估計,因此不可能估計出比真實值還小的數,即真實代價≥估計代價。
估計函式實際上是一種樂觀的估計,在這種樂觀估計的前提下,越悲觀越靠近真實值。即估計值在滿足≤真實值的前提下,估計函式的值越大越好。
五、迭代加深搜尋演算法:總體上按照深度優先演算法方法進行。多次從起點出發做深搜,每次規定乙個深度限制dm。劣勢:會有重複搜尋,從時間效率上不如廣搜,好處是因為有步數的限制所以不用判重。
廣搜有可能比深搜號,但廣搜擴充套件出來的情況可能更多。
六、alpha-beta剪枝
極大極小搜尋法(待更新)
《演算法筆記》廣度優先搜尋 BFS 初步學習
bfs一般由佇列實現,且總是按層次的順序進行遍歷,其基本寫法如下 void bfs int s 下面是對每乙個步驟的說明 1.定義佇列q,並將起點s入隊 2.寫乙個while迴圈,迴圈條件是佇列q非空 3.在while迴圈裡,先取出隊首元素top,然後訪問他 訪問可以是任何事情,例如輸出 訪問完將其...
搜尋演算法初步總結
廣度優先搜尋一層一層地進行遍歷,每層遍歷都以上一層遍歷的結果作為起點,遍歷乙個距離能訪問到的所有節點。需要注意的是,遍歷過的節點不能再次被遍歷。第一層 第二層 第三層 每一層遍歷的節點都與根節點距離相同。設 di 表示第 i 個節點與根節點的距離,推導出乙個結論 對於先遍歷的節點 i 與後遍歷的節點...
演算法筆記 演算法初步之排序
壹.直接插入排序 自己的理解 插入排序是將陣列當成摸牌 1.預設的將第一張牌a 0 認為已經在手上了,從i 1開始摸牌,暫時放在temp裡,即temp a i 2.j i表示當前放在temp裡的牌應該放的位置,即a j 為了確定是哪一張牌應該放在這個位置,需要用temp與a j 1 當前應該放的位置...