乍一看,这似乎是多背包问题(http://www.or.deis.unibo.it/knapsack.html,第 6.6 章“多背包问题 - 近似算法”),但实际上它是一个调度问题因为它涉及到时间因素。不用说,解决这些类型的问题很复杂。一种方法是将它们建模为网络流并使用像 GOBLIN 这样的网络流库。
在您的情况下,请注意您实际上并不想以最佳方式填充存储,因为如果您这样做,则更有可能存储较小的数据包,因为它会导致更紧密的包装。这很糟糕,因为如果将大包裹留在机器上,那么您未来的包装将变得越来越糟糕。您要做的是优先存储较大的包裹,即使这意味着在商店中留出更多额外空间,因为这样您将来会获得更大的灵活性。
下面是如何用一个简单的算法来解决这个问题:
(1) 确定 bin 大小并对其进行排序。例如,如果您有 3 个存储空间分别为 20 GB、45 GB 和 70 GB,那么您的目标是 { 20, 45, 70 }。
(2) 按大小对所有数据包进行排序。例如,您可能有数据包:{ 2, 2, 4, 6, 7, 7, 8, 11, 13, 14, 17, 23, 29, 37 }。
(3) 如果任何包裹的总和 > 95% 的商店,则将它们放入该商店并转到步骤 (1)。不是这里的情况。
(4) 生成两个包的所有排列。
(5) 如果任何排列的总和 > 95% 的存储,则将它们放入该存储中。如果有领带,则更喜欢与更大包装的组合。在我的示例中,有两个这样的对 { 37, 8 } = 45 和 { 17, 2 } = 19。(请注意,使用 { 17, 2 } 胜过使用 { 13, 7 })。如果您找到一个或多个匹配项,请返回步骤 (1)。
好的,现在我们只剩下一家商店:70 和以下包裹:{ 2, 4, 6, 7, 7, 11, 13, 14, 23, 29 }。
(6) 将烫发数加 1 并转到步骤 5。例如,在我们的例子中,我们发现没有 3 烫发加到 70 的 95% 以上,但 4 烫发 { 29, 23, 14, 4 } = 70。最后,我们留下了机器上留下的包 { 2, 6, 7, 7, 11, 13 }。请注意,这些大多是较小的软件包。
请注意,perms 以相反的词法顺序进行测试(最大的在前)。例如,如果你有“abcde”,其中 e 是最大的,那么 3-perms 的逆词法顺序是:
cde
bde
ade
bce
ace
等
该算法非常简单,可以根据您的情况产生良好的结果。