考虑数学运算的非恒定时间复杂度(大数)

时间:2012-03-02 22:10:58

标签: complexity-theory big-o

鉴于伪代码:

e = 1
sum = 1
for i=2 upto n
  e *= 10
  sum += i * e

做指数起诉乘法,因为它更快。假设n可以是10 ^ 1000或更大,你会如何获得这样的大O符号。

当然它将至少达到O(n),但乘法和加法会增加多少复杂性。再次,有大量的数字。

我目前正在Ruby中这样做。我认为每种语言都有不同的实现数学运算的方式,所以通用的解决方案很好。

1 个答案:

答案 0 :(得分:2)

为了使用n大到10 ^ 1000,你肯定需要使用 BigNumber 实现进行算术运算。

由于您正在使用算术运算的软件实现,这意味着它们的时间复杂度可能取决于您正在使用的数字的大小(位数)。在添加的情况下,复杂性可能是线性的,对于乘法,它将是二次的或在任何情况下都是超线性的。

在这种情况下,您所要做的就是将复杂性插入到上面的算法中,以获得组合的复杂性。

例如,如果你有:

for i = 2 to n
   <multiplication operation>

假设乘法是n的大小(位数)的二次方,那么O(mult) = (log n) ^ 2。然后for循环的大哦复杂性将是:

n * O(mult) = O(n * ((log n) ^ 2))

在您的示例中,for循环包含三个可能“昂贵”的操作:

for i = 2 to n
   e *= 10          //   e = e * 10
   sum += i * e     //   sum = sum + i * e

在上文中,昂贵的操作包括:mult1: e*10mult2: i * eadd: sum + (result of i*e)

它们的综合复杂性将是O(mult1 + mult2 + sum),它将取三个中最大的值。在这种情况下,绝对是mult2

因此,如果你可以在乘法运算上获得一个界限,那么总和就是复杂性,如上所述:n * O(mult),假设数字大小的二次实现,将会是转换为:O(n * log(n))

至于估计arithemetic操作的运行时特性,here's a nice table from Wikipedia of different algorithms for basic arithmetic operations