zoukankan      html  css  js  c++  java
  • python 排序 拓扑排序

    在计算机科学领域中,有向图的拓扑排序是其顶点的先行排序,对于每个从顶点u到顶点v的有向边uv,在排序的结果中u都在v之前。

    如果图是有向无环图,则拓扑排序是可能的(为什么不说一定呢?)

    任何DAG具有至少一个拓扑排序,并且这些已知算法用于在线性时间内构建任何DAG的拓扑排序

    图论:是组合数学的一个分支,它和其他分支比如:群论、拓扑学、矩阵论有着密切的关系。图是图论的主要研究对象。图是由若干给定的顶点以及连接两定点的变构成的图形,这些图形通常用来描述某些事物间的某种特定关系。顶点用于代表事物,而顶点之间的边则代表事物之间具有这种特定关系。

    在图论中,由一个有向无环图的顶点组成的序列,并且仅当满足以下条件时,称为改图的一个拓扑排序:

      每个顶点只出现一次

      当在序列中A出现在B以前,则图中不存在由B指向A的路径

    算法思想

    卡恩算法

      找到入度为0的点,将该点放到结果中,然后再图中将此节点相连的边删去,重新搜索图,再次找到入度为0的点,因为这个点的父节点已经出现在结果集中,所以该点也能被放入结果集中。重复直到图中没有入度为0的点

      如果此时结果集中的点个数等于原来图中的点的个数,就说明排序成功完成,否则就说明待排序的图不是有向无环图,无法排序

    算法步骤

      对于已经是有向无环图的排序过程:

      找到入度为0的点,放入结果集中,然后删去与该节点相连的边

      重复执行上述操作,直到结果中点的个数和图的节点数相同

    算法实现:

      

    def topological_sort(G):
        '''找到入度为0的节点a,然后将其放在序列中,删去这个a的邻接点列表'''
        topological_list=[]
        node_list=list(range(len(G)))
        node_list_temp=copy.deepcopy(node_list)#为node_list选择的备份原因如下:
        #如果找到的第一个入度为0的点不删去,那么每次while结束选择的都将是这个点
        #但是也不能在遍历node_list时删去,那样会造成死循环(类似与for i in range(a):,在循环中又对a进行操作的意思
        while True:
            
            if len(topological_list)==len(G):
                return topological_list
            node_list=node_list_temp
            for node in node_list:
                flage=True
                for i in range(len(G)):#在所有结点的邻接点列表中遍历,若均未存在,说明不依赖任何点,即入度为0
                    if node in G[i]:
                        flage=False
                        break
                if flage:
                    node_list_temp.remove(node)
                    G[node]=[]#选择置空,否则会造成下标溢出
                    topological_list.append(node)
                    break
        # return topological_list
    

    效率分析

      线性时间

    产生和检测有向无环图

    欧拉把问题的实质归于一笔画问题,即判断一个图是否能够遍历完所有的边而没有重复,而柯尼斯堡七桥问题则是一笔画问题的一个具体情境。欧拉最后给出任意一种河──桥图能否全部走一次的判定法则,从而解决了“一笔画问题”。对于一个给定的连通图,如果存在超过两个(不包括两个)奇顶点,那么满足要求的路线便不存在了,且有n个奇顶点的图至少需要n/2笔画出。如果只有两个奇顶点,则可从其中任何一地出发完成一笔画。若所有点均为偶顶点,则从任何一点出发,所求的路线都能实现,他还说明了怎样快速找到所要求的路线。[1]

      

     

  • 相关阅读:
    Excel导出失败的提示
    C#中将一个引用赋值null的作用
    POJ2112Optimal Milking(二分法+floyd最短+网络流量)
    三年流水账
    OpenCV(C++接口)学习笔记1-图像读取、显示、保存
    thinkphp3.2 代码生成并点击验证码
    8.19! 今天我有18生日,点击阅读或顶部 尾随幸运的一天!生日知识!↓——【Badboy】
    如何系统地学习JavaScript
    HDU 3065 病毒在继续 (AC自己主动机)
    使用Canvas和Paint自己绘制折线图
  • 原文地址:https://www.cnblogs.com/Gaoqiking/p/11412248.html
Copyright © 2011-2022 走看看