请原谅我对图论词汇的小知识。
我只能用常见的英语单词来描述问题。也许有人可以指出我正确的方向和/或条款来查找。
问题出现在可视化编程语言的实现中。顶点是函数/方法,边缘在函数之间传输数据。现在有以下问题:
可以允许将顶点A的输出与 Collection<的类型连接起来。 TItem> 到顶点B的输入,类型为 TItem 。然后将类型为 TItem 的顶点B输出到输入顶点C,类型为 Collection< TItem> 。这将告诉编译器它必须围绕顶点B包装 foreach 函数以将B的函数应用于来自A的集合中的每个项目,并将新项目作为集合输出到C的输入。因此从A到B的边缘是多对一连接,从B到C是一对多。
现在实际问题是,什么样的算法会找到被一对多连接包围/隔离的(定向)子图?以便编译器将foreach函数包装在这个特定的子图周围?我试图在这张图片中想象出问题:
答案 0 :(得分:2)
请注意,图表中可能有多个此类子图。
要查找每个节点,请访问图形中的所有节点,并计算父节点/子节点以确定它是否是所需集合的成员,然后将所有标记的节点分离到各自的子图形或 cliques < / em>的。可以在维基百科上找到使用派系的一般程序:The Clique Problem。
答案 1 :(得分:1)
我建议使用以下算法:
第1步遍历所有节点。如果找到蓝色节点,请在有向图中执行depth-first search以找出可从中获取的白色节点集。在执行DFS时不要交叉蓝色节点。与节点集一起,存储在DFS期间发现的起始蓝色节点和外出蓝色节点。
最终会有多组白色节点,以及有关传入和传出蓝色节点的信息:
(忍受我,我的老鼠绘画技巧真的很糟糕)
第2步如您所见,您可能有重叠。有两种方法可以解决这个问题:
之后使用disjoint-set data structure合并重叠集。这导致 O(n²+ m)最坏情况运行时。
通过修改标准DFS算法,避免首先创建重叠。它应该检测您何时到达您在之前探索过的集合中已经看到的节点。然后它不应该进一步探索子图,但记录当前探索的集合和重叠的集合将在以后合并。然后,您可以在合并图中找到已连接的组件。这会给你一个 O(n + m)运行时,这要好得多。
最终得到一组不相交的白色节点以及相应的传入和传出蓝色节点: