- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是我为 Kosaraju 算法编写的代码的第一部分。
###### reading the data #####
with open('data.txt') as req_file:
ori_data = []
for line in req_file:
line = line.split()
if line:
line = [int(i) for i in line]
ori_data.append(line)
###### forming the Grev ####
revscc_dic = {}
for temp in ori_data:
if temp[1] not in revscc_dic:
revscc_dic[temp[1]] = [temp[0]]
else:
revscc_dic[temp[1]].append(temp[0])
print revscc_dic
######## finding the G#####
scc_dic = {}
for temp in ori_data:
if temp[0] not in scc_dic:
scc_dic[temp[0]] = [temp[1]]
else:
scc_dic[temp[0]].append(temp[1])
print scc_dic
##### iterative dfs ####
path = []
for i in range(max(max(ori_data)),0,-1):
start = i
q=[start]
while q:
v=q.pop(0)
if v not in path:
path.append(v)
q=revscc_dic[v]+q
print path
代码读取数据并正确形成 Grev 和 G。我已经为迭代 dfs 编写了代码。我怎样才能包括找到完成时间?我知道用纸和笔找到完成时间,但我不明白作为代码的完成时间部分??我该如何实现它.. 只有在这之后我才能继续我的下一部分代码。请帮助。提前致谢。
data.txt 文件包含:
1 4
2 8
3 6
4 7
5 2
6 9
7 1
8 5
8 6
9 7
9 3
请保存为data.txt。
最佳答案
使用递归 dfs,很容易看出给定顶点何时“完成”(即当我们访问了 dfs 树中的所有子节点时)。可以在递归调用返回后立即计算完成时间。
然而,对于迭代 dfs,这并不容易。现在我们正在使用 while 循环迭代处理队列,我们已经丢失了一些与函数调用相关联的嵌套结构。或者更准确地说,我们不知道回溯何时发生。不幸的是,如果不向我们的顶点堆栈添加一些额外信息,就无法知道回溯何时发生。
向您的 dfs 实现添加完成时间的最快方法如下:
##### iterative dfs (with finish times) ####
path = []
time = 0
finish_time_dic = {}
for i in range(max(max(ori_data)),0,-1):
start = i
q = [start]
while q:
v = q.pop(0)
if v not in path:
path.append(v)
q = [v] + q
for w in revscc_dic[v]:
if w not in path: q = [w] + q
else:
if v not in finish_time_dic:
finish_time_dic[v] = time
time += 1
print path
print finish_time_dic
这里使用的技巧是,当我们从堆栈中弹出 v
时,如果这是我们第一次看到它,那么我们再次将它添加回堆栈。这是使用:q = [v] + q
完成的。我们必须将 v
压入堆栈 before 我们压入它的邻居(我们编写压入 v
的代码 before插入 v
的邻居的 for 循环) - 否则这个技巧不起作用。最终我们将再次从堆栈中弹出v
。此时,v 已完成!我们之前见过 v
,所以,我们进入 else 情况并计算新的完成时间。
对于提供的图表,finish_time_dic
给出了正确的完成时间:
{1: 6, 2: 1, 3: 3, 4: 7, 5: 0, 6: 4, 7: 8, 8: 2, 9: 5}
请注意,尽管我们正在插入图形到堆栈上两次。然而,存在更优雅的解决方案。我推荐阅读 Magnus Lie Hetland(ISBN:1430232374、9781430232377)的 Python 算法:掌握 Python 语言中的基本算法 的第 5 章。问题 5-6 和 5-7(第 122 页)准确描述了您的问题。作者回答了这些问题并给出了问题的替代解决方案。
问题:
5-6 In recursive DFS, backtracking occurs when you return from one of the recursive calls. But where has the backtracking gone in the iterative version?
5-7. Write a nonrecursive version of DFS that can deal determine finish-times.
答案:
5-6 It’s not really represented at all in the iterative version. It just implicitly occurs once you’ve popped off all your “traversal descendants” from the stack.
5-7 As explained in Exercise 5-6, there is no point in the code where backtracking occurs in the iterative DFS, so we can’t just set the finish time at some specific place (like in the recursive one). Instead, we’d need to add a marker to the stack. For example, instead of adding the neighbors of u to the stack, we could add edges of the form
(u, v)
, and before all of them, we’d push(u, None)
, indicating the backtracking point foru
.
关于python - kosaraju 使用迭代 dfs 寻找完成时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24051386/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 8 年前。 Improve
假设我们在有向图上运行 sharir kosaraju 算法。我们在这张图上有一条弧 (u,v)。在这个算法中,我们有两个 DFS 通过。现在假设我们将顶点 u 插入到第一棵深度树 T 中。v 可以出
在有向图中,要找到强连通分量(使用 Kosaraju 算法),如果我们可以在完成时间之前使用节点的反向列表然后遍历原始图,为什么我们必须转置邻接矩阵(反转所有边的方向) .换句话说,我们会找到所有顶点
我使用的是 mac、4GB RAM 和 CLion IDE。编译器是 Clang。我需要在这个深度优先搜索的递归实现中允许更多的递归(目前在具有 80k 节点的图上失败)。 typedef unord
我为已过截止日期的作业编写了此代码。 此实现完全适用于各种较小的测试用例,并在图表中显示 5 个最大的强连通组件的大小。 但是当我在大约 875714 个顶点的分配数据集上运行它时,它似乎永远执行。
我正在尝试解决 http://www.spoj.com/problems/BOTTOM/ 以下是我要执行的步骤: 1) 使用 Kosaraju 算法找到强连通分量。 2) 考虑一个强连接的组件。考虑一
谁能给我解释一下 Kosaraju 寻找连通分量的算法背后的逻辑? 我已阅读 description ,尽管我不明白反转图上的 DFS 如何检测强连通分量的数量。 def dfs(visited, s
有一个著名的求强连通分量的算法叫做 Kosaraju 算法,它使用两个 DFS 来解决这个问题,并在 θ(|V| + |E|) 时间。 首先,我们对图 (GR) 的补集使用 DFS 来计算顶点的反向后
这是我为 Kosaraju 算法编写的代码的第一部分。 ###### reading the data ##### with open('data.txt') as req_file:
我正在学习 Kosaraju 算法以从这里找到强连通分量 Kosaraju algorithm . 但是我不明白按照完成时间的递减顺序执行 dfs(G^T) 的必要性是什么,即上面链接中第 3 点中提
我无法理解 Kosaraju 用于查找有向图的强连通分量的算法。这是我笔记本上的内容(我是学生 :D): 从任意顶点开始(用#1 标记)并执行 DFS。当你不能再进一步时,用 #2 标记最后访问的顶点
假设我们有一个有向图,它不是一个完整的图并且有多个 SCC。我想知道如果我们转置图形并使用 Kosaraju 算法,强连通分量的模式是否会改变?通过说“转置图形”我的意思是翻转边缘的方向。如果我们尝试
我目前有一个 Kosaraji 算法的工作实现,给定一个没有权重的有向图,将在图中打印 SCC。 我想对其进行调整,以便它也说明 SCC 之间的边缘位置。 代码如下: from collections
Kosaraju 的算法陈述如下: #Input is graph G 1-define G_rev (links in reversed order) 2-Find the finishing ti
我是一名优秀的程序员,十分优秀!