有向图寻找环路python_有向图的深度优先搜索 —— 找出环路

本文通过一个生动的房间探索例子,详细解释了如何使用深度优先搜索在有向图中寻找环路。从房间1出发,记录探索路径,最终在房间5发现环路并返回,模拟了Java程序中虚拟机栈帧的变化和递归过程。
摘要由CSDN通过智能技术生成

一、目标

找出下图(有向图)中的回路

fdcd89dc560f5484512ed39859d72383.png

二、策略

1,深度优先搜索:顾名思义,就是从某个顶点开始探索,会一直探索到某个可能路径的尽头才会停止探索,并原路返回(下面的例子,

并不会一直原路返回到原点,而是每次原路返回一个顶点,就会探索从该点向下的所有路径情况,以此类推);

2,按道理需要从1~7个点都探索一下,看有没有某个回路包含自己;为了简化,我们只从顶点1探索;

3,假设我手中有个笔记本,分别记录3件事情,如下:

48b49b58c6c4c4a1503ea0c197dfcaa8.png

我准备从房间1(如下图)开始探索如下图所示的区域,看能不能发现其中的某个回路(就像鬼打墙那样的回路,会一直路过相同的地方);

fa409b64a1d5e05e57a05ac0cf150b45.png

三,实施

1,我进入房间1,发现有一把钥匙,可以打开房间1中的那两扇门;

A,然后房间1中还有一个柜子localCycles,我撕了一张空白的纸放进柜子中,准备记录一些东西:

b1039bae390778401e25ba73445927eb.png

B,我在我随身携带的本子上记录如下内容:

44a2419228f5d37543ef51a32b27aed1.png

C,使用这个房间的钥匙去打开一扇未曾打开过的门;

我使用房间1中的钥匙打开了东边的门,至于为什么选择东边的门而不是南边的门,我想可能是因为我没有强迫症吧,哪扇门都可以,哈哈;

D,我站在两个房间连接的过道上(其实还是在房间1中的),发现下一个是房间3;

我得先拿出我随身携带的本子,看看有没有这个房间3的相关信息:

1e74e0b0475fedc9984ce592c2ceafcf.png

2,由于本子上并没有房间3的任何信息,所以我走进了房间3;

并且房间3看起来和房间1是一模一样,只是我并没有发现任何钥匙;

A,同样的,我会撕下一张空白的纸放进柜子localCycles中:

877b46ba1ac4555c2332732232e3af53.png

B,我在我随身携带的本子上记录如下内容:

14ca5e6d65ce16c0413c0ef3a26fe519.png

C,使用这个房间的钥匙去打开一扇未曾打开过的门;

因为我没有任何房间3的钥匙,所以即使房间3有门,我也是打不开的,何况,房间3也没有门;没得办法,没有更深的房间可以去了,这条路算是走到了尽头;

E,所以我在我的本子上记录如下内容:

a8b899b0b232dce1f2f7dac91ebf1bb0.png

F,我要原路返回(我用脑子记下了我来时的路,也可以记在本子上)了,我得带上房间3柜子里的纸片,因为回到房间1后,还需要用到它;

3&#x

Python 中可以使用深度优先搜索 (DFS) 和拓扑排序 (Topological Sorting) 两种算法来查找有向图中的环路。 1. DFS 算法: 在 DFS 中,我们遍历整个图,并且记录每个点的访问状态。当我们遍历到一个已经被访问过的点时,意味着我们找到了一个环路。 以下是一个基于 DFS 的有向图环路查找算法的 Python 代码: ```python def has_cycle(graph): visited = set() for node in graph: if node not in visited: if dfs(graph, node, visited): return True return False def dfs(graph, node, visited): visited.add(node) for neighbor in graph[node]: if neighbor not in visited: if dfs(graph, neighbor, visited): return True else: return True visited.remove(node) return False ``` 2. 拓扑排序算法: 拓扑排序是一种对有向无环图 (DAG) 进行排序的算法。如果有向图中存在环路,则无法进行拓扑排序。 以下是一个基于拓扑排序的有向图环路查找算法的 Python 代码: ```python def has_cycle(graph): in_degree = {node: 0 for node in graph} for node in graph: for neighbor in graph[node]: in_degree[neighbor] += 1 queue = [node for node in graph if in_degree[node] == 0] visited = set(queue) while queue: node = queue.pop(0) for neighbor in graph[node]: in_degree[neighbor] -= 1 if in_degree[neighbor] == 0: queue.append(neighbor) visited.add(neighbor) return len(visited) != len(graph) ``` 以上就是 Python 中两种基本的有向图环路查找算法。如果您需要更加高效的实现,建议使用 Tarjan 算法或 Kosaraju 算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值