【问题标题】:How do I evaluate and explain the running time for this algorithm?如何评估和解释该算法的运行时间?
【发布时间】:2014-11-05 16:34:05
【问题描述】:

伪代码:

    s <- 0
    for i=1 to n do
        if A[i]=1 then 
            for j=1 to n do
                {constant number of elementary operations}
            endfor
        else
            s <- s + a[i]
        endif
    endfor

其中 A[i] 是一个包含 n 个整数的数组,每个整数都是 1 到 6 之间的随机值。

我在这里不知所措...从我的笔记和其他一些在线资源中挑选,我得到了

T(n) = C1(N) + C2 + C3(N) + C4(N) + C5

其中 C1(N) 和 C3(N) = for 循环,C4(N) = 基本运算的常数。虽然我有一种强烈的感觉,我错了。

【问题讨论】:

  • 什么是 A[i]?你永远不会初始化它。
  • A[i] 的复杂度也是多少?
  • 这个问题只表明 A 是一个由 n 个整数组成的数组,每个整数都是 1 到 6 之间的随机值...
  • 您从 1..n 循环,每个循环也从 1..n 循环(在最坏的情况下)。 O(n^2) 对吗?
  • Running time 是您使用基准测试的目的。你说的是time complexity

标签: algorithm time evaluation


【解决方案1】:

您从 1..n 循环,每个循环也从 1..n 循环(在最坏的情况下)。 O(n^2) 对吗?

换一种说法:你不应该添加 C3(N)。如果您有两个来自 1..n 的独立 for 循环,就会出现这种情况。但是你有一个 nested 循环。您将运行内循环 N 次,外循环 N 次。 N*N = O(n^2)。

【讨论】:

  • 所以基本上我只需要写 T(n) = O(N^2) 吗?还是我应该添加第三个 C3(N) ?
  • 当人们谈论时间复杂度时,他们期望像 O(n^2) 或 O(nlgn) 这样的东西。即使您 确实 有两个来自 1..n 的循环(未嵌套),您仍然会写 O(n) not O(n) + O( n)。哎呀,你可能有 50,000 个从 1..n 开始的循环;仍然是 O(n)。
【解决方案2】:

让我们想一想这个算法的作用。

你基本上循环遍历数组中的每个元素至少一次(外部 for,带有 i 的那个)。有时,如果 A[i] 的值为 1,那么您也将使用 j for 再次循环整个循环。

在最坏的情况下,您正在运行一个全为 1 的数组。

在这种情况下,您的复杂性是:

  • 初始化时间
  • n *(测试 a[i] 的时间 == 1 + n * {constant ...} 的时间)

这意味着:T = T(s) + n * (T(test) + n * T(const)) = n^2 * T(const) + n*T(test) + T(s)。 渐近,这是​​一个 O(n^2)。

但这是一个最坏情况的分析(大多数时候你应该执行的分析)。如果我们想要一个平均案例分析怎么办?

在这种情况下,假设 A 中的值均匀分布,您将访问 j 的 for 循环,平均 1/6 次。

所以你会得到: - 初始化时间 - n * (测试时间 a[i] == 1 + 1/6 * n * {constant ...}的时间 + 5/6 * T(increment s)

这意味着:T = T(s) + n * (T(test) + 1/6 * n * T(const) + 5/6 * T(inc s)) = 1/6* n^2 * T(const) + n * (5/6 * T(inc s) + T(test)) + T(s)。

同样,这仍然是 O(n^2),但根据 T(inc s) 的值,这可能大于或小于其他情况。

有趣的练习:您能否估计 A 中值的一般分布而不是均匀分布的预期平均运行时间?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-16
    • 1970-01-01
    • 2014-11-07
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多