背包问题-解谜的组合优化



我的问题如下图所示https://i.stack.imgur.com/n6mZt.png

我有一个有限的(但相当大的)数量的这样的碎片,需要以一种方式堆叠,使剩余的区域是尽可能小的。工件锁定在水平轴(时间)上,高度固定。它们只能堆叠。

剩余区域由堆栈的最大值定义,该最大值取决于已选择的棋子。示例图像中的最佳组合是[1 1 0]。(琐细的[0 0 0]情况将不被其他约束所允许)

我唯一的变量是二进制(Yes或No)。目标比我所描述的要复杂一些,但我现在最大的问题是如何表述表达式

Max{Stacked_Pieces} - Stacked_Pieces_Profile

中的目标函数。这个表达式的结果当然是一个向量(时间序列),但它将通过其他操作进一步简化为一个数字。

基本上我的问题是如何写

Max{A} - A, where A = 1xN vector

以一种与线性(甚至二次)目标相容的方式。还是我在处理一个非线性问题?

编辑:这个问题就像一个背包问题,主要的区别是没有背包要填。也就是说,背包的大小根据所选择的部件而变化,并且总是等于堆叠轮廓的顶部

谢谢大家!

根据我的理解,你基本上可以把它作为一个普通的背包问题在多次迭代中解决,找到最小值。

现在,找到背包的高度是一个问题,这意味着你需要多次迭代。因为你需要解决背包问题,看看某个高度是否可行,所以你需要多次迭代。

请注意,您确实知道高度的上限和下限。我不确定旋转是否适用,但您可以在这里填写空白:

  • Min = max(最小件的最大高度,总尺寸/宽度)
  • Max = sum(所有块的高度).

基本上解决它意味着找到适合所有部分的最小高度[Min <= x <= Max]。最简单的方法是使用'for'循环,但你可以做得更好:

  1. 尝试min, max, half
  2. if half fits -> max = half;(1)
  3. 如果一半不合适-> min =一半;(1)

对于求解背包问题,对于每次迭代,我会检查是否所有的片段仍然可以被拟合。如果可以的话,使用位掩码和and/OR/XOR操作来加快速度。

基本上你可以这样做:

  • 抓取位'x'。填充下一个块
  • 检查这是否导致一个可能的解决方案
  • 查找下一个可以填充的位

请注意,您可能希望在c++中使用内在函数来加快此速度。现代CPU在这方面做得很好。

关于代码:我曾经编写过一些代码来解决混乱的立方体;我敢肯定,如果你谷歌一下,你会找到一些快速的解决方案。

祝你好运!

最新更新