performance - 偶长路径算法

标签 performance algorithm depth-first-search

我被要求写一个高效的算法,在有向图中找到从给定顶点到它们的路径具有偶数路径的所有顶点。

这是我的想法:

(很像DFS的“Visit”算法)

Visit(vertex u)

     color[u]<-gray
     for each v E adj[u]
       for each w E adj[v]
            if color[w] = white then
                     print w
                     Visit(w)

我认为它可行,但我很难计算它的效率,尤其是当图形带有循环时。你能帮帮我吗?

最佳答案

如果我可以提出替代方案 - 我会减少问题并使用 DFS 而不是修改 DFS

给定一个图 G = (V,E),创建一个图 G' = (V,E') 其中 E'={(u ,v) | V 中有 w 使得 (u,w) 和 (w,v) 在 E) 中
换句话说,我们正在创建一个图 G',当且仅当存在从 u 到 v 的长度为 2 的路径时,它具有边 (u,v)。

鉴于该图,我们可以推导出以下算法[高级伪代码]:

  1. 从 G 创建 G'
  2. 在来自源 s 的 G' 上运行 DFS,并标记 DFS 标记的相同节点。

解决方案的正确性和时间复杂度分析:

复杂性: 复杂度显然是 O(min{|V|^2,|E|^2} + |V|),因为第 1 部分 - 因为最多 min{|E |^2,|V|^2} 边在 G' 中,因此步骤 2 的 DFS 在 O(|E'| + |V|) = O(min{|V|^2 ,|E|^2} + |V|)

正确性:
如果算法发现从v0到vk存在路径,那么从DFS的正确性来看——G'上存在路径v0->v1->...->vk,所以存在路径v0->v0'->v1->v1'->...->vk 在 G 上的偶数长度。
如果在G上有一条从v0vk的偶数路径,则设为v0->v1 ->...->vk。那么 v0->v2->...->vkG' 上的路径,并且会被 DFS 找到 - 从 DFS 的正确性来看。

作为旁注:
减少问题而不是修改算法通常更不容易受到错误的影响,并且更容易分析和证明正确性,因此您通常应该尽可能选择这些而不是修改算法。

编辑: 关于您的解决方案:嗯,分析它表明它们几乎相同 - 除了我生成 E' 作为预处理,并且您在每次迭代中即时生成它。
由于您的解决方案是动态生成边缘 - 它可能需要多次完成一些工作。但是,由于每个顶点最多被访问一次,因此它最多被限制为作业的 |V| 次。
假设|E| = O(|V|^2) 为简单起见,为您的解决方案提供 O(|V|^3) 的总运行时间上限。
也是一个下界,看例子a clique ,在任何节点的每次visit()期间,算法都会做O(|V|^2)来生成所有的可能性,而visit() 一种可能性,因为我们恰好访问了 |V| 个节点,所以我们得到了 Omega(|V|^3) 的总运行时间
因为我们发现解既是O(|V|^3)又是Omega(|V|^3),所以它是的总和Theta(O(|V|^3))

关于performance - 偶长路径算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10190643/

相关文章:

mysql - mysql 或 sqlite 中的深度优先搜索 (DFS)

python - 为什么我的 Iterative Deepening Depth-First Search 实现占用的内存与 BFS 一样多?

java - 暂时减慢处理速度

java - JMH - List#addAll 比 ArrayList#new 更快?

java - 如何获取字符串的所有子序列组合(在 Java 或 C++ 等中)

java - 组合优化实现

c - 为什么我的 rust 病比我的C内存操纵慢?

java - 为什么减少循环次数并不能加快程序速度?

c++ - 查找排序范围内元素数量的最快方法是什么?

javascript - 如何将具有父子关系的嵌套数组转换为普通数组?