【问题标题】:Is there an alternative to fixed-size array for coordinate system?坐标系中是否有固定大小数组的替代方法?
【发布时间】:2018-06-20 11:24:25
【问题描述】:

情况

我已经实现了一个随机游走算法来生成类似地牢的迷宫。该算法有多个“步行者”,每个“步行者”随机贡献于同一个迷宫。您可以通过以下网址了解算法的工作原理:https://thomaskerbrat.github.io/procedural-maze/ (如果动画过快,请重新加载页面以获得新的迷宫。)

迷宫是一步一步生成的,每次渲染。红色方块代表每个步行者在地图上的前进。

在这个实现中,我有一个 固定大小 数组,表示游戏的图块(地板、墙壁或无)。默认情况下,网格为 64 x 64。

问题

当算法到达我无法超越的边缘时,walker 停止生成路径。

我的问题是:有没有办法用不受初始尺寸限制的数组替换固定大小的数组?

问题是我想执行查找以了解相邻单元格的内容。使用固定大小的数组很容易做到这一点,我只需访问适当的索引(事先检查它们不超过网格大小)。但是我在网上没有找到解决方案。

我提出的解决方案示例

到目前为止,我想出了一个我想要放置在网格中的元素的列表,并为查找保留一个双哈希图。

考虑在 10x10 网格中具有以下坐标的点列表:

  • A (4,5)
  • B (8,2)
  • C (4,2)
  • D (8,5)
  • E (3,7)
  • F (3,2)

相应的 hash-map 会将 X 和 Y 坐标映射到内存中的对象:

  • 3
    • 2 -> F
    • 7 -> E
  • 4
    • 2 -> C
    • 5 -> 一个
  • 8
    • 2 -> B
    • 5 -> D

为了查看相邻单元格是否存在或检查其内容,我检查哈希映射是否将 X 坐标作为键(指向另一个哈希映射),如果是,我也会这样做Y坐标最终找到一个单元格的事情,或者没有。

那么,你怎么看?您是否知道某种“标准”方法,或者至少是众所周知的方法?

【问题讨论】:

  • 如何使用一个非常大的初始数组,比如 1024x1024,然后裁剪它?
  • 所以你想创建一个可能永远不会完成的算法......听起来很有趣......只需将array替换为list,或者使用数组被动态绑定的编程语言跨度>
  • 你可以创建一个sparse matrix 表示并让数组增长到你喜欢的大小。您唯一的限制是内存。或者,如果你想溢出到磁盘,你唯一的限制就是你有多少磁盘空间。我假设你有一些条件可以杀死步行者。
  • @justhalf 重点是不要使用固定大小的数组。
  • 那就更新你的理解吧。 Storing a sparse matrix 子主题描述了几种不是固定大小数组的表示。例如,您接受的答案对应维基百科文章中描述的“坐标列表”。

标签: algorithm coordinates


【解决方案1】:

一种方法是不使用数组,而是使用一组坐标来记录所有访问过的位置,计算步行的跨度,并在步行后将其映射到适当大小的网格:

该方案随机行走一个walker,对行走的范围没有限制,然后构建一个自动适应数据大小的数据结构;它使用有序序列和索引。

1- 在位置 (0, 0) 处启动您的 walker,一个元组,并将其插入集合中。
2-步行者:
2-1- 为步行者创建一个新的坐标元组,其新位置行 +/- 1 和/或列 +/-1 用于步骤的每个方向。
2-2- 通过在每一步将其插入到集合中来记录这个新位置。
3-继续走直到完成。
4- 从步行位置生成网格:
4-1- 找到最小和最大行和列来确定跨度。
4-3- 为行和列创建一个大小为 max-min 的网格。
4-4-通过将步行坐标更改为网格坐标来填充访问的位置。

如果您需要按顺序执行这些步骤,则可以使用有序集或地图。 如果可以多次访问位置,则可以改用序列(数组、列表...),或者如果您需要跟踪访问的顺序,则可以使用到时间步序列的映射。

实现(python)可能如下所示:

"""
a 2D grid that auto adjusts its size to the data.
coordinates are tuples of integers in the range -1e9 <-> 1e9
"""


class SpanGrid:

    def __init__(self, coordinates):
        self.coordinates = coordinates
        self.grid = None
        self.rows = None
        self.columns = None
        self.make_grid()

    def make_grid(self):
        self._find_num_rows_columns()
        self._populate_grid()

    def _find_num_rows_columns(self):
        self.minrow, self.mincol = 1e9, 1e9
        self.maxrow, self.maxcol = -1e9, -1e9
        for row, col in self.coordinates:
            self.minrow = row if row < self.minrow else self.minrow
            self.mincol = col if col < self.mincol else self.mincol
            self.maxrow = row if row > self.maxrow else self.maxrow
            self.maxcol = col if col > self.maxcol else self.maxcol
        self.rows = self.maxrow - self.minrow + 1
        self.columns = self.maxcol - self.mincol + 1

    def _populate_grid(self):
        self.grid = [[None for dummycol in range(self.columns)]
                     for dummyrow in range(self.rows)]
        for r, c in self.coordinates:
            self.grid[r - self.minrow][c - self.mincol] = True

    def __str__(self):
        result = []
        for line in self.grid:
            res = ''
            for pos in line:
                res += str(pos) if pos else ' -  '
                res += ' '
            result.append(res)
        return '\n'.join(result)


if __name__ == '__main__':

    import random
    visited = set()
    offsets = ((1, 0), (-1, 0), (0, 1), (0, -1))
    start = (0, 0)
    current = start
    visited.add(current)
    for _ in range(100):
        cur_row, cur_col = current
        row_offset, col_offset = random.choice(offsets)
        current = (cur_row + row_offset, cur_col + col_offset)
        visited.add(current)

    grid = SpanGrid(visited)
    print(grid)

示例输出:

 -   True True True True True True  -   
 -   True True True True True True True 
 -   True True True True True True  -   
True True True True True True  -    -   
True True True True True True  -    -   
 -   True True True True  -    -    -   
 -   True  -    -    -    -    -    -  

============================================================================

 -    -    -    -    -    -    -    -    -   True  -    -   
 -    -    -    -    -    -    -    -   True True True  -   
 -    -    -    -    -   True True  -   True True True True 
True True True True True True True  -   True True True True 
 -   True True True True True True True True True True  -   
 -    -    -   True True True True True  -    -    -    -   

============================================================================

 -    -    -    -    -    -    -   True True True True  -    -    -    -    -    -    -    -    -   
 -    -    -    -    -    -    -   True  -    -   True True True  -    -   True True  -    -    -   
 -    -    -    -    -    -    -   True True  -   True True True  -   True True True  -    -    -   
 -    -    -    -    -    -    -   True True True True True True True True True  -    -    -    -   
 -   True True  -    -    -    -    -   True  -   True True True  -    -   True True  -    -    -   
True True True True  -    -    -    -   True  -    -   True True  -    -   True True True  -    -   
True True True True  -    -   True True True  -    -    -   True  -    -    -   True True  -    -   
 -    -    -   True True True True  -    -    -    -    -    -    -    -   True True  -    -    -   
 -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -   True True True True 
 -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -   True 
 -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -   True True 
 -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -    -   True 

【讨论】:

  • 这与 OP 中提出的解决方案有什么区别?
  • OP 建议使用哈希映射,并在步进前查找相邻单元格;该解决方案随机行走一个步行者,对行走的范围没有限制,然后构建一个自动调整数据大小的数据结构;它使用有序序列和索引。
猜你喜欢
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 2011-02-28
  • 2019-08-17
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多