我正在尝试解决一个奇怪的垃圾箱包装问题。原始问题的链接在这里 (对不起,很长的问题,感谢您的耐心等待)
我正在重复以下问题:我正在尝试编写一个为分隔面板生成绘图的应用程序。
我有 N 个隔间(2D 矩形)(N <= 40)。每个隔间都有一个相关的最小高度 (minHeight[i]) 和最小宽度 (minWidth[i])。面板本身也有一个 MAXIMUM_HEIGHT 约束。
这 N 个隔间必须在一个列式网格中一个在另一个之上堆叠,以便每个隔间都满足上述约束。
此外,每列的宽度由该列中每个隔间的 minWidths 的最大值决定。
此外,每列的高度应该相同。这决定了面板的高度
我们可以在任何列的剩余空间中添加备用隔间,或者我们可以将任何隔间的高度/宽度增加到指定的最小值之外。但是,我们不能旋转任何隔间。
OBJECTIVE: TO MINIMIZE TOTAL PANEL WIDTH.
面板的 MAXIMUM_HEIGHT = 2100mm, minwidth range (350mm to 800mm), minheight range (225mm to 2100mm)
根据选择的答案,我制定了整数线性规划。但是,考虑到问题的组合性质,求解器似乎“挂”在 N > 20 上。
我现在正在尝试实施一个变通解决方案。
隔间按 minWidths 的降序排列。如果 minWidths 相等,则按 minHeights 的降序对它们进行排序。然后我使用First Fit 递减启发式
来解决它。这给了我总面板宽度的上限,以及当前列宽的列表。
现在我尝试使面板宽度更小,并尝试将我的馈线安装在那个更小尺寸的面板中。(我能够以有效的方式检查馈线是否适合给定的列宽列表)
面板宽度可以通过以下方式缩小:
1. 取任意一列,将其替换为下一个较低 minWidth 进纸器的一列。如果该列已经是最低的 minWidth,则尝试将其删除并检查。
2. 取任意一列,将其替换为具有更高 minWidth 进纸器的列,然后移除另一列。
3.还有什么办法,不知道有没有人指出会很高兴。
我已经正确实施了第一种方式。以下是代码。但是,我无法正确地将其他方式放入代码中。
for ( int i = 0; i < columnVector.size(); i++ ) {
QVector< Notepad::MyColumns > newVec( columnVector );
if ( newVec[i].quantity > 0
&& ( i > 0 || newVec[i].quantity > 1 ) ) {
newVec[i].quantity--;
if ( i < columnVector.size() - 1 )
newVec[i+1].quantity++;
float fitResult = tryToFit( newVec, feederVector );
myPanelWidth = fitResult ? fitResult : myPanelWidth;
if ( fitResult ) { // if feeders fit, then start the iteration again.
columnVector = newVec;
i = -1;
}
}
}
任何帮助将不胜感激。
谢谢