Algorithm 背包0-1路径重建(携带哪些物品)
我知道如何用动态规划方法解决背包0-1问题,但在不影响O(N*C)(N个项目,C个容量)的复杂性的情况下,我很难确定要取哪些项目Algorithm 背包0-1路径重建(携带哪些物品),algorithm,path,dynamic-programming,knapsack-problem,bottom-up,Algorithm,Path,Dynamic Programming,Knapsack Problem,Bottom Up,我知道如何用动态规划方法解决背包0-1问题,但在不影响O(N*C)(N个项目,C个容量)的复杂性的情况下,我很难确定要取哪些项目 有什么想法吗(我更喜欢自下而上的方法)?假设,现在您正在数组bool[]a中存储结果,其中a[I]是真的,当sumI可以实现时。 您需要另一个数组int[]b,其中b[i]是您放入背包中以实现sumi的最后一个元素 那么,你去哪里了 a[i] = true; 你需要 a[i] = true; b[i] = current_item; 然后,找到哪些项目可以实现su
有什么想法吗(我更喜欢自下而上的方法)?假设,现在您正在数组
bool[]a
中存储结果,其中a[I]
是真的,当sumI
可以实现时。您需要另一个数组
int[]b
,其中b[i]
是您放入背包中以实现sumi
的最后一个元素
那么,你去哪里了
a[i] = true;
你需要
a[i] = true;
b[i] = current_item;
然后,找到哪些项目可以实现sumi
是一个简单的循环
PS为了简单起见,我使用了两个数组,但显然数组
a
可以删除。这里有一个修改,可以在O(n)次内重建路径
boolean[] solution = new boolean[nItems];
for (int i = nItems, c = maxCapacity; i > 0 && c > 0; i--) {
int iThItemAddedValue = value[i - 1][c - weights[i - 1]] + values[i - 1];
int iThItemInheritedValue = value[i - 1][c];
if (iThItemAddedValue > iThItemInheritedValue) {
solution[i - 1] = true;
c = c - weights[i - 1];
} else {
solution[i - 1] = false;
}
}
int背包(int重量[],int利润[],int物品数量,int容量){
对于(int-var=0;var
在呼叫者中打印tmpList,您将得到答案检查所附图像中的sol公共类背包问题{
私有静态int[][]缓存;
公共静态void main(字符串[]args){
int val[]=新的int[]{60100120};
int wt[]=新的int[]{10,20,30};
int W=50;
int n=val.length;
系统输出println(背包(W,wt,val,n));
打印值(wt,val);
}
/**
*此方法将使用
*重量小于或等于的更大值
*配重
*@param w给定重量
*@param wt权重数组
*@param val值数组
*@param n数组的长度
*@返回我们可以获得的最大值
*/
私有静态int背包(int w,int[]wt,int[]val,int n){
cache=newint[n+1][w+1];
对于(int i=1;i),我实际上对如何重建感兴趣(即打印获得最大值的项目)。我提出了一个解决方案,其时间复杂度为O(N*C)
,但使用O(N*C)空间。我不认为只有一个或两个数组就可以重建。@leden这正是这种方法的作用,只有一个数组。描述的哪一部分不清楚?@Nikita Rybak:你能进一步阐述你的解决方案吗?谢谢!@axel22你需要关于哪一部分的信息,构造b
,或者用它来重建e解决方案?如何使用b
重新创建解决方案?打印“tmpList”数组,它将打印路径请您的帖子,并将实际代码显示为文本而不是屏幕截图。其他人无法从您的图像复制和粘贴。有关详细信息,谢谢。答案中的链接已失效。
int knapsack(int weight[], int profit[], int no_of_items, int capacity) {
for (int var = 0; var <= capacity; ++var) {
dp[0][var] = 0;
}
for (int var = 0; var <= no_of_items; ++var) {
path[var] = false;
}
int using_item_i, without_using_item_i;
for (int i = 1; i <= no_of_items; ++i) {
for (int j = 1; j <= capacity; ++j) {
without_using_item_i = dp[i - 1][j];
using_item_i = 0;
if ((weight[i]) <= j) {
using_item_i = dp[i - 1][j - weight[i]] + profit[i];
}
if (using_item_i >= without_using_item_i) {
taken[i][j] = true;
dp[i][j] = using_item_i;
} else {
taken[i][j] = false;
dp[i][j] = without_using_item_i;
}
}
}
//Reconstructing back the path
int j = capacity;
for (int i = no_of_items; i >= 0; --i) {
if (taken[i][j]) {
path[i] = true;
cnt++;
}
j = j - weight[i];
}
return dp[no_of_items][capacity];
}
public class Knapsackproblem {
private static int[][] cache;
public static void main(String[] args) {
int val[] = new int[]{60, 100, 120};
int wt[] = new int[]{10, 20, 30};
int W = 50;
int n = val.length;
System.out.println(knapSack(W, wt, val, n));
printValues(wt,val);
}
/**
* This method will find the result with
* more value with weight less than or equal
* to given weight
* @param w given weight
* @param wt arrays of weights
* @param val array of values
* @param n length of the array
* @return max value we can obtain
*/
private static int knapSack(int w, int[] wt, int[] val, int n) {
cache = new int[n+1][w+1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= w; j++) {
if(j < wt[i-1]){
cache[i][j] = cache[i-1][j];
}else {
cache[i][j] = Math.max(cache[i-1][j],(cache[i-1][j-wt[i-1]])+val[i-1]);
}
}
}
for (int[] aCache : cache) {
System.out.println(Arrays.toString(aCache));
}
return cache[n][w];
}
private static void printValues(int[] wt, int[] val) {
int m = cache.length-1;
int n = cache[0].length-1;
util(wt,val,m,n);
}
private static void util(int[] wt, int[] val, int m, int n) {
if(m <=0 || n<=0) return;
if((cache[m][n] != cache[m-1][n]) && (cache[m][n] != cache[m][n-1])){
System.out.println(val[m-1]+"-->"+wt[m-1]);
util(wt, val, m-1, (n - wt[m - 1] + 1));
}else
if(cache[m][n] == cache[m-1][n]){
util(wt,val,m-1,n);
}
else if(cache[m][n] == cache[m][n-1])
util(wt,val,m,n-1);
else
util(wt,val,m,(n-val[m-1]+1));
}
}