我目前正在处理背包问题,以返回最佳解决方案的集合。
这是我的方法:
public static int knapsackArray(int val[], int wt[], int W) {
//Get the total number of items.
int N = wt.length;
//Create a matrix.
int[][] V = new int[N + 1][W + 1];
//all columns at row 0 to be 0
for (int col = 0; col <= W; col++) {
V[0][col] = 0;
}
//Fill the first row with 0
for (int row = 0; row <= N; row++) {
V[row][0] = 0;
}
for (int item=1;item<=N;item++){
for (int weight=1;weight<=W;weight++){
if (wt[item-1]<=weight){
V[item][weight]=Math.max (val[item-1]+V[item-1][weight-wt[item-1]], V[item-1][weight]);
}
else {
V[item][weight]=V[item-1][weight];
}
}
}
//Printing the matrix
for (int[] rows : V) {
for (int col : rows) {
System.out.format("%5d", col);
}
System.out.println();
}
return V[N][W];
}
我有另一种方法,它将Item集和预算作为参数,并为此问题返回一组最佳解决方案:
public static Set<Item> knapsack(Set<Item> items, int budget) {
//create array of wieghts
int[] weights = new int[items.size()];
//create array of values
int[] values = new int[items.size()];
int i = 0;
for (Item x : items){
weights[i] = x.getWeight();
values[i] = x.getValue();
//System.out.println(x);
i++;
}
/*int N = weights.length;
int[][] V = new int[N + 1][budget + 1];*/
int j = knapsackArray(values, weights, budget);
System.out.println(j);
return null;
}
我的问题是如何将此矩阵设置为最佳项目集。这是 - 我的方法 - 甚至是解决这个问题的好方法吗?
答案 0 :(得分:0)
除了您创建的值矩阵,在knapsackArray
内,您还可以创建第二个矩阵来跟踪您到达该点的方式。 (即你采取的最后一个元素)这样,一旦你完成了你的DP解决方案,你就可以追溯你在路上获得的所有元素。另外,为了能够将值传递回knapsack
,您需要将设置参数传递给knapsackArray
。
以下是我概述的方法的粗略演示。
public static int knapsackArray(int val[], int wt[], int W, Set<int> itemIndices) {
// ...
// Create a matrix.
int[][] V = new int[N + 1][W + 1];
int[][] G = new int[N + 1][W + 1];
// ...
for (int item=1;item<=N;item++) {
for (int weight=1;weight<=W;weight++) {
if (wt[item-1]<=weight) {
int candidate = val[item-1] + V[item-1][weight-wt[item-1]];
if(candidate > V[item-1][weight]) {
V[item][weight] = candidate;
G[item][weight] = item - 1;
}
else {
V[item][weight] = V[item-1][weight];
G[item][weight] = -1;
}
}
else {
V[item][weight]=V[item-1][weight];
G[item][weight] = -1;
}
}
}
int currentItem = N;
int currentWeight = W;
while(currentItem >= 1) {
if(G[currentItem][currentWeight] >= 0) {
itemIndices.add(currentItem - 1);
currentWeight = currentWeight - wt[currentItem - 1];
currentItem = G[currentItem][currentWeight] + 1;
}
else {
currentItem = currentItem - 1;
}
}
// ...
return V[N][W];
}
执行此操作后,您可以实际处理该参数Set<int> itemIndices
中的索引,并在Set<Item> items
方法中填充knapsack
,如下所示。
public static Set<Item> knapsack(Set<Item> items, int budget) {
// ...
Set<Item> itemsToAdd;
Set<int> itemIndices;
int j = knapsackArray(values, weights, budget, itemIndices);
int i = 0;
for (Item x : items) {
if(itemIndices.contains(i)) {
itemsToAdd.add(x);
}
i++;
}
return itemsToAdd;
}