假设我有一个内存要求为logN + 1的算法,其中N是问题的大小(要处理的位数)。我建议第二个版本将此内存需求减少到(logN)/ 2 + 1。我已经了解到在Big-O分析中忽略了常量,因此算法版本都具有O(logN)的复杂性。
现在,如果我计算使用第二版算法保存的内存,我会得到
内存保存在N = M(N)= 1 - [(logN)/ 2 + 1] / [logN + 1]
lim N→∞M(N)= 1/2
表明渐渐地我将永远保存50%的内存。我很困惑为什么我无法在Big-O分析中看到这种收益?
我的第二个问题是:如果我对Big-O符号的理解是错误的,那么突出显示算法第二版中保存的内存的正确方法是什么?
答案 0 :(得分:5)
请记住,big-O表示法不包括常数因子。函数f(n)= n和g(n)= 10 100 n都是O(n),尽管f(n)是比g(n)小得多的函数。< / p>
您的分析是正确的 - 如果您可以使用空间(log n)/ 2 - 1,那么您将(在极限范围内)将所需的内存量减半。然而,这不会出现在大O分析中,因为大O忽略了常数因素。正如其他一些答案中所提到的,big-O表示法可以捕获长期增长率,虽然常量可能会告诉您更多关于绝对使用空间的数量,但常量不能控制长期空间使用的期限增长率。 p>
如果您想进行更精确的分析,可以在之前和之后给出准确的内存使用,然后说您已将内存使用量减少了50%。关于算法和数据结构的许多论文确实包含了常数因素,并提到它们正在获得恒定的加速。例如,Cholesky factorization算法和高斯消元都给出了求解线性系统的O(n 3 )算法,但是当可以使用Cholesky分解时,它可以减少约50%的运算。大多数涵盖这些主题的教科书都会提到虽然两种算法都是O(n 3 ),但前者在可以使用时优于后者。
希望这有帮助!
答案 1 :(得分:2)
Big-O没有考虑常数因素。它只是算法如何缩放的度量 - 因此与log N成比例增长的任何东西都是O(log N)。这是一个相对的衡量标准,就像说两个人加薪10%,即使一个人的工资从10,000增加到12,000,另一个人从1,000,000增加到1,200,000。如果你被告知他们每年增加10%,你不会想到知道某人的总工资是多少,所以如果你知道算法增长O(log N),不要指望知道算法的总成本。
如果算法的第二个版本使用了一半的内存但具有相同的缩放行为,那么只需说它使用了一半的内存。