我正在创建一个广度优先搜索功能,它将从给定节点返回到网络中所有节点的最短距离数组,然后为所有节点创建这些最短距离的矩阵。它适用于较小的网络,但当我尝试将其扩展到更大的网络时,我收到一个错误,列表索引超出范围。
我的功能是
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],}
是否有人注意到任何会导致它在更大的网络上出现此错误的函数?
谢谢!
答案 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)