列表索引超出广度优先搜索功能的范围错误

时间:2017-04-16 17:03:04

标签: python numpy breadth-first-search

我正在创建一个广度优先搜索功能,它将从给定节点返回到网络中所有节点的最短距离数组,然后为所有节点创建这些最短距离的矩阵。它适用于较小的网络,但当我尝试将其扩展到更大的网络时,我收到一个错误,列表索引超出范围。

我的功能是

def bfs_short(G,node):
    queue=[]
    visit=[]
    parent=[]
    for n in range(len(G)):
        visit.append(False)
        parent.append(None)
    queue.append(node)
    visit[node]=True
    while len(queue)!=0:
        current=queue.pop(0)
        for a in G[current]:
            if visit[a]==False:
                visit[a]=True
                parent[a]=current
                queue.append(a)
    distances=[]
    for n in range(len(G)):
        distances.append(0)
    for n in range(len(G)):
        dist=0
        current=n
        while parent[current]!=None:
            dist=dist+1
            current=parent[current]
        distances[n]=dist
    return distances

    V=len(G.keys())
    dist_matrix=np.empty([V, V])
    keys = G.keys()
    for k in keys:
        dist_matrix[k,:]=bfs_short(G,k)
    return dist_matrix

错误是:

<ipython-input-296-b89665c85020> in bfs_short(G, node)
     11         current=queue.pop(0)
     12         for a in G[current]:
---> 13             if visit[a]==False:
     14                 visit[a]=True
     15                 parent[a]=current

IndexError: list index out of range

这个微小的邻接矩阵可以正常工作

G_dict2 = {0:[1,3], 1:[0,2,5], 2:[1,3], 3:[0,2], 4:[1,2,3], 5:[0,4], 6:[3,4]}

但它在使用更大的网络时会出错。网络太大(约2,000个节点)实际粘贴在这里,但我不确定一个小的摘录是否有助于照亮任何东西。

network= {0: [1, 2],
 1: [6, 0, 7],
 2: [8, 9, 10],
 3: [4, 1, 5],
 4: [11, 12, 13],
 5: [14, 15, 16],
 6: [17, 1, 18],
 7: [19, 20, 1],
 8: [21, 2, 3],
 9: [2, 22, 23],
 10: [24, 2, 25],
 11: [4],
 12: [4, 13, 26],
 13: [12, 4, 27],
 14: [28, 29, 30],
 15: [31, 5, 32],
 16: [33, 5],
 17: [6, 34, 35],
 18: [36, 37, 38],
 19: [7, 39, 40],
 20: [41, 7, 42],}

是否有人注意到任何会导致它在更大的网络上出现此错误的函数?

谢谢!

1 个答案:

答案 0 :(得分:0)

当我读取代码时,只有当邻接矩阵中的某个节点的值大于或等于len(G_dict2)时,才会发生此错误。

如果邻接列表中的节点大于G_dict2中的最大密钥,则很容易发生这种情况。如果网络中的最大节点是2017,但是存在列表21: [2018],或者邻接矩阵缺少节点,即,对于某个节点i没有条目,其中i <1。 len(G_dict2),在这种情况下,访问的长度对于最大可能的节点值来说太短。您可以使用以下方法对此进行测试:

from itertools import chain
assert max(chain(*G_dict2.values())) < len(G_dict2), "You got an out of range because G_dict2 has a node with id {} which is larger than the range of visit (0, {})".format(max(chain(*G_dict2.values())), len(G_dict2) - 1)
assert max(G_dict2.keys()) < len(G_dict2), "You got an out of range because visit is constructed by iterating over the *number* of keys in the dict, but the node {} is not in the range (0, len(G_dict2)-1) = (0, {})".format(max(G_dict2.keys()), len(G_dict2)-1)

您可以通过根据所有邻接列表中的最大值初始化访问来解决问题,例如:

from itertools import chain
visit = [False]*(max(chain.from_iterable(G.values()))+1)
parent = [None]*(max(chain.from_iterable(G.values()))+1)