包装矩形算法

Posted

技术标签:

【中文标题】包装矩形算法【英文标题】:Packing Rectangles Algorithm 【发布时间】:2011-11-26 16:58:12 【问题描述】:

我需要解决以下问题: 我有多个大小的矩形:宽度高度,宽度/2高度/2,宽度/4高度/4,宽度/8高度/8 ...等

我需要将这些矩形打包在一个大小为 x*width y*height 的大矩形中,这样没有矩形重叠,矩形随机分布在包装中,任何矩形至少应该接触另一个矩形。我尝试了一个相当基本的贪心算法,但它失败了。

你能给我一些解决问题的建议吗?

谢谢!

编辑:每种尺寸可以有多个矩形

这不是家庭作业。我正在尝试创建与ted.com 上的效果类似的效果

随机我的意思是可能存在多个满足约束的矩形包装。该算法不应在每次运行时产生相同的包装。

【问题讨论】:

这是作业吗?如果是这样,请将其标记为作业。 您需要提供更多细节。您是否有每个矩形尺寸中的一个(例如 1 个单元边,1 个 0.5 个单元边等...),或者您有任意数量的矩形大小供您使用?另外,随机定义.. 你可以窃取 Window 8 的“地铁”代码 :-) 听起来很像我之前回答的一个问题:***.com/questions/7439560/… 【参考方案1】:

这听起来像rectangle packing problem。那里有一个指向algorithm 的链接。该代码尽可能紧密地打包矩形。您说您希望矩形分布随机,我猜这意味着并非所有大小相同的矩形都彼此相邻,并且所有矩形都展开以填充大矩形。也许上面链接中的代码是获得一些想法的一个很好的起点。

【讨论】:

【参考方案2】:

您可以使用空间索引或四叉树来细分二维平面。这个想法是将二维问题简化为一维问题。获得空间索引(或空间填充曲线)并且可以将 2d 离散化为 1d 后,您可以使用 1d 来搜索相似性或从低到高或相反的排序,例如按长度。如果您收到此订单,则可以将索引计算回二维表示,并以最有效的方式将它们打包到您的容器中。制作空间索引的方法有很多。一些最好但很难制作的是希尔伯特曲线。另一种是 z 曲线或 morton 曲线。它与 zizag-curve 不同,因为它将平面细分为 4 个正方形(不是矩形)。

编辑:这是一个 Jquery 插件的链接:http://www.fbtools.com/jquery/treemap/ 这里有世界人口:http://www.fbtools.com/jquery/treemap/population.html

编辑:http://people.csail.mit.edu/konak/papers/socg_2008-circular_partitions_with_applications_to_visualization_and_embeddings.html

编辑:http://lip.sourceforge.net/ctreemap.html

【讨论】:

感谢您的链接。很有帮助。【参考方案3】:

在每一步中,您都将新矩形的表面除以 4。

SUM(1/4n for n in [0,inf]) = 4/3**

所以你能做的最好的就是把你的矩形放在一个矩形的表面上 4/3(高*宽)

(这是一个下限)

@mloskot 算法给出了一个可能的解决方案,它将位于表面 3/2*(height*width) 的矩形中:这是一个插图:

我看不出你能做得更好。

【讨论】:

【参考方案4】:

假设每种尺寸只有一个矩形,您可以尝试复制纸张尺寸的排列。将矩形按大小从大到小排序,然后

    选取第一个矩形并将其放置在目标平面的角上。 取下一个矩形(断言它小于前一个矩形) 旋转大约 90 度 放置 它的较短尺寸与最后一个较大邻居的较长尺寸相邻 其长边与目标平面的边缘或同一相邻平面的边缘相邻 尺寸 重复 2 - 4

我意识到描述可能不清楚,所以这里是展示解决方案的图片 - 它应该有助于掌握它:

【讨论】:

在你的例子中,你在每一步将表面除以 2 (A1,A2 ...),但在所需的算法中它是 4 ...所以这里出了点问题 A 系列纸张这样工作是因为边长比为 1:sqrt(2),其他纸张尺寸不这样包装。 (我经常想知道为什么 A 系列在国际上并不常见……) @Ricky Bobby 好点,我在阅读问题时错过了这些细节。 @spraff 我并不是要以 1:1 的比例给出与所讨论的问题相对应的示例。我宁愿给出一些想法。【参考方案5】:

这很像MIP-mapping

【讨论】:

每种尺寸可以有多个矩形。

以上是关于包装矩形算法的主要内容,如果未能解决你的问题,请参考以下文章

Javascript中矩形的合理包装

妹子-girls

Ray-AABB交叉检测算法

是否有按物品尺寸包装箱子的背包算法?

UVA 10652 Board Wrapping(二维凸包)

如何使用 iphone sdk 中的 corePlot 库将 CPTAxisLabel 包装成两行?