繁体   English   中英

检查有向无环图中两个顶点之间是否存在路径 - 查询

[英]Check if there exist a path between two vertices in directed acyclic graph - queries

这个问题可以很容易地在每个查询的 O(n + m) 中解决,但是这有可能以比 O(n²) 更好的预处理以更复杂的方式回答此类查询吗?

在树中,可以通过使用预序和顺序轻松完成。 我在 DAG 中尝试过类似的东西,但没有任何意义。

我也尝试过把这个问题改成 LCA in DAG problem,但是在 DAG 中找到 LCA 解决得不够快。


准确地说,约束让我们说:

n - 顶点数,最多 10^5

m - 边数,最多 10^5

q - 查询数,最多 10^5

有趣的问题。 我的直觉说“不”。 不过我还没想好。

但是(假设这个问题不是理论问题),出于实际目的,您可以使用Bloom filter

使用布隆过滤器解决您的问题的一种可能解决方案是首先生成 K 个不同顺序的图,并为每个顺序存储从节点到其索引的映射。 然后,为了测试从 N1 到 N2 的“可达性”,您检查(foreach 顺序)N1 的索引是否小于 N2 的索引(此检查是 O(1))。 如果这对所有订单都成立,那么它是可以达到的( 假设 K 足够大)。 (根据您的实际用例,偶尔生成此类误报甚至可能是可以的,或者您可以运行可靠的 O(N+M) 检查)。 否则,绝对不是。

我有一种感觉,可能有以下几行的解决方案,但这绝不是一个完整的解决方案。

让 S 是顶点的子集。 对于图中的每个顶点 V,考虑集合 D_S(V),我定义如下: D_S(V) = {V} 如果 V 在 S 中,否则,D_S(V) 是 {V} 与V 的所有直接后代 W 的集合 D_S(W)。(也就是说,它是“V 的所有最终后代,但是只要碰到 V 的一个元素就停止递归”。)问题是:我们能找到一个集合吗? S 使得 S 的大小为 O(f(N)) 并且 D_S(V) 对于所有 V 的大小为 O(g(N)),其中 f 和 g 是渐近次线性的? (例如,也许我们可以同时实现两者的 sqrt。)

如果我们能找到这个,那么我建议采用以下策略。 对于预处理,为 S 中的每个 U 创建一个哈希表,其中包含最终可从 U 到达的所有顶点。这可以在 O(f(N) * M) 中实现; 这不一定比 O(N^2) 好,但至少比 O(M*Q) 好。

现在回答一个查询“U 是否可以从 V 到达?”,如果 V 在 S 中,这是微不足道的。否则,我们检查是否 V = U,在这种情况下它也是微不足道的。 最后,我们将相同的过程应用于 V 的所有后代,递归地,如果通过上述两种情况中的任何一种,答案为“是”,则返回“是”,但仅当我们找不到 U 时才返回“否”。这个递归需要O(g(N)) 步。

剩下的问题是如何选择 S。我认为如果该图来自出度遵循幂律的某个过程,则可能只采用出度最高的 sqrt(N) 顶点。 但是例如,如果我们有 N=2*K 个顶点 (i, 0) 和 (i, 1) 上的图,有 K^2​​ 条边:从每个 (i, 0) 到每个 (j, 1); 那么就没有合适的子集 S。但也许没有合适的 S 的图必须具有一定程度的一致性,我们可以利用......或者可能没有。 我不知道。 任何想法,让我知道!

通过压缩强连通分量,任何用于 DAG 可达性查询的算法都可以用于回答一般有向图上的此类查询。 所以我不认为 DAG 条件可以降低复杂性。

对于有向图的可达性查询,本文提到的索引构建技术可能对某些情况有所帮助。

如果您正在考虑通过一些预处理来提供快速的多个 path_exists(src_vertex, dest_vertex) 查询,请考虑调用Warshall 的算法来确定传递闭包,该闭包告诉有向图中任意两个任意节点之间是否存在路径,作为预处理步骤(可能在服务器启动时)。 该算法的最坏情况时间复杂度为 O(n^3),空间复杂度为 O(n^2),其中 n 是节点数。 该算法的 output 是一个 nxn 矩阵,其中如果 node_i 和 node_j 之间存在路径,则 matrix[i][j] = 1,否则为零。 因此,在查询服务时,您可以通过在传递闭包矩阵中查找 (i,j) 对来在 O(1) 时间内返回结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM