關於回溯法的概念,這篇文章講的比較通俗易懂:https://blog.csdn.net/jarvischu/article/details/16067319
貼出閱讀這篇文章後解決01揹包問題的Java代碼,註釋中加入了自己的理解
package com.zxg.algorithm.backtrack;
/**
* 回溯法解01揹包問題
* 揹包問題的概念不再贅述。這裏主要講解下回溯法思路。
* 將每一個物品分爲裝載和不裝載兩條路徑,一個接一個的遍歷,每遍歷一個物品就會產生兩條分支
* 那麼就會組成一棵樹,深度遍歷這棵樹,找出最優解
* 參考:https://blog.csdn.net/jarvischu/article/details/16067319
*/
public class PackageQuestion {
public int[] weight;
public int[] value;
public int[] take;
int curWeight = 0;
int curValue = 0;
int bestValue = 0;
int[] bestChoice;
int count;
int maxWeight = 0;
public void init(int[] weight, int[] value, int maxWeight) {
if (weight == null || weight.length == 0
|| value == null || value.length == 0
|| weight.length != value.length || maxWeight <= 0) {
System.out.println("args wrong!");
return;
}
this.value = value;
this.weight = weight;
this.maxWeight = maxWeight;
count = value.length;
take = new int[count];
bestChoice = new int[count];
}
public int[] maxValue(int x) {
//走到了葉子節點
if (x > count - 1) {
//更新最優解
if (curValue > bestValue) {
bestValue = curValue;
for (int i = 0; i < take.length; i++) {
bestChoice[i] = take[i];
}
}
} else {
//遍歷當前節點(物品)的子節點:0 不放入揹包 1:放入揹包
for (int i = 0; i < 2; i++) {
take[x] = i;
if (i == 0) {
//不放入揹包,接着往下走
maxValue(x + 1);
} else {
//約束條件,如果小於揹包容量
if (curWeight + weight[x] <= maxWeight) {
//更新當前重量和價值
curWeight += weight[x];
curValue += value[x];
//繼續向下深入
maxValue(x + 1);
//回溯法重要步驟,個人感覺也是精華所在。
// 當從上一行代碼maxValue出來後,需要回溯容量和值
curWeight -= weight[x];
curValue -= value[x];
}
}
}
}
System.out.println(bestValue);
return bestChoice;
}
public static void main(String[] args) {
PackageQuestion question = new PackageQuestion();
question.init(new int[]{7, 3, 4, 5},new int[]{42, 12, 40, 25},10);
int[] result = question.maxValue(0);
}
}