分析短算法的运行时间
Analyzing runtime of a short algorithm
我得到了以下代码:
public class alg
{
public static int hmm (int x)
{
if (x == 1)
{
return 2;
}
return 2*x + hmm(x-1);
}
public static void main (String[] args)
{
int x = Integer.parseInt(args[0]);
System.out.println(hmm(x));
}
}
所以第一个问题是,这个算法算什么?
我刚刚在 eclipse 中输入并运行了它
所以我可以更好地看到它的作用(之前是伪代码,我不能在这里输入它所以我输入了代码)。我已经意识到该算法执行以下操作:它将接受输入并将其乘以其以下数字。
例如:
input = 3, output = 12 because 3*4 = 12.
Or Input = 6, output 42 because 6*7 = 42.
好了,下一个问题是我的问题。我被要求分析这个算法的运行时间,但我不知道从哪里开始。
我会说,一开始,当我们定义 x 时,我们已经得到 time = 1
我相信 if 循环也会给出 time = 1
。
最后一部分,return 2x + alg(x-1)
应该给 "something^x" 或者..?
所以最后我们得到了类似 "something^x" + 2 的东西,我怀疑那是对的:/
编辑,也设法输入了伪代码:)
Input: Integer x with x > 1
if x = 1 then
return 2;
end if
return 2x + hmm(x-1);
函数计算
f(x) = 2(x + x-1 + x-2 + ... + 1)
它会在 O(x)
中 运行,即 x
次将被调用为恒定时间 O(1)
。
遇到问题时,请尝试使用(小)数字遍历代码。
这算什么?
我们以hmm(3)
为例:
3 != 1
,所以我们计算2 * 3 + hmm(3-1)
。向下一个递归级别。
2 != 1
,所以我们计算2 * 2 + hmm(2-1)
。向下一个递归级别。
1 == 1
,所以我们return2
。不再递归,因此 hmm(2-1) == hmm(1) == 2
.
- 回溯一级递归,我们得到
2 * 2 + hmm(1) = 2 * 2 + 2 = 4 + 2 = 6
。因此 hmm(2) = 6
- 再往上一层,我们得到
2 * 3 + hmm(2) = 6 + 6 = 12
如果仔细观察,算法会计算出:
2*x + ... + 4 + 2
我们可以反转这个并分解出 2
并得到
2 * (1 + 2 + ... + x)
.
这是一个arithmetic progression,我们有一个众所周知的公式(即x² + x
)
需要多长时间?
渐近运行时间为O(n)
.
没有循环,所以我们只需要计算递归的次数。人们可能会想计算各个计算步骤,但每一步都是常数,所以我们通常将它们组合成一个常数因子 k
.
O(n)
是什么意思?
好吧...我们进行 x - 1
递归步骤,每一步递减 x
1
,直到达到 x == 1
。从x = n
到x = 1
有n - 1
这样的步骤。因此,我们需要 k * (n - 1)
操作。
如果你认为n
很大,- 1
就可以忽略不计,所以我们放弃它。我们还删除了常数因子,因为对于大 n
,O(nk)
和 O(n)
也没有太大区别。
我得到了以下代码:
public class alg
{
public static int hmm (int x)
{
if (x == 1)
{
return 2;
}
return 2*x + hmm(x-1);
}
public static void main (String[] args)
{
int x = Integer.parseInt(args[0]);
System.out.println(hmm(x));
}
}
所以第一个问题是,这个算法算什么? 我刚刚在 eclipse 中输入并运行了它 所以我可以更好地看到它的作用(之前是伪代码,我不能在这里输入它所以我输入了代码)。我已经意识到该算法执行以下操作:它将接受输入并将其乘以其以下数字。 例如:
input = 3, output = 12 because 3*4 = 12.
Or Input = 6, output 42 because 6*7 = 42.
好了,下一个问题是我的问题。我被要求分析这个算法的运行时间,但我不知道从哪里开始。
我会说,一开始,当我们定义 x 时,我们已经得到 time = 1
我相信 if 循环也会给出 time = 1
。
最后一部分,return 2x + alg(x-1)
应该给 "something^x" 或者..?
所以最后我们得到了类似 "something^x" + 2 的东西,我怀疑那是对的:/
编辑,也设法输入了伪代码:)
Input: Integer x with x > 1
if x = 1 then
return 2;
end if
return 2x + hmm(x-1);
函数计算
f(x) = 2(x + x-1 + x-2 + ... + 1)
它会在 O(x)
中 运行,即 x
次将被调用为恒定时间 O(1)
。
遇到问题时,请尝试使用(小)数字遍历代码。
这算什么?
我们以hmm(3)
为例:
3 != 1
,所以我们计算2 * 3 + hmm(3-1)
。向下一个递归级别。2 != 1
,所以我们计算2 * 2 + hmm(2-1)
。向下一个递归级别。1 == 1
,所以我们return2
。不再递归,因此hmm(2-1) == hmm(1) == 2
.- 回溯一级递归,我们得到
2 * 2 + hmm(1) = 2 * 2 + 2 = 4 + 2 = 6
。因此hmm(2) = 6
- 再往上一层,我们得到
2 * 3 + hmm(2) = 6 + 6 = 12
如果仔细观察,算法会计算出:
2*x + ... + 4 + 2
我们可以反转这个并分解出 2
并得到
2 * (1 + 2 + ... + x)
.
这是一个arithmetic progression,我们有一个众所周知的公式(即x² + x
)
需要多长时间?
渐近运行时间为O(n)
.
没有循环,所以我们只需要计算递归的次数。人们可能会想计算各个计算步骤,但每一步都是常数,所以我们通常将它们组合成一个常数因子 k
.
O(n)
是什么意思?
好吧...我们进行 x - 1
递归步骤,每一步递减 x
1
,直到达到 x == 1
。从x = n
到x = 1
有n - 1
这样的步骤。因此,我们需要 k * (n - 1)
操作。
如果你认为n
很大,- 1
就可以忽略不计,所以我们放弃它。我们还删除了常数因子,因为对于大 n
,O(nk)
和 O(n)
也没有太大区别。