传递归约算法:伪代码?
我一直在寻找一种算法来对图执行传递约简,但没有成功。我的算法圣经(Cormen 等人的算法简介)中没有任何内容,虽然我已经看到了大量传递闭包伪代码,但我无法找到任何减少的东西。我得到的最接近的是 Volker Turau 的《Algorithmische Graphtheorie》(ISBN:978-3-486-59057-9),但不幸的是我无法访问这本书!维基百科没有任何帮助,谷歌也没有发现任何东西。 :^(
有谁知道执行传递归约的算法吗?
I have been looking for an algorithm to perform a transitive reduction on a graph, but without success. There's nothing in my algorithms bible (Introduction To Algorithms by Cormen et al) and whilst I've seen plenty of transitive closure pseudocode, I haven't been able to track down anything for a reduction. The closest I've got is that there is one in "Algorithmische Graphentheorie" by Volker Turau (ISBN:978-3-486-59057-9), but unfortunately I don't have access to this book! Wikipedia is unhelpful and Google is yet to turn up anything. :^(
Does anyone know of an algorithm for performing a transitive reduction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
见哈里·许。 “一种查找有向图的最小等价图的算法。”,Journal of the ACM,22(1):11-16,1975 年 1 月。下面的简单三次算法(使用 N x N 路径矩阵)足以满足 DAG,但 Hsu 将其推广到循环图。
See Harry Hsu. "An algorithm for finding a minimal equivalent graph of a digraph.", Journal of the ACM, 22(1):11-16, January 1975. The simple cubic algorithm below (using an N x N path matrix) suffices for DAGs, but Hsu generalizes it to cyclic graphs.
我使用的传递归约算法的基本要点是
我在同一脚本中使用的传递闭包算法非常相似,但最后一行是
The basic gist of the transitive reduction algorithm I used is
The transitive closure algorithm I used in the same script is very similar but the last line is
基于 Alan Donovan 提供的参考资料,其中指出您应该使用路径矩阵(如果存在从节点 i 到节点 j 的路径,则该矩阵的值为 1),而不是邻接矩阵(仅当存在边时该矩阵的值为 1)从节点 i 到节点 j)。
下面是一些示例 python 代码,以显示解决方案输出之间的差异
:
Based on the reference provided by Alan Donovan, which says you should use the path matrix (which has a 1 if there is a path from node i to node j) instead of the adjacency matrix (which has a 1 only if there is an edge from node i to node j).
Some sample python code follows below to show the differences between the solutions
Output:
关于传递归约的维基百科文章指向 GraphViz 中的实现(开源) 。不完全是伪代码,但也许可以从某个地方开始?
LEDA 包含一个传递归约算法。我不再有 LEDA 书 的副本,并且此功能可能是书出版后添加的。但如果它在那里,那么就会有对算法的很好的描述。
Google 指出有人建议将其纳入 Boost 的一种算法 。我没有尝试阅读它,所以也许不正确?
另外,这个可能值得一看。
The Wikipedia article on transitive reduction points to an implementation within GraphViz (which is open source). Not exactly pseudocode, but maybe someplace to start?
LEDA includes a transitive reduction algorithm. I don't have a copy of the LEDA book anymore, and this function might have been added after the book was published. But if it's in there, then there will be a good description of the algorithm.
Google points to an algorithm that somebody suggested for inclusion in Boost. I didn't try to read it, so maybe not correct?
Also, this might be worth a look.
伪Python中的深度优先算法:
该算法不是最优的,但处理了先前解决方案的多边跨度问题。结果与 graphviz 生成的 tred 非常相似。
Depth-first algorithm in pseudo-python:
The algorithm is sub-optimal, but deals with the multi-edge-span problem of the previous solutions. The results are very similar to what tred from graphviz produces.
“girlwithglasses”的算法忘记了冗余边可以跨越三个边的链。要更正,请计算 Q = R x R+,其中 R+ 是传递闭包,然后删除 R 中出现在 Q 中的所有边。另请参阅维基百科文章。
The algorithm of "girlwithglasses" forgets that a redundant edge could span a chain of three edges. To correct, compute Q = R x R+ where R+ is the transitive closure and then delete all edges from R that show up in Q. See also the Wikipedia article.
移植到 java / jgrapht,本页上的 python 示例来自@Michael Clerx:
单元测试:
测试输出
ported to java / jgrapht, the python sample on this page from @Michael Clerx:
unit test :
test ouput
这是一个借鉴了 NetworkX 图书馆。其中使用的两个函数是拓扑排序(用于检测循环)和 DFS(用于查找从凝视顶点可到达的所有顶点)。所有这些都可以在没有任何依赖的情况下实现,我在我的 GitHub 上有一个完整的实现。但是,它位于私人存储库中,因此,我将模块的完整内容复制粘贴到此处。
有关提高算法效率的详细讨论,请参阅 这个。
Here is a Python implementation that borrows from the NetworkX library. Two functions used in it are topological sort to detect cycles, and DFS to find all vertices reachable from a staring vertex. All of these can be implemented without any dependencies, I’ve a complete implementation on my GitHub. However, it’s in a private repo, so, I’m copy-pasting the complete content of the module here.
For a detailed discussion of improving the efficiency of the algorithm, see this.