基本概念
- 有向⽆环图:没有环的有向图
- 拓扑序:有向图 的拓扑序是指满⾜下列条件的顶点序列 v1,v2,…,vn
- 对于每⼀条边(vi. vj) ,都有i < j
以这张图为例:
- 没有从后面指到前面的箭头(边)。
算法的基本原理
代码实现
import numpy as np
import pandas as pd
MAX_VERTICES_NUM = 1000000
edges = [[2, 3], [2, 5], [2, 6], [3, 5], [3, 4], [6, 7], [5, 6], [5, 7], [4, 5], [1, 7], [1, 5], [1, 4]]
class Graph:
def __init__(self):
# 邻接表
self.Adj = [[] for i in range(MAX_VERTICES_NUM)]
self.vis = [False for i in range(MAX_VERTICES_NUM)]
# 当前结点的数量
self.v_num = 0
# 拓扑排序的cur label
self.cur_label = 0
# 拓扑排序的f值
self.f_list = list()
def load_edges(self, edges):
node_list = []
for head, tail in edges:
node_list.append(head)
node_list.append(tail)
self.Adj[head].append(tail)
for l in self.Adj:
l.sort()
# 统计结点数量
self.v_num = np.unique(node_list).size
# cur label初始化
self.cur_label = self.v_num
# f值列表初始化
self.f_list = [-1 for i in range(MAX_VERTICES_NUM)]
def explore(self, v):
self.vis[v] = True
for u in self.Adj[v]:
if not self.vis[u]:
self.explore(u)
self.f_list[v] = self.cur_label
self.cur_label -= 1
def topo_sort(self):
self.vis = [False for i in range(MAX_VERTICES_NUM)]
# 结点从1开始
for v in range(1, MAX_VERTICES_NUM):
if not self.vis[v]:
self.explore(v)
print(self.f_list[:self.v_num + 1])
G = Graph()
G.load_edges(edges)
G.topo_sort()
输出结果为:[-1, 3, 1, 2, 4, 5, 6, 7]
。忽略第0个值,从第1个值开始,它代表的是每个结点的位置。也就是[2, 3, 1, 4, 5, 6, 7]
。
参考文献
- https://blog.csdn.net/qq_26760433/article/details/84242686