我正在寻找一个概念来随机分布正方形的圆圈,这样它们就不会重叠。所有圆圈的大小相同。圆圈覆盖的区域可以很高,直到理论最大值为ca. 90%的正方形(其中它们是完全有序的)。应该放置大约200个圆圈,我想准确指定圆圈数。 (需要分布作为FE分析的模型生成的输入,顺便说一句)
使用直接将算法顺序放置在空闲点上的算法,不可能覆盖超过54%,这并不奇怪,因为在某些时候没有剩余空间。因此,以前的SO线程并没有真正解决我的问题(越来越近:Placing random circles without overlap (and without using brute force)?)
随着一组有序圆圈的圆圈的简单随机位移,分布似乎“不够随机”。
到目前为止,我提出的所有概念,无论是复杂还是蛮力风格。我最喜欢的方法是确定下一个圆圈可以放置的所有可能位置,以便剩余空间足够大以放置剩余的圆圈。然后随机选择其中一个位置,依此类推。但是:确定剩余空间的“容量”并不容易,而且在数值上非常复杂。我真的不知道该怎么做,以及是否可以通过合理的数值努力来完成。
第二个想法是一个billard模拟:将所有圆圈放在任何模式中并模拟一个大池子。相当蛮力和数字也非常昂贵。我也有点害怕去世问题。
数字3更具数学性,并且基于为每个圆圈定义具有随机“强度”的潜在场,因此在圆之间存在某种引力并计算平衡状态。为此开发数学模型并非易事,而且非常重要......
所以 - 最后 - 问题:你有什么建议解决这个问题尽可能轻量级?你知道我应该考虑解决这个问题的算法吗?你对我的想法有何看法?
提前全部谢谢!我很高兴看到你的答案。
答案 0 :(得分:2)
2个想法:
不要将方块视为一个封闭的盒子,而是将顶部移开,让圆圈在重力作用下落入打开的盒子中。通过在圆圈落下之前改变圆圈的位置,您可以创建随机性。这可能与你的billards例子相同或类似。
或
使用Quadtrees划分框中的空格并使用碰撞检测随机检查重叠,在这种情况下,可能只需要将圆的中心设置为另一个中心的半径大于半径的两倍并且盒子的墙壁大于半径。通过使用四叉树,这将使算法更有效。
答案 1 :(得分:2)
首先使用basic algorithm绘制尽可能多的不会发生碰撞的圆圈。当它完成(并且它不能达到200个圆圈)时,开始推入圆圈。我的意思是用物理引擎将它们推入物理引擎: http://www.sgtconker.com/2010/09/article-xna-farseer-platform-physics-tutorial/(不使用重力)。
答案 2 :(得分:1)
也许你可以找到一个几何属性,它只适用于200个包装,而不适用于199个或更少的包装。然后在保留属性的同时逐步构建包装。
例如,您可以检查几个可用的200个包装并测量所有圆心之间的最大距离 - m 。然后逐步构造一个包装,保留 m 。
我不知道这样的构造多久会成功,但你可以添加更多不变的属性,因为你希望增加成功的机会。
答案 3 :(得分:1)
如果你有时会有大量的圆圈使你接近或最大包装,那么最好的解决办法就是从你的圆圈开始最大限度地包装在某个角落(我猜是六边形包装)和然后做一个物理模拟,你添加一些“温度”,即你随机踢一些圆圈让它们碰撞一段有限的时间。
我担心,如果你有这么多圈子,任何有效的解决方案将接近最大包装,你可能永远无法适应所有圈子。
答案 4 :(得分:1)
假设你想要n = 200个圆圈。我的建议是选择一个比n大得多的数字,比如m = 300,并在广场内的随机位置产生那么多点。这组m点是圆心的候选集。现在生成一个包含m个顶点的图形,每个点对应一个顶点,其中两个顶点通过边连接,当且仅当它们的点之间的距离小于圆直径时 - 正是在这种情况下我们将被禁止在解决方案中包含两个圈子,因为它们会重叠。
现在,您可以模拟选择哪个候选圆心应该实际变为圆maximum independent set problem的问题:在此图中找到一个最大尺寸的顶点集,其中包含集合中没有两个顶点的属性边缘。这将找到一组圆心,使得它们的圆圈中没有两个会重叠。如果此组包含多于n个圆圈,则丢弃随机选择的圆圈,直到只剩下n个圆圈。如果找到的圈数少于n个,则需要增加m并重试。
不幸的是,最大的独立集问题是NP难的,所以我不知道在300顶点图上求解是否可行。 (反过来,我不知道300个随机中心是否会给你足够的灵活性来找到200个非重叠的圆......)但无论如何,你通常会用两种方法之一解决最大独立集:
那些维基百科页面包含描述这些问题算法的论文的链接,虽然仍然是指数时间,但比标准的“完全回溯”算法要快得多。要记住几件事:
答案 5 :(得分:1)
@ toto2 @cyborg @TokenMacGuy
更新
我已经使用FarseerPhysicsEngine实现了 billard解决方案并稍微玩了一下。在实施解决方案的过程中,我稍微修改了一下问题:):不要将所有圆圈保持在框内,我允许圆圈移动到边框之外,让外部部分重新出现在另一边(非常类似于oldschool小行星游戏)。这使得我的分布适合于在x和y方向上的无限重复,这对于基础有限元建模任务来说甚至更好。这伴随着关于物理模拟的一些其他问题,因为这不是原始问题的一部分,所以我只会描述那些,如果有人特别感兴趣的话。
所以我做了什么:我按照想要的顺序排列尽可能多的圆圈,或者按照最密集的顺序排列(圆圈的中心是六边形顺序)。我在圆圈周围留下了一个边距,使模拟更加稳定。有时会发生圆圈重叠的情况。每个圆圈都有一个随机的速度矢量和质量。其他一切都是碰撞检测和处理,由物理引擎完成。
结果:适用于大量圈子。
如果使用少量圆圈进行,则它们会粘在一起。我无法解释原因。可能是Fraseer没有将碰撞建模为理想弹性,因此能量消散。我不知道是否,以及是否有财产。当我为运动设置摩擦为零时,这可能会导致这种聚类:
无论如何,我对很多圈子的结果感到非常满意 - 因为到目前为止这是未解决的部分,我认为这样做。遗憾的是,我没有时间深入研究其他概念,尽管我以后肯定会对它们进行更深入的研究。
谢谢大家参与!!获得所有输入很有趣!如果您对解决方案有进一步的想法或意见,请告诉我。