代码之家  ›  专栏  ›  技术社区  ›  user5979174

如何在这个背包java代码中返回权重和相应的索引?

  •  2
  • user5979174  · 技术社区  · 7 年前

    this website 关于背包0-1问题。

    我想修改他们提供的程序,以便返回选择的值以及相应的索引。例如,对于这种情况,解决方案输出390,但我希望它能够输出390 而且 打印出已选择的值。所以在这种情况下,我希望它打印:

    Items selected :
    #2 60
    #3 90
    #5 240
    

    以下是我目前掌握的情况:

    // A Dynamic Programming based solution for 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(int W, int wt[], int val[], int n)
        {
            int i, w;
        int K[][] = new int[n+1][W+1];
                int[] selected = new int[n + 1];
    
        // Build table K[][] in bottom up manner
        for (i = 0; i <= n; i++)
        {
            for (w = 0; w <= W; w++)
            {
                if (i==0 || w==0){
                    //selected[i] = 1;
                    K[i][w] = 0;
                }
                else if (wt[i-1] <= w){
                    selected[i] = 1;
                    K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w]);
                }
                else{
                    selected[i]=0;
                    K[i][w] = K[i-1][w];
                }
            }
        }
         System.out.println("\nItems selected : ");
            for (int x = 1; x < n + 1; x++)
                if (selected[x] == 1)
                    System.out.print(x +" ");
            System.out.println();
    
        return K[n][W];
        }
    
    
        // Driver program to test above function
        public static void main(String args[])
        {
            int val[] = new int[]{300,60,90,100,240};
        int wt[] = new int[]{50,10,20,40,30};
        int W = 60;
        int n = val.length;
        System.out.println(knapSack(W, wt, val, n));
        }
    }
    

    1 回复  |  直到 7 年前
        1
  •  1
  •   River Marcus Downing    7 年前

    不幸的是,在动态规划问题中,很难设置选择哪些项目。由于解决方案必然基于子问题的解决方案,因此您还需要存储在每个子解决方案中选择的项,然后在最后将其聚合。

    System.out.println("\nItems selected : ");
    int tempW = W;
    int y = 0; //to index in selected
    for (int x = n; x > 0; x--){
        if ((tempW-wt[x-1] >= 0) && (K[x][tempW] - K[x-1][tempW-wt[x-1]] == val[x-1]) ){
            selected[y++] = x-1; //store current index and increment y
            tempW-=wt[x-1];
        }
     }
     for(int j = y-1; j >= 0; j--){
        System.out.print("#" + (selected[j]+1) + " ");
        System.out.println(val[selected[j]]);
    }
    

    这将打印:

    Items selected:
    #2 60
    #3 90
    #5 240
    390
    

    for 环出于同样的原因,我们首先必须回溯:从起点开始,有许多路要走,而从终点开始,只有一条路回到起点。