如果存在循环则进行拓扑排序的算法

问题描述 投票:12回答:2

某些编程语言(如)允许模块之间存在循环依赖性。由于编译器在编译一个模块时需要知道所有导入模块的所有定义,因此如果某些模块相互导入或发生任何其他类型的循环,则通常必须做一些额外的工作。在那种情况下,编译器可能无法像没有导入周期的模块那样优化代码,因为导入的功能可能尚未被分析。由于二进制对象没有依赖关系,因此通常只需要以这种方式编译一个周期的一个模块。我们称这样的模块loop-breaker

特别是如果导入循环是交错的,那么有趣的是,在编译由数百个模块组成的大型项目时,如何最大程度地减少循环中断器的数量。

是否存在一种算法,该算法在给定一组依赖关系的情况下输出最少数量的模块,这些模块需要作为中断程序进行编译才能成功编译程序?

示例

我试图澄清这个例子中我的意思。

考虑具有四个模块ABCD的项目。这是这些模块之间的依赖关系的列表,条目X y表示y取决于x

C广告ABD b

以ASCII图可视化的相同关系:

D ---> B^ / ^| / || / || L |A-> C

此依赖关系图中有两个循环:ADBACB。为了打破这些循环,例如可以将模块CD编译为循环断路器。显然,这不是最佳方法。将A编译为一个循环中断器完全可以打破两个循环,并且您需要少编译一个模块作为一个循环中断器。

algorithm directed-graph topological-sort
2个回答
17
投票

这是称为minimum feedback vertex set的NP-hard(和APX-hard)问题。正如我对您的应用程序所期望的那样,由于Demetrescu and Finocchi (pdf, Combinatorial Algorithms for Feedback Problems in Directed Graphs (2003)")而产生的近似算法在实践中在没有长的简单周期的情况下效果很好。


3
投票

这里是在Python中的操作方法:

© www.soinside.com 2019 - 2024. All rights reserved.