几种简单的求素数算法的复杂度分析

    素数的算法有很多种,现在主要讲两种算法及其改进版本的复杂度分析,解释性能提升的幅度。现以求100000内素数为例,两种算法分别是:
      1.基础思路是去掉偶数,包括取模的范围,代码如下:
           print(2)

     for i in range(3,100000,2):
      for a in range(3,int(i*0.5)+1,2):
       if i%a == 0:
       break
       else:
         print(i,end = ' ')
此两层循环的算法的复杂度为0.5n((n**0.5+1)/2)

          2.应用一个素数定理:大于6的素数一定与6的倍数相邻,代码如下:
              print(2,3,end = ' ')

    t = 100000 // 6 + 1
    for i in range(1,t):
     x = 6 * i - 1
    for j in range(3,int(x**0.5)+1,2):
    if x % j == 0:
    break
     else:
      print(x ,end = ' ')

     y = 6 * i + 1
     for j in range(3, int(y0.5)+1,2):
     if y % j == 0:
     break
    else:
      print(x ,end = ' ')
此算法的复杂度为(n/3052)(n
0.5+1)/2,将总范围分成30为一块,则6的倍数有5个,相邻的数就是10个。

                     优化思路:
                     对于1号算法,我们知道末尾是5的数一定能被5整除,所以末位是5的数一定不是素数,复杂度可以降为0.4*n*((n**0.5+1)*0.4)。不是偶数且末为不是5,就剩(1,3,7,9),所以4/10=0.4,第二层循环也是如此。优化效率提升56%(0.5**2/0.4**2-1=0.56)。
                     对于2号算法,思路也是刨去末位为5的数。例如,30~60这一块内,6的倍数有(36,42,48,54,60),相邻的数是(35,37,41,43,47,49,53,55,59,61),有两个末位是5的数(35,55),所以将总范围分成30为一块,只需计算8个数,优化后复杂度为(n/30*(5*2-2))*(n**0.5+1)*0.4=4/15*n*(n**0.5+1)*0.4。相比优化后的1号算法,优化后的2号算法效率提升50%(其余项约分,只剩0.4/(4/15),所以0.4/(4/15)-1=0.5)。

                    综上可见,降低算法复杂度是提高解决问题效率的不二法门。

猜你喜欢

转载自blog.51cto.com/13886271/2154947
今日推荐