我需要一种算法,它可以在箱子中给出(空间)最佳的块排列。一种方法是将更大的块放在第一位。但请看这个算法在这个例子中是如何失败的:
Chunks Bins
-----------------------------
AAA BBB CC DD ( ) ( )
Algorithm Result
-----------------------------
biggest first (AAABBB ) (CC )
optimal (AAACCDD) (BBB)
“Biggest first”不适合DD。也许建立一个像这样的表是有帮助的:
Size 1: ---
Size 2: CC, DD
Size 3: AAA, BBB
Size 4: CCDD
Size 5: AAACC, AAADD, BBBCC, BBBDD
Size 6: AAABBB
Size 7: AAACCDD, BBBCCDD
Size 8: AAABBBCC, AAABBBDD
Size 10: AAABBBCCDD
答案 0 :(得分:3)
这基本上是bin-packing问题的变体。已知这个问题是NP难的,因此不要指望为复杂情况(即有许多对象和容器)找到有效的最优算法。
但是,如果您的对象/容器数量相对较少,您可能会很好地使用depth-first search详尽地搜索所有可能的组合。
这很容易实现:只需取第一个对象,然后递归地重新运行算法,第一个对象依次放在每个二进制位中(即从可用的二进制空间中减去对象的大小)。最后,您只需要跟踪到目前为止找到的最佳“解决方案”,并在尝试完所有组合后将其作为最终答案返回。
您也可以通过以下方式使此算法算法运行得更快:
根据问题规模的评论进行了更新
鉴于您看起来要处理的内容非常多,您可能需要尝试以下方法:
答案 1 :(得分:2)
Mikera是对的:这个多Knapsack个问题(bin包装问题的一个变体)是NP hard。
以下是您的几个选项(从我对类似问题的回答中复制):
蛮力,或者更好,分支和束缚。不会扩展(根本没有!),但会找到最佳解决方案(可能不会在我们有生之年)。
确定性算法:对最大尺寸的块进行排序,逐个浏览该列表并为其指定最佳剩余点。这将很快完成,但解决方案可能远非最佳(或可行)。 Here's a nice picture showing an example what can go wrong.但是如果你想保持简单,就可以了。
元启发式,从确定性算法的结果开始。这将在合理的时间内给你一个非常好的结果,比人类想出的更好。根据您提供的时间和问题的难度,它可能是也可能不是最佳解决方案。那里有几个库,例如Drools Planner(开源java)。
答案 2 :(得分:1)
此问题的一般最佳算法尚不存在(请参阅bin packing problem)。您可以在维基百科上找到一些不同的方法和/或谷歌搜索“垃圾箱包装问题”,也许“背包问题”也会提供一些帮助。
答案 3 :(得分:0)
Donald Knuth的Dancing Links算法很快就能找到“确切覆盖”问题的解决方案。