某些编程语言(如haskell)允许模块之间存在循环依赖性。由于编译器在编译一个模块时需要知道所有导入模块的所有定义,因此如果某些模块相互导入或发生任何其他类型的循环,则通常必须做一些额外的工作。在那种情况下,编译器可能无法像没有导入周期的模块那样优化代码,因为导入的功能可能尚未被分析。由于二进制对象没有依赖关系,因此通常只需要以这种方式编译一个周期的一个模块。我们称这样的模块loop-breaker
特别是如果导入循环是交错的,那么有趣的是,在编译由数百个模块组成的大型项目时,如何最大程度地减少循环中断器的数量。
是否存在一种算法,该算法在给定一组依赖关系的情况下输出最少数量的模块,这些模块需要作为中断程序进行编译才能成功编译程序?
我试图澄清这个例子中我的意思。
考虑具有四个模块A
,B
,C
和D
的项目。这是这些模块之间的依赖关系的列表,条目X y
表示y
取决于x
:
C广告ABD b
以ASCII图可视化的相同关系:
D ---> B^ / ^| / || / || L |A-> C
此依赖关系图中有两个循环:ADB
和ACB
。为了打破这些循环,例如可以将模块C
和D
编译为循环断路器。显然,这不是最佳方法。将A
编译为一个循环中断器完全可以打破两个循环,并且您需要少编译一个模块作为一个循环中断器。
这是称为minimum feedback vertex set的NP-hard(和APX-hard)问题。正如我对您的应用程序所期望的那样,由于Demetrescu and Finocchi (pdf, Combinatorial Algorithms for Feedback Problems in Directed Graphs (2003)")而产生的近似算法在实践中在没有长的简单周期的情况下效果很好。
这里是在Python中的操作方法: