【问题标题】:Finding the neighbors of all map coordinates查找所有地图坐标的邻居
【发布时间】:2017-04-20 01:30:21
【问题描述】:

我需要帮助优化我的代码。这是有问题的卑鄙功能。

def FindAllNeighborCoords(cardinal_neighbor_array, principle_neighbor_array, width, height):

    # Loop through every coordinate on the map.
    for x in xrange(width):
        for y in xrange(height):

            # These if checks make sure the coordinate is in the map.
            if x - 1 >= 0:
                cardinal_neighbor_array[x, y].add((x - 1, y))
                principle_neighbor_array[x, y].add((x - 1, y))

            if y - 1 >= 0:
                cardinal_neighbor_array[x, y].add((x, y - 1))
                principle_neighbor_array[x, y].add((x, y - 1))

            if y + 1 < height:
                cardinal_neighbor_array[x, y].add((x, y + 1))
                principle_neighbor_array[x, y].add((x, y + 1))

            if x + 1 < width:
                cardinal_neighbor_array[x, y].add((x + 1, y))
                principle_neighbor_array[x, y].add((x + 1, y))

            if x - 1 >= 0 and y - 1 >= 0:
                principle_neighbor_array[x, y].add((x - 1, y - 1))

            if x - 1 >= 0 and y + 1 < height:
                principle_neighbor_array[x, y].add((x - 1, y + 1))

            if x + 1 < width and y - 1 >= 0:
                principle_neighbor_array[x, y].add((x + 1, y - 1))

            if x + 1 < width and y + 1 < height:
                principle_neighbor_array[x, y].add((x + 1, y + 1))

print cardinal_neighbor_array[20, 20]
set([20, 21), (21, 20), (19, 20), (20, 19)])

这个函数循环遍历地图上的每个人的坐标,找到周围邻居坐标的邻居并将它们保存到一个集合中。它搜索两种邻居类型 - 基数和本金。或者,4 和 8。每组都放置在一个二维数组中。然后,我可以通过执行诸如 cardinal_array[0, 0] 之类的操作来获取坐标的邻居,这将返回一组坐标。我希望这是有道理的!我在我的项目中使用了 TON 邻居,因此一次查找和存储它们比重复查找它们更快。我的引擎的很大一部分都使用这些邻居集,所以我宁愿加快它目前的工作方式,也不愿做出任何重大改变。这些集合由包含每个邻居的 (x, y) 坐标的元组组成。如果您有更好的解决方案,可以更改元组。此函数在地图生成期间调用一次,是迄今为止最慢的。

【问题讨论】:

    标签: python performance numpy set


    【解决方案1】:

    有一些显而易见的事情要做。所有像if x - 1 &gt;= 0 这样的语句都应该替换为if x &gt; 0,因为这样可以节省一个加法。一旦你确定了像x &gt; 0 这样的表达式的真值,如果你以后需要它,就使用这个结果。例如:

            if x > 0:
                cardinal_neighbor_array[x, y].add((x - 1, y))
                principle_neighbor_array[x, y].add((x - 1, y))
                if y > 0:
                    principle_neighbor_array[x, y].add((x - 1, y - 1))
                if y < height-1:
                    principle_neighbor_array[x, y].add((x - 1, y + 1))
    

    您可以改进上面最后的if 语句:在第一个循环开始之前声明一个变量hm1 = height-1,并在必要时在循环内使用该变量。否则,height-1 会一遍又一遍地计算。 Python 不会为你优化这类事情。

    这些相对较小。我看到的最大问题是您在内部循环中进行 12 次数组查找。每个像principle_neighbor_array[x, y] 这样的表达式都涉及到一个二维数组的查找,这一定是昂贵的。所以在你的内部循环的顶部,声明两个局部变量,它们是你要使用的集合的同义词:

    for x in xrange(width):
        for y in xrange(height):
            cardinal_set = cardinal_neighbor_array[x, y]
            principle_set = principle_neighbor_array[x, y]
    

    重写循环内的所有代码以使用这两个集合。您为每次迭代保存十次数组查找。

    我不知道这会有多大帮助,但它很容易做到,而且肯定会有所改善。

    【讨论】:

      【解决方案2】:

      您正在执行 2 倍于所需的操作。

      如果 A 是 B 的邻居,那么显然 B 是 A 的邻居。

      与其检查所有 4 或 8 个方向,不如检查其中的一半,例如仅北部、东北部、东部和东南部,当您同时找到 (A, B) 和 (B, A) 配对的热门记录时。

      【讨论】:

        猜你喜欢
        • 2020-03-05
        • 1970-01-01
        • 2020-01-29
        • 1970-01-01
        • 2015-07-11
        • 2014-02-26
        • 1970-01-01
        • 2015-01-01
        • 1970-01-01
        相关资源
        最近更新 更多