【问题标题】:Select items in 0/1 knapsack ,where two items have same benefits |maximize value and minimize weight选择 0/1 背包中的物品,其中两个物品具有相同的好处 |最大化价值和最小化重量
【发布时间】:2015-10-07 13:43:12
【问题描述】:

在 0/1 背包问题中,如果两个项目具有相同的值,我如何选择项目。应选择权重较小的值,如何检查该条件?我使用动态编程具有以下功能。

static int[] knapsack(int maxWeight, double[] weight, double[] value, int n) {
    //n = no. if items
    int i, w;

    double array[][] = new double[n + 1][maxWeight + 1];
    for (i = 0; i <= n; i++) {
        for (w = 0; w <= maxWeight; w++) {
            if (i == 0 || w == 0)
                array[i][w] = 0;
            else if (weight[i - 1] <= w)
                array[i][w] = max(value[i - 1] + array[i - 1][(w -(int) weight[i - 1])], array[i - 1][w]);
            else
                array[i][w] = array[i - 1][w];
            if (i != 0 || w != 0)
                System.out.print(array[i][w] + "\t");
        }
        System.out.println();
    }

    int[] selected = new int[n + 1];
    for (int j = n, wt = maxWeight; j > 0; j--) {   
        if (array[j][wt] != array[j - 1][wt]) {
            if (array[j][wt] == array[j][wt - 1]) {
                selected[j] = 0;
                break;
            }
            selected[j] = 1;
            wt = wt - (int) weight[j - 1];
        }
        else
            selected[j] = 0;
    }
    /** Print finally selected items **/
    System.out.println("\nItems selected : ");
    for (int k = 1; k < n + 1; k++)
        if (selected[k] == 1)
            System.out.print(k +" ");
        System.out.println();

        return selected;
}

对于这种情况:(i,v): (4,45)(3,20)(5,30)(2,45) ,maxWeight = 5; 如果第 1 项和第 4 项具有相同的值,则应选择权重较小的第 4 项。我如何在上面的代码中实现这个条件。 问题陈述:

您的目标是确定要放入哪些内容 包装,使总重量小于或等于包装 限制和总成本尽可能大。你更愿意 发送一个重量较轻的包裹,以防有多个包裹 同价包。

【问题讨论】:

    标签: java dynamic-programming knapsack-problem


    【解决方案1】:

    如果您的意思是通过最小化 重量 最大化价值。你可以检查一下

    令DP[i][j]为能得到的最大值!

    W[i][j] 是要使用的最小权重!!

    那么,

    if(Current Weight > Element's Weight)
    {
          if(DP[i-1][j-Weight[i]]+Value[i]>DP[i-1][j]){
                 DP[i][j]=DP[i-1][j-Weight[i]]+Value[i];
                 Weight[i][j]= Weight[i-1][j-Weight[i]]+Value[i]
          }
          else if(DP[i-1][j-Weight[i]]+Value[i] <  DP[i-1][j] ){
                 DP[i][j]=DP[i-1][j];
                 Weight[i][j]=Weight[i-1][j];
          } 
          else{                   //Note this is the tricky part elsewise the 
                                  //Above conditions are simple Knapsack conditions
    
                 DP[i][j]=DP[i-1][j];   //Both of them are equal We will get same Value . Thus we cannot maximise it in any other way!!
                 Weight[i][j]=minimum ( Weight[i-1][j] ,Weight[i-1][j-Weight[i]]+A[i]);
    
          }
    }
    else
    {
                 DP[i][j]=DP[i-1][j];
                 Weight[i][j]=Weight[i-1][j];
    }
    

    注意除非第一个 if 中的第三个条件,否则该解决方案是微不足道的! 我们需要不惜一切代价将乐趣最大化!所以我们不搞砸了! 但是当两种情况的乐趣相同时,我们需要选择重量较小的,否则我们最终会在相同价值的背包中获得更多的重量!

    我假设你知道背包 0/1 问题,所以我没有解释第一个和第二个条件!!

    【讨论】:

    • 不,这不像我必须全身心地减轻重量。我已经用问题陈述编辑了这个问题。如果我删除具有相同价值且权重更大的项目,则 DP 不会最大化价值
    • @Ankita 你看到完整的答案了吗!!我也回答了你提到的整个问题,因为另一个问题更简单! Morover这个问题与Spoj(在线法官)上的派对时间表相同,我已经使用与我的答案中描述的相同的逻辑解决了它!如果答案正确,请务必查看并接受以促进努力!
    • 我接受这个答案,因为它通过最小化 Weight 来解决最大化价值,但是我现在采用了不同的方法,首先按重量的升序对项目进行排序。
    • 按重量分类并不能确保最优成本,这会带来问题!
    • @ShubhamSharma ,我们是否需要为权重使用额外的数组?重量[][]
    【解决方案2】:

    如果您只需要选择重量最小的项目,那么为什么不让它循环遍历选项并将object[i] 的重量与[i + 1] 的对象的重量进行比较,如果它更低的话只需将其与下一个进行比较,否则为object[i] = object[i + 1],依此类推。我是否正确理解了这个问题?

    【讨论】:

      猜你喜欢
      • 2016-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 2016-10-28
      • 1970-01-01
      • 2018-02-10
      相关资源
      最近更新 更多