什么构成指数时间复杂度?

时间:2019-01-18 22:59:35

标签: algorithm time-complexity big-o

我正在比较两种确定数字是否为质数的算法。我正在查看时间复杂度的上限,但我无法理解两者之间的时间复杂度差异,尽管实际上一种算法要比另一种算法快。

此伪代码以指数时间O(2 ^ n)运行:

Prime(n):
    for i in range(2, n-1)
        if n % i == 0
            return False
    return True

此伪代码的运行时间是上一个示例的一半,但是我一直在努力了解时间复杂度是否仍为O(2 ^ n):

Prime(n):
    for i in range(2, (n/2+1))
        if n % i == 0
            return False
    return True

3 个答案:

答案 0 :(得分:3)

作为关于big-O(big-O)和big-Θ(big-Theta)的简单直觉,它们是关于在显着增大目标O的大小时如何更改需要执行的操作次数。问题(例如2倍)。

线性时间复杂度意味着您将大小增加了2倍,所需执行的步骤数也增加了约2倍。这就是所谓的Θ(n),通常是可互换但不准确的O(n)OΘ之间的区别在于O仅提供上限,而{{ 1}}保证上下限。

对数时间复杂度(Θ)表示,将大小增加2倍时,需要执行的步骤数将增加一定数量的操作。例如,使用二进制搜索,您只需一次矿石循环迭代就可以在两倍长的列表中找到给定元素。

类似地,指数时间复杂度(对于某些常数Θ(log(N))Θ(a^N))意味着如果将问题的大小仅增加1,则需要多进行a > 1倍的运算。 (请注意,aΘ(2^N)之间有细微的差别,实际上第二个更为通用,两者都位于指数时间之内,但两者都不能全部涵盖,请参见wiki一些详细信息)

请注意,这些定义在很大程度上取决于您如何定义“任务的大小”

正如@DavidEisenstat正确指出的那样,可以在两种情况下看到您的算法:

  1. 一些固定宽度的数字(例如32位数字)。在这种情况下,素数测试算法复杂性的一个明显度量就是被测值本身。在这种情况下,您的算法是线性的。

  2. 实际上,在很多情况下,素数测试算法应适用于非常大的数字。例如,当今使用的许多加密算法(例如Diffie–Hellman key exchangeRSA)都依赖于非常大的素数,例如512位,1024位等等。同样在那些上下文中,安全性是根据那些位数而不是特定的质数来衡量的。因此,在这种情况下,衡量任务大小的自然方法是位数。现在出现了问题:使用您的算法,我们需要执行多少次操作才能检查以位为单位的已知大小的值?显然,如果值2^Θ(N)具有N位,则它约为m。因此,您的算法从线性N ≈ 2^m转换为指数Θ(N)。换句话说,要解决一个仅长1位的值的问题,就需要做大约2倍的工作。

答案 1 :(得分:1)

指数与线性是一个有关如何表示输入和机器模型的问题。如果输入以一元表示(例如,将7发送为1111111),并且机器可以对数字进行恒定的时分,那么可以,该算法是线性时间。但是,n的二进制表示形式大约使用lg n位,并且数量n与lg n呈指数关系(n = 2 ^(lg n))。

鉴于两种解决方案的循环迭代次数均在一个常数因子之内,所以它们在同一大O类Theta(n)中。如果输入具有lg n位,则为指数;如果输入具有n位,则为线性。

答案 2 :(得分:0)

我希望这能为您解释为什么它们实际上是线性的。

假设您调用函数并查看它们执行了多少时间

Prime(n): # 1 time 
    for i in range(2, n-1) #n-1-1 times
        if n % i == 0  # 1 time 
            return False # 1 time

    return True # 1 time


# overall -> n

Prime(n): # Time
    for i in range(2, (n/2+1)) # n//(2+1) -1-1 time
        if n % i == 0 # 1 time
            return False # 1 time
    return True # 1 time

# overall -> n/2 times -> n times

这表明素数是线性函数

O(n ^ 2)可能是由于调用此函数的代码块引起的。

相关问题