我有一个DAG存储应用程序中某些对象之间的关系。通过在现有的下面添加新的顶点来更新此结构(即,隐式地在新顶点中创建新边),然后(在任何以后的时间)从那里到其他顶点的新边,我想确保图表保持DAG,i。即我的代码不会创建周期。
我是否必须为每个插入和连接操作添加cycle detection,或者是否有我可以在插入时遵循的规则,这将保证我不会产生循环?
我能想到的一种方法是存储每个节点的topological level,并且只允许指向更高级别(远离源节点)的新边缘。然而,看起来这实际上会让我失去我希望通过使用DAG而不是一组普通树来实现的大量灵活性。
答案 0 :(得分:6)
您还可以存储反向链接,并检查正在添加的边的终点节点是否未出现在原始节点的任何父节点中。这比进行全周期检测要快。基本上这将是反向链路上的最短路径算法,对于DAG而言应该是线性操作。
正如@Markus所说,如果你没有创建到和从新节点到现有节点的链接,你应该无法创建通过向图表引入新节点来实现循环。
答案 1 :(得分:5)
当通过添加新顶点然后从那里添加新边到其他顶点来更新此结构时
如果所有新边缘来自新顶点,您将不会创建周期。
如果您还要从旧节点添加到的新顶点,则您的选项取决于图形的预期形状。它们都归结为部分排序的变化,但是有一些黑客能够为树木,森林,钻石网格等提供更好的性能。您对预期的整体图形形状了解多少?
答案 2 :(得分:4)
在this article中,有一个用于维护拓扑排序的在线算法(第4页)。
答案 3 :(得分:3)
您可以做的是保持节点按拓扑顺序排序(搜索“拓扑排序”)。从低阶到高阶节点添加弧时,您知道没有创建循环。在相反的情况下,您需要逐步更新拓扑排序,同时运行循环检测。