[英]Optimizing Prime Number Python Code
我對python世界和一般的編碼世界還比較陌生,因此我不確定如何優化python腳本。 我擁有的腳本如下:
import math
z = 1
x = 0
while z != 0:
x = x+1
if x == 500:
z = 0
calculated = open('Prime_Numbers.txt', 'r')
readlines = calculated.readlines()
calculated.close()
a = len(readlines)
b = readlines[(a-1)]
b = int(b) + 1
for num in range(b, (b+1000)):
prime = True
calculated = open('Prime_Numbers.txt', 'r')
for i in calculated:
i = int(i)
q = math.ceil(num/2)
if (q%i==0):
prime = False
if prime:
calculated.close()
writeto = open('Prime_Numbers.txt', 'a')
num = str(num)
writeto.write("\n" + num)
writeto.close()
print(num)
你們中有些人可能會猜到我正在計算素數。 它調用的外部文件包含2到20之間的所有素數。之所以要進入while循環,是因為我希望能夠控制它運行了多長時間。
如果您有什么建議可以消除其中的混亂情況,請做出回應,謝謝。
與對整數進行操作相比,對文件的讀寫非常慢。 您只需刪除所有文件I / O,即可將算法加速100倍:
import itertools
primes = {2} # A set containing only 2
for n in itertools.count(3): # Start counting from 3, by 1
for prime in primes: # For every prime less than n
if n % prime == 0: # If it divides n
break # Then n is composite
else:
primes.add(n) # Otherwise, it is prime
print(n)
更快的素數生成算法將是篩子。 這是Python中的Eratosthenes篩子:
end = int(input('Generate primes up to: '))
numbers = {n: True for n in range(2, end)} # Assume every number is prime, and then
for n, is_prime in numbers.items(): # (Python 3 only)
if not is_prime:
continue # For every prime number
for i in range(n ** 2, end, n): # Cross off its multiples
numbers[i] = False
print(n)
保持文件中所有素數的存儲和加載效率很低。 通常,文件訪問非常慢。 而是將素數保存到列表或雙端隊列。 對於此初始化, calculated = deque()
,然后簡單地添加新的質數與calculated.append(num)
。 同時輸出帶有print(num)
數,並將結果通過管道傳輸到文件中。
當發現num
不是質數時,就不必繼續檢查所有其他除數。 因此,請打破內循環:
if q%i == 0:
prime = False
break
您不需要檢查所有以前的素數就可以檢查新的素數。 由於每個非素數都需要分解為兩個整數,因此至少其中一個因子必須小於或等於sqrt(num)
。 因此,將搜索范圍限制為這些除數。
您的代碼的第一部分也使我感到惱火。
z = 1
x = 0
while z != 0:
x = x+1
if x == 500:
z = 0
這部分似乎與以下內容相同:
for x in range(500):
另外,您將x
限制為500個質數,為什么不簡單地使用一個計數器,如果找到質數則增加計數並同時進行檢查,如果達到限制則中斷? 我認為這將更具可讀性。
通常,您不需要引入限制。 您可以隨時按Ctrl+C
來中止程序。
但是,正如其他人已經指出的那樣,對於中等或較大的素數,您選擇的算法的性能將非常差。 有更有效的算法來查找素數: https : //en.wikipedia.org/wiki/Generating_primes ,尤其是https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 。
您正在將空白行寫入文件,這將進行int()追溯。 另外,我猜您需要從換行符中刪除rstrip()。
我建議使用兩個不同的文件-一個用於初始值,一個用於所有值-初始和最近計算。
如果您可以將值保留在內存中一段時間,那將比重復遍歷文件快得多。 但是,當然,這將限制您可以計算的素數的大小,因此,對於較大的值,您可以根據需要返回到文件迭代方法。
對於計算大小適中的素數,篩子實際上是相當不錯的,並且值得一看。
當您遇到較大的素數時,最好先除以前n個素數,再進行Mill輪Miller-Rabin的除法。 如果Miller-Rabin概率性地表明該數字可能是質數,則您要進行完全的除法或AKS或類似操作。 米勒·拉賓(Miller Rabin)可以說“這可能是素數”或“這絕對是復合的”。 AKS給出了明確的答案,但是速度較慢。
FWIW,我在http://stromberg.dnsalias.org/~dstromberg/primes/上收集了很多與素數相關的代碼
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.