Return 使用 Kahn 算法的图形中的所有拓扑排序顺序?
Return all topological sort orderings in a graph using Kahn's algorithm?
我正在尝试解决一种情况,我已经实现了卡恩的算法来查找和 return 图中的一种拓扑排序。但是,我想尝试实现这个以便 return 所有拓扑顺序。例如,如果一个图有 4 个具有以下边的节点:
(1 2)
(1 3)
(2 3)
(2 4)
它将return以下两种可能的拓扑顺序:
[1 2 3 4]
[1 2 4 3]
无论如何我可以用下面的代码来做这个:
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)
# The function to do Topological Sort.
def topologicalSort(self):
# Create a vector to store indegrees of all
# vertices. Initialize all indegrees as 0.
in_degree = [0]*(self.V)
# Traverse adjacency lists to fill indegrees of
# vertices. This step takes O(V+E) time
for i in self.graph:
for j in self.graph[i]:
in_degree[j] += 1
# Create an queue and enqueue all vertices with
# indegree 0
queue = []
for i in range(self.V):
if in_degree[i] == 0:
queue.append(i)
#Initialize count of visited vertices
cnt = 0
# Create a vector to store result (A topological
# ordering of the vertices)
top_order = []
# One by one dequeue vertices from queue and enqueue
# adjacents if indegree of adjacent becomes 0
while queue:
# Extract front of queue (or perform dequeue)
# and add it to topological order
u = queue.pop(0)
top_order.append(u)
# Iterate through all neighbouring nodes
# of dequeued node u and decrease their in-degree
# by 1
for i in self.graph[u]:
in_degree[i] -= 1
# If in-degree becomes zero, add it to queue
if in_degree[i] == 0:
queue.append(i)
cnt += 1
# Check if there was a cycle
if cnt != self.V:
print "There exists a cycle in the graph"
else :
#Print topological order
print top_order
#Test scenario
g = Graph(4);
g.addEdge(1, 2);
g.addEdge(1, 2);
g.addEdge(2, 3);
g.addEdge(2, 4);
g.topologicalSort()
您的问题陈述与 NetworkX all topo sorts 函数匹配。
如果您只想要结果,我建议按原样调用它们的函数。
如果你想破解一个实现,他们的源代码可能会告诉你自己的。在那种情况下,您可能会选择从 Kahn 的算法切换到他们引用的 Knuth 的算法。
请注意,图节点索引以 0
:
开头
g.addEdge(1, 2); # replace with 0, 1 and so on
通过这个修改,这个算法returns只有一个拓扑排序,而图可以有更多的排序,因为我们总是select只有队列中的第一个项目。要获得所有排序,您可以使用此修改后的代码:
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)
# The function to do Topological Sort.
def topologicalSort(self):
# Create a vector to store indegrees of all
# vertices. Initialize all indegrees as 0.
in_degree = [0] * self.V
# Traverse adjacency lists to fill indegrees of
# vertices. This step takes O(V+E) time
for i in self.graph:
for j in self.graph[i]:
in_degree[j] += 1
# Create an queue and enqueue all vertices with
# indegree 0
queue = []
for i in range(self.V):
if in_degree[i] == 0:
queue.append(i)
self.process_queue(queue[:], in_degree[:], [], 0)
def process_queue(self, queue, in_degree, top_order, cnt):
if queue:
# We have multiple possible next nodes, generate all possbile variations
for u in queue:
# create temp copies for passing to process_queue
curr_top_order = top_order + [u]
curr_in_degree = in_degree[:]
curr_queue = queue[:]
curr_queue.remove(u)
# Iterate through all neighbouring nodes
# of dequeued node u and decrease their in-degree
# by 1
for i in self.graph[u]:
curr_in_degree[i] -= 1
# If in-degree becomes zero, add it to queue
if curr_in_degree[i] == 0:
curr_queue.append(i)
self.process_queue(curr_queue, curr_in_degree, curr_top_order, cnt + 1) # continue recursive
elif cnt != self.V:
print("There exists a cycle in the graph")
else:
#Print topological order
print(top_order)
g = Graph(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(1, 3);
g.topologicalSort()
输出:
[0, 1, 2, 3]
[0, 1, 3, 2]
我正在尝试解决一种情况,我已经实现了卡恩的算法来查找和 return 图中的一种拓扑排序。但是,我想尝试实现这个以便 return 所有拓扑顺序。例如,如果一个图有 4 个具有以下边的节点:
(1 2)
(1 3)
(2 3)
(2 4)
它将return以下两种可能的拓扑顺序:
[1 2 3 4]
[1 2 4 3]
无论如何我可以用下面的代码来做这个:
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)
# The function to do Topological Sort.
def topologicalSort(self):
# Create a vector to store indegrees of all
# vertices. Initialize all indegrees as 0.
in_degree = [0]*(self.V)
# Traverse adjacency lists to fill indegrees of
# vertices. This step takes O(V+E) time
for i in self.graph:
for j in self.graph[i]:
in_degree[j] += 1
# Create an queue and enqueue all vertices with
# indegree 0
queue = []
for i in range(self.V):
if in_degree[i] == 0:
queue.append(i)
#Initialize count of visited vertices
cnt = 0
# Create a vector to store result (A topological
# ordering of the vertices)
top_order = []
# One by one dequeue vertices from queue and enqueue
# adjacents if indegree of adjacent becomes 0
while queue:
# Extract front of queue (or perform dequeue)
# and add it to topological order
u = queue.pop(0)
top_order.append(u)
# Iterate through all neighbouring nodes
# of dequeued node u and decrease their in-degree
# by 1
for i in self.graph[u]:
in_degree[i] -= 1
# If in-degree becomes zero, add it to queue
if in_degree[i] == 0:
queue.append(i)
cnt += 1
# Check if there was a cycle
if cnt != self.V:
print "There exists a cycle in the graph"
else :
#Print topological order
print top_order
#Test scenario
g = Graph(4);
g.addEdge(1, 2);
g.addEdge(1, 2);
g.addEdge(2, 3);
g.addEdge(2, 4);
g.topologicalSort()
您的问题陈述与 NetworkX all topo sorts 函数匹配。
如果您只想要结果,我建议按原样调用它们的函数。
如果你想破解一个实现,他们的源代码可能会告诉你自己的。在那种情况下,您可能会选择从 Kahn 的算法切换到他们引用的 Knuth 的算法。
请注意,图节点索引以 0
:
g.addEdge(1, 2); # replace with 0, 1 and so on
通过这个修改,这个算法returns只有一个拓扑排序,而图可以有更多的排序,因为我们总是select只有队列中的第一个项目。要获得所有排序,您可以使用此修改后的代码:
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)
# The function to do Topological Sort.
def topologicalSort(self):
# Create a vector to store indegrees of all
# vertices. Initialize all indegrees as 0.
in_degree = [0] * self.V
# Traverse adjacency lists to fill indegrees of
# vertices. This step takes O(V+E) time
for i in self.graph:
for j in self.graph[i]:
in_degree[j] += 1
# Create an queue and enqueue all vertices with
# indegree 0
queue = []
for i in range(self.V):
if in_degree[i] == 0:
queue.append(i)
self.process_queue(queue[:], in_degree[:], [], 0)
def process_queue(self, queue, in_degree, top_order, cnt):
if queue:
# We have multiple possible next nodes, generate all possbile variations
for u in queue:
# create temp copies for passing to process_queue
curr_top_order = top_order + [u]
curr_in_degree = in_degree[:]
curr_queue = queue[:]
curr_queue.remove(u)
# Iterate through all neighbouring nodes
# of dequeued node u and decrease their in-degree
# by 1
for i in self.graph[u]:
curr_in_degree[i] -= 1
# If in-degree becomes zero, add it to queue
if curr_in_degree[i] == 0:
curr_queue.append(i)
self.process_queue(curr_queue, curr_in_degree, curr_top_order, cnt + 1) # continue recursive
elif cnt != self.V:
print("There exists a cycle in the graph")
else:
#Print topological order
print(top_order)
g = Graph(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(1, 3);
g.topologicalSort()
输出:
[0, 1, 2, 3]
[0, 1, 3, 2]