Python 给出概率论界的大O表示法?
我试图估计以下算法的运行时复杂性:Python 给出概率论界的大O表示法?,python,algorithm,runtime,complexity-theory,Python,Algorithm,Runtime,Complexity Theory,我试图估计以下算法的运行时复杂性: for i in range(0, len(arr)): for j in range(i+1, len(arr)): if distance(arr[i], arr[j]) > 2: pass 距离函数的复杂度为min(len(arg1),len(arg2))。理论上,参数的最大长度可以达到N,但在实践中,它通常超过N的20% 由此,我可以将运行时函数估计为: f(N)=N*(N/2)*(N*.2) 那
for i in range(0, len(arr)):
for j in range(i+1, len(arr)):
if distance(arr[i], arr[j]) > 2:
pass
距离函数的复杂度为min(len(arg1),len(arg2))
。理论上,参数的最大长度可以达到N,但在实践中,它通常超过N的20%
由此,我可以将运行时函数估计为:
f(N)=N*(N/2)*(N*.2)
那是大O符号中的O(N^2)还是O(N^3)?如果是O(n^3),那么在实践中,如何证明运行时总是更接近O(n^2)而不是O(n^3)
谢谢还是O(n^3)
。人们可能会认为O(0.0000001*n^3)
比O(n^2)
更好。但是如果我们讨论一个算法的理论复杂性,那么只要假设n
可以大到10^100
,你就会明白O(n^3)
在性能方面“更差”。让len(arr)=n
由于原始状态在第二个循环中,让我们看看它运行了多少次
内部循环运行
第一次N-1次
第二次N-2次
第三次N-3次
。。。
...
第(N-1)次为1次
很明显,总数是=(N-1)(N)/2=X(比如说)。距离函数是X次执行的,在<强>渐近分析< /强>中,我们考虑最坏的情况,这意味着距离函数的复杂性为O(n)。
因此T(N)=((N-1)(N)/2)N=Y(假设)
使用大O的定义
Y=1,c=1
因此T(N)=O(N^3)你问:
如果是O(n^3),那么在实践中,如何证明运行时总是更接近O(n^2)而不是O(n^3)
答案是“更近”并不重要。只有“大于”和“小于”的物质
大O给出一个上限
如果一个过程的运行时复杂度最终超过了任何常数c或更大的c*n^2,并且有足够大的值n,那么它不可能是O(n^2)
这是因为big-O操作符没有给出估计;它给出了一个上限。即使是在固定时间内运行的过程也仍然是O(n^3)。(它也是O(n^2)、O(log(n))、O(n!)等等)。这是因为对于某些常量乘数c和较大的n值,它比所有这些运行时都要小
一个具体的例子
为了使这一点具体化,请考虑以下内容:
>>> def fa(n):
... return n * n * n // 10
...
>>> def f2(n):
... return n * n
...
>>> def f3(n):
... return n * n * n
...
对于上述运行时和较小的n
,fa
仍然小于或等于f2
:
>>> fa(10), f2(10), f3(10)
(100, 100, 1000)
但是如果我们将n
乘以10,fa
超过f2
>>> fa(100), f2(100), f3(100)
(100000, 10000, 1000000)
不难看出,即使我们通过一个恒定的乘数c
来增加f2
,我们仍然可以找到n
的值,使得fa(n)
更大
>>> def f2_boost(n, c):
... return f2(n) * c
...
>>> fa(1000), f2_boost(1000, 10), f3(1000)
(100000000, 10000000, 1000000000)
为什么要使用常数乘数?
运行时为n^3*0.1的过程与运行时为1000*n^3的过程属于同一个big-O类别,您可能仍然会感到困惑。毕竟,这两个运行时之间的绝对差异是巨大的
这有点难以解释,但当您提醒自己大O符号应该用来描述缩放行为时,它就开始有意义了。或者,换一种说法,大O表示法应该描述当我们改变用于测量的单位大小时,运行时是如何变化的
让我们举一个具体的例子:假设你想知道一座建筑物的高度。假设有人说“哦,大约300米。”你可能会对这个回答感到满意;你可能不在乎它到底有315米;300是一个足够好的估计。但如果他们说“哦,大约300米……或者是300英尺?”你可能会觉得不太满意,因为300米的高度是300英尺的三倍多
在计算机科学中,我们在测量时间时就遇到了这个问题。事实上,情况更糟。不同的计算机可能比其他计算机快得多,也可能慢得多。如果我们用“计算机执行的计算次数”来度量时间,那么对于某些计算机,我们将以百分之一秒来度量时间,而对于其他计算机,我们将以十亿分之一秒来度量时间。如果我们想以一种不会被巨大差异扭曲的方式来描述算法的行为,那么我们需要一种“尺度不变”的度量——也就是说,无论我们使用百分之一秒还是十亿分之一秒作为单位,这种度量都能给出相同的答案
大O表示法提供了这样一种度量。它为我们提供了一种测量运行时的方法,而无需太多地担心我们用来测量时间的单位的大小。本质上,说一个算法是O(n^2)就是说,对于任何等于或大于某个值c的时间单位,n都有一个对应的值,因此对于所有较大的值n,我们的过程都将在c*n^2之前完成
估计运行时
如果您想讨论估算运行时,那么您需要一个名为“大θ”的度量。简而言之,大O给出了任意大乘法器c的上界;大ω给出了任意大乘法器c的下界;大θ给出了一个定义上界和下界的函数,这取决于乘数c的选择
在您的例子中,较大的θ值将是O(n^3),因为您可以选择一个常数乘数c1,使c1*n^3始终大于n^3/10,并且您可以选择一个常数乘数c2,使c2*n^3始终小于n^3/10
.1*O(N^3)
仍然是O(N^3)
。这与O(N^2)
并不接近。嘿,非常感谢你的详细回答。我想我也可以把它写成f(N)=N*(N/2)*d(N)。如果我能在d(N)上断言一个上界,这将使我