我在了解
的最终输出时遇到问题for i in edgeList:
adjacencyList[i[0]].append(i[0])
在下面的代码中。我尝试在每一行中打印出语句以尝试理解,但仍然感到困惑。
vertexList = ["0","1","2","3","4","5","6"]
edgeList = [(0,1), (0,2),(1,0), (1,3), (2,0), (2,4), (2,5), (3,1), (4,2), (4,6), (5,2), (6,4)]
adjacencyList = [[] for vertex in vertexList]
for i in edgeList:
adjacencyList[i[0]].append(i[1])
print(adjacencyList)
Output: [[1, 2], [0, 3], [0, 4, 5], [1], [2, 6], [2], [4]]
这是否由于列表理解而在for循环中发生了for循环?欣赏是否有人可以说明这里发生的事情。 (这与图论中的BFS有关)
答案 0 :(得分:2)
您的adjacencyList
构造错误。
替换
adjacencyList[i[0]].append(i[0])
与adjacencyList[i[0]].append(i[1])
。我在另一个内部看不到任何for循环。您的时间复杂度为O(n)
。
adjacencyList
的目的是存储给定节点的所有相邻节点,在您的情况下,它是列表的索引。
更改后,您的输出应为
[[1,2],[0,3],[0,4,5],[1],[2,6],[2],[4]]
由此您可以将0解释为具有1和2作为邻居。 2具有0和3个邻居,3具有0,4和5作为邻居,依此类推。
请注意,如果您有{2,60,1000,4}之类的节点,则此方法将失败。在这种情况下,最好使用节点字典和邻居列表。
答案 1 :(得分:2)
graphviz是可视化图形问题的一个很好的工具,它带有dot
命令。首先创建edgelist.dot
,其中包含edgeList
变量中的所有边:
digraph G {
0 -> 1
0 -> 2
1 -> 0
1 -> 3
2 -> 0
2 -> 4
2 -> 5
3 -> 1
4 -> 2
4 -> 6
5 -> 2
6 -> 4
}
(您可以通过较短的方式来编写此代码)。
然后通过dot
填充它:
c:\srv\tmp> dot -Tsvg -o edgelist.svg edgelist.dot
,然后打开创建的edgelist.svg
文件:
邻接列表是可以从特定节点访问的节点列表,例如对于节点0
,有指向节点1
和2
的箭头,因此adjacencyList[0]
,即节点0
的邻接列表应为[1, 2]
。
类似地,从节点2
出发的箭头到达节点0
,4
和5
,因此adjacencyList[2]
应该是[0, 4, 5]
按顺序依次遍历每个节点,邻接列表以以下结尾:
[[1, 2], [0, 3], [0, 4, 5], [1], [2, 6], [2], [4]]
^ ^ ^ ^ ^ ^ ^
item/index: 0 1 2 3 4 5 6
在您的代码中,此行:
adjacencyList = [[] for vertex in vertexList]
仅将adjacencyList
创建为空列表([]
)的列表,其长度等于顶点数。
然后进行循环:
for i in edgeList:
adjacencyList[i[0]].append(i[0])
试图填充它。要找出问题所在,我们可以重写for循环,以便将edgeList
中的边缘解包:
for (start, end) in edgeList:
adjacencyList[start].append(..?..)
显然..?..
应该是end
而不是开始:
for start, end in edgeList:
adjacencyList[start].append(end)
现在您可以看到for循环正在执行我们在上面手动执行的操作,对于每个边(start, end)
,它会将end
添加到start
的邻接列表中。
附录:对于顶点(0
,1
等)的值与数组索引相同的情况,您的代码效果很好。尽管效率很高,但它在教学上可能不是可取的(或者也许是,我不知道;-)在任何情况下,如果我们重命名顶点,以使0
变成"A"
,{{1 }}变成1
等,您需要为邻接表使用其他数据结构,例如:
"B"
打印:
from collections import defaultdict
edgeList = [("A", "B"),
("A", "C"),
("B","A"), ("B","D"),
("C","A"), ("C","E"), ("C","F"),
("D","B"),
("E","C"), ("E","G"),
("F","C"),
("G","E")]
adjacencyList = defaultdict(list)
for start, end in edgeList:
adjacencyList[start].append(end)
print(sorted(adjacencyList.items()))
表示[('A', ['B', 'C']), ('B', ['A', 'D']), ('C', ['A', 'E', 'F']), ('D', ['B']), ('E', ['C', 'G']), ('F', ['C']), ('G', ['E'])]
的邻接列表是'A'
等。
有可能(可能有益于运行时间)将此版本转换为第一个版本(尤其是比Python更静态的语言)。