【问题标题】:Oh no Another BigO one哦不 另一个 BigO 的
【发布时间】:2011-10-30 21:30:48
【问题描述】:

我最近一直在做 BigO,我得到的公式没问题,但我写了一段代码,它接受并输入并返回完成排序所花费的时间。所以我有输入和时间,我如何使用它来分类它是什么类型的 BigO?我已经制作了图表,可以看到它们是哪种类型,但我不能使用公式来做到这一点?我不擅长数学,我认为这是我的问题!

例如我得到:

Size  Time    Operations
200    2     163648
400    1     162240
800    15    2489456
1600   6     10247376
3200   19    40858160
6400   79    165383984
12800  318   656588080
25600  1274  2624318128
51200  5059  10476803408
102400 20333 41969291968

通过查看图表和比较,我知道这是 O(n^2),但是如何证明呢?

【问题讨论】:

  • O 表示法依赖于操作次数,而不是秒意义上的时间。
  • 你只能通过严格分析源代码来“证明”它。没有多少样本可以“证明”任何事情。 (换句话说,大 O 表示法完全是关于渐近行为;即“足够大”输入的行为。“足够大”没有固定定义;您必须分析算法本身。)
  • A O(n^2) 算法也是 O(n^n) 例如,因此只需给出一些可笑的糟糕指数函数作为答案是微不足道的,并且答案将是正确的。您真正需要的是 Θ,它限制了您的运行时间上下。

标签: math computer-science big-o


【解决方案1】:

是的,您可以对一千种不同的输入大小进行采样,然后尝试从中得出一个 Big-O 值,但您不应该这样做 - 不仅因为它实际上并不能证明任何事情,还因为 不是重点

证明 O(n^2) 的方法是在代码本身上证明它,而不是通过实验。实际运行时间并不重要,因为 Big-O 表示法对此没有任何说明 - 简单来说,它只指定您将用于计算确切运行的任何公式的 主要项时间,在为该功能执行的操作数量的意义上。常量被丢弃,更小的术语也是如此 - 函数的实际运行时间可能是 1000n^2+1000000n,但这仍然是 O(n^2)。

【讨论】:

  • 这解释了为什么如果我看不到操作我无法弄清楚,我已经编辑了我的代码以显示操作,有人可以展示如何证明它的 O(n^2 ) 那呢?我觉得有必要看一个与我的问题相关的例子。
  • @EricBanderhide:不,因为你无法通过样本证明(而且我怀疑这个数字实际上反映了真实的操作数量,无论如何)。正如 paxdiablo 所提到的,你能做的最好的事情就是得到一个 belief 它是 n^2 - 因为 (2n)^2 = 4(n^2),而你的数字表明,对于大多数情况下,当输入大小加倍时,“操作”的时间/数量大约会增加四倍。然而,没有实际代码什么都无法证明
【解决方案2】:

您无法从这张表中用数学方法证明任何东西;如果 Time 对于所有较大的值都保持在 20333,则复杂度可能是 O(1)。

您可以做的最好的事情是尝试将几条曲线拟合到此表中,并根据奥卡姆剃刀选择最佳拟合。

【讨论】:

    【解决方案3】:

    您无法通过查看时间来证明它,您只能通过分析代码来查看执行了多少步骤来证明它。这样做的原因是,所花费的时间不仅是您的程序的功能,而且还有许多其他您无法控制的事情。

    例如,谁能说您的机器在您的程序的一次特定测试运行期间是否没有在其他进程中花费过多的时间?这类事情可以使用统计方法减少到一定程度,但证明需要可靠的数据。

    可以做的是查看你的一些数据点以获得支持,因为它是 O(n2) .看看最后四个条目:

    Input       Time
      128        318
      256       1274   1274 /  318 = 4.006
      512       5059   5059 / 1274 = 3.971
     1024      20333  20333 / 5059 = 4.019
    

    您可以看到,输入大小每翻一番都会产生大约 4 倍的时间乘数效应,这往往表明 O(n2) 属性。

    但这只是支持。它仅适用于特定范围的输入值,并且如前所述,受您无法控制的因素的影响。另请注意,如果所花费的时间不是一个简单的时间,那么支持将更难看出。例如,如果时间函数是t = <sup>n<sup>2</sup></sup>/<sub>10</sub> + 123n + 123456789,则计算起来会有点困难。

    【讨论】:

      【解决方案4】:

      仅仅通过对值进行比较可能没有任何意义。但是,如果您使用此值(x 轴:输入,y 轴:时间)绘制图形,您将获得曲线或线性形状或其他。使用此信息,您可以预测该函数的 BigO 值。当然可能(不总是)一些影响该进程运行的中断,但这不会在整个期间持续。这是轻微的开销不会影响结果的。 为了预测 BigO 值,您将需要一些微积分知识,以便在形状和 BigO 结果之间进行类比。

      例如,假设您有一个线性形状,并且您知道它的含义是 O(n)。此时,您达到了该结果,因为您知道线性函数图的形状并且您的图看起来像它。为了达到真正的证明,您必须绘制函数曲线和与您的图形最接近的数学函数图形。

      还有一些其他函数,例如 Big-Theta 、 Small-Omega ,它们将您的函数从上层或下层绑定。数学函数可能是它们两者,但结果是,您的 Big-O 函数最接近那个形状。

      【讨论】:

        猜你喜欢
        • 2011-02-18
        • 1970-01-01
        • 2011-05-04
        • 1970-01-01
        • 2015-07-24
        • 1970-01-01
        • 2011-09-28
        • 2020-05-25
        • 1970-01-01
        相关资源
        最近更新 更多