我有迭代平方的以下实现:
def power(a, b):
result = 1
while b > 0:
if b % 2 == 1:
result = mult(result, a)
a = mult(a, a)
b = b // 2
return result
mult()
方法将2个给定数字相乘,如果其中一个长度为x
位且另一个长度为y
位,则乘法运算的次数将为采取x*y+(x+y)
操作,我需要在复杂性分析中考虑。
我正在尝试找到一个O()
符号限制,当a为n位长时,作为n
和m
的函数完成的arithemtic操作的数量,并且b是m位长。我只需要考虑乘法线,并检查最坏的情况。
最坏的情况是b
是一个m位数,其中所有m
二进制数字都是1,然后我有循环的m
次迭代,在每次迭代中if条件是真的。
我不知道该怎么做才能在计算中考虑a
每次迭代增长的事实?我怎么把它放在某种有限的总和中,我可以计算几何级数?
由于
答案 0 :(得分:2)
另外,我知道将2位x位和y位相乘 导致x * y +(x + y)arithemtic操作。
那不是(一般而言)是真的。处理器将在规定数量的周期中将两个数字相乘,无论它们是否大。除非你处理大量的数字,否则你应该考虑渐近复杂度(O),乘法作为一个运算,同样适用于加法,除法......
在您的代码中,每次循环迭代(if b % 2 == 1
,可能result = result*a
,a = a*a
,b = b // 2
),您有四个操作中的三个。复杂性仅取决于循环的迭代次数,即:log2(b),因为b在每次迭代中除以2。
对于大量数据,您有两个可能对渐近复杂性产生影响的操作:result = result*a
和a = a*a
。如果n是数字的位数,则Cpython使用Karatsuba multiplication,即O(n ^ log2(3))。
我将详细阐述a*a
。当你取一个数字的平方时,你大致将位数乘以2。考虑log2(b)循环:a*a
在第一次迭代中取O(n ^ log2(3)),O(2n ^ log2(3))int第二次,O(4n ^ log2(3))在第二个,...,O(bn)^ log2(3))中的最后一个。总和是O((b * log2(b)* n)^ log2(3)),如果我没有错!
对于a*a
,如果你被绑定到一个O(x * y)mutlplication算法,那么对于你的log2(b)循环,你有
那个O(b ^ 2 * n ^ 2)= O(2 ^ 2m * n ^ 2)我想(现在没时间检查!)。
答案 1 :(得分:1)
我认为这种算法的复杂性与a。
无关在审查复杂性时,我认为由于m,循环次数是最高复杂度的主要索引。
运行b的值,如果b>我们可以看到以下数字。 0计算如下:
有趣的是,我们看到每2的倍数(即1,2,4,8,16,32,64)增加了n个循环。
粗略地说,我会说这个算法的复杂性紧跟O(log2(n))。
答案 2 :(得分:0)
嗯,经过一些分析,我认为power
方法的迭代次数将是i(从0到m-1)的总和:2^(2i-1)*n+(2^(i-1)+2^i*n+(2^i*n)^2+2^(i+1)*n
并且它很直接获得复杂性:O(4^m*n^2)