我有一个DAG G =(V,E),它是邻接列表表示。我试图根据附加到顶点的一些参数来压缩它。
现在我有一个图G =(V,E)和一个包含V的子集的列表。
任何想法如何有效地从原始图中找到子集顶点的边?
我需要使用原始图表连接子集。
看看这个图
{9:[10],7:[9],8:[9],6:[7],3:[8],2:[3,4],5:[4,6], 4:[7],1:[2]}
现在,如果我采用子集[1,4,7]
如何找到子集的连接?请将传递闭包视为一个问题。我需要找到所有边缘而不是传递闭包中的重复。
答案 0 :(得分:0)
将子集(让我们称之为 S )放入哈希表中。然后遍历邻接列表,并查看每个边缘,看它的第一个顶点是否在哈希表中。通过这种方式,您可以在 O (| S | + | E |)中获得所需的所有边缘。
答案 1 :(得分:0)
一种简单的方法是找到原始图表的transitive closure(使用Floyd-Warshall),然后使用它将边缘添加到结果图表中。
通过查找传递闭包,您有一个邻接矩阵,只要原始图中的顶点x和y之间存在任何路径(直接或间接),矩阵[x] [y]就为真。使用它,你可以简单地为子集图中的每对顶点a和b添加边(a,b)iff matrix [a] [b]为真(即原始图中有一条从a到b的路径) )。
这最终会添加比严格必要更多的边缘,但它会为您提供准确的子集图。
答案 2 :(得分:0)
首先,你必须利用一些算法来获得传递闭包。从您的示例看,图表似乎非常稀疏,因此使用Johnson's Algorithm而不是Floyd-Warshall。 Johnson's Algo要求O((V ^ 2)* log V + VE)小于Floyd-Warshall的O(V ^ 3)稀疏图。请注意,只有当您有一个大型稀疏图时,这种差异才会明显。
现在添加表单的边缘<的x,y>对于子集图中的每对顶点,如果x可以从y到达(将由Johnson的Algo给出)。
答案 3 :(得分:0)
如果您的子集是S,则可以执行| S | depth-first searches(或breadth-first searches)确定子集图中的边。每次搜索都是 O(V + E),所以 O(V ^ 2 + VE)或更好 O(S(V + E)),如果S很小。然后,您可能希望使用transitive reduction删除不必要的边。
如果您的图表不完全非循环,那么几乎肯定会首先合并strongly connected components。这样做很便宜,可以大大减少所需的工作。