如何有效地确定基于3D体素的房间是否密封


10

我一直无法有效地确定大型房间是否封闭在基于体素的3D房间中,因此遇到了一些问题。我正在尽最大努力在不寻求帮助的情况下解决问题,但还没有尽力放弃,所以我在寻求帮助。

为了澄清起见,密封是房间内没有孔。有氧气密封器,用于检查房间是否密封,并根据氧气输入水平进行密封。

现在,这就是我的操作方式:

  • 从封口砖上方的块开始(通风口在封口的顶面上),递归遍历所有6个相邻方向
  • 如果相邻的图块是完整的非真空图块,请继续执行循环
  • 如果相邻的块未满,或者是真空块,则递归检查其相邻块是否存在。
  • 每次检查图块时,递减计数器
  • 如果计数为零,则最后一个块与真空砖相邻,则返回该区域未密封
  • 如果计数为零,并且最后一个块不是真空块,或者递归循环在计数器为零之前结束(没有真空块),则该区域将被密封

如果该区域未被密封,请进行一些更改以再次运行循环:

  • 检查相邻块中的“透气”砖块而不是真空砖块
  • 代替使用减量计数器,直到发现没有相邻的“透气空气”砖块为止。
  • 循环完成后,将每个选中的块设置为真空砖。

这是我正在使用的代码:http : //pastebin.com/NimyKncC

问题:

我每3秒运行一次此检查,有时一个封闭程序必须循环遍历数百个块,并且在一个拥有很多氧气封闭程序的广阔世界中,每隔几秒钟的这些多个递归循环在CPU上可能很难。

我想知道是否有人在优化方面有更多经验可以帮助我,或者至少可以指出正确的方向。谢谢你


仅检查何时发生变化才是开始。每三秒钟检查一次似乎有点过头了,因为您知道体素何时发生变化可能会破坏密封。如果组成密封房间的体素被更改,则可以标记要重新检查的房间,否则不要打扰。
MichaelHouse

由于在这3秒钟的时间内可能会有数百个体素发生变化,所以我认为定期进行此操作比检查附近是否有任何更改会更有效。我会尝试一下。
NigelMan1010

哦,好吧,如果数百个体素可以在3秒钟的时间内更改,那么您可能会遇到许多性能问题。开始分析您的代码以发现低效率。祝好运!
MichaelHouse

Answers:


3

最佳解决方案将取决于多个因素,例如预期的房间大小。

  1. 仅在实际更改时才进行检查。

方法1:

您可以使用A *查找从通风口到通风口上方的瓷砖/通风口本身或通往真空的瓷砖的路径。如果找到路径,则说明房间未密封。这与您当前的方法没什么不同,但是应该更快。找到后,进行“填充”以将瓷砖设置为真空。

方法二:

也许您的外部结构不太复杂-考虑到房间下面有一个表面,您不需要在所有6个方向上移动,因此您应该沿着该表面移动,将每个瓷砖标记为您要移动的真空。


0

进行递归搜索时,是否确定您没有多次检查同一体素?从您描述算法的方式我无法确定,但是您应该具有某种标志来指示您是否已经递归扩展体素,因此您不应重复进行多次。

就像Byte56所说的那样,您还应该仅在情况发生变化时检查泄漏。根据更改的频率,这可以极大地减少您的工作量。您甚至还可以在连续调用该算法之间缓存信息,这可以使您在第一次调用之后进行的计算量变得微不足道。

编辑:

我看了看你的一些代码。就像我在第一段中一样,您似乎正在使用LinkedList来指示是否已经检查了体素。如果为此使用LinkedList以外的其他方法,则可能会得到更好的结果。也许尝试一个HashSet之类的东西?这样可以将检查方法的复杂度从O(n)降低到O(1)。


是的,我将其添加到一个名为“ checked”的LinkedList中,然后在检查之前检查该列表是否包含该位置。我认为检查是否有所更改也将占用大量CPU,因为在这3秒钟的时间内可能已更改了数百个体素。不过,在这种情况下,我将看到哈希表与链表的比较。
NigelMan1010 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.