繁体   English   中英

计算图中路径的递归函数的复杂性

[英]Complexity of a recursive function that counts paths in graph

我找到了一个有向图的函数,该函数针对其中的顶点“ u”和“ v”,计算从“ u”到“ v”的所有可能的走行,且走行上恰好有k条边。 代码和算法来自这里 所以,

// C++ program to count walks from u to v with exactly k edges
#include <iostream>
using namespace std;

// Number of vertices in the graph
#define V 4

// A naive recursive function to count walks from u to v with k edges
int countwalks(int graph[][V], int u, int v, int k)
{
   // Base cases
   if (k == 0 && u == v)      return 1;
   if (k == 1 && graph[u][v]) return 1;
   if (k <= 0)                return 0;

   // Initialize result
   int count = 0;

   // Go to all adjacents of u and recur
   for (int i = 0; i < V; i++)
       if (graph[u][i])  // Check if is adjacent of u
           count += countwalks(graph, i, v, k-1);

   return count;
}

我试图找到并证明该算法的复杂性。 根据帖子:

“上述函数的最差情况时间复杂度是O(V ^ k),其中V是给定图中顶点的数量。我们可以通过绘制递归树来简单地分析时间复杂度。最坏情况发生在完整图上。在最坏的情况是,递归树的每个内部节点将恰好有n个子节点。”

但是,我找不到找到可以分析的树的递归,以证明该算法为O(V^k) 另外,我认为最好的情况是Theta(1) 真的吗? 一般情况如何?

对于完整的图形,每个节点都相互连接,因此for循环将使|V| 递归调用。 这将在每个递归调用中发生,直到k变为1,因此总共O(|V|^k)递归调用。

您可以这样表达:

T(V, k) = |V|*T(V, k - 1)
        = |V|*|V|*T(V, k - 2)
        = |V|^2*|V|*T(V, k - 3)
        = ...

它始终为T(V, _)因为可以多次访问一个节点。

最好的情况确实是O(1) ,如果在第一个调用期间触发条件,则前三个条件之一将被触发。

我不确定一般情况,但我认为仍然应该很糟糕。 考虑一个链表图和一个巨大的k :为了使k变为0或1,您将多次移动相同的边。随着添加更多路径,这种情况会变得越来越糟。

通用“平均案例”分析在这样的问题中有点不适,因为您可以选择如何定义“随机”图。 一种方法是说,对于0 <= p <= 1,每个可能的边都以概率p出现,然后尝试根据p分析平均案例运行时间。 但是,还有其他方法可以定义随机图。 同样,平均案例分析通常很困难。 但是,如果您定义“平均”的含义(即,表示随机图的含义),则有人可能会对此表示怀疑。

暂无
暂无

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

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