動態規劃—01揹包問題
01揹包問題屬於經典的動態規劃問題,場景描述如下:
形象描述:賊,夜入豪宅,可偷之物甚多,而負重能力有限,偷哪些才更加不枉此行?
進一步抽象的話,就是:
給定內,選擇其中若干個(也即每種物品可以選0個或1個),設計選擇方案使得物品的總價值最高
頂級抽象描述就是數學語言了,數學語言描述如下:
條件:
1:求解0-1規劃問題:
0-1揹包問題子結構:選擇一個給定物品 ,則需要 比較 選擇
的形成的子問題的最優解 與 不選擇
的子問題的最優解。分成兩個子問題,進行選擇比較,選擇最優的。
為最優解。即只需要一個判斷三條件的公式就能求出最優解:
有了這個判斷三條件的公式,程式碼實現起來就比較輕鬆了,Java實現原始碼如下:
public class CB { public static void main(String[] args) { int totalWeight = 10;//物品個數,揹包容量 Bean[] data = new Bean[]{new Bean(0, 0), new Bean(2, 6), new Bean(2, 3), new Bean(6, 5), new Bean(5, 4), new Bean(4, 6)}; System.out.println(getMaxValue(data, totalWeight)); } public static int getMaxValue(Bean[] data, int totalWeight) { int n = data.length; int[][] table = new int[n][totalWeight + 1]; for (int i = 1; i < n; i++) { //物品 for (int w = 1; w <= totalWeight; w++) {//揹包大小 if (data[i].weight > w) { //當前物品i的重量比揹包容量j大,裝不下,肯定就是不裝 table[i][w] = table[i - 1][w]; } else { //裝得下,Max{裝物品i, 不裝物品i} table[i][w] = Math.max(table[i - 1][w], table[i - 1][w - data[i].weight] + data[i].value); } } } for (int f = 0; f < table.length; f++) { System.out.println(Arrays.toString(table[f])); } return table[n - 1][totalWeight]; } static class Bean { int weight = 0; int value = 0; Bean(int w, int v) { weight = w; value = v; } @Override public String toString() { return weight + "" + value; } } }
我們初始化五個數對 ,總重量
,演算法的最終輸出如下:
