Algorithm 有界背包算法返回的几种组合

Algorithm 有界背包算法返回的几种组合,algorithm,optimization,knapsack-problem,Algorithm,Optimization,Knapsack Problem,这个任务类似于有界背包问题BKP。 我们有大约300种不同的膳食,参数包括:ID、价格、重要性/等级、类别 例如: id price importance type ----------------------------- 1 100 78 butter 2 50 89 milk 3 70 66 milk 4 66 50 butter 我们想选择前十名的最佳产品组合,但

这个任务类似于有界背包问题BKP。 我们有大约300种不同的膳食,参数包括:ID、价格、重要性/等级、类别

例如:

id  price  importance  type
-----------------------------
1   100     78         butter
2   50      89         milk
3   70      66         milk
4   66      50         butter
我们想选择前十名的最佳产品组合,但根据具体配置,我们只需要3种黄油、2种面包和2种牛奶。前10名组合必须具有最高的重要性总和。 我们还必须考虑到现有的预算

这和背包问题有点不同,因为这里我们想要的是前十名的结果,而不仅仅是最好的。
同一组的每顿饭/产品(如黄油)的价格和重要性/等级都不同。

一种启发式方法可能足够了,就是使用一种进化算法,这种算法往往非常容易编程,适用于人口相当多的背包类问题,让它进化一段时间,然后只取前10个解决方案


获得可证明的前10个解决方案当然会更难——这显然是NP难的。一种方法是将其求解为最优,记录解决方案,添加约束以排除该解决方案,然后解决。重复这样做,直到你得到前10个解决方案。

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

总体DP 在动态规划算法中,对于每个状态,我们只存储一个最佳部分解。通常我们不存储部分解:只存储其成本和一些简单的回溯信息,以便以后重建。由于最优子结构性质,我们不存储状态的其他解:任何代价较低的部分解都具有比最佳部分解的相同连续性更差的连续性

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

前向式DP中的转换将照常进行。当你考虑某个状态时,你应该迭代它的k个最好的部分解决方案,并尝试以各种可能的方式继续它们中的每一个,例如,不接受新的项目。对于每个延续,查看其状态。将延续插入到最佳部分解决方案的排序列表中。如果结果是k+1部分解,则去掉最差的一个

最肯定的是,您不希望将部分解决方案本身存储在DP中。相反,只存储每个部分解决方案的总成本和回溯信息。回溯信息应足以明确地确定DP中以前的部分解决方案。通过这种方式,您可以找到最佳的k解决方案。与只找到一个最佳解决方案相比,具有k个最佳解决方案的DP解决方案占用的内存要多出Ok倍,背包占用的时间要多出Ok^2倍或Ok log k

特殊问题 在我看来,您应该使用两级算法来解决您的问题:

在每个项目类别中运行有界背包问题的DP。因此,您将获得该类别的k个项目的最佳组合,每个总成本和项目数量有限。 找到步骤1中获得的解决方案的最佳组合。必须从所考虑的每个类别中选择一个解决方案。 对于单个类别,从背包大小为W的N个项目列表中选择s个项目的DP求解似乎需要花费Os N W k^2时间。在步骤2中合并来自c类别的解决方案似乎需要Oc W^2 k^2,但如果使用平衡树进行合并,则可以将其减少到Oc W k logW k