递归背包返回错误的答案

时间:2013-11-15 20:39:10

标签: java dynamic knapsack-problem

以下代码应该返回16,据我所知,但由于某种原因,它返回10.有谁知道我的bug可能是什么?基本上它是Java中的背包问题,我已经在纸上完成了整个代码,它似乎给了我正确的答案,但我无法弄清楚为什么当它正常运行时,它返回10.

非常感谢任何帮助。谢谢!

import java.util.Stack;

public class knapsackProblem
{

  public static int optimalValue(Stack<item> items, int totalWeight)
  {
    if (items.isEmpty())
      return 0;

    int value = items.peek().value;
    int weight = items.peek().weight;

    items.pop();

    if (totalWeight<weight)
      return optimalValue(items, totalWeight);

    return Math.max(optimalValue(items,totalWeight), value + optimalValue(items, totalWeight-weight));
  }

  public static void main(String args[])
  {
    int knapsackWeight = 15;
    Stack<item> items = new Stack<item>();

    items.push(new item(7,10));
    items.push(new item(3,6));

    System.out.println(optimalValue(items, knapsackWeight));

  }
}

class item
{
  public int weight;
  public int value;

  public item(int aWeight, int aValue)
  {
    weight = aWeight;
    value = aValue;
  }
}

2 个答案:

答案 0 :(得分:1)

您的Stack正在通过电话进行修改。所以像

这样的一行
return Math.max(optimalValue(items,totalWeight), value + optimalValue(items, totalWeight-weight));

每次通话都会有两个不同的项目副本。不是你想要的。

不要使用Stack,而是尝试更改内容以使用ArrayList。然后将您正在评估的项目的索引传递给optimalValue方法。这应该可以帮助您正确处理项目。

答案 1 :(得分:0)

我还没有完成整个算法,但一个明显的问题是,每次在optimalValue上调用Stack时,它都会从堆栈中弹出一个或多个项目。但是Stack和堆栈中的项目是对象,这意味着它们是通过引用传递的。所以在这一行:

return Math.max(optimalValue(items,totalWeight), value + optimalValue(items, totalWeight-weight));

这会两次调用optimalValue。第一次使用items作为参数进行调用时,optimalValue会弹出items中的一个或多个元素。然后语句再次使用optimalValue作为参数调用items - 这将 NOT 使用您传递给第一个{{1}的相同items堆栈调用,但它会使用optimalValue ,但已弹出的项目仍然会弹出(从第一次调用开始)。我真的怀疑这是你想要的。如果你这样做,那么在某些时候我认为你必须复制items。或者你需要重新思考并以不同的方式进行操作(也许你可以使用数组或Stack,这样项目实际上不会弹出,但你可以从一个{传递“起始索引” {1}}调用递归调用)。

除了这个问题,我不知道你的解决方案是否还有其他问题。