Big o 这个函数的大O复杂性是什么?
这是一段代码,我最初的想法是,它的复杂度是n,因为它只是输入,没有平方,没有任何东西,但是当研究n/2时,我发现它的大O复杂度是Log(m),所以现在我很困惑,这的大O复杂度是Log(m)吗?如果是,为什么会这样?让我们假设将Big o 这个函数的大O复杂性是什么?,big-o,Big O,这是一段代码,我最初的想法是,它的复杂度是n,因为它只是输入,没有平方,没有任何东西,但是当研究n/2时,我发现它的大O复杂度是Log(m),所以现在我很困惑,这的大O复杂度是Log(m)吗?如果是,为什么会这样?让我们假设将范围内的所有内容都计算在内,而将循环作为基本操作 然后,为了找到除法函数基本运算数的渐近上界,我们需要一个上界,给定函数的输入n,循环执行时的次数 我们可以简单地反转循环,它将变得非常明显(忽略地板): 求和表达式通过1的步骤从0到log2(n)运行i,这意味着循环运行(忽
范围内的所有内容都计算在内,而将循环作为基本操作
然后,为了找到除法
函数基本运算数的渐近上界,我们需要一个上界,给定函数的输入n
,循环执行时的次数
我们可以简单地反转循环,它将变得非常明显(忽略地板):
求和表达式通过1
的步骤从0
到log2(n)
运行i
,这意味着循环运行(忽略地板)log2(n)+1次,反过来意味着O(log2(n))
为函数的时间复杂度提供了一个渐近上界。在这种情况下,如果输入是单个数字,我们不能假设算术运算需要恒定的时间。从形式上讲,算法的“输入大小”应该以位为单位来度量,并且划分一个需要更多位来表示的数字需要更多的时间
您的代码实际上使用的是浮点数,这意味着数字的实际大小与表示浮点数所需的位数没有直接关系(我们必须忽略实际浮点数的位数是固定的,否则“输入大小”和“时间复杂度”的概念就毫无意义)。分析一个类似的整数算法比较简单;让我们假设该算法取一个整数,并执行n=n//2
或n=n>>1
而不是n=math.floor(n/2)
。整数n
采用O(logn)
位来表示
实际的时间取决于时间;我们可以说时间复杂度是O(D(n)logn)
其中D(n)
是除法算法的时间复杂度。有各种具有不同时间复杂度的除法算法,这也取决于所用乘法算法的时间复杂度。另一方面,由于除以2相当于右移1位,如果我们编写算法使用位移位(或者如果除法算法在这种特殊情况下将其优化为位移位),我们将得到D(n)=O(logn)
,因为位移位在位数上需要线性时间。在这种情况下,原始算法的时间复杂度将是O(log^2n)
,因此每当循环变量除以2时,其大-O复杂度就是O(log(n))?另外,O(log2(n))与O(log(n))是一样的吗?@AedenSchmidt它并没有那么容易;您需要定义基本运算是什么,然后从数学上推导出基本运算数的上限(在使用大O表示法的情况下),通常用于足够大的输入,以便忽略任何低阶项。我想你可能想读一下大O符号和渐近复杂性的基础知识。例如,请参见主题log2(n)
与log(n)
不同,因为log(n)
通常是log10(n)
或ln(n)
,但渐进地,它们可以被认为是相同的解释。
def dividing(n):
while n!=1:
n=math.floor(n/2)
return True
while(invariant) { basic-operation }
// The value of 'n' until termination of
// the while loop, in reverse (n here == n_start)
1 + 2 + 4 + ... + n
= 2^0 + 2^1 + 2^2 + ... + 2^(log2(n))
= sum_{i=0}^{i=log2(n_start)} 2^i