小编典典

警告: timeit由于硬件或Python版本的差异,结果可能会有所不同。

下面是一个脚本,它比较了许多实现:

ambi_sieve_plain,

rwh_primes,

rwh_primes1,

rwh_primes2,

sieveOfAtkin,

埃拉托斯特尼筛法,

孙达拉姆3,

sieve_wheel_30,

ambi_sieve(需要numpy)

primesfrom3to(需要numpy)

primesfrom2to(需要numpy)

在使用psyco测试的简单Python方法中,对于n = 1000000, rwh_primes1是测试最快的方法。

+---------------------+-------+

| Method | ms |

+---------------------+-------+

| rwh_primes1 | 43.0 |

| sieveOfAtkin | 46.4 |

| rwh_primes | 57.4 |

| sieve_wheel_30 | 63.0 |

| rwh_primes2 | 67.8 |

| sieveOfEratosthenes | 147.0 |

| ambi_sieve_plain | 152.0 |

| sundaram3 | 194.0 |

+---------------------+-------+

在没有psyco的情况下,经过测试的普通Python方法中n = 1000000, rwh_primes2是最快的。

+---------------------+-------+

| Method | ms |

+---------------------+-------+

| rwh_primes2 | 68.1 |

| rwh_primes1 | 93.7 |

| rwh_primes | 94.6 |

| sieve_wheel_30 | 97.4 |

| sieveOfEratosthenes | 178.0 |

| ambi_sieve_plain | 286.0 |

| sieveOfAtkin | 314.0 |

| sundaram3 | 416.0 |

+---------------------+-------+

在所有测试的方法中,允许numpy,对于n = 1000000, primesfrom2to是测试最快的方法。

+---------------------+-------+

| Method | ms |

+---------------------+-------+

| primesfrom2to | 15.9 |

| primesfrom3to | 18.4 |

| ambi_sieve | 29.3 |

+---------------------+-------+

使用以下命令测量时间:

python -mtimeit -s"import primes" "primes.{method}(1000000)"

用{method}每个方法名称替换。

primes.py:

#!/usr/bin/env python

import psyco; psyco.full()

from math import sqrt, ceil

import numpy as np

def rwh_primes(n):

# https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188

""" Returns a list of primes < n """

sieve = [True] * n

for i in xrange(3,int(n**0.5)+1,2):

if sieve[i]:

sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i)+1)

return [2] + [i for i in xrange(3,n,2) if sieve[i]]

def rwh_primes1(n):

# https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188

""" Returns a list of primes < n """

sieve = [True] * (n/2)

for i in xrange(3,int(n**0.5)+1,2):

if sieve[i/2]:

sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1)

return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]]

def rwh_primes2(n):

# https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188

""" Input n>=6, Returns a list of primes, 2 <= p < n """

correction = (n%6>1)

n = {0:n,1:n-1,2:n+4,3:n+3,4:n+2,5:n+1}[n%6]

sieve = [True] * (n/3)

sieve[0] = False

for i in xrange(int(n**0.5)/3+1):

if sieve[i]:

k=3*i+1|1

sieve[ ((k*k)/3) ::2*k]=[False]*((n/6-(k*k)/6-1)/k+1)

sieve[(k*k+4*k-2*k*(i&1))/3::2*k]=[False]*((n/6-(k*k+4*k-2*k*(i&1))/6-1)/k+1)

return [2,3] + [3*i+1|1 for i in xrange(1,n/3-correction) if sieve[i]]

def sieve_wheel_30(N):

# http://zerovolt.com/?p=88

''' Returns a list of primes <= N using wheel criterion 2*3*5 = 30

Copyright 2009 by zerovolt.com

This code is free for non-commercial purposes, in which case you can just leave this comment as a credit for my work.

If you need this code for commercial purposes, please contact me by sending an email to: info [at] zerovolt [dot] com.'''

__smallp = ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,

61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139,

149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,

229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311,

313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401,

409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491,

499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599,

601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683,

691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,

809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887,

907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997)

wheel = (2, 3, 5)

const = 30

if N < 2:

return []

if N <= const:

pos = 0

while __smallp[pos] <= N:

pos += 1

return list(__smallp[:pos])

# make the offsets list

offsets = (7, 11, 13, 17, 19, 23, 29, 1)

# prepare the list

p = [2, 3, 5]

dim = 2 + N // const

tk1 = [True] * dim

tk7 = [True] * dim

tk11 = [True] * dim

tk13 = [True] * dim

tk17 = [True] * dim

tk19 = [True] * dim

tk23 = [True] * dim

tk29 = [True] * dim

tk1[0] = False

# help dictionary d

# d[a , b] = c ==> if I want to find the smallest useful multiple of (30*pos)+a

# on tkc, then I need the index given by the product of [(30*pos)+a][(30*pos)+b]

# in general. If b < a, I need [(30*pos)+a][(30*(pos+1))+b]

d = {}

for x in offsets:

for y in offsets:

res = (x*y) % const

if res in offsets:

d[(x, res)] = y

# another help dictionary: gives tkx calling tmptk[x]

tmptk = {1:tk1, 7:tk7, 11:tk11, 13:tk13, 17:tk17, 19:tk19, 23:tk23, 29:tk29}

pos, prime, lastadded, stop = 0, 0, 0, int(ceil(sqrt(N)))

# inner functions definition

def del_mult(tk, start, step):

for k in xrange(start, len(tk), step):

tk[k] = False

# end of inner functions definition

cpos = const * pos

while prime < stop:

# 30k + 7

if tk7[pos]:

prime = cpos + 7

p.append(prime)

lastadded = 7

for off in offsets:

tmp = d[(7, off)]

start = (pos + prime) if off == 7 else (prime * (const * (pos + 1 if tmp < 7 else 0) + tmp) )//const

del_mult(tmptk[off], start, prime)

# 30k + 11

if tk11[pos]:

prime = cpos + 11

p.append(prime)

lastadded = 11

for off in offsets:

tmp = d[(11, off)]

start = (pos + prime) if off == 11 else (prime * (const * (pos + 1 if tmp < 11 else 0) + tmp) )//const

del_mult(tmptk[off], start, prime)

# 30k + 13

if tk13[pos]:

prime = cpos + 13

p.append(prime)

lastadded = 13

for off in offsets:

tmp = d[(13, off)]

start = (pos + prime) if off == 13 else (prime * (const * (pos + 1 if tmp < 13 else 0) + tmp) )//const

del_mult(tmptk[off], start, prime)

# 30k + 17

if tk17[pos]:

prime = cpos + 17

p.append(prime)

lastadded = 17

for off in offsets:

tmp = d[(17, off)]

start = (pos + prime) if off == 17 else (prime * (const * (pos + 1 if tmp < 17 else 0) + tmp) )//const

del_mult(tmptk[off], start, prime)

# 30k + 19

if tk19[pos]:

prime = cpos + 19

p.append(prime)

lastadded = 19

for off in offsets:

tmp = d[(19, off)]

start = (pos + prime) if off == 19 else (prime * (const * (pos + 1 if tmp < 19 else 0) + tmp) )//const

del_mult(tmptk[off], start, prime)

# 30k + 23

if tk23[pos]:

prime = cpos + 23

p.append(prime)

lastadded = 23

for off in offsets:

tmp = d[(23, off)]

start = (pos + prime) if off == 23 else (prime * (const * (pos + 1 if tmp < 23 else 0) + tmp) )//const

del_mult(tmptk[off], start, prime)

# 30k + 29

if tk29[pos]:

prime = cpos + 29

p.append(prime)

lastadded = 29

for off in offsets:

tmp = d[(29, off)]

start = (pos + prime) if off == 29 else (prime * (const * (pos + 1 if tmp < 29 else 0) + tmp) )//const

del_mult(tmptk[off], start, prime)

# now we go back to top tk1, so we need to increase pos by 1

pos += 1

cpos = const * pos

# 30k + 1

if tk1[pos]:

prime = cpos + 1

p.append(prime)

lastadded = 1

for off in offsets:

tmp = d[(1, off)]

start = (pos + prime) if off == 1 else (prime * (const * pos + tmp) )//const

del_mult(tmptk[off], start, prime)

# time to add remaining primes

# if lastadded == 1, remove last element and start adding them from tk1

# this way we don't need an "if" within the last while

if lastadded == 1:

p.pop()

# now complete for every other possible prime

while pos < len(tk1):

cpos = const * pos

if tk1[pos]: p.append(cpos + 1)

if tk7[pos]: p.append(cpos + 7)

if tk11[pos]: p.append(cpos + 11)

if tk13[pos]: p.append(cpos + 13)

if tk17[pos]: p.append(cpos + 17)

if tk19[pos]: p.append(cpos + 19)

if tk23[pos]: p.append(cpos + 23)

if tk29[pos]: p.append(cpos + 29)

pos += 1

# remove exceeding if present

pos = len(p) - 1

while p[pos] > N:

pos -= 1

if pos < len(p) - 1:

del p[pos+1:]

# return p list

return p

def sieveOfEratosthenes(n):

"""sieveOfEratosthenes(n): return the list of the primes < n."""

# Code from: , Nov 30 2006

# http://groups.google.com/group/comp.lang.python/msg/f1f10ced88c68c2d

if n <= 2:

return []

sieve = range(3, n, 2)

top = len(sieve)

for si in sieve:

if si:

bottom = (si*si - 3) // 2

if bottom >= top:

break

sieve[bottom::si] = [0] * -((bottom - top) // si)

return [2] + [el for el in sieve if el]

def sieveOfAtkin(end):

"""sieveOfAtkin(end): return a list of all the prime numbers

using the Sieve of Atkin."""

# Code by Steve Krenzel, , improved

# Code: https://web.archive.org/web/20080324064651/http://krenzel.info/?p=83

# Info: http://en.wikipedia.org/wiki/Sieve_of_Atkin

assert end > 0

lng = ((end-1) // 2)

sieve = [False] * (lng + 1)

x_max, x2, xd = int(sqrt((end-1)/4.0)), 0, 4

for xd in xrange(4, 8*x_max + 2, 8):

x2 += xd

y_max = int(sqrt(end-x2))

n, n_diff = x2 + y_max*y_max, (y_max << 1) - 1

if not (n & 1):

n -= n_diff

n_diff -= 2

for d in xrange((n_diff - 1) << 1, -1, -8):

m = n % 12

if m == 1 or m == 5:

m = n >> 1

sieve[m] = not sieve[m]

n -= d

x_max, x2, xd = int(sqrt((end-1) / 3.0)), 0, 3

for xd in xrange(3, 6 * x_max + 2, 6):

x2 += xd

y_max = int(sqrt(end-x2))

n, n_diff = x2 + y_max*y_max, (y_max << 1) - 1

if not(n & 1):

n -= n_diff

n_diff -= 2

for d in xrange((n_diff - 1) << 1, -1, -8):

if n % 12 == 7:

m = n >> 1

sieve[m] = not sieve[m]

n -= d

x_max, y_min, x2, xd = int((2 + sqrt(4-8*(1-end)))/4), -1, 0, 3

for x in xrange(1, x_max + 1):

x2 += xd

xd += 6

if x2 >= end: y_min = (((int(ceil(sqrt(x2 - end))) - 1) << 1) - 2) << 1

n, n_diff = ((x*x + x) << 1) - 1, (((x-1) << 1) - 2) << 1

for d in xrange(n_diff, y_min, -8):

if n % 12 == 11:

m = n >> 1

sieve[m] = not sieve[m]

n += d

primes = [2, 3]

if end <= 3:

return primes[:max(0,end-2)]

for n in xrange(5 >> 1, (int(sqrt(end))+1) >> 1):

if sieve[n]:

primes.append((n << 1) + 1)

aux = (n << 1) + 1

aux *= aux

for k in xrange(aux, end, 2 * aux):

sieve[k >> 1] = False

s = int(sqrt(end)) + 1

if s % 2 == 0:

s += 1

primes.extend([i for i in xrange(s, end, 2) if sieve[i >> 1]])

return primes

def ambi_sieve_plain(n):

s = range(3, n, 2)

for m in xrange(3, int(n**0.5)+1, 2):

if s[(m-3)/2]:

for t in xrange((m*m-3)/2,(n>>1)-1,m):

s[t]=0

return [2]+[t for t in s if t>0]

def sundaram3(max_n):

# https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/2073279#2073279

numbers = range(3, max_n+1, 2)

half = (max_n)//2

initial = 4

for step in xrange(3, max_n+1, 2):

for i in xrange(initial, half, step):

numbers[i-1] = 0

initial += 2*(step+1)

if initial > half:

return [2] + filter(None, numbers)

################################################################################

# Using Numpy:

def ambi_sieve(n):

# http://tommih.blogspot.com/2009/04/fast-prime-number-generator.html

s = np.arange(3, n, 2)

for m in xrange(3, int(n ** 0.5)+1, 2):

if s[(m-3)/2]:

s[(m*m-3)/2::m]=0

return np.r_[2, s[s>0]]

def primesfrom3to(n):

# https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188

""" Returns a array of primes, p < n """

assert n>=2

sieve = np.ones(n/2, dtype=np.bool)

for i in xrange(3,int(n**0.5)+1,2):

if sieve[i/2]:

sieve[i*i/2::i] = False

return np.r_[2, 2*np.nonzero(sieve)[0][1::]+1]

def primesfrom2to(n):

# https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188

""" Input n>=6, Returns a array of primes, 2 <= p < n """

sieve = np.ones(n/3 + (n%6==2), dtype=np.bool)

sieve[0] = False

for i in xrange(int(n**0.5)/3+1):

if sieve[i]:

k=3*i+1|1

sieve[ ((k*k)/3) ::2*k] = False

sieve[(k*k+4*k-2*k*(i&1))/3::2*k] = False

return np.r_[2,3,((3*np.nonzero(sieve)[0]+1)|1)]

if __name__=='__main__':

import itertools

import sys

def test(f1,f2,num):

print('Testing {f1} and {f2} return same results'.format(

f1=f1.func_name,

f2=f2.func_name))

if not all([a==b for a,b in itertools.izip_longest(f1(num),f2(num))]):

sys.exit("Error: %s(%s) != %s(%s)"%(f1.func_name,num,f2.func_name,num))

n=1000000

test(sieveOfAtkin,sieveOfEratosthenes,n)

test(sieveOfAtkin,ambi_sieve,n)

test(sieveOfAtkin,ambi_sieve_plain,n)

test(sieveOfAtkin,sundaram3,n)

test(sieveOfAtkin,sieve_wheel_30,n)

test(sieveOfAtkin,primesfrom3to,n)

test(sieveOfAtkin,primesfrom2to,n)

test(sieveOfAtkin,rwh_primes,n)

test(sieveOfAtkin,rwh_primes1,n)

test(sieveOfAtkin,rwh_primes2,n)

运行脚本会测试所有实现都给出相同的结果。

2020-02-05

python求小于n的所有素数_Python-列出N以下所有素数的最快方法相关推荐

  1. python求小于n的所有素数_python - 列出N以下所有素数的最快方法 - 堆栈内存溢出...

    警告:由于硬件或Python版本的不同, timeit结果可能会有所不同. 下面是一个脚本,比较了许多实现: 非常感谢斯蒂芬为使sieve_wheel_30引起我的注意. 值得罗伯特·威廉·汉克斯 ( ...

  2. python求1到n的乘积_Python简单实现两个任意字符串乘积的方法示例

    本文实例讲述了Python简单实现两个任意字符串乘积的方法.分享给大家供大家参考,具体如下: 题目: 给定两个任意数字组成的字符串,求乘积,字符可能很大,但是python具有无限精度的整数在这里就不需 ...

  3. python求小于n的所有素数_python使用筛选法计算小于给定数字的所有素数

    本文实例为大家分享了python计算小于给定数字的所有素数的具体代码,供大家参考,具体内容如下 代码思路:首先列出指定范围内所有候选数字,然后从前往后依次选择一个数字去除以后面所有数字,能够被整除的肯 ...

  4. python求小于n的所有素数_快速找出N以内的所有素数解法,python版本。这个应该是最快的了...

    作者:Raffeale/于大伟 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数. 一般正常人的解法是两次循环,假设求小于N的所有素数.一次用N-1之间的所有数去 ...

  5. python求1到100偶数和_python 求1-100之间的奇数或者偶数之和的实例

    python 求1-100之间的奇数或者偶数之和的实例 如下所示: i=0 sum1=0 sum2=0 while i<=100: if i%2==0: sum1+=i else: sum2+= ...

  6. python求一条线的长度_python求线段的长度-女性时尚流行美容健康娱乐mv-ida网

    女性时尚流行美容健康娱乐mv-ida网 mvida时尚娱乐网 首页 美容 护肤 化妆技巧 发型 服饰 健康 情感 美体 美食 娱乐 明星八卦 首页  > 高级搜索 excel里去掉最高分最低分再 ...

  7. python求小于n的所有素数_用python求出2000000内所有素数的和?不知怎么写?

    展开全部 import itertools import time N = 2000000 L = range(N) def findnxt(s): flag = 0 for n in itertoo ...

  8. 在python中求小于100的所有合数_python输出100以内的质数与合数

    __author__ = 'Yue Qingxuan' # -*- coding: utf-8 -*- #求质数 p=[2] for i in range(2,101): for temp in ra ...

  9. python 求3位数的水仙花数_python 求3到8位数的水仙花数Pycharm实现

    #-*- coding: utf-8-*- import time import math #获取3位数的水仙花数 start1 = time.time() start = time.time() n ...

最新文章

  1. jackson 解析json问题
  2. 第二部分:IDEA 常用设置
  3. 获取文件名和路径函数
  4. 使用Docker打包发布Django应用
  5. Mybatis Plus——[Could not set property 'id' of '***' with value]解决方案
  6. python自带的sum()函数和numpy库中的sum()函数的区别
  7. 第2章线性表的基本使用及其cpp示例(第二章汇总,线性表都在这里)
  8. 在实际项目中,如何选择合适的机器学习模型?
  9. KITTI激光雷达点云解析与图像反投影
  10. 研发感悟:从CPU架构图谈谈开发工作
  11. 配置docker加速器
  12. 水果销售管理系统课程设计报告
  13. 旋转矩阵是正交矩阵与伴随性质的证明
  14. matlab实现通信系统,香农定理的介绍
  15. 2021国际货币论坛金融科技分论坛隆重举行 聚焦“数字金融人才培养”
  16. python爬虫——汽车之家数据
  17. springbootvue简单的景点信息管理系统
  18. linux 命令行获取时间,【Linux】让命令提示符显示日期和时间
  19. java ico图标_javaweb中如何给自己的网站更改ico图标
  20. svg 中 text dx dy 含义

热门文章

  1. Matlab isnan isinf median circshift 函数
  2. 路路通软件android版,家校路路通app
  3. 凸优化之共轭函数(二)
  4. oracle omf管理,论OMF管理文件的重要性
  5. 《五朵金花》电影影评
  6. 面对人工智能,我们应有的态度
  7. 【noip模拟赛1】古韵之鹊桥相会(最短路)
  8. 箭头函数与普通函数,以及使用场景
  9. Vue3动态引入图片
  10. JSON数据交互和RESTful支持