在我們的一生中,會遇到很多重要的岔路口。在岔路口上,每個選擇都會影響我們今後的人生。有的人在每個岔路口都能做出最正確的選擇,最後生活、事業都達到了乙個很高的高度;而有的人一路選錯,最後碌碌無為。如果人生可以量化,那如何才能在岔路口做出最正確的選擇,讓自己的人生「最優」呢?
可以借助前面學過的貪心演算法,在每次面對岔路口的時候,都做出看起來最優的選擇,期望這一組選擇可以使得我們的人生達到「最優」。但是貪心演算法並不一定能得到最優解。
1.八皇后問題
有乙個8x8的棋盤,希望往裡放8個棋子(皇后),每個棋子所在的行、列、對角線都不能有另乙個棋子。你可以看我畫的圖,第一幅圖是滿足條件的一種方法,第二幅圖是不滿足條件的。八皇后問題就是期望找到所有滿足這種要求的放棋子方式。
把這個問題劃分成8個階段,依次將8個棋子放到第一行、第二行、第三行……第八行。在放置的過程中,我們不停地檢查當前的方法,是否滿足要求。如果滿足,則跳到下一行繼續放置棋子;如果不滿足,那就再換一種方法,繼續嘗試。
public
class
queensof8
for(
int column =
0; column <8;
++column)}}
private
boolean
isok
(int row,
int column)
if(leftup >=0)
}if(rightup <8)
}--leftup;
++rightup;
}return
true;}
private
void
printqueens
(int
result)
else
} system.out.
println()
;}system.out.
println();}}
2.0-1揹包0-1揹包是非常經典的演算法問題,很多場景都可以抽象成這個問題模型。這個問題的經典解法是動態規劃,不過還有一種簡單但沒有那麼高效的解法,那就是回溯演算法。
0-1揹包問題有很多變體,裡介紹一種比較基礎的。有乙個揹包,揹包總的承載重量是wkg。現在有n個物品,每個物品的重量不等,並且不可分割。現在期望選擇幾件物品,裝載到揹包中。在不超過揹包所能裝載重量的前提下,如何讓揹包中物品的總重量最大?
實際上,揹包問題在貪心演算法已經講過乙個,不過那裡講的物品是可以分割的,我可以裝某個物品的一部分到揹包裡面。今天的這個揹包問題,物品是不可分割的,要麼裝要麼不裝,所以叫0-1揹包問題。顯然,這個問題已經無法通過貪心演算法來解決了。現在來看看用回溯演算法如何來解決。
對於每個物品來說,都有兩種選擇,裝進揹包或者不裝進揹包。對於n個物品來說,總的裝法就有2n種,去掉總重量超過wkg的,從剩下的裝法中選擇總量最接近wkg的。不過,我們如何才能不重複地窮舉出這2n種裝法呢?
這裡就可以用回溯的方法。可以把物品依次排列,整個問題就分解為了n個階段,每個階段對應乙個物品怎麼選擇。先對第乙個物品進行處理,選擇裝進去或者不裝進去,然後再遞迴地處理剩下的物品。
public
class
zopakage
return;}
f(i +
1, cw, items, n, w);if
(cw + items[i]
<= w)
}}
總結:回溯演算法本質上就是列舉,優點在於其類似於摸著石頭過河的查詢策略,且可以通過剪枝少走冤枉路。它可能適合應用於缺乏規律,或我們還不了解其規律的搜尋場景中。 回溯 皇后 演算法筆記 演算法筆記 回溯法
1 0 1揹包問題 思路 構造乙個二叉樹,每個商品都有兩種狀態,要或者不要。如果要就在這個節點的左枝掛子節點,如果不要就在右節點掛子節點。如果全部商品都分配完狀態之後就回溯,回溯到乙個還有其他選擇的節點,接著往這個選擇發展節點,然後再回溯,然後再往下。直到無路可走,就結束了。假如限制重量是10,總共...
回溯 皇后 演算法筆記 演算法筆記
分治演算法 線性時間選擇 o n 33 隨機線性選擇 偽 o n int partition type a,int p,int r return table n 1 w 1 main function else else lowcost i 0 for int i 1 i n i int temp ...
回溯 皇后 演算法筆記 演算法筆記
遞迴演算法 能夠用遞迴解決的問題需要滿足三個條件 原問題可以轉換為乙個或多個子問題來求解,而這些子問題的求解方法和原問題完全相同,只是規模不同 遞迴呼叫次數必須是有限的 必須有結束遞迴的條件 遞迴出口 來終止遞迴。設計遞迴演算法模式先求解問題的遞迴模型。在設計遞迴演算法的時候,如果糾結遞迴樹的每乙個...