2 回答

TA貢獻1826條經驗 獲得超6個贊
您可以使用該multiprocessing庫來完成此操作?;舅枷胧怯袃山M流程。第一個過程可以queue用素數填充 a,然后您可以委托其他過程來處理這些素數并打印您的完美數字。
我確實做了一些更改并實現了一個基本is_prime功能。(請注意,對于此實現,您只需要檢查直到數字的平方根)。有更好的方法,但這不是這個問題的目的。
無論如何,我們的append_primes函數與您的第一個循環相同,除了不是將素數附加到列表中,而是將素數放入隊列中。我們需要某種信號來表明我們已經完成了附加素數,這就是我們q.put("DONE")最后的原因。"DONE"只要處理得當,它是任意的,可以是您想要的任何類型的信號。
然后,這perfect_number有點像你的第二個循環。它接受一個素數并打印出一個完美數(如果存在)。您可能希望將其退回,但這取決于您的要求。
最后,運行和執行多處理的所有邏輯都必須位于一個if __name__ == "__main__"塊內,以避免在文件被腌制并發送到新進程時一遍又一遍地重新運行。我們初始化我們的隊列并創建/啟動將素數附加到該隊列的過程。
當它運行時,我們創建了我們自己的多處理池版本。標準 mp 池不與隊列一起玩,所以我們必須有點花哨。我們初始化我們想要運行的最大進程數,并將其設置為當前 cpu 計數減 1(因為 1 將運行該append_primes函數。
我們循環q直到"DONE"返回(記住,這是我們的信號來自append_primes)。我們將不斷循環處理進程池,直到找到可用的進程。一旦發生這種情況,我們將創建并啟動該過程,然后繼續進行下一個數字。
processes最后,我們進行一些清理,并通過調用哪些塊來確保所有內容都完成,Process.join()直到進程完成執行。我們也確保prime_finder已經完成。
import multiprocessing as mp
import os
import queue
import time
def is_prime(n):
""" Returns True if n is prime """
for i in range(2, int(n**0.5)):
if n%i == 0:
return False
return True
def append_primes(max, q):
""" Searches for primes between 2 and max and adds them to the Queue (q) """
pid = os.getpid()
for num in range(2, int(max)+1):
if is_prime(num):
print(f"{pid} :: Put {num} in queue.")
q.put(num)
q.put("DONE") # A signal to stop processing
return
def perfect_number(prime, limit = 25000000000000000000):
""" Prints the perfect number, if it exists, given the prime """
pp = 2**prime
perfect = (pp - 1) * (pp // 2)
if perfect > limit:
return
if is_prime(pp - 1):
print(f"{os.getpid()} :: Perfect: {perfect}", flush = True)
return
if __name__ == "__main__":
q = mp.Queue()
max = 1000 # When to stop looking for primes
prime_finder = mp.Process(target = append_primes, args = (max, q,))
prime_finder.start()
n_processes = os.cpu_count() - 1 # -1 because 1 is for prime_finder
processes = [None]*n_processes
for prime in iter(q.get, "DONE"):
proc_started = False
while not proc_started: # Check each process till we find an 'available' one.
for m, proc in enumerate(processes):
if proc is None or not proc.is_alive():
processes[m] = mp.Process(target = perfect_number, args = (prime, ))
processes[m].start()
proc_started = True # Get us out of the while loop
break # and out of the for loop.
for proc in processes:
if proc is None: # In case max < n_processes
continue
proc.join()
prime_finder.join()
如果您只想查看完美數字,請注釋掉其中的print語句。append_primes前面出現的數字是進程的ID(只是為了讓你可以看到有多個進程同時工作)

TA貢獻1784條經驗 獲得超9個贊
當您可以將第二個循環的邏輯放在第一個循環中時,為什么要同時執行 2 個 for 循環:只是使用 bool 來確定您是否已達到限制,而不是完美循環中的 break。
你也不需要檢查if num > 1。只需從范圍開始2
primes=[]
limit = 25_000_000_000_000_000_000
reached_limit = False
def is_prime(n):
return 2 in [n,2**n%n]
for num in range(2, 1_000_000_000_000):
for i in range(2,num):
if (num % i) == 0:
break
else:
primes.append(num)
if not reached_limit:
pp = 2 ** num
perfect = (pp - 1) * (pp // 2)
if perfect > limit:
reached_limit = True
elif is_prime(pp-1):
print(perfect)
添加回答
舉報