繁体   English   中英

Big O:这是递归算法最严格的上限吗?

[英]Big O: is this the tightest upper bound for recursive algorithm?

我的算法的时间复杂度是否低于O(| 2 (2 + log3(n)) - 1 |)

是否有更优雅的方式来编写它?

int cantor(int low, int high) {
    int gap= (high - low) / 3;

    if (high < low)
        return 0;
    else if (high == low)
        return low;
    else
        return cantor(low, low + gap) + cantor(high - gap, high);
}

在下面运行Java程序会产生关键点,其中n =整数输入, o =操作数, b =上限(需要>= o

n    o    b 

0     1     1.0   <- critical point
1     3     3.0   <- critical point
2     3     5.194250610520971
3     7     7.0   <- critical point
4     7     8.592185156484856
5     7     10.04233615383682
6     7     11.388501221041942
7     7     12.65392426064557
8     7     13.85409969044663
9     15    15.0  <- critical point
10    15    16.099749365620383
11    15    17.159572545935887
12    15    18.184370312969712
13    15    19.178087273270823
14    15    20.143957171877723
15    15    21.08467230767364
16    15    22.0025040190721
17    15    22.899390537770895
18    15    23.777002442083877
19    15    24.636792344342172
20    15    25.480033236937405
21    15    26.30784852129114
22    15    27.1212358323658
23    15    27.92108616334829
24    15    28.708199380893266
25    15    29.48329693358293
26    15    30.2470323529008
27    31    31.0  <- critical point

这是java代码:

public class recursionTreeTimeComplexity {

    static int calls = 0;

    static int cantor(int low, int high) {

        calls++;

        int gap = (high - low) / 3;

        if (high < low)
            return 0;
        else if (high == low)
            return low;
        else
            return cantor(low, low + gap) + cantor(high - gap, high);
    }

    public static void main(String[] args) {

        for (int i = 0; i < 1000; i++) {
            calls = 0;
            cantor(0, i);

            // |(2^log3(n)+2)|-1
            System.out.println(i + "\t" + calls + "\t" + Math.abs((Math.pow(2, ((Math.log(i) / Math.log(3)) + 2)) - 1)));    
        }
    }
}

假设算法是O(f(n))意味着时间大致与f(n)成比例(因为n足够大)。 [ 更新:这不完全准确,因为实际时间可能会有很大差异,而且不必单调增加。 更确切地说,这意味着时间的上限大致与f(n)成比例。

因此,在使用O符号时添加常量是无关紧要的:O(f(n)+ k)与O(f(n))相同,因为最终f(n)部分将占主导地位且k部分将成为可以忽略不计。 此外,由于这是一个比例,乘以一个常数是无关紧要的; O(kf(n))与O(f(n))相同,因为它们都说它基本上与f(n)成比例。 这意味着原始表达式中的+1是无关紧要的,因为2 (2 + x) = 4 * 2 x也是2+ ,这意味着您只是乘以常数。 所以你的原始表达式可以简化为O(2 ^(log 3 n))。 这似乎是正确的; 因为我确定你注意到,如果T(n)是算法的运行时间,那么基本上T(n)= 2T(n / 3)[非常粗略,但这对于这个目的来说足够好],这意味着如果我们假设T(1)= 1,则T(3)= 2,T(9)= 4,T(27)= 8等。

我们可以进一步简化。 log 3 n = log 2 n / log 2 3; 因此2 ^(log 3 n)= 2 ^(log 2 n / log 2 3)=(2 ^ log 2 n)^(1 / log 2 3)= n ^(1 / log 2 3)= n ^(记录3 2)。 因此算法的时间可以表示为O(n ^(log 3 2)),或约O(n 0.6309 )。

暂无
暂无

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

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