【问题标题】:Several combination returned by bounded Knapsack algorithm有界背包算法返回的几种组合
【发布时间】:2015-11-14 14:26:04
【问题描述】:

此任务类似于有界背包问题 (BKP)。 我们有大约 300 种不同的餐点,其参数如下:ID、价格、重要性/评级、类别

例如:

id  price  importance  type
-----------------------------
1   100     78         butter
2   50      89         milk
3   70      66         milk
4   66      50         butter

我们想选择TOP-10的最佳产品组合,但在具体配置中,我们只想取3种黄油、2种面包和2种牛奶。这 TOP-10 组合必须具有最高的重要性总和。 我们还必须考虑可用的预算。

这与背包问题有点不同,因为这里我们想要 TOP-10 的结果,而不仅仅是最好的。 并且同一组的每餐/产品(例如黄油)具有不同的价格和重要性/评级。

【问题讨论】:

    标签: algorithm optimization knapsack-problem


    【解决方案1】:

    我认为价格是整数且相当小,您正在考虑一些学校类型的 DP 解决方案。

    一般的DP

    在动态规划算法中,对于每个状态,我们只存储一个最佳部分解。通常我们不会物理存储部分解决方案:只存储它的成本和一些简单的回溯信息,以便以后重建它。由于最优子结构属性,我们不存储状态的其他解决方案:具有更差成本的任何部分解决方案都具有比最佳部分解决方案的相同延续更差的延续。

    为了找到问题的 k 个最佳解决方案,您可以简单地存储 DP 的每个状态的 k 个最佳部分解决方案。如果对于某些状态,解决方案少于 k 个,则存储所有解决方案。为什么我们可以放弃一个比其他部分解决方案更差的部分解决方案k?因为它的任何延续都会比那些 k 更好的部分解决方案的相同延续更糟糕。

    前向式 DP 中的转换照常完成。当您考虑某个状态时,您应该迭代其所有 k 个最佳部分解决方案,并尝试以所有可能的方式继续它们中的每一个(例如,是否采用新项目)。对于每个延续,查看其状态。将延续插入最佳部分解决方案的排序列表中。如果结果有 k+1 个部分解,则丢弃最差的一个。

    您当然不想将部分解决方案本身存储在 DP 中。相反,只存储每个部分解决方案的总成本和回溯信息。回溯信息应该足以明确地确定 DP 中先前的部分解决方案。通过这种方式,您可以找到最佳 k 解决方案。似乎具有 k 最佳解决方案的 DP 解决方案需要 O(k) 倍的内存和 O(k^2) 倍的时间(或O(k log k)) 与仅找到一个最佳解决方案相比。

    特殊问题

    在我看来,你应该用两级算法来解决你的问题:

    1. 针对每个项目类别中的有界背包问题运行 DP。因此,您将获得 k 个该类别项目与每个总成本(以及有限数量的项目)的最佳组合。
    2. 找到在步骤 1 中获得的解决方案的最佳组合。必须从所考虑的每个类别中选择一个解决方案。

    对于单个类别,解决 DP 从具有 W 背包大小的 N 个项目列表中选择 s 个项目似乎需要 O(s NW k^2) 时间。在步骤 2 中合并来自 c 类别的解决方案似乎需要 O(c W^2 k^2),但它可以简化为 O(c W k log(W k)) 如果使用平衡树进行合并。

    【讨论】:

      【解决方案2】:

      一种可能足够的启发式方法是使用具有相当大种群的进化算法(对于背包类型问题往往相当容易编程),让它进化一段时间,然后只取前 10 个解决方案.

      获得可证明的前 10 名解决方案当然会更难(字面意思是——这显然是 NP 难的)。一种方法是将其解决到最优,记录解决方案,添加约束以排除该解决方案,然后解决。重复此操作,直到您获得前 10 个解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-17
        • 2013-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-12
        相关资源
        最近更新 更多