从中心开始用较小的矩形填充大矩形的算法

时间:2013-02-26 01:40:01

标签: algorithm geometry greedy knapsack-problem

我有各种尺寸的矩形,我试图将它们装入从中心开始的更大的矩形。下面你会看到我创建的动画,用于直观地描述需要发生的事情。

我一直在努力想出一种模拟这种行为的方法。有什么与此类似的存在吗?我只需指出正确的方向。

enter image description here

以下是一个非常粗略的解释:

初始化

  • n矩形
  • 开头
  • 按密度排序(它们实际上是三维立方体鸟瞰图
  • 将第一个矩形放在中心

剩余的矩形(尽可能多地适合) 尝试将中心的最高密度分组并向外移动

Dimensions = { width: 400, height: 300 }
Boundries = {
  WEST = 0,
  EAST = Dimensions.width,
  NORTH = 0,
  SOUTH = Dimensions.height
}

// each rectangle has width, height, and other information
rectArr = Array of {width:60, height:40}

root = { x:EAST/2, y:SOUTH/2 }

foreach rect in rectArr {
  // I will always traverse from the root and try to go left and right. If I cannot, I move up and try the same thing. I then move down. The problem is if there are 5 or more rows. I will be starting from the root and going up, then down, then up-up, then down. It's like I have two parallel trees.

  // Try to branch left or right
  if rect.width <= (Boundries.EAST - ('rightmost rectangle'.x + 'rightmost rectangle'.width/2)) branch-right
  if rect.width <= (('leftmost rectangle'.x + 'leftmost rectangle'.width/2) - Boundries.WEST) branch-left
  // Try to branch up or down
  if rect.height <= ((root.x + root.height/2) - Boundries.NORTH) branch-up
  if rect.height <= (Boundries.SOUTH - (root.x + root.height/2)) branch-down
}

1 个答案:

答案 0 :(得分:1)

编辑:开始写这个太早了。此解决方案仅适用于填充较大的矩形,尽可能多的小矩形,假设较小矩形的位置是静态的。

听起来像动态编程解决方案在这里效果最好;如果你还没有学过算法,我建议你研究贪婪算法的定义,动态规划算法的定义,各种例子,以及你使用的算法而不是其他算法。

这个问题与加权调度问题非常相似,但是在2个维度上。在加权调度中,我们给出一个区间和一组子区间,并要求确定其总和权重最大且范围不重叠的子区间集:

|--------------------------|
|{--a--}-------------------|
|----{------b-------}------|
|--------{----c----}-------|
|--------------------{-d-}-|

如果我们将其扩展为二维,则较大的区间将是边界矩形的x / y长度,子区间将是较小矩形的x / y长度,子区间的权重是较小的矩形。

在贪婪的算法中,我们会尝试用尽可能多的最大子矩形填充边界矩形,然后尝试适应第二大的第三大,然后第三大,依此类推你的矩形适合。它的问题在于,当使用1个最大的子矩形时,最终可能会填充较少的边界矩形,而不是使用第二个最大的4个矩形(考虑到我们有一个边长为6的边界正方形的情况,最大的子方块的边长为5,第二大的子方块的边长为3)。看起来您的初始解决方案可能遇到同样的问题。

动态编程解决方案将较大的问题分解为重叠的子问题,然后根据子问题的结果构建解决方案。在矩形的情况下,你想为你的集合中的每个矩形提出相同的问题:当我包含它时或者当我不在我的解决方案中包含它时,结果会更好。根据此问题的答案,您可以将矩形添加到解决方案集中并删除与其重叠的所有其他矩形,或者只删除该矩形并继续。我建议使用以下psudeo代码:

compute_opt ( set of rectangles ){
  if(set.size == 0)
    return 0
  return max (area of selected rectangle i +  
              compute_opt( rectangles that don't overlap with i) ,
              compute_opt( rectangles without rectangle i included) )
}

我在记忆方面有点生疏,所以我不会在这里讨论它。但有关加权调度的详细信息,请参阅this princeton lecture on dynamic programming。考虑到区间问题的具体情况,您应该能够找出矩形问题的具体细节。