【问题标题】:Define recursive algorithm complexity定义递归算法复杂度
【发布时间】:2017-11-20 23:18:56
【问题描述】:

我试图了解我需要如何定义算法的复杂性。例如,我有这两种算法:

static int z1 = 23;
static int z2 = 27;
static int z3 = 26;

void g(int n, int i) {
        if (!i) return;
        for (int j=2*n; j > 0; --j) {
            g(n,i-1);
        }
    } 

void f(int n) {
    if (!n) return;
    for (int i = 0; i < z1%10; ++i) {
        f(n/(z3%10+2));
    }
    g(n,z2%3);
    f(n/(z3%10+2));
    g(n,z2%3);
}

让我们寻找一个函数g:

void g(int n, int i) {                 T1
        if (!i) return;                T2
        for (int j=2*n; j > 0; --j) {  T3
            g(n,i-1);                  T(i-1)
        }
    } 

T(n) = T1 + T2 + (2n) * (T3 + T(i-1)) + T2。

如果我这么认为

T1 = T2 = T3 = 1。

然后我有:

T(n) = 1 + 1 + 1 + (2n) * (1 + T(i-1)) + 1 = 3 + 2n + 2n * T(i-1)。

现在我去掉常量并拥有:

T(n) = n + n * T(i-1) = n(1+T(i-1)) 等于 O(n^2)。

现在我们可以寻找第二个函数 f:

void f(int n) {                         
    if (!n) return;                     T1
    for (int i = 0; i < z1%10; ++i) {   T2
        f(n/(z3%10+2));                 T3
    }                 
    g(n,z2%3);                          T4
    f(n/(z3%10+2));                     T5
    g(n,z2%3);                          T6
}

其中 T3 = T5 = T(n/8)。 其中 T1 = T2 = 1。 其中 T4 = T6 = O(n^2) = n^2。

T(n) = T1 + 3(T2 + T(n/8)) + T4 + T(n/8) + T6。

T(n) = 1 + 3(1 + T(n/8)) + n^2 + T(n/8) + n^2。

T(n) = 4 + 4T(n/8) + 2n^2 | :2.

T(n) = 2 + 2T(n/8) + n^2。

由此,我得到 O(n^3log n)。

我理解对了吗?还是我有大问题?因为我不知道如何检查自己。

【问题讨论】:

    标签: algorithm math recursion time-complexity master-theorem


    【解决方案1】:

    在递归计算g函数中只有i被改变,所以它的复杂度是T(n, i)。为此,我们有

    T(n, i) = 2n * T(n, i - 1)

    所以

    T(n, i) = O((2n)^i)

    您的f 函数实现了一些“分而治之”类型的算法。原始问题分为几个较小的任务。为了计算这种算法的复杂性,应用了主定理。你可以在这里阅读https://en.wikipedia.org/wiki/Master_theorem。我认为阅读这篇文章给你的不仅仅是我的解释。根据这个定理 函数f的复杂度G(n)

        G(n) = 4G(n / 8) + 2T(n, 0)
        G(n) = 4G(n / 8) + 2
        G(n) = O(n^(2 / 3))
    

    【讨论】:

    • 这应该是一条评论。 =)
    【解决方案2】:

    你的第一个函数的成本可以写成:

    G(n) = 1 + 2n * G(n - 1)

    这导致 O(n2)。

    至于其他功能,我假设您想说:

    static int z3 = 26; // and not 'z2'
    

    此外,由于值是硬编码的,为什么要保持代码密集,重写为:

    void f(int n) {
        if (!n) return;
        for (int i = 0; i < 3; ++i) {
            f(n/8);
        }
        g(n, 0);
        f(n/8);
        g(n, 0);
    }
    

    现在可以更轻松地确定复杂性,例如:

    F(n) = 1 + 3F(n/8) + G(0) + F(n/8) + G(0) = 1 + 4F(n/8) + 2G(0)

    我们知道G(0) = 1,因此上面变成:

    F(n) = 3 + 4F(n/8)

    在哪里可以申请Master Theorem,根据这个在线Project Nayuki,我们得到:

    Θ(n^ ( log_8{4} ) )

    【讨论】:

      猜你喜欢
      • 2021-05-28
      • 1970-01-01
      • 2013-04-28
      • 2011-02-12
      • 2015-05-13
      相关资源
      最近更新 更多