我可以使用动态编程来解决这个问题吗?

时间:2015-10-25 20:31:20

标签: c recursion combinations dynamic-programming

我对动态编程的经验很少。我用它来解决DNA对齐问题,基本背包问题和简单的寻路问题。我明白它们是如何工作的,但它并不是我觉得非常舒服的东西。

我有一个让我想起0-1动态编程的问题,但差异让我失望了,我不确定我是否仍然可以使用这种技术,或者我是否必须接受递归方法

我们说我有一个项目列表,每个项目都有不同的值,权重和成本。每个项目可能不止一个。

让我们说我必须选择最有价值的那些项目的组合,但仍然在重量和成本的限制范围内。到目前为止,我已经用2个约束描述了背包问题。但是区别在于:

所选项目的值会根据我在组合中的数量而变化。

让我们说每个项目都有一个与之相关的功能,告诉我这些项目的组合对我来说是多么值得。它是一个基本的线性函数,例如 value_of_item = -3(该项目的数量)+ 50

所以,如果我在组合中有一个项目,那么它对我的价值是47.如果我有2个,那么他们每个人只有44个。

如果我为此使用动态编程表,那么对于每个单元格,我必须回溯以查看该项目是否已经在当前组合中,使得DP无意义。但也许有一种方法可以重新解决问题,因此我可以利用DP。

希望这是有道理的。

另一种方法是生成每个项目组合,在成本和重量的限制内,计算每个组合的价值,选择最有价值的组合。对于1000个项目的列表,这将是一个昂贵的搜索,并且它是我反复计算的东西。我想找到一种方法来利用DP的优势。

1 个答案:

答案 0 :(得分:0)

如果您的功能是

形式
value(x, count) = base(x) - factor(x) * count, factor(x) > 0,

然后您可以通过拆分项目将问题减少到标准背包:

x -> x_1 to x_max_count
value_new(x_i) = value(x, i)
weight(x_i) = weight(x)

现在,您可以轻松验证新问题的最佳解决方案是否使用某个项目x_j,而不使用每个x_i和i<学家

矛盾证明:假设存在这样的最优解S,它使用x_j,但不使用x_i,j>一世。然后有一个替代解决方案S'使用x_i而不是x_j。由于j>我,

value_new(x_j) = value(x, j) 
               = base(x) - factor(x) * j 
               < base(x) - factor(x) * i
               = value(x, i)
               = value_new(x_i)

因此S'的价值高于S,我们达成了矛盾。

此外,我们可以允许factor(x) = 0,这对应于标准的背包项目。

但是如果存在形式的约束

value(x, count) = base(x) + factor(x) * count

其中factor(x)是任意值,上面的解决方案不再有效,因为最后一项是具有最大值的项。也许一些复杂的DP修改可能允许你使用这些约束,但我没有看到问题本身的任何修改立即使用DP。

本主题的一些研究(更一般):