如何找到不超过某个值的最大项目?例如,我有45个这样的值:1.0986122886681098,1.6094379124341003,3.970291913552122,3.1354942159291497,2.5649493574615367。我需要找到最大可能的组合,不超过30.7623。
我不能使用强力来找到所有组合,因为组合的数量会很大。所以我需要使用一些贪心算法。
答案 0 :(得分:4)
这是Knapsack problem的一个实例。它是NP-hard,因此对于45个项目,您必须使用一些启发式算法(例如Hill Climbing)来查找可接受的估算值。要找到最佳解决方案,除了尝试所有可能性(这是不可行的)之外别无选择。了解您的分布可能会改变这种情况。如果许多物品本身超过限制,则可以丢弃它们。或者,如果限制非常接近所有数字的总和,则可能只需要包含最多约5个项目的组合; 45选择5仍然可行。
答案 1 :(得分:0)
你搜索的是我猜的背包问题。这个解决方案对您有帮助吗?
http://rosettacode.org/wiki/Knapsack_problem/Unbounded/Python_dynamic_programming
查看" 1.2 DP,单一尺寸"下的解决方案。我认为这不是蛮力。你应该能够适应你的问题。
答案 2 :(得分:0)
您可以尝试找到近似解决方案:
Multiply your floats by appropriate number (for example, 100), do the same for sum.
Round floats to the nearest integers (or Ceil them to larger integers)
like Round(1.0986122886681098 * 100) = 110
Solve subset sum problem for integers with DP
Check that sum of floats doesn't excess the limit
(due to rounding errors)
如果您有很多非常接近的浮点数,您可能希望使用优化算法(如提到的Hill Climbing)来优化解决方案
答案 3 :(得分:0)
这个问题可以表述为零一分配问题,并用线性编程包解决,例如GLPK,它可以处理整数编程问题。问题是找到二进制变量x[i]
,使得x[i]*w[i]
的总和尽可能大,并且小于规定的限制,其中w[i]
是加起来的值。
我的建议是使用现有的包裹;组合优化算法通常非常复杂。您可以使用某些包的Python界面;我不知道GLPK是否有这样的界面,但可能有些包。