我已经阅读了Knapsack问题的许多变体,但我负责的版本有点不同,我不太明白如何解决它。
我有一个表示权重的整数数组(即{1,4,6,12,7,2}),并且只需要找到一个可以累加目标权重的解决方案。
我理解基本算法,但我无法理解如何实现它。
首先,我的基本案例是什么?是数组为空时?目标已达到?目标已经过度?或者也许是一些组合?
其次,当目标被超越时,我如何回溯并尝试下一个项目?
第三,我应该回归什么?我应该回来注册(在这种情况下,我应该打印出来吗?)?或者我是否返回数组,最终的回报是解决方案?
答案 0 :(得分:0)
仔细考虑您要解决的问题。为了解决这个问题,我是 考虑Knapsack算法的输入和输出。
输入:一组整数(背包)和一个整数(建议的总和)
输出:一组整数,用于加总建议的总和,或为空。
通过这种方式,您的代码可能如下所示
public int[] knapsackSolve(int[] sack, int prospectiveSum) {
//your algorithm here
}
递归算法很简单。首先计算麻袋的总和。如果它等于 prospectiveSum然后返回麻袋。否则迭代麻袋,并为每个项目初始化一个新的背包,删除该项目。打电话给背包解决这个问题。如果有解决方案,请将其退回。否则继续下一个项目。
例如,如果我们调用knapsackSolve({1,2,3},5),算法会尝试1 + 2 + 3 = 5,这是假的。所以它遍历{1,2,3}并在子列表{2,3},{1,3}和{1,2}上调用knapsackSolve。 knapsackSolve({2,3},5)是返回解决方案的那个。
这不是一个非常有效的算法,尽管它很好地说明了背包问题的复杂程度!
答案 1 :(得分:0)
基本上背包问题被表述为(来自Wikipedia):"给定一组具有质量和值的项目,确定要包含在集合中的每个项目的数量,以便总重量小于或等于给定限度,总值尽可能大。对于您的问题,我们只对重量感兴趣。因此,您可以将所有值设置为1.此外,我们只想知道是否可以准确达到目标重量。我想你可以只使用一次重量而不是多次? 使用动态编程可以很好地解决这个问题。你熟悉这个原则吗?应用动态编程比回溯更优雅,更快速地编程。但是,如果您只允许进行回溯,请使用上面发布的user2738608的方法。