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)上断言一个上界,这将使我