如何在2D数组上随机生成布局?

时间:2012-06-29 16:35:31

标签: algorithm layout knapsack-problem

我有一个预定大小的2D数组和一个编号矩形列表,以适应该空间。这些矩形中的每一个都具有已知的固定高度和宽度。保证2D阵列足够大以适应所有矩形。

我需要将这些矩形中的每一个随机放入数组中,以便不重叠并放置所有矩形。它们可以放置在任何方向。想象一下,将您的船只放置在战舰游戏中,只需要更多不同的船型和更大的格栅。

完成的数组应如下所示:(0表示空格,非零数字表示矩形编号)

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0 4 4 4 0
0 1 1 0 2 2 2 2 2 0 0 0 4 4 4 0
0 1 1 0 2 2 2 2 2 0 0 0 0 0 0 0
0 0 0 0 2 2 2 2 2 0 0 0 0 0 0 0
0 0 0 0 2 2 2 2 2 0 5 5 0 0 0 0
0 3 3 3 3 3 0 0 0 0 5 5 0 0 0 0
0 3 3 3 3 3 0 7 7 7 5 5 6 6 0 0
0 0 0 0 0 0 0 7 7 7 5 5 6 6 0 0

我考虑过的一种方法是针对每个矩形,选择随机放置和方向,尝试将其放置在矩阵中。如果检测到与先前放置的块发生碰撞,请再试一次。这可能是最简单的实现,但它似乎不是非常有效,并且它不会以明确确定的方式终止(列表末尾附近的矩形可能会与之前生成的块保持冲突很长一段时间)。 / p>

是否有更好的方法可以解决这个问题,以便放置后面的矩形?

4 个答案:

答案 0 :(得分:1)

遵循方法:

  • 找出您的最小尺寸。计算小于此的大小 尺寸,但在您的盒子中适合多次。 例如:最小尺寸为7厘米/英寸,盒子为120厘米/英寸。选择120/20 = 6厘米/英寸。我希望你的问题足够小,因为你将存储所有可能的问题 列表中的坐标。在这种情况下,我们有20x20 = 400坐标。

  • 为了保证无法阻挡整个区域,请选择矩阵,其中最小尺寸(x,y)大于或等于矩形最大尺寸的 double 四倍(例如,矩形的最大长度= 8,x和y必须至少为32)并且矩阵的整个区域至少有一个面积是所有插入元素的两倍。

  • 选择放置:使用随机数生成器随机选择坐标。将矩形放在给定坐标上,并选择随机方向。尝试将矩形设置到框中,如果它首先不适合,则旋转它。如果仍然不适合,请尝试下一个坐标。

  • 如果它最终适合,请从列表中删除与矩形重叠的所有坐标。所以你只选择其他矩形的有效坐标。

  • 随机化:不要使用线性同余生成器(不幸的是,它适用于大多数编程语言的任务标准)。它们具有糟糕的多维特征。使用安全随机,硬件生成器或已知的好的,例如梅森旋转算法。

答案 1 :(得分:1)

IMO问题降级为问题 - “我们是否有足够的空间来适应下一个矩形以及如何以有效的方式找到这个地方?” 所以:

  1. 初始条件 - 我们在“可用矩形列表”中有1个矩形可用(初始矩阵),基本上我们只需存储自由矩形的高度和重量以及初始矩阵上的左上角位置
  2. 选择随机矩形添加=“toAdd”,将其从“list to add rectangles”
  3. 中删除
  4. 随机选择等于或大于“toAdd”=“available”的免费可用矩形,将其从“可用矩形列表”中删除,如果没有可用的矩形则转到步骤2
  5. 在“可用”上选择随机位置,在其上添加“toAdd”矩形
  6. 剪切“可用”矩形以减去“toAdd”。这里可以应用不同的切割策略,但最后您可以获得最多4个新的可用矩形
  7. 将新的可用矩形添加到“可用矩形列表”
  8. 转到第2步
  9. 算法不是最优的,因为在理想世界中,我们应该在步骤6中连接2个可用的邻居。

答案 2 :(得分:0)

这个问题与roguelike Dungeon地图生成完全一样。对于不同的外观,有很多方法。

我建议从这里采用BSP树方法(步骤很简单): http://www.futuregadgetlab.com/proceduraldungeon/

答案 3 :(得分:0)

您可以简化计算并从旋转的某些限制开始,然后您可以使用kd树。一个很好的例子是jquery masonry插件或jquery treemap算法。我的想法是在某处放置一个矩形,将x点分开到左边,y指向树的右边。