包装矩形以紧凑地表示

时间:2020-03-06 14:55:24  来源:igfitidea点击:

我正在寻找指向以下问题的解决方案的指针:我有一组矩形,这些矩形的高度已知,并且x位置也是如此,我想将它们打包为更紧凑的形式。我想要一个小的绘图(所有矩形的宽度都相同,但实际生活中宽度可能会有所不同),而不是。

-r1-
  -r2--
     -r3--
       -r4-
        -r5--

就像是。

-r1-  -r3-- 
  -r2-- -r4-
         -r5--

所有提示将不胜感激。我不一定要寻找"最佳"解决方案。

解决方案

像这样吗?

  • 按x位置对矩形集合进行排序
  • 编写一种方法来检查在x轴的特定间隔上存在哪些矩形
Collection<Rectangle> overlaps (int startx, int endx, Collection<Rectangle> rects){
...
}
  • 遍历矩形的集合
Collection<Rectangle> toDraw;
Collection<Rectangle> drawn;
foreach (Rectangle r in toDraw){
Collection<Rectangle> overlapping = overlaps (r.x, r.x+r.width, drawn);
int y = 0;
foreach(Rectangle overlapRect in overlapping){
y += overlapRect.height;
}
drawRectangle(y, Rectangle);
drawn.add(r);
}

问题是一个简单的变体,但是我们可能会获得一些有关为"装箱"问题开发的启发式方法的提示。关于此的文章很多,但是此页是一个良好的开端。

将类似俄罗斯方块的游戏放入网站。根据参数生成掉落的块和游戏区域的大小。根据设计的紧凑性(更少的自由空间=更多的积分)向玩家奖励积分。让网站访问者为我们执行工作。

矩形是否都具有相同的高度?如果它们是问题,而问题仅在于将每个矩形放入哪一行,那么问题归结为对所有形式为"矩形X不能与以下行在同一行"的矩形对(X,Y)的一系列约束。矩形Y"是指矩形X在x方向上与矩形Y重叠。

为此,采用"贪婪"算法对矩形进行从左到右的排序,然后将每个矩形依次分配给其适合的编号最小的行。因为矩形是从左到右处理的,所以只需要担心当前矩形的左边缘是否会与其他任何矩形重叠,这在某种程度上简化了重叠检测算法。

我无法证明这是最佳解决方案,但另一方面也无法想到任何反例。任何人?

Topcoder进行了竞争,以解决此问题的3D版本。获胜者在这里讨论了他的方法,这可能对我们来说很有趣。

我以前曾处理过这样的问题。最直观的图片可能是大矩形在底部,小矩形在顶部,有点像将它们全部放入一个容器中并摇晃它,使较重的矩形掉到底部。因此,要做到这一点,首先要按面积(或者宽度)递减的顺序对数组进行排序-我们将首先处理较大的项目并建立起地面的图片。

现在的问题是,如果我正确理解的话,就是将y坐标分配给一组给出x坐标的矩形。

遍历矩形数组。对于每个矩形,将矩形的y坐标初始化为0。然后通过增加该矩形的y坐标进行循环,直到它不与任何先前放置的矩形相交为止(我们需要跟踪先前放置过的矩形)。承诺刚找到的y坐标,然后继续处理下一个矩形。