【问题标题】:How to calculate average asymptotic running time in Big-O notation?如何以 Big-O 表示法计算平均渐近运行时间?
【发布时间】:2020-02-17 17:13:59
【问题描述】:

试图理解我理解的渐近符号用于描述算法的性能。我是否正确地说存在最坏、最好和平均的情况?例如,对于以下代码,Big-O 表示法的平均渐近运行时间是多少?

for (int i = 0; i < size; i++)
{
    printf("%d\n", i);
}
for (int i = 0; i < size; i++)
{
    for (int j = 0; j < size; j++)
    {
        printf("%d\n", i + j);
    }
}

会是 O(n^2) 吗?

【问题讨论】:

  • 假设你的意思是时间复杂度是size的函数,那么区分最佳情况/最坏情况/平均情况是没有意义的,因为只有一个可能的输入算法中任何给定的size

标签: c++ performance big-o complexity-theory


【解决方案1】:

我是否正确地说存在最坏、最好和平均的情况?

通常只关注最坏情况和平均情况,但如果您愿意,也可以考虑最佳情况。

会是 O(n^2) 吗?

你所拥有的是典型的O(n^2) 复杂性,是的。最好的、平均的和最差的,它们对于您的特定情况都是一样的。如果您可以尽早跳出循环,或者有条件地跳过整个循环,它们就不一样了。

编辑:平均和最佳案例复杂度不同时的示例:

for(var i = 0; i < len; ++i) 
  if(arr[i] == needle)
    return needle;

这充其量是一个常数操作,即 O(1),如果元素被立即找到,最坏的情况是 O(n) 线性操作——特别是线性搜索。

【讨论】:

  • 我明白了。您能否提供一个最坏情况和平均情况不同的代码示例?如果没有,您是否可以向我指出任何具体资源以帮助我更详细地理解这一点?
  • 不同的最差和平均复杂度有点困难,但我编辑了一个不同的最佳和平均/最差复杂度的示例。前者更难,因为渐近复杂度一开始就被设计成相当悲观的。
  • @AaySquare 快速排序具有最坏情况复杂度 O(n^2) 和平均情况复杂度 O(n log n)。如果选择带有随机化的枢轴,则随机选择不太可能但可能会导致任何特定输入的最坏情况行为。
【解决方案2】:

我是否正确地说存在最坏、最好和平均的情况?

案例只是所有可能输入的某个子集,可能是具有所有可能输入大小的一个输入的子集。因此,例如,排序算法的一个案例可能是所有可能输入数组集合的某个子集,也可能只是每个输入大小恰好具有一个元素的那些子集。使用这个定义,最坏的情况是输入的子集,这样它们会导致算法针对给定的输入大小执行最多的指令;最好的情况是在每个输入大小下需要最少步数的输入集;并且平均情况就像在每个大小的所有可能实例上运行类型的预期值(根据上面的简单定义,平均“情况”根本不是真正的情况,更像是假设情况)。

对于每种情况,我们都可以关联一个渐近界——上界、下界或两者兼而有之。通常感兴趣的是最坏情况的上限,有时是最好情况的下限。但是说最好情况的上限或最坏情况的下限也不是不对的。

您发布的代码的工作量总是与size 值的平方成正比。从这个意义上说,它是O(size^2)。也是size^2的Omega和Theta。如果算法得到的输入的比特大小与大小成正比,那么这就是真正的复杂度。如果算法将size 的值作为输入(使用log(size) 位表示),那么复杂度实际上是指数级的——size 方面的复杂度可能被称为伪多项式

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多