回溯法解決組合問題的優化

2021-09-16 20:59:02 字數 1181 閱讀 3499

當n=4,k=2時的遞迴樹,在這棵樹中,明顯存在著乙個地方是沒有必要去走的,就是在最後取n=4這個地方。在[1,2,3,4]中取2個數,我們根本就沒有必要嘗試去取4,這是因為嘗試取4之後,無法再取任意乙個數了。在現在的演算法中,還是嘗試了取4,取完4後,發現第二個數字取不了了,所以只好再返回回去。這一部分wan'q可以把它剪掉,換句話說,只需要嘗試取1、取2、取3就好了。在這個圖中,看起來好像只優化了1步,因為當前的資料量比較小,尤其是k的值比較小,只需要取2個數。在這個數中,k的值其實就是整棵樹的深度,如果初始化的時候n比較大,陣列中的數比較多,k又比較大的話,這棵樹會非常龐大。按照現在的演算法,就會嘗試非常多不需要的可能性,將這些可能性去掉,將大大地優化演算法的效率。

在這樣一棵搜尋樹中減去了一些分支,不去進行搜尋,就叫做剪枝。

要剪枝的部分其實是在for迴圈中,在for迴圈中,從i=start開始,一直遍歷到i==n這個地方。但是遍歷到了i==n,在進行下一步的時候,還需要繼續取數,在下一步的時候,就已經沒得可取了,所以,在每一步的時候,其實不需要遍歷到i==n的地方。

首先,當進入到這個遞迴函式的時候,c中就已經存放著當前這個組合中已經尋找到的元素了。這個組合中,一共要有k個元素,當前已經尋找到了c這個集合中存放的元素相應的還有k-c.size()個空位 。換句話說,就應該從n到start這麼多個資料中,來尋找這麼多個元素來填補這些空位。在這次for迴圈中,一旦選定了乙個i,相當於在[i..n]中至少要有k-c.size()個元素。換句話說,[i...n]這個區間中,前閉後閉的區間中,至少要有k-c.size()個元素。此時,這個問題就變成了,i取多少,[i...n]中會有k-c.size()個元素呢?i最多為 n-(k-c.size())+1,n-(k-c.size())+1是小於等於n的,換句話說,每次在遞迴呼叫的時候,這個for迴圈遍歷的次數變少了。達到了剪枝的作用,進而達到了優化效能的目的。

回溯法 解決堡壘問題

描述 城堡是乙個4 4的方格,為了保衛城堡,現需要在某些格仔裡修建一些堡壘。城堡中的某些格仔是牆,其餘格仔都是空格,堡壘只能建在空格裡,每個堡壘都可以向上下左右四個方向射擊,如果兩個堡壘在同一行或同一列,且中間沒有牆相隔,則兩個堡壘都會把對方打掉。問對於給定的一種狀態,最多能夠修建幾個堡壘。輸入 每...

火車排程問題的回溯法解決

問題描述 火車編號為 1 9,且不重複。如 編號分別為 1 2 3 4 5 的5個火車順序進站,那麼進站序列為 12345 全部進站後再順序出站,則出站序列為 54321 如果先進1,2,然後2出站,然後1出站,然後再3進站 出站,4進站 出站,5進站 出站,那麼出站序列就為21345.詳細描述 i...

回溯法解決N皇后的問題

使用回溯法解決n皇后的問題 def mk lst size 生成棋盤 return 0 for i in range size for j in range size def is legal posi loca,size 判斷是否合法座標 x,y loca 0 loca 1 size 1 if 0...