【发布时间】:2017-03-07 13:34:28
【问题描述】:
给定一个 (1xN) 正权重列表(不一定是整数,即浮点数)和一个等长 (1xN) 相应成本列表,我想找到权重列表的子集,其总和恰好等于给定总和 S 和具有最低成本(与权重列表中的子集对应的成本*权重之和)。最好用 Python 编写(如果可能的话),因为我不太擅长其他语言!
例子:
w = [2.5, 3.0, 1.0, 5.5] # Weight list
c = [1.0, 1.5, 2.0, 3.0] # Cost list
S = 6.5 # Target sum
对于这种情况,我们有两个可能的子集总和为 S:
sub1 = [2.5, 3.0, 1.0]
sub2 = [1.0, 5.5]
这些子集的成本是:
cost1 = 2.5*1.0+3.0*1.5+1.0*2.0 = 9.0
cost2 = 1.0*2.0+5.5*3.0 = 18.5
由于子集 1 的成本最低 (9.0),这是我想要的子集。
一种可能的解决方案当然是计算所有可能的组合,然后只选择计算成本中的最小值。我希望有一个更有效的解决方案来解决这个问题。
我已经搜索了不同的解决方案,但我只能找到解决等和问题的 Python 解决方案,而不能同时获得最低成本。以下是此类解决方案的示例:Algorithm to find which number in a list sum up to a certain number。
【问题讨论】:
-
权重至少是正数吗?无论如何,这是一个非常简单的具有单个等式约束的 0-1 整数线性规划问题。因此,诸如分支定界算法之类的东西将起作用,尽管可能有更简单的方法。动态编程当然是一种自然的方式。你试过什么?
-
作为参考,这被称为子集和问题en.m.wikipedia.org/wiki/Subset_sum_problem,并且普遍认为不存在有效的解决方案。 (当然你要求的不是一个有效的解决方案,只是一个解决方案)
-
我更新了问题。是的,权重是正实值。我希望至少比检查所有可能的组合更有效。
-
@sheg 如果您查看我链接的维基百科页面,它解释了我们目前知道的最有效的算法。你不能指望比他们做得更好。您只需要稍微修改一下即可针对您的权重测试可能的解决方案。应该是一个相当微不足道的修改
-
你的工作在哪里?是时候跟进 Cruncher 的研究了。我会注意到,即使您的数据不是整数,您也可以通过使用整数来打开一些选项。 OP 可以表示为精确整数,也可以使用 epsilon。
标签: python dynamic-programming knapsack-problem integer-programming