比较算法的复杂度

时间:2019-06-12 21:50:24

标签: algorithm data-structures time-complexity big-o notation

我目前正在了解Big O Notation的运行时间和摊销时间。

我有以下问题:

基于分而治之原理的两种算法可用于解决复杂性n的问题。 算法1将问题分为18个小问题,并且需要O(n ^ 2)个运算才能将子解决方案组合在一起。 算法2将问题分为64个小问题,并且需要O(n)运算才能将子解决方案组合在一起。

哪种算法更好和更快(对于大n)?

我猜想第二个算法更好,因为它需要更少的时间(O(n)比O(n ^ 2)更快)。 我猜对了吗?

小问题的数量是否会影响算法的速度,还是总是需要固定的时间?

2 个答案:

答案 0 :(得分:1)

在这种情况下,它可能不打算成为陷阱,但是请务必小心,并且可能会发生一些违反直觉的事情。陷阱(如果发生的话)主要是这样的:与产生了多少子问题相比,子问题要小得多?

例如,对于算法1而言,如果子问题是当前问题的大小的1/5或更小(也许它们意味着它们将是当前大小的1/18?),那么对时间复杂度以O(n²)为单位。但是,如果问题的大小仅减少4倍,那么我们已经达到O(n 2.085 ),并且如果域仅被切成一半(但仍然是18倍)然后一直到O(n 4.17 )。

与算法2相似,请确保是否将程序切成64个子问题,每个子问题的大小是大小的1/64,则总时间复杂度将为O(n log n)。但是,如果子问题甚至更大,例如大小的1/63,我们立即将层次结构的整个步骤上移至O(n 1.004 )-指数中的一个小常数仍然,但不再是对数线性的。使问题的大小变成原来的1/8,复杂度变成二次方,如果我们在每一步中仅将问题大小减半,就一直到O(n 6 )!另一方面,如果问题只缩小了 little 一点,即缩小了大小的1/65,那么复杂度立即又不再是对数线性的,但是这次又朝另一个方向发展,变为O(n)。

所以它可以采用任何一种方式,具体取决于子问题的缩小速度,问题陈述中未明确提及。希望很明显,仅仅比较“每个步骤的附加处理”是不够的,总的来说还是不够的。每步处理很多是无法克服的缺点,但如果“收缩因子”比“扇出因子”小,则每步处理很少的优点很容易丢失。 >

答案 1 :(得分:0)

Master theorem用于分治法的渐近分析,它将为您提供直接获得答案而不是猜测的方法。

T(n) = aT(n/b) + f(n)   

其中T是主要问题,n是输入集合,a是您划分为子问题的数量,b是每个子问题输入集合减少的因数,f(n)是函数将子问题分解和组合在一起。从这里我们找到c:

f(n) is O(n^c)

例如,在示例算法1中,c = 2,在算法2中,c =1。对于算法1和2,值a分别为18和64。下一部分是您的问题缺少适当信息的地方,因为未提供b。 换句话说,要获得清晰的答案,您需要知道每个子问题划分原始输入的因素。

if c < logb(a) then T(n) is O(n^logb(a))
if c = logb(a) then T(n) is O(n^c log(n))
if c > logb(a) then T(n) is O(f(n))