【问题标题】:Algorithm for calculating the area of a region in a grid of squares用于计算正方形网格中区域面积的算法
【发布时间】:2015-03-13 04:24:59
【问题描述】:

我正在开发一款使用瓷砖地图的游戏。地图上的方格可以是墙也可以是空的。我正在尝试开发的算法应该在地图上取一个点并返回从该点可以到达的单元格的数量(等于包含该点的扇区的面积)。

让执行算法的函数取一个 x 坐标、一个 y 坐标和一个二维数组形式的地图。

function sectorArea(x_coord,y_coord,map) { ... }

假设地图看起来像这样(其中 1 代表墙壁):

map = [0,0,1,0,0,0],
      [0,0,1,0,0,0],
      [1,1,1,0,0,0],
      [0,0,0,0,0,0]

然后是sectorArea(0,0,map) == 4sectorArea(4,0,map) == 15

我的幼稚实现是递归的。目标单元格被传递给go 函数,然后在任何相邻的空单元格上递归 - 最终传播到扇区中的所有空单元格。它运行得太慢,很快就达到了调用堆栈限制:

function sectorArea(x_coord,y_coord,map) {
    # First convert the map into an array of objects of the form:
    # { value: 0 or 1,
    #   visited: false }
    objMap = convertMap(map);

    # The recursive function:
    function go(x,y) {
        if ( outOfBounds(x) || outOfBounds(y) || 
             objMap[y][x].value == 1 || objMap[y][x].visited )
            return 0;
        else
            objMap[y][x].visited = true;
            return 1 + go(x+1,y) + go(x-1,y) + go(x,y+1) + go(x,y-1);
    }
    return go(x_coord,y_coord);
}

谁能推荐一个更好的算法?如果足够准确,非确定性解决方案实际上会很好,因为速度是主要问题(该算法可以在单个滴答中的不同点上调用 3 或 4 次)。

【问题讨论】:

    标签: algorithm area sector


    【解决方案1】:

    也许您可以加快算法本身的速度。 Wikipedia 建议扫描线方法是有效的。

    对于重复调用:可以缓存结果,这样就不用每次都重新计算面积了。

    一种方法可能是在您的图块旁边保留一个整数区域图。这表示几个区域,其中一个特殊值(例如 -1)表示没有区域。 (此区域地图也可用作您的 visited 属性。)除此之外,保留一个(短)区域数组及其区域。

    在你上面的例子中:

    • 当你计算(0, 0)的面积时,你会将0分配给西北角的四个瓦片。您还将面积 4 附加到面积数组中。

    • 当您计算 (0, 1) 的面积时,您会注意到该坐标的区域地图的值为零,而不是 -1。这意味着该区域已经被计算出来了。

    • 当你计算(4, 4)的面积时,你会在区域图中找到-1。这意味着该区域尚未计算。这样做,用 1 标记区域并将新区域 15 附加到区域数组。

    我不知道董事会多久更换一次。当您必须重新计算区域时,将区域图清空并清空数组列表。

    区域地图只创建一次,它不会在每次滴答时都重新创建。 (当objMap 经常被重新创建而不是被覆盖时,我可以将其视为您代码中的潜在瓶颈。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 2013-11-13
      相关资源
      最近更新 更多