繁体   English   中英

在2D网格上找到8个邻居的节点

[英]Find a nodes 8 neighbors on a 2D grid

我需要找到二维数组中任何节点的基数和对角线邻居。 采取以下数组。 我正在从数组中[1,1]的1中搜索。 它应该返回周围的0。 我可以找到邻居,就像下面的一些代码所示,但是它们太慢了。

[[0, 0, 0]
 [0, 1, 0]
 [0, 0, 0]]

我可以像这样蛮力返回周围所有8个节点的坐标。

def ReturnNeighbors(x, y):
    numpy.array([(x-1, y), (x, y-1), (x+1, y), (x, y+1),
               (x-1, y-1), (x+1, y+1), (x-1, y+1), (x+1, y-1)])

def ReturnNeighbors_4(x, y):
    for i in xrange(x - 1, x + 2):
        for j in xrange(y - 1, y + 2):
            if (i, j) != (x, y):
                yield (i, j)

或者通过计算到所有节点的距离并返回距离<2的节点,但是我发现的这些和其他解决方案都很慢。 我要学习麻木的全部原因是为了提高速度。 我想我需要使用scipy convolve2d或cKDtree,但是它们对我来说太复杂了。

我切换到numpy之前的处理方式是我的数组充满了实际的节点对象作为值。 每个对象将其x和y坐标存储在网格中以及一组相邻对象。 像这样。 我不能再使用此方法了,因为要填充一个巨大的充满节点的数组需要很长时间。 即使在100x100的小型地图中,也可以包含10000个节点对象! 我计划以后不仅要拥有更大的地图,而且要在任何给定时间激活多个地图。 由于节点的印记,我实际上已经用尽了内存来尝试创建更大的地图。 它适用于小型地牢,但不适用于模拟了多个地图的世界。

ExampleNode(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.neighbors = set()

        # The neighbors are found and added to the above set later.

node = Example(0, 0)

for neighbor in node.neighbors:
    do thing with each neighbor

由于多种原因,我需要一个节点邻居。 使用细胞自动机对地图进行平滑处理,在战斗中向附近溅血,使用广度优先搜索进行寻路等等。 这是针对我正在创建的流氓对象。 蛮力方法适用于60x60小型地牢,但现在我正在扩大范围并生成世界地图。 它只有200x200,而且非常慢。

假设输入数组的名称为A ,其中包含所有整数,并且我们仅处理其中的1s并尝试获取其邻居。 这是这样做的一种方法-

# Get offsets for row and column
R_offset,C_offset = np.meshgrid(np.arange(-1,2),np.arange(-1,2))

# Get row and column indices for places where elements are 1s
R_match,C_match = np.nonzero(A==1)

# Store number of matches as it would be frequently used
N = R_match.size

# Get offsetted row, col indices for all matches
R_idx = (R_match[:,None,None] + R_offset).reshape(N,-1)
C_idx = (C_match[:,None,None] + C_offset).reshape(N,-1)

# Based on boundary conditions set invalid ones to zeros
valid_mask = (R_idx>=0) & (C_idx>=0) & (R_idx<A.shape[0]) & (C_idx<A.shape[1])
valid_mask[:,4] = 0 # Set the pivot(self/center) ones to invalid

# Using valid mask, "cut off" elements from each group of 9 elems
cut_idx = valid_mask.sum(1).cumsum()

# Finally form groups
grps_R = np.split(R_idx[valid_mask],cut_idx)[:-1]
grps_C = np.split(C_idx[valid_mask],cut_idx)[:-1]

样本运行以及有关如何解释和使用输出的解释-

In [256]: A
Out[256]: 
array([[1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 0, 1]])

In [257]: grps_R
Out[257]: [array([1, 0, 1]), array([1, 2, 3, 1, 3, 1, 2, 3]), array([2, 3, 2])]

In [258]: grps_C
Out[258]: [array([0, 1, 1]), array([1, 1, 1, 2, 2, 3, 3, 3]), array([3, 3, 4])]

因此,基于A的三个1s ,我们有三个组。

第一个在左上角-

In [259]: np.column_stack((R_match[0],C_match[0]))  # First point
Out[259]: array([[0, 0]])

In [260]: np.column_stack((grps_R[0],grps_C[0]))    # Its three neighbors
Out[260]: 
array([[1, 0],
       [0, 1],
       [1, 1]])

第二个是(2,2) -

In [263]: np.column_stack((R_match[1],C_match[1]))  # Second point 
Out[263]: array([[2, 2]])

In [264]: np.column_stack((grps_R[1],grps_C[1]))    # Its eight neighbors
Out[264]: 
array([[1, 1],
       [2, 1],
       [3, 1],
       [1, 2],
       [3, 2],
       [1, 3],
       [2, 3],
       [3, 3]])

最后第三个是(4,5) -

In [265]: np.column_stack((R_match[2],C_match[2]))  # Third point 
Out[265]: array([[3, 4]])

In [266]: np.column_stack((grps_R[2],grps_C[2]))    # Its three neighbors
Out[266]: 
array([[2, 3],
       [3, 3],
       [2, 4]])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM