如何忽略拓扑排序中的循环?

时间:2013-08-17 08:12:21

标签: javascript algorithm sorting graph

我使用this library在JS中对图形执行拓扑排序。问题是在极少数情况下图表将包含循环。这些是结构的一小部分,因此掉落一些边缘不会对最终结果产生很大影响。然而,算法出现时就会中断。更新它的最有效方法是什么,以便在有一个或两个循环时不会崩溃?

2 个答案:

答案 0 :(得分:7)

根据维基百科:

  

当且仅当图形没有有向循环时,也就是说,如果它是有向无环图(DAG),则可以进行拓扑排序。

因此,如果图表包含循环,则无法找到有效的topsort。我猜你使用的库要求输入图是一个DAG。因此,算法因该要求而中断。

但是,如果您仍想查找一些topsort,可以对图表进行以下修改之一: 1)构造图的随机生成树。通过这种方式,您可以将图形修改为DAG,并且可以在新图形上运行topsort算法。

2)找到图中强连接的组件(使用Tarjan的强连接组件算法)。新图是DAG,因此您可以在其上运行topsort算法。

我建议您使用这两个选项,因为至少会有几个具有这些算法的JavaScript库(对于1.您可以使用构建图的最小生成树(MST)的库)。最佳实现,两种算法都具有线性复杂性。

此外,您可以运行自己的修改后的DFS算法,该算法会删除它找到的每个图形周期的单个边缘。

答案 1 :(得分:1)

最小化删除的弧数以留下非循环图的问题称为feedback arc set。您链接的拓扑排序使用重复查找度为0的顶点并删除它的算法。对于反馈弧集的Eades-Lin-Smyth启发式算法并不遥远,可归纳如下。如果存在度为0的顶点v,则将其删除,递归残差图,并将v添加到订单前面。如果存在out-degree 0的顶点v,则将其删除,递归残差图,并将v附加到订单。否则,让v具有最大的度数减去in-degree,删除所有传入的弧,然后继续。