背包问题的变体


11

如果现在必须将背包中的项目数限制为常数那么在动态编程情况下如何解决背包问题?这是相同的问题(最大重量,每个商品的值均为,重量),但您只能将项添加到背包,显然需要优化背包的值。pWvwp

我们需要三维还是没有三维我们可以找到其他方法。我试图简单地在单元格中的背包中添加项目数,并在最后加上最大值,即项目数<=但这不是最佳解决方案。p


这是一个不错的家庭作业。你尝试了什么?您喜欢进行动态编程吗?(如果没有,也许尝试一些练习来练习。)您是否研究了背包问题的标准动态编程算法?寻找一种修改该标准方法的方法。您的主要任务是设计子问题集应该是什么。在标准方法中,子问题的特征在于一个参数(对项目权重的限制)。您可能会考虑使用两个参数(因此会有更多的子问题)。尝试各种可能性-您会得到什么?
DW

Answers:


9

非常好的问题!

您是对的两次:

  1. 在背包中传播物品数量不会导致最佳解决方案。
  2. 一种解决方案包括添加第三维。这很简单,但是在这样做时必须考虑一些事实。但是请注意,这不是唯一的选择

在下面,我假设您熟悉基于动态编程的解决方案。特别是,我不会讨论如何向后遍历表以确定解决方案

让我们首先关注典型情况:项目数量不受限制。在这种情况下,您只需要构建一个表,其中当背包的总容量等于并且仅考虑前项时,包含最佳值。从这里:牛逼ĴĴTTi,jij

Ti,j=max{Ti,j1,Tiwj,j1+vj}

其中和代表第个项目的权重和值。如果是背包的总容量,并且总共有物品,则最佳解由。已知该算法在伪多项式时间内运行,其优点之一是它仅考虑适合最大容量的那些组合。wjvjjCNTC,N

但是,在添加约束时,这还不够:最大项数。原因是先前的重复公式未考虑项目的不同组合:p

  1. 首先,如果则使得该个项目加入到背包,尽管考虑项目的最大数量的 ---这样你可能会违反你的约束。好吧,您可能很想在此处应用前面的公式来跟踪每个步骤中插入的项目数,并且如果当前背包中的项目数超过,则不要添加其他项,但是,Ti,j1<(Tiwj,j1+vj)Ti,j=(Tiwj,j1+vj)jpp
  2. 其次,如果则以便不添加该项目,但如果最佳解决方案已经包含要插入背包的最大物品数量,那么这可能是一个大错误。原因是我们没有适当地进行比较:一方面,要保留由前一个选择的项组成的最优解;另一方面,要插入第个项目,并另外考虑前一个具有个项目的最佳子集。Ti,j1>(Tiwj,j1+vj)Ti,j=Ti,j1Ti,j1p(j1)j(p1)(j1)

因此第一个解决方案包括添加第三维。对于您的情况,让是背包的容量为时的最佳解决方案,仅考虑前项目,并且不允许在背包中放入个以上的项目。现在,Ti,j,kijk

  • 如果要计算的的项目数严格小于或等于可插入的项目数(),则照常进行,但使用相同的值:Ti,j,kjkkTi,j,k=max{Ti,j1,k,Tiwj,j1,k+vj}
  • 现在,如果您必须为严格大于可插入的项目数()的项目数计算,则:Ti,j,kj>kTi,j,k=max{Ti,j1,k,Tiwj,j1,k1+vj}

第一个表达应该清楚。由于表格第层是第二项,因此按上述要求跟踪了第项中项的最佳组合。(k1)T(k1)(j1)

该算法的有效实现不需要为所有计算。请注意,前面的递归关系将层与关联,因此可以在两个连续层之间进行交替(例如,如果您对的最优解感兴趣,则只需使用两个连续层即可:0和1、1和2、2和3、3和4,您就完成了)。换句话说,该算法占用了基于动态编程的传统方法所需内存的两倍,因此仍可以在伪多项式时间内运行。Ti,j,kkk(k1)k=4

但是请注意,这不是唯一的解决方案!还有另一个您可能会发现更优雅。在前面的公式中,我们检索了由第一个中不超过项构成的最优解,即。但是,应该清楚的是仅使用原始表,它就等于!即,也可以通过考虑1个,2个,3个...的最优解来检索不超过项的最优解。(k1)(j1)Ti,j1,k1maxp=0,j1{Ti,p}k(j1)项...为了使这种公式化起作用,您还应该跟踪每个部分解决方案中考虑的项数,以便每个像元需要两个整数。该存储器占用导致与上述算法完全相同的存储器需求(使用层形式的三维)k

希望这可以帮助,


非常好的答复,谢谢。通过实现第3个维度,我已经能够在您发布之前解决它。
user11536 2013年

好的,非常感谢您结束问题,并很高兴听到您喜欢这个答复。为了阐明我的想法,我还尝试了使用Python实现此算法。如果您有兴趣查看它,请告诉我,我会很乐意将其发布(或发送给您)。干杯,
卡洛斯·利纳雷斯·洛佩斯

多维背包问题的惊人解释。但是,我想知道是否有类似的情况,但是元素恰好有k个,所以我们只会查看第3维的第k列返回的值。如果没有值,则返回0。我不确定自己是否正确,因为我还是动态编程的新手。
SteveIrwin 2014年

@CarlosLinaresLópez很好的答案。您也可以分享python脚本吗?也许将其发布在gist.github.com上?
2015年

1
嗨@Carlos!我在此处发布了一个使用您的替代公式的后续问题:在0/1背包中找到n个最佳项目。无论如何,我希望您过得愉快!
萨德·马里克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.