Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何获取0-1背包中所选物品的列表?_Java_Algorithm_Dynamic Programming_Knapsack Problem - Fatal编程技术网

Java 如何获取0-1背包中所选物品的列表?

Java 如何获取0-1背包中所选物品的列表?,java,algorithm,dynamic-programming,knapsack-problem,Java,Algorithm,Dynamic Programming,Knapsack Problem,我有一个简单的背包问题解决方案的代码,我想得到所选项目的索引列表,目前它返回的是所选项目值的总和。 任何帮助都将不胜感激。 JAVA代码: /* package whatever; // don't place package name! */ import java.util.*; import java.lang.*; import java.io.*; /* Name of the class has to be "Main" only if the class is public.

我有一个简单的背包问题解决方案的代码,我想得到所选项目的索引列表,目前它返回的是所选项目值的总和。 任何帮助都将不胜感激。 JAVA代码:

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
/* A Naive recursive implementation of 0-1 Knapsack problem */
class Knapsack
{

    // A utility function that returns maximum of two integers

     static int max(int a, int b) {

        return (a > b)? a : b; }

     // Returns the maximum value that can be put in a knapsack of capacity W
     static int knapSack(float W, float wt[], int val[], int n)
     {
        // Base Case

    if (n == 0 || W == 0)
        return 0;

    // If weight of the nth item is more than Knapsack capacity W, then
    // this item cannot be included in the optimal solution
    if (wt[n-1] > W)
      {

        return knapSack(W, wt, val, n-1);
      }
    // Return the maximum of two cases: 
    // (1) nth item included 
    // (2) not included
    else { 
        return max( val[n-1] + knapSack(W-wt[n-1], wt, val, n-1),
                     knapSack(W, wt, val, n-1)
                      );
    }            
      }


   // Driver program to test above function
   public static void main(String args[])
   {
        int val[] = new int[]{29,74,16,55,52,75,74,35,78};
        float wt[] = new float[]{85.31f,14.55f,3.98f,26.24f,63.69f,76.25f,60.02f,93.18f,89.95f};
    float  W = 75f;
    int n = val.length;
    System.out.println(knapSack(W, wt, val, n));
    }
}
当前结果:148
预期结果:2,7

以下是如何做到这一点,尽管它使用了一些额外的内存-

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
/* A Naive recursive implementation of 0-1 Knapsack problem */
class Knapsack
{

    // A utility function that returns maximum of two integers

     static int max(int a, int b) {

        return (a > b)? a : b; }

     // Returns the maximum value that can be put in a knapsack of capacity W
     static int knapSack(float W, float wt[], int val[], int n,int visited[])
     {
        // Base Case

    if (n == 0 || W == 0)
        return 0;

    // If weight of the nth item is more than Knapsack capacity W, then
    // this item cannot be included in the optimal solution
    if (wt[n-1] > W)
      {

        return knapSack(W, wt, val, n-1,visited);
      }
    // Return the maximum of two cases: 
    // (1) nth item included 
    // (2) not included
    else {

        int v1[]=new int[visited.length];
        System.arraycopy(visited, 0, v1, 0, v1.length);
        int v2[]=new int[visited.length];
        System.arraycopy(visited, 0, v2, 0, v2.length);
        v1[n-1]=1;

        int ans1 = val[n-1] + knapSack(W-wt[n-1], wt, val, n-1,v1);
        int ans2 = knapSack(W, wt, val, n-1,v2);
        if(ans1>ans2){
            System.arraycopy(v1, 0, visited, 0, v1.length);
            return ans1;
        }
        else{
            System.arraycopy(v2, 0, visited, 0, v2.length);
            return ans2;
        }
    }            
      }


   // Driver program to test above function
   public static void main(String args[])
   {
        int val[] = new int[]{29,74,16,55,52,75,74,35,78};
        float wt[] = new float[]{85.31f,14.55f,3.98f,26.24f,63.69f,76.25f,60.02f,93.18f,89.95f};
    float  W = 75f;
    int n = val.length;
    int visited[] = new int[n];
    System.out.println(knapSack(W, wt, val, n, visited));
    for(int i=0;i<n;i++)
        if(visited[i]==1)
            System.out.println(i+1);
    }
}

我所做的是创建了一个已访问数组,如果使用当前元素,则我将当前元素的已访问标记为1,否则它将保持为零。最后,我遍历了这个数组,并打印了访问的每个元素都是1-

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
/* A Naive recursive implementation of 0-1 Knapsack problem */
class Knapsack
{

    // A utility function that returns maximum of two integers

     static int max(int a, int b) {

        return (a > b)? a : b; }

     // Returns the maximum value that can be put in a knapsack of capacity W
     static int knapSack(float W, float wt[], int val[], int n,int visited[])
     {
        // Base Case

    if (n == 0 || W == 0)
        return 0;

    // If weight of the nth item is more than Knapsack capacity W, then
    // this item cannot be included in the optimal solution
    if (wt[n-1] > W)
      {

        return knapSack(W, wt, val, n-1,visited);
      }
    // Return the maximum of two cases: 
    // (1) nth item included 
    // (2) not included
    else {

        int v1[]=new int[visited.length];
        System.arraycopy(visited, 0, v1, 0, v1.length);
        int v2[]=new int[visited.length];
        System.arraycopy(visited, 0, v2, 0, v2.length);
        v1[n-1]=1;

        int ans1 = val[n-1] + knapSack(W-wt[n-1], wt, val, n-1,v1);
        int ans2 = knapSack(W, wt, val, n-1,v2);
        if(ans1>ans2){
            System.arraycopy(v1, 0, visited, 0, v1.length);
            return ans1;
        }
        else{
            System.arraycopy(v2, 0, visited, 0, v2.length);
            return ans2;
        }
    }            
      }


   // Driver program to test above function
   public static void main(String args[])
   {
        int val[] = new int[]{29,74,16,55,52,75,74,35,78};
        float wt[] = new float[]{85.31f,14.55f,3.98f,26.24f,63.69f,76.25f,60.02f,93.18f,89.95f};
    float  W = 75f;
    int n = val.length;
    int visited[] = new int[n];
    System.out.println(knapSack(W, wt, val, n, visited));
    for(int i=0;i<n;i++)
        if(visited[i]==1)
            System.out.println(i+1);
    }
}

我所做的是创建了一个已访问数组,如果使用当前元素,则我将当前元素的已访问标记为1,否则它将保持为零。最后,我迭代了这个数组,并打印了访问的每个元素都是1,尽管接受的解决方案做了需要的事情,但我认为它有一些缺陷。基本上,我们可以使用一个技巧来提高时间效率,并跟踪选定的项目

背包问题可以用动态规划来解决,这意味着,我们需要缓存中间结果,并使用它们进行更少的计算。请注意,接受的代码不存储中间结果,这意味着某些组合的计算不止一次。这在这里有很好的描述:。 回到您的问题,关于GeekForgeks的文章没有告诉您如何恢复所选项目:

我们可以使用缓存阵列还原选定的项目: 我们从最后一个元素开始,因为我们的缓存是2d数组,这是

var r = K.length -1
car c = K(0).length -1 
var curr = K(r)(c)
现在,虽然我们没有到达第一行,但我们不检查第一行,因为它是辅助的,我们将当前值与前一行同一列中的值进行比较。如果它们相同,这意味着,我们没有使用相应的项,所以我们只转到r-1行。如果它们不同-使用了项,我们将同时更新行和列

// here I use same names as in the geekforgeeks article 
// val - array of values
// K - cache for intermediate results, 
// wt - array of weights

    i = K.length - 1
    j = W
    while (i > 0) {
      k = K(i)(j)
      if (k != K(i - 1)(j)) {
        println("selected item: val(i - 1)")
        j -= wt(i - 1)
      }
      i -= 1
    }

我在这里发现了这种方法:

即使被接受的解决方案做了需要做的事情,我认为它有一些缺陷。基本上,我们可以使用一个技巧来提高时间效率,并跟踪选定的项目

背包问题可以用动态规划来解决,这意味着,我们需要缓存中间结果,并使用它们进行更少的计算。请注意,接受的代码不存储中间结果,这意味着某些组合的计算不止一次。这在这里有很好的描述:。 回到您的问题,关于GeekForgeks的文章没有告诉您如何恢复所选项目:

我们可以使用缓存阵列还原选定的项目: 我们从最后一个元素开始,因为我们的缓存是2d数组,这是

var r = K.length -1
car c = K(0).length -1 
var curr = K(r)(c)
现在,虽然我们没有到达第一行,但我们不检查第一行,因为它是辅助的,我们将当前值与前一行同一列中的值进行比较。如果它们相同,这意味着,我们没有使用相应的项,所以我们只转到r-1行。如果它们不同-使用了项,我们将同时更新行和列

// here I use same names as in the geekforgeeks article 
// val - array of values
// K - cache for intermediate results, 
// wt - array of weights

    i = K.length - 1
    j = W
    while (i > 0) {
      k = K(i)(j)
      if (k != K(i - 1)(j)) {
        println("selected item: val(i - 1)")
        j -= wt(i - 1)
      }
      i -= 1
    }

我在这里找到了这种方法:

检查这个链接-它有一个关于如何做的视频教程,我认为它比书面解决方案更容易理解。我后来注意到了,但你的解决方案是递归的,而不是dp。所以视频中的方法不适合你。您可以做的是创建一个已访问的数组,该数组的已访问[i]如果使用第i个元素,则为1;如果使用第i个元素,则为0not@monster无法理解你能在代码中修改它吗?检查这个链接-它有一个关于如何做的视频教程,我认为它比书面解决方案更容易理解。我后来注意到了,但你的解决方案是递归的,而不是dp。所以视频中的方法不适合你。您可以做的是创建一个访问数组,如果您使用的是第i个元素,则访问的[i]=1,如果使用的是第0个元素,则访问的[i]=0not@monster无法理解您能在代码中修改它吗?在这个解决方案中,可以通过使用布尔数组而不是int来节省一些内存,因为int可以在2-4字节之间,布尔值只有1字节。不要将数组中的元素设置为1,而是将其设置为true,这样就可以了。有人可以在Python中翻译相同的代码吗?在这个解决方案中,可以使用布尔数组而不是int来保存内存,因为int可以在2-4字节之间,boolean仅为1字节。与其将数组中的元素设置为1,不如将其设置为true,就这样。有人可以用python翻译相同的代码吗