将 Numpy 数组转换为单调图 (networkx)

Convert Numpy Array to Monotone Graph (networkx)

我有一个简单的 1 和 0 数组,我想在满足以下条件的情况下使用 NetworkX 将该数组转换为图形:

有一个名为 from_numpy_matrix

的内置函数

this

目标是使用此图并显示我可以从矩阵的左下角(想想栅格数据集)到达右上角,而无需向后或向下移动。

示例数组:

array = [[0,0,1,0,0],
         [1,0,0,1,0],
         [1,0,1,1,0],
         [0,0,1,1,0]]
myarray = np.array(array)

0 means go area, 1 means blocked.

那很有趣。

from_numpy_matrix 没有帮助,因为没有从迷宫到邻接矩阵的简单转换。相反,迭代允许的位置(即 "not wall")并检查在允许的方向(上、右、对角线右上)是否有允许的位置要容易得多。

import numpy as np
import matplotlib.pyplot as plt
import networkx as nx

def maze_to_graph(is_wall, allowed_steps):
    """
    Arguments:
    ----------
    is_wall       -- 2D boolean array marking the position of walls in the maze
    allowed_steps -- list of allowed steps; e.g. [(0, 1), (1, 1)] signifies that
                     from coming from tile (i, j) only tiles (i, j+1) and (i+1, j+1)
                     are reachable (iff there is no wall)

    Returns:
    --------
    g             -- networkx.DiGraph() instance
    pos2idx       -- dict mapping (i, j) position to node idx (for testing if path exists)
    idx2pos       -- dict mapping node idx to (i, j) position (for plotting)
    """

    # map array indices to node indices and vice versa
    node_idx = range(np.sum(~is_wall))
    node_pos = zip(*np.where(~is_wall))
    pos2idx = dict(zip(node_pos, node_idx))

    # create graph
    g = nx.DiGraph()
    for (i, j) in node_pos:
        for (delta_i, delta_j) in allowed_steps: # try to step in all allowed directions
            if (i+delta_i, j+delta_j) in pos2idx: # i.e. target node also exists
                g.add_edge(pos2idx[(i,j)], pos2idx[(i+delta_i, j+delta_j)])

    idx2pos = dict(zip(node_idx, node_pos))

    return g, idx2pos, pos2idx

def test():
    arr = np.array([[0,0,1,0,0],
                    [1,0,0,1,0],
                    [1,0,1,1,0],
                    [0,0,1,1,0]]).astype(np.bool)

    steps = [(0, 1),  # right
             (-1, 0), # up
             (-1, 1)] # diagonal up-right

    g, idx2pos, pos2idx = maze_to_graph(arr, steps)

    nx.draw(g, pos=idx2pos, node_size=1200, node_color='w', labels=idx2pos)

    start = (3, 0)
    stop = (0, 4)
    print "Has path: ", nx.has_path(g, pos2idx[start], pos2idx[stop])

    return