【问题标题】:Knapsack algorithm for multiplication乘法的背包算法
【发布时间】:2012-05-11 14:22:52
【问题描述】:

我有一组 N 数字,每个数字都附加一些成本,问题是选择所有可能的数字集作为列表,使其乘积小于某个数字 M,按照排序成本的总和。

例如:- 数字集是

(number, costOfThatNumber) : {(90, 10) , (80, 20), (60, 40), (40, 60), (15, 85)},

并且产品必须小于,Prod <= 1000

可能的解决方案是:-

[Solution 1 :- {(15, 85), (40, 60)} :- Product = 600 (which is less than, 1000), cost = 85 + 60 = 145]
[Solution 2 :- {(15, 85), (80, 20)} :- Product = 900 and cost = 105]

所以列表变成了{Solution2, Solution1}

PS :-

  1. 这不是作业问题,在采访中被问到。我只被问到算法,我只能说它看起来有点像背包问题,但用于乘法。
  2. 如果我无法正确解释问题,请原谅。

【问题讨论】:

  • 如果不是最佳解决方案,即使有人给我一个蛮力算法,我也会很感激,我什至可以找到一种方法来选择所有可能的集合子集。
  • 你的例子错了吗? 15*80不是900……不应该是(15, 85),(60,40)吗?

标签: algorithm knapsack-problem


【解决方案1】:

我认为可以将问题简化为背包问题。

注意

x1 * x2 * ... * xn <= M <-> 
log(x1*x2*...*xn) <= log(M) <-> 
log(x1) + log(x2) + ... + log(xn) <= log(M)

所以可以用背包找到最优解:

weight'(item) = log(weight(item))
value(item) = value(item)
M' = log(M)
run Knapsack on the items with weight', value, M'

需要更多的工作来获得所有可行的解决方案,不仅是最佳解决方案,而且由于这些解决方案的数量是指数级的(2^n 如果M = infinity),我怀疑甚至有伪多项式解决方案。

一个无效的解决方案只是创建power set(包含所有可能集合的集合),并检查每个集合的可行性及其值,并根据它们的值将可行的解决方案存储在有序集合中。 This post 解释了如何获得电源组。

【讨论】:

  • 这是最佳算法肯定具有指数运行时间(以获得所有解决方案)的少数情况之一,这仅仅是因为最坏情况下的输出大小是指数的。在所有情况下,输出大小都是复杂度的下限。如果您需要计算并填充内存中的 X 个位置,则需要 X 步来完成,尽管每个结果的计算可能很琐碎,但无法绕过它。
【解决方案2】:

如上所述,这不是背包问题。只需按升序排序,从头开始挑选直到达到产品限制,然后根据成本重新排序。如前所述,不要求总成本应低于任何阈值或限制,因此最佳解决方案只是选择具有最小第一个元素的对。

【讨论】:

    猜你喜欢
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 2011-12-28
    相关资源
    最近更新 更多