我正在阅读一个例子,其中以下等同于O(N):
O(N + P), where P < N/2
O(N + log N)
有人可以用外行的方式解释上面两个例子与O(N)是一样的吗?
答案 0 :(得分:1)
我们总是选择更大的一个。
在这两种情况下,N都大于另一部分。
在第一种情况P < N/2 < N
在第二种情况下log N < N
因此,两种情况下的复杂性都是O(N)
。
答案 1 :(得分:1)
设f和g是在实数的某个子集上定义的两个函数。一个人写道
f(x)= O(g(x))为x - >无限
当且仅当存在正常数M使得对于所有足够大的x值,f(x)的绝对值最多为M乘以g(x)的绝对值。也就是说, f(x)= O(g(x))当且仅当存在正实数M和实数x0时
<强> | F(X)| &lt; = M | g(x)|对于所有x&gt; X0 强>
所以在你的情况下1:
f(N) = N + P <= N + N/2
我们可以设置M = 2然后:
|f(N)| <= 3/2|N| <= 2|N| (N0 could any number)
所以:
N+p = O(N)
在你的第二种情况下,我们也可以设置M = 2和N0 = 1来满足:
|N + logN| <= 2 |N| for N > 1
答案 2 :(得分:1)
Big O notation
通常只提供函数wiki的增长率的上限。这两种情况的含义,如P < N
和logN < N
。因此O(N + P) = O(2N) = O(N)
与O(N + log N) = O(2N) = O(N)
相同。希望能回答你的问题。
答案 3 :(得分:0)
为了便于理解,您可以假设O(n)
表示复杂性是n的order,而O
符号表示上限(或最差的复杂性)案件)。所以,当我说O(n+p)
时,它表示n + p的顺序。
让我们假设在最坏的情况下p = n / 2,那么n + n / 2的顺序是什么?它仍然是O(n)
,即线性,因为常量确实构成了Big-O表示法的一部分。
类似,对于O(n+logn)
,因为logn永远不会大于n
。因此,整体复杂性变得线性。
答案 4 :(得分:0)
简而言之
如果N是函数而C是常数:
O(N+N/2)
:
If C=2, then for any N>1 :
(C=2)*N > N+N/2,
2*N>3*N/2,
2> 3/2 (true)
O(N+logN)
:
If C=2, then for any N>2 :
(C=2)*N > N+logN,
2*N > N+logN,
2>(N+logN)/N,
2> 1 + logN/N (limit logN/N is 0),
2>1+0 (true)
反例O(N^2)
:
No C exists such that C*N > N^2 :
C > N^2/N,
C>N (contradiction).
无聊的数学部分
我认为混淆的根源是等号登录O(f(x))=O(N)
并不意味着平等!通常如果x = y则y = x。但是请考虑O(x)=O(x^2)
这是真的,但反向是假的:O(x^2) != O(x)
!
O(f(x))
是函数增长速度的上限。
上限不是确切的值。
如果g(x)=x
是某个函数f(x)
的上限,那么函数2*g(x)
(通常情况下,任何增长速度都快于g(x)
)也是f(x)
的上限。 {1}}。
正式定义是:如果您选择任何常量f(x)
,则函数g(x)
将被其他函数C
约束,从某些x_0
开始{{1}始终大于g(x)
。
f(x)
与f(x)=N+N/2
相同。如果我们采用3*N/2=1.5*N
而我们的常数g(x)=N
则C=2
的增长速度超过2*g(x)=2*N
:
如果1.5*N
和C=2
,那么任何x_0=1
n>(x_0=1)
。
同样适用于N + log(N):
2*N > 1.5*N
对任何C*N>N+log(N)
C>(N+logN)/N
C>1+log(N)/N
...take n_0=2
C>1+1/2
C>3/2=1.5
使用C=2
:2*N>N+log(N)
,
e.g。
N>(n_0=2)
现在有趣的部分是:2*3>3+log(3), 6>3+1.58=4.68
...
2*100>100+log(100), 200>100+6.64
...
&amp; N
。例如。 N^2
增长速度超过N squared
:
N
显然不存在大于变量的单个常量。想象一下这样一个常数C*N > N^2
C > N^2/N
C > N
。然后从C=C_0
函数N开始大于常量N=C_0+1
,因此不存在这样的常量。
为什么这在计算机科学中很有用?
在大多数情况下,计算精确的算法时间或空间没有意义,因为它取决于硬件速度,语言开销,算法实现细节和许多其他因素。
C
符号提供了估算哪种算法更好地独立于现实世界并发症的方法。很容易看出,O(N)优于O(N ^ 2),从某些Big O
开始,无论两个函数前面有哪些常数。
另一个好处是能够通过浏览程序和使用n_0
属性来估算算法的复杂性:
Big O
具有for x in range(N):
sub-calc with O(C)
和
O(N)
仍然具有for x in range(N):
sub-calc with O(C_0)
sub-calc with O(C_1)
的复杂性,因为“乘以常数规则”。
O(N)
“{产品规则”的复杂性为for x in range(N):
sub-calc with O(N)
。
O(N*N)=O(N^2)
具有for x in range(N):
sub-calc with O(C_0)
for y in range(N):
sub-calc with O(C_1)
复杂度的“定义(只需要O(N+N)=O(2*N)=O(N)
)”。
C=2*C_original
具有for x in range(N):
sub-calc with O(C)
for x in range(N):
sub-calc with O(N)
的复杂性,因为“如果O(N^2)
是其他函数的总和,则增长最快的术语将确定O(f(x))
”(参见数学部分中的说明)。
最后的话
f(x)
比我在这里写的要多得多!例如,在某些现实世界的应用程序和算法中,有用的Big-O
可能非常大,以至于复杂性较差的算法在实际数据上运行得更快。
CPU缓存可能会在其他渐近良好的算法中引入意外的隐藏因素。
等等...