演算法之窮舉(泊松分酒)
- 2019 年 10 月 27 日
- 筆記
窮舉法
又稱暴力破解法,就是把所有條件,相關情況統統考慮進去,讓電腦進行檢索,指導得出與之所有條件符合的結果
(但是,暴力破解法對電腦資源耗費嚴重,如果條件太複雜,運算速度緩慢,為了解決這一問題,我們可以事先把與之不相關的條件進行限制,減少電腦的運算量)
泊松分酒
有3個容器,容量分別為12升,8升,5升。其中12升中裝滿酒,另外兩個空著。
要求你只用3個容器操作,最後使得某個容器中正好有6升酒。
分酒規則 1 –> 2 –> 3 –> 1
- 大瓶子只能倒入中瓶子
- 中瓶子只能倒入小瓶子
- 小瓶子只能倒入大瓶子
- 小瓶子只有在已經裝滿的情況下才能倒入大瓶子
- 若小瓶子被倒空,則無論中瓶子是否滿,應馬上從中瓶子倒入小瓶子
之所以要規定倒酒的順序是為了防止狀態重複。而根據這5條規則,大瓶子每次倒入中瓶子的酒總是8升,小瓶子每次倒入大瓶子的酒總是5升。
程式碼實現
package cn.itcast.recursion; public class ShareWine { public static void main(String[] args) { ShareWine shareWine = new ShareWine(); shareWine.backBottle(12, 0, 0); } //定義三個瓶子的容量 private int b1 = 12; private int b2 = 8; private int b3 = 5; private int m = 6;//目標酒量 //假設一開始,12,0,0 public void backBottle(int bb1, int bb2, int bb3) { System.out.println("bb1酒量:" + bb1 + " bb2酒量:" + bb2 + " bb3酒量:" + bb3); if (bb1 == m || bb2 == m || bb3 == m) { System.out.println("find the bottle"); return; } //瓶子2還有酒&&瓶子3沒滿 if (bb2 != 0 && bb3 != b3) { //沒到5升,倒不滿 if (bb2 + bb3 <= b3) { backBottle(bb1, 0, bb2 + bb3); } else { //第二個參數:剛開始bb2有那麼多酒,倒進bb3之後,bb3滿了,bb2就等於之前的bb2 -(滿了之後的b3-沒倒之前的bb3) backBottle(bb1, bb2 - (b3 - bb3), b3); } //瓶子3滿了,往瓶子1倒 } else if (bb3 == b3) { //沒到12升,倒不滿 if (bb3 + bb1 <= b1) { backBottle(bb1 + bb3, bb2, 0); } else { backBottle(b1, bb2, bb3 - (b1 - bb1)); } //從瓶子1往瓶子2倒酒 } else if (bb2 == 0) { if (bb1 >= b2) { backBottle(bb1 - b2, b2, bb3); } else { backBottle(0, bb1, bb3); } } } }
列印結果:
bb1酒量:12 bb2酒量:0 bb3酒量:0
bb1酒量:4 bb2酒量:8 bb3酒量:0
bb1酒量:4 bb2酒量:3 bb3酒量:5
bb1酒量:9 bb2酒量:3 bb3酒量:0
bb1酒量:9 bb2酒量:0 bb3酒量:3
bb1酒量:1 bb2酒量:8 bb3酒量:3
bb1酒量:1 bb2酒量:6 bb3酒量:5