寻找递归关系和复杂性

时间:2015-08-29 18:34:43

标签: c complexity-theory recurrence

根据操作次数,找出递归关系!

a = N;
var = 0;
while (a > 1) 
{
var = var + a; 
num = 2 * var; 
a = a / 2;
}

我认为将形成的重现关系是:(分配操作不计算在内)

T(n)= (from a=1 to N)Σ(3)

我是对的吗?

现在使用这种递归关系,如何找到它的复杂性。

3 个答案:

答案 0 :(得分:1)

你想要做的是找出这个操作被调用多少次,所以考虑一下:每次调用后a除以2,所以如果M = N / 2则T(M)= T(N) - 1

现在,此循环的每次迭代再次划分N,以便您获得以下内容:

T(N) = T(N/2) + 1 = ... = k + T(N/(2^k))

停止条件为:a>1因此您需要检查何时N/(2^k) <= 1

N/2^k = 1 -> log (n) = k

所以T(N) = log(n) + T(1) = log(n)

这是“大O”符号的答案。

答案 1 :(得分:1)

经验方法:

首先通过简化代码来减少代码中的“教育噪音”并添加迭代计数器(c)。然后查看结果(N,计数),经过一段时间后,您会看到[^ 1,2,4,8,16,...]中所有N的2 ^ count = N.

因此复杂性Compl(loop)= O(log_2(N))。

let rec loop a c = 
    match a with
    | x when x > 1 -> 
        let a1 = a / 2
        loop a1 (c+1)
    | _ -> (a,c)

// after staring at the result of the computation we came up with this theory:
let theory n = int (System.Math.Log10(float n) / System.Math.Log10(2.0))

[1..64] 
|> List.map (fun a -> a,loop a 0, theory a) 
|> List.map (fun (a0,(a,c),aa) -> a0,c,aa)

数据:

  

[(1,0,0); (2,1,1); (3,1,1); (4,2,2); (5,2,2); (6,2,2); (7,2,2);      (8,3,3); (9,3,3); (10,3,3); (11,3,3); (12,3,3); (13,3,3);      (14,3,3); (15,3,3); (16,4,4); (17,1,4); (18,4,4); (19,4,4);      (20,4,4); (21,4,4); (22,4,4); (23,4,4); (24,4,4); (25,4,4);      (26,4,4); (27,4,4); (28,4,4); (29,4,4); (30,4,4); (31,4,4);      (32,5,5); (33,5,5); (34,5,5); (35,5,5); (36,5,5); (37,5,5);      (38,5,5); (39,5,5); (40,5,5); (41,5,5); (42,5,5); (43,4,5);      (44,4,5); (45,5,5); (46,5,5); (47,5,5); (48,5,5); (49,5,5);      (50,5,5); (51,5,5); (52,5,5); (53,5,5); (54,5,5); (55,5,5);      (56,5,5); (57,5,5); (58,5,5); (59,5,5); (60,5,5); (61,5,5);      (62,5,5); (63,5,5); (64,6,6)]

答案 2 :(得分:1)

重现关系是:

T(1) = a
T(n) = b + T(n/2)

第一部分来自循环变量等于1的情况,在这种情况下,只执行循环顶部的比较。第二行来自循环体中完成的恒定工作量b,加上使用更新的循环变量值执行循环的时间。

前几个词是:

n   T
1   a
2   a + b
4   a + 2b
8   a + 3b

基于此,我们可以猜出一般形式:

T(n) = a + b log n

证明这是一项运动;但你可以将其插入到递归关系中,看它是否满足要求。

渐近复杂度是对数的。