首页 > 编程语言 >数据结构与算法Python版 拓扑排序与强连通分支

数据结构与算法Python版 拓扑排序与强连通分支

时间:2025-01-01 17:29:02浏览次数:3  
标签:排序 Python self dfs 算法 顶点 连通分支 数据结构

文章目录


一、图的应用-拓扑排序

拓扑排序Topological Sort

  • 工作流程图得到工作次序排列的算法,称为“拓扑排序”
  • 拓扑排序处理一个有向无环图DAG,输出顶点的线性序列。使得两个顶点v,w,如果图中有(v,w)边,在线性
    序列中v就出现在w之前。
  • 拓扑排序广泛应用在依赖事件的排期上,还可以用在项目管理、数据库查询优化和矩阵乘法的次序优化上

拓扑排序的实现

  • 拓扑排序可以采用深度优先搜索DFS实现。
    • 将工作流程建立为图,工作项是节点依赖关系是有向边。工作流程图一定是个有向无环图DAG,否则出现循环依赖。
    • 对DAG图调用DFS算法,以得到每个顶点的“结束时间”,按照每个顶点的“结束时间”从大到小排序,输出这个次序下的顶点列表
  • 根据遍历次序的不同,拓扑排序的结果可能有多个

示例:

在这里插入图片描述

# 将工作流程建立为图
dfs_g = DFSGraph()
dfs_g.add_edge("3/4 cup milk", "1 cup mix")
dfs_g.add_edge("1 egg", "1 cup mix")
dfs_g.add_edge("1 tbl oil", "1 cup mix")
dfs_g.add_edge("1 cup mix", "pour 1/4 cup")
dfs_g.add_edge("1 cup mix", "heat syrup")
dfs_g.add_edge("heat griddle", "pour 1/4 cup")
dfs_g.add_edge("pour 1/4 cup", "turn when bubbly")
dfs_g.add_edge("turn when bubbly", "eat")
dfs_g.add_edge("heat syrup", "eat")

dfs_g.dfs()
res = []
for i in dfs_g.vertexes.values():
    res.append((i.finish, i.key))
# 按照每个顶点的“结束时间”从大到小排序
res.sort(key=lambda x: x[0], reverse=True)
print("拓扑排序结果:", res)


### 输出结果
拓扑排序结果: [(18, 'heat griddle'), (16, '1 tbl oil'), (14, '1 egg'), (12, '3/4 cup milk'), (11, '1 cup mix'), (10, 'heat syrup'), (8, 'pour 1/4 cup'), (7, 'turn when bubbly'), (6, 'eat')]

在这里插入图片描述

二、图的应用-强连通分支

强连通分支Strongly Connected Components

  • 强连通分支,定义为图G的一个子集C。C中的任意两个顶点v,w之间都有路径来回,即(v,w)(w,v)都是C的路径,而且C是具有这样性质的最大子集
  • Transposition转置:一个有向图G的转置GT,定义为将图G的所有边的顶点交换次序,如将(v,w)转换为(w,v)。图和转置图在强连通分支的数量和划分上,是相同的。
  • 常用强连通分支算法有Tarjan算法、Gabow算法(对Tarjan的改进)和Kosaraju算法,这些算法的基本思想是进行深度优先搜索,并通过标记来识别强连通分支。

在这里插入图片描述

寻找强连通分支(在图中发现高度聚集节点群)的应用

  • 网络分析
    • 在社交网络分析中,强连通分支可以帮助识别紧密联系的小团体或者社区。
    • 在通信网络中,强连通分支可用于优化路由策略,提高网络的稳定性和效率。
  • 算法设计:在算法设计中,特别是在有向图的处理算法中,例如拓扑排序,识别强连通分支可以简化问题,使得算法更加高效。
  • 系统建模:在系统动态和反馈系统分析中,强连通分支能够揭示系统内部各部分之间的相互作用和依赖关系。
  • 程序分析:在软件工程中,特别是在编译器的控制流分析中,强连通分支有助于理解程序中的循环结构,优化代码。
  • 经济学和博弈论:在经济学模型中,强连通分支可以用来分析市场中的不同参与者之间的相互作用和影响。
  • 生物信息学:在生物信息学中,可以通过分析蛋白质之间的相互作用网络,利用强连通分支来识别关键的生物分子和途径。
  • 数据挖掘:在数据挖掘中,识别大型数据库中的强连通分支有助于发现数据之间的深层次联系。

在这里插入图片描述

强连通分支算法-Kosaraju算法思路

  • 首先,对图G调用深度优先搜索DFS算法,为每个顶点计算“结束时间”;
  • 然后,将图G进行转置,得到GT;
  • 再对GT调用DFS算法,但在dfs函数中,对每个顶点的搜索循环里,要以顶点的“结束时间”倒序的顺序来搜索。
  • 每次DFS访问到的节点构成一个强连通分支

示例

### 更新了DFSGraph类
class DFSGraph(Graph):
    def __init__(self):
        super().__init__()
        self.time = 0

    def dfs(self, keys_order=None):
        """keys_order参数:可指定遍历顶点的次序"""
        # 初始化顶点颜色和前驱
        for v in self:
            v.set_color("white")
            v.set_pred(-1)
        # 遍历未访问的顶点
        if keys_order:
            for key in keys_order:
                v = self.vertexes.get(key)
                if v.get_color() == "white":
                    scc = [] # 记录每个强连通分支
                    self.dfsvisit(v, scc)
                    print(scc)
        else:
            for v in self:
                if v.get_color() == "white":
                    self.dfsvisit(v)

    def dfsvisit(self, start_v: Vertex, tmp=[]):
        tmp.append(start_v.key)
        start_v.set_color("gray")
        self.time += 1
        # 记录第几步访问到这个顶点
        start_v.discovery = self.time
        for next_v in start_v.get_connections():
            # 递归访问未访问的顶点并记录前驱
            if next_v.get_color() == "white":
                next_v.set_pred(start_v)
                self.dfsvisit(next_v, tmp)
        start_v.set_color("black")
        self.time += 1
        # 记录在第几步完成了此顶点探索
        start_v.finish = self.time
        
        
edges = [
    ["A", "B"],
    ["B", "C"],
    ["B", "E"],
    ["C", "C"],
    ["C", "F"],
    ["D", "B"],
    ["D", "G"],
    ["E", "D"],
    ["E", "A"],
    ["F", "H"],
    ["G", "E"],
    ["H", "I"],
    ["I", "F"],
]
# 对图G调用DFS算法,为每个顶点计算“结束时间”
dfs_g = DFSGraph()
for i in edges:
    dfs_g.add_edge(i[0], i[1])
dfs_g.dfs()
res = []
for i in dfs_g.vertexes.values():
    res.append((i.finish, i.key))
res.sort(key=lambda x: x[0], reverse=True)  # “结束时间”从大到小排序
print("第一趟DFS按“结束时间”从大到小排序:")
print(res)
keys_order = [i[1] for i in res]


### 输出结果
第一趟DFS按“结束时间”从大到小排序:
[(18, 'A'), (17, 'B'), (16, 'E'), (15, 'D'), (14, 'G'), (10, 'C'), (9, 'F'), (8, 'H'), (7, 'I')]

第一趟DFS后
在这里插入图片描述

# 按照第一步记录的完成时间逆序对反转图进行DFS
dfs_gt = DFSGraph()
for i in edges:
    dfs_gt.add_edge(i[1], i[0])
print("强连通分支如下:")
dfs_gt.dfs(keys_order)


### 输出结果
强连通分支如下:
['A', 'E', 'B', 'D', 'G']
['C']
['F', 'I', 'H']

转置后第二趟DFS后
在这里插入图片描述

强连通分支如下:

在这里插入图片描述


您正在阅读的是《数据结构与算法Python版》专栏!关注不迷路~

标签:排序,Python,self,dfs,算法,顶点,连通分支,数据结构
From: https://blog.csdn.net/zljgzw/article/details/144869432

相关文章

  • 【“C语言高冷,Java正统,python亲民...”】
    1.引言     在编程语言的世界中,每种语言不仅是工具,还带有一定的文化和气质特征。例如,人们将C语言称为“高冷”,因为它以性能和底层控制而闻名;Java被认为“正统”,它的“编写一次,到处运行”理念深入人心;Python则以其简单易用和包容性社区被称为“亲民”。     ......
  • 基于高德地图API在Python中实现地图功能的方法
      本文介绍在高德开放平台中,申请、获取地图API的Key的方法;同时通过简单的Python代码,调取API信息,对所得Key的可用性加以验证。  首先,我们进入高德开放平台的官方网站。如果大家是第一次使用高德地图开放平台,那么需要点击右上角注册一个开发者账号。  注册完毕后,登录这一账......
  • 使用Arduino, Python, Lua等来做单片机开发等同于走绝路!
    一,首先问一下:你们知道Arduino,Python,Lua等做单片机开发到底是什么原理?这边给出一个Lua的:  https://www.cnblogs.com/yangfengwu/p/9315841.html实际上就是说Arduino,Python,Lua做开发是调用的别人使用C语言封装的函数!现在思考下:1,别人能100%的把单片机的所有功能......
  • 【Miscellaneous】一道高质量的杂项题,涉及暴破、Cloakify-python2、零宽、emoji-AES等
    引言下半年很忙,好久不做题,趁2025元旦放假整理一道高质量的题目,怀念一下繁忙的2024年。题目考虑到某公司的不分享精神或许会有版权之类的争端,文件链接以后就不放了。名称:happymd5提示:有好多奇奇怪怪的MD5值,这是用来干什么的呢。Writeup(WP)题目附件cipher.zip压缩包,里面两个......
  • 【Python系列】处理空请求体Body
    ......
  • Python PySide + SQLite3 开发的 《️ POS点销管理系统》可用初型
    图:   目录:开发说明书:POS点销管理系统开发说明1.系统概述本系统是一个基于PythonPySide6开发的现代化POS点销管理系统,集成了商品管理、库存管理、会员管理、订单管理等核心功能。2.技术栈开发语言:Python3.8+GUI框架:PySide6数据库:SQLite3......
  • Python生成验证码
    1.Python3.x中安装Pillow模块pipinstallpillow 2.Python生成验证码(Python生成数字英文验证码,Python生成验证码,文章摘自:https://www.cnblogs.com)'''PIL(PythonImagingLibrary)是Python一个强大方便的图像处理库,名气也比较大。不过只支持到Python2.7在Python2中......
  • python毕设 物业管理系统程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景在当今社会,随着城市化进程的加速,物业管理的规模和复杂度不断增加。关于物业管理系统的研究,现有研究主要以传统管理模式向数字化转型为......
  • 《100天学习Python:从入门到精通》——第4天:Python变量的定义及使用
    大家好啊,今天我就来和大家分享一下关于变量的定义及使用吧。1.Python变量的定义及初始化Python变量名要求:1.变量名只能由字母、下划线、数字组成,不能是别的符号。2.变量名开头只能是字母和下划线,不能是数字。3.尽量不要与Python标准库里的函数或第三方模块中的函数重名。......
  • python下载,安装,环境配置
    下载地址:PythonWindows版本下载|Python中文网官网选择路径安装完成检测安装是否成功使用win+r启动运行对话框,输入cmd进入命令行。输入piplist输入wherepython查看python.exe的路径环境配置win+r打开运行对话框,输入sysdm.cp1,回车后进入系统......