Topological Sort with simple input results in "IndexError: list index out of range"
Topological Sort with simple input results in "IndexError: list index out of range"
我在研究拓扑排序时遇到了GeeksforGeek's Python code。
# Python program to print topological sorting of a DAG
from collections import defaultdict
# Class to represent a graph
class Graph:
def __init__(self,vertices):
self.graph = defaultdict(list) # dictionary containing adjacency List
self.V = vertices #No. of vertices
# function to add an edge to graph
def addEdge(self,u,v):
self.graph[u].append(v)
# A recursive function used by topologicalSort
def topologicalSortUtil(self,v,visited,stack):
# Mark the current node as visited.
visited[v] = True
# Recur for all the vertices adjacent to this vertex
for i in self.graph[v]:
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)
# Push current vertex to stack which stores result
stack.insert(0,v)
# The function to do Topological Sort. It uses recursive
# topologicalSortUtil()
def topologicalSort(self):
# Mark all the vertices as not visited
visited = [False]*self.V
stack =[]
# Call the recursive helper function to store Topological
# Sort starting from all vertices one by one
for i in range(self.V):
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)
# Print contents of stack
print stack
# Driver Code
g = Graph(6)
g.addEdge(5, 2)
g.addEdge(5, 0)
g.addEdge(4, 0)
g.addEdge(4, 1)
g.addEdge(2, 3)
g.addEdge(3, 1)
print "Following is a Topological Sort of the given graph"
g.topologicalSort()
但是,我更改了输入,因为我想测试我的项目所需的实际案例。
g = Graph(5)
g.addEdge(1, 2);
g.addEdge(2, 3);
g.addEdge(3, 4);
g.addEdge(4, 5);
但我在循环函数中遇到“列表索引超出范围”异常,我不明白为什么。
堆栈跟踪
IndexError Traceback (most recent call last)
<ipython-input-8-cb05f6defc6c> in <module>
54
55 print("Following is a Topological Sort of the given graph")
---> 56 g.topologicalSort()
<ipython-input-8-cb05f6defc6c> in topologicalSort(self)
37 for i in range(self.V):
38 if visited[i] == False:
---> 39 self.topologicalSortUtil(i,visited,stack)
40
41 # Print contents of stack
<ipython-input-8-cb05f6defc6c> in topologicalSortUtil(self, v, visited, stack)
21 for i in self.graph[v]:
22 if visited[i] == False:
---> 23 self.topologicalSortUtil(i,visited,stack)
24
25 # Push current vertex to stack which stores result
<ipython-input-8-cb05f6defc6c> in topologicalSortUtil(self, v, visited, stack)
21 for i in self.graph[v]:
22 if visited[i] == False:
---> 23 self.topologicalSortUtil(i,visited,stack)
24
25 # Push current vertex to stack which stores result
<ipython-input-8-cb05f6defc6c> in topologicalSortUtil(self, v, visited, stack)
21 for i in self.graph[v]:
22 if visited[i] == False:
---> 23 self.topologicalSortUtil(i,visited,stack)
24
25 # Push current vertex to stack which stores result
<ipython-input-8-cb05f6defc6c> in topologicalSortUtil(self, v, visited, stack)
20 # Recur for all the vertices adjacent to this vertex
21 for i in self.graph[v]:
---> 22 if visited[i] == False:
23 self.topologicalSortUtil(i,visited,stack)
24
IndexError: list index out of range
IndexError: list index out of range
是因为此示例代码假定顶点从零开始编号。
列表visited
初始化为:
visited = [False]*self.V
因此,如果图初始化为 5 个顶点,则 visited
的索引将为 0、1、2、3、4。
然后,函数 topologicalSortUtil(self, v, visited, stack)
执行下面的第 22 行,顶点 5
超出范围,因为范围从 0 到 4:
21 for i in self.graph[v]:
---> 22 if visited[i] == False:
23 self.topologicalSortUtil(i,visited,stack)
以下使用从零开始的顶点索引的代码按预期工作。
g = Graph(5)
g.addEdge(0, 1)
g.addEdge(1, 2)
g.addEdge(2, 3)
g.addEdge(3, 4)
print("Following is a Topological Sort of the given graph")
g.topologicalSort()
输出:
Following is a Topological Sort of the given graph
[0, 1, 2, 3, 4]
适用于任意顶点数的拓扑排序实现
以下实现不需要您指定顶点数,因为每当通过 add_edge
方法将新顶点添加到图中时,计数会自动增加。
此外,顶点不需要以任何特定数字开头。我继续清理格式以使用标准的蛇形命名约定。
from collections import defaultdict
class Graph:
def __init__(self):
self.graph = defaultdict(list) #dictionary containing adjacency List
def add_edge(self,u,v):
self.graph[u].append(v)
def topological_sort(self) -> list:
visited = set()
reverse_topo = list()
vertices = set(self.graph.keys())
for vertex in vertices:
if vertex not in visited:
self._topological_sort_util(vertex, visited, reverse_topo)
return list(reversed(reverse_topo))
def _topological_sort_util(self, vertex, visited, reverse_topo):
visited.add(vertex)
for adj_vertex in self.graph[vertex]:
if adj_vertex not in visited:
self._topological_sort_util(adj_vertex, visited, reverse_topo)
reverse_topo.append(vertex)
g = Graph()
g.add_edge(1, 2)
g.add_edge(2, 3)
g.add_edge(3, 4)
g.add_edge(4, 5)
print("Following is a Topological Sort of the given graph")
vertices_topo_sorted = g.topological_sort()
print(vertices_topo_sorted)
输出
Following is a Topological Sort of the given graph
[1, 2, 3, 4, 5]
我在研究拓扑排序时遇到了GeeksforGeek's Python code。
# Python program to print topological sorting of a DAG
from collections import defaultdict
# Class to represent a graph
class Graph:
def __init__(self,vertices):
self.graph = defaultdict(list) # dictionary containing adjacency List
self.V = vertices #No. of vertices
# function to add an edge to graph
def addEdge(self,u,v):
self.graph[u].append(v)
# A recursive function used by topologicalSort
def topologicalSortUtil(self,v,visited,stack):
# Mark the current node as visited.
visited[v] = True
# Recur for all the vertices adjacent to this vertex
for i in self.graph[v]:
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)
# Push current vertex to stack which stores result
stack.insert(0,v)
# The function to do Topological Sort. It uses recursive
# topologicalSortUtil()
def topologicalSort(self):
# Mark all the vertices as not visited
visited = [False]*self.V
stack =[]
# Call the recursive helper function to store Topological
# Sort starting from all vertices one by one
for i in range(self.V):
if visited[i] == False:
self.topologicalSortUtil(i,visited,stack)
# Print contents of stack
print stack
# Driver Code
g = Graph(6)
g.addEdge(5, 2)
g.addEdge(5, 0)
g.addEdge(4, 0)
g.addEdge(4, 1)
g.addEdge(2, 3)
g.addEdge(3, 1)
print "Following is a Topological Sort of the given graph"
g.topologicalSort()
但是,我更改了输入,因为我想测试我的项目所需的实际案例。
g = Graph(5)
g.addEdge(1, 2);
g.addEdge(2, 3);
g.addEdge(3, 4);
g.addEdge(4, 5);
但我在循环函数中遇到“列表索引超出范围”异常,我不明白为什么。
堆栈跟踪
IndexError Traceback (most recent call last)
<ipython-input-8-cb05f6defc6c> in <module>
54
55 print("Following is a Topological Sort of the given graph")
---> 56 g.topologicalSort()
<ipython-input-8-cb05f6defc6c> in topologicalSort(self)
37 for i in range(self.V):
38 if visited[i] == False:
---> 39 self.topologicalSortUtil(i,visited,stack)
40
41 # Print contents of stack
<ipython-input-8-cb05f6defc6c> in topologicalSortUtil(self, v, visited, stack)
21 for i in self.graph[v]:
22 if visited[i] == False:
---> 23 self.topologicalSortUtil(i,visited,stack)
24
25 # Push current vertex to stack which stores result
<ipython-input-8-cb05f6defc6c> in topologicalSortUtil(self, v, visited, stack)
21 for i in self.graph[v]:
22 if visited[i] == False:
---> 23 self.topologicalSortUtil(i,visited,stack)
24
25 # Push current vertex to stack which stores result
<ipython-input-8-cb05f6defc6c> in topologicalSortUtil(self, v, visited, stack)
21 for i in self.graph[v]:
22 if visited[i] == False:
---> 23 self.topologicalSortUtil(i,visited,stack)
24
25 # Push current vertex to stack which stores result
<ipython-input-8-cb05f6defc6c> in topologicalSortUtil(self, v, visited, stack)
20 # Recur for all the vertices adjacent to this vertex
21 for i in self.graph[v]:
---> 22 if visited[i] == False:
23 self.topologicalSortUtil(i,visited,stack)
24
IndexError: list index out of range
IndexError: list index out of range
是因为此示例代码假定顶点从零开始编号。
列表visited
初始化为:
visited = [False]*self.V
因此,如果图初始化为 5 个顶点,则 visited
的索引将为 0、1、2、3、4。
然后,函数 topologicalSortUtil(self, v, visited, stack)
执行下面的第 22 行,顶点 5
超出范围,因为范围从 0 到 4:
21 for i in self.graph[v]:
---> 22 if visited[i] == False:
23 self.topologicalSortUtil(i,visited,stack)
以下使用从零开始的顶点索引的代码按预期工作。
g = Graph(5)
g.addEdge(0, 1)
g.addEdge(1, 2)
g.addEdge(2, 3)
g.addEdge(3, 4)
print("Following is a Topological Sort of the given graph")
g.topologicalSort()
输出:
Following is a Topological Sort of the given graph
[0, 1, 2, 3, 4]
适用于任意顶点数的拓扑排序实现
以下实现不需要您指定顶点数,因为每当通过 add_edge
方法将新顶点添加到图中时,计数会自动增加。
此外,顶点不需要以任何特定数字开头。我继续清理格式以使用标准的蛇形命名约定。
from collections import defaultdict
class Graph:
def __init__(self):
self.graph = defaultdict(list) #dictionary containing adjacency List
def add_edge(self,u,v):
self.graph[u].append(v)
def topological_sort(self) -> list:
visited = set()
reverse_topo = list()
vertices = set(self.graph.keys())
for vertex in vertices:
if vertex not in visited:
self._topological_sort_util(vertex, visited, reverse_topo)
return list(reversed(reverse_topo))
def _topological_sort_util(self, vertex, visited, reverse_topo):
visited.add(vertex)
for adj_vertex in self.graph[vertex]:
if adj_vertex not in visited:
self._topological_sort_util(adj_vertex, visited, reverse_topo)
reverse_topo.append(vertex)
g = Graph()
g.add_edge(1, 2)
g.add_edge(2, 3)
g.add_edge(3, 4)
g.add_edge(4, 5)
print("Following is a Topological Sort of the given graph")
vertices_topo_sorted = g.topological_sort()
print(vertices_topo_sorted)
输出
Following is a Topological Sort of the given graph
[1, 2, 3, 4, 5]