图应用拓扑排序算法python

#File Name : 图的拓扑排序算法.py
#拓扑排序:在任何一个节点之前,所依赖的节点都做完
#找到所有入度为0的节点,这些节点代表不需要任何的依赖
#删除这些,又有新的入度为0的节点,删掉代表已经做完
#要求有向图且不能有环,有环代表循环依赖

from queue import Queue

class Node(object):
    def __init__(self,value=None):
        self.value = value #节点的值
        self.come = 0 #节点入度
        self.out = 0 #节点出度
        self.nexts = [] #节点的邻居节点
        self.edges = [] #在节点为from的情况下,边的集合
class Edge(object):
    def __init__(self,weight=None,fro,to):
        self.weight = weight # 边的权重
        self.fro = fro # 边的from节点
        self.to = to #边的to节点
class Graph(object):
    def __init__(self):
        self.nodes = {} #图所有节点的集合  字典形式 :{节点编号:节点}
        self.edges = [] #图的边集合
def creatGraph(matrix):
    # 二维数组matrix [权重  从那个点的值  去哪个点的值]
    graph = Graph()
    # 建立所有节点
    for edge in matrix:
        weight = edge[0]
        fro = edge[1]
        to = edge[2]
        if fro not in graph.nodes:
            graph.nodes[fro] = Node(fro)
        if to not in graph.nodes:
            graph.nodes[to] = Node(to)
    #建立所有的边
        fromNode = graph.nodes[fro]
        toNode = graph.nodes[to]
        newEdge = Edge(weight,fromNode,toNode)
        fromNode.nexts.append(toNode) #加上邻居指向
        fromNode.out+=1 #出度+1
        toNode.come+=1 #to 的入度+1
        fromNode.edge.append(newEdge) #边的集合+1
        graph.edges.append(newEdge)

    return graph

def sortedTopology(graph):
    inmap = {} #统计当前所有节点的入度
    queue_zero_come = Queue() #所有入度为0的点入队列
    for node in graph.nodes.values():
        inmap[node] = node.come
        if node.come==0:
            queue_zero_come.put(node)
    #将入度为0的节点加入到列表中
    res = []
    while queue_zero_come.empty() == False :
        cur = queue_zero_come.get()
        res.append(cur)
        # 消除影响,将后序节点的入度减一
        for next in cur.nexts:
            inmap[next] = inmap[next]-1
            if inmap[next] == 0:
                queue_zero_come.put(next)
    return  res

 

拓扑排序是对有向无环进行排序的一种算法,它可以找到一种满足所有任务依赖关系的顺序。在Python中,可以使用collections模块中的deque来实现拓扑排序算法。具体实现步骤如下: 1. 统计每个顶点的入度,即每个顶点有多少个前驱节点。 2. 将入度为0的顶点加入队列。 3. 从队列中取出一个顶点,将其加入结果列表中,并移除该顶点及其相关边。 4. 对于该顶点的所有后继节点,将其入度减1,如果入度为0,则将其加入队列。 5. 重复步骤3和4,直到队列为空。 6. 如果结果列表的长度不等于中顶点的个数,则说明中存在环,无法进行拓扑排序。 下面是一个示例代码,实现了对一个有向无环进行拓扑排序: ``` from collections import deque def topological_sort(graph): # 统计每个顶点的入度 in_degree = {v: 0 for v in graph} for v in graph: for neighbor in graph[v]: in_degree[neighbor] += 1 # 将入度为0的顶点加入队列 queue = deque([v for v in graph if in_degree[v] == 0]) # 保存拓扑排序的结果 result = [] while queue: # 取出队列中的顶点 v = queue.popleft() result.append(v) # 移除顶点及其相关边 for neighbor in graph[v]: in_degree[neighbor] -= 1 if in_degree[neighbor] == 0: queue.append(neighbor) # 判断是否存在环 if len(result) != len(graph): raise ValueError("中存在环,无法进行拓扑排序。") return result # 测试 graph = { 'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': [] } try: result = topological_sort(graph) print("拓扑排序结果:", result) except ValueError as e: print(e) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值