對於迭代加深搜尋,網路上並沒有明確地闡明它的定義到底是什麼,我們可以感性地理解一下迭代加深。
圖示:
在圖中,中間的紅點(s)點為搜尋的原點。對於某種題目(後文會說明),我們的搜尋可以表示為如圖所示的過程。
傳統的dfs
傳統的dfs在圖中可以表示為從s點出發的紅線所示的路徑,這條路徑可以用」不撞南牆不回頭「來形容。因為沒有搜到搜尋的邊界就不會停下來,而且搜尋的層數越深,產生的冗餘狀態——既與正解無關的狀態就產生地越多。
迭代加深搜尋
而藍色的半透明圓圈所示的就是乙個迭代假設的過程,在限制了搜尋深度的情況下在有限的深度內尋找最優解。迭代加深搜尋適用於傳統搜尋後繼狀態多、深度上限較小的問題。在圖中,迭代加深就可以避免傳統dfs搜得過深、搜得過窄的情況。
經典問題
最經典的就是西洋棋問題,在複雜的中間局面裡面你不會搜尋得很深。而在殘局中,有時你甚至會搜尋到100層以上。
核心思想
有一位叫做bruce moreland的人這樣說:
有乙個思想,就是一開始只搜尋一層,如果搜尋的時間比分配的時間少,那麼搜尋兩層,然後再搜尋三層,等等,直到你用完時間為止。偽**上述的敘述用**可以表示為:這足以保證很好地運用時間了。如果你可以很快搜尋到乙個深度,那麼你在接下來的時間可以搜尋得更深,或許你可以完成。如果局面比你想象的複雜,那麼你不必搜尋得太深,但是至少有合理的著法可以走了,因為你不太可能連1層搜尋也完不成。
for (depth = 1; ; depth ++)
圖示 上圖為傳統搜尋的圖示(圖摘)
 上圖為啟發式(a*)搜尋的圖示(圖摘)
傳統的dfs
可以在第一張圖中看出,傳統的dfs搜尋會搜出很多的冗餘狀態,導致程式的搜尋量大大增加,降低程式效率。所以對比a*搜尋,我們可以稱傳統搜尋為」盲搜「。
啟發式(a*)搜尋
啟發式搜尋和核心就是它的估價函式,啟發式搜尋中的估價函式所起的作用可以感♂性地理解為」還有幾步能到目標答案「,」距離正解還有多遠「,……等等。乙個啟發式搜尋的效率往往取決於估價函式的質量。對比與傳統的dfs,啟發式搜尋可以被稱為」有目標的搜尋「。
所以說,a*搜尋與其說是一種搜尋的方法,不如說a*的估價函式是一種針對dfs的強力的剪枝。
題目大意
給定乙個由1到n的數字組成的組成的序列,問最少需要幾步」剪下-貼上「操作才能使該數列變為公升序的有序數列。(1
大概思路
由題目可知,本題最壞的情況下也最多隻會移動n-1步(雖然在實際情況中最多只有5步),所以可以在搜尋的同時限制搜尋層數,既使用迭代加深。
繼續考慮每一層的情況,因為9!=362880,所以每一層的狀態非常的龐大,因此我們可以採用a*剪枝。
考慮每乙個序列後續不正確的數字個數h,每一次剪下最多3個數字後續數字發生改變,每次剪下最多可減少3個不正確的後續數字。所以在當前層d,最大層maxd時,最多可減少的不正確後續數字是3*(maxd-d),若h>3*(maxd-d),則剪枝。
**
#include
const
int maxn = 9;
int n,a[maxn];
inline
bool end()
return
true;
}inline
int h()
int maxd;
const
int intsz = sizeof(int);
const
int asz = sizeof(a);
bool dfs(int d)
}return
false;
}inline
int solve()
int main()
return
0;}
A 搜尋演算法
啟發式搜尋演算法 要理解 a 搜尋演算法,還得從啟發式搜尋演算法開始談起。所謂啟發式搜尋,就在於當前搜尋結點往下選擇下一步結點時,可以通過乙個啟發函式 來進行選擇,選擇代價最少的結點作為下一步搜尋結點而跳轉其上 遇到有乙個以上代價最 少的結點,不妨選距離當前搜尋點最近一次展開的搜尋點進行下一步搜尋 ...
A 搜尋演算法
a 演算法是基於bfs的一種入門級啟發式搜尋演算法,就是將bfs的佇列改為基於估價的優先佇列,可以快速地找到答案。優先隊列為小根堆 while 優先佇列不為空 取出隊頭並擴充套件 將擴充套件節點以估價值 當前值為優先順序入隊 endwhile估價函式越接近真實值演算法越優,但一定不能大於真實值,否則...
搜尋演算法小結
搜尋演算法是利用計算機的高效能來有目的的窮舉乙個問題的部分和所有的可能情況,從而求出問題的解的一種方法。常用的搜尋演算法有 一.回溯法 回溯演算法是所有搜尋演算法中最為基本的一種演算法,其採用了一種 走不通就掉頭 思想作為其控制結構,其相當於採用了先根遍歷的方法來構造解答樹,可用於找解或所有解以及最...