4.Python算法之试探算法思想(回溯法)
1.什么是試探算法?
?2.試探算法的解題的基本步驟
3.試探算法的思想
4.試探算法適合的問題
5.試探算法解決“八皇后”的問題
1.什么是試探算法?
? ? 試探算法也叫回溯法,試探算法的處事方式比較委婉,它暫時放棄關于問題規(guī)模大小的限制,并將問題的候選解按某種順序逐一枚舉和檢驗。當發(fā)現(xiàn)當前候選解不可能是正確的解時,就選擇下一個候選解。如果當前候選解不滿足問題規(guī)模要求外, 能夠滿足所有其他要求,則繼續(xù)擴大當前候選解的規(guī)模,并繼續(xù)試探。如果當前候選解滿足包括問題規(guī)模在內(nèi)的所有要求,該候選解就是問題的一個解。在試探算法中,放棄當前候選解,并繼續(xù)尋找下一個候選解的過程稱為回溯。擴大當前候選解的規(guī)模,并繼續(xù)試探的過程稱為向前試探。
2.試探算法的解題的基本步驟
3.試探算法的思想
? ? 為了求得問題的正確解,試探算法會先委婉地試探某種可能的情況。在進行試探的過程中,一旦發(fā)現(xiàn)原來選擇的假設情況是不正確的,立即會自覺的退回一步重新選擇,然后繼續(xù)向前試探,如此這般反復進行,直至得到解或證明無解時才死心.
4.試探算法適合的問題
? ? 比如有一個元組n組成的一個狀態(tài)空間,關于元組n,有多個條件組成的約束集合,滿足這個條件約束集合的任一n元組為問題的一個解。只要檢測出元組中有一個違反了約束,就可以肯定這個元組就不是問題的解,因而不必去搜素和檢測它們,試探算法就是針對這類問題而推出的,比枚舉算法的效率更高。
5.試探算法解決“八皇后”的問題
? ? “八皇后”問題是一個古老而著名的問題,是試探法的典型例題。該問題由19世紀的數(shù)學家高斯于1850年手工解決:在8×8的國際象棋上擺放8個皇后,使其不能互相攻擊,即任意兩個皇后都不能處于同一行、同一列或同一斜線上,問有多少種擺法。
? ? 可以將整個問題簡化為4×4的棋盤,就有兩種擺法,每行擺在列2、4、1、3或列3、1、4、2上
? ? ?試探算法將每行的可行位置入棧(就是放入數(shù)組a[5],用的是a[1]~a[4]),不行就退棧還列重新試,直到找到一套方案并輸出,接著從第一行換列重試其他方案。
? ? ?為了簡化問題,考慮到8個皇后不同行,則每一行放置一個皇后,每一行的皇后可以放置于第0~7列,我們認為每一行的皇后有8種狀態(tài)。那么,只要套用子集樹模板,從第0行開始,自上而下,對每一行的皇后,遍歷它的8個狀態(tài)即可。
n = 8 x = [] # 一個解(n元數(shù)組) X = [] # 一組解# 沖突檢測:判斷x[k] 是否與前面的x[0] ~ x[k-1] def conflict(k):global xfor i in range(k): # 遍歷前面的x[0] ~ x[k-1]:if x[i] == x[k] or abs(x[i] - x[k]) == abs(i - k): # 判斷是否與x[k]沖突return Truereturn False# 套用子集樹模板 def queens(k): # 到達第k行global n, x, Xif k >= n: # 超出最底行X.append(x[:]) # 保存(一個解),注意x[:]else:for i in range(n): # 遍歷第0~n-1列(即n個狀態(tài))x.append(i) # 皇后置于第i列,入棧if not conflict(k): # 剪枝queens(k + 1)x.pop() # 回溯,出棧def show(x):global nfor i in range(n):print('. ' * (x[i]) + 'X ' + '. ' * (n - x[i] - 1))if __name__ == '__main__':queens(0) # 從第0行開始print(X[-1], '\n')show(X[-1])程序運行結果:
總結
以上是生活随笔為你收集整理的4.Python算法之试探算法思想(回溯法)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python多任务(8.进程与线程之间的
- 下一篇: websocket python爬虫_p