簡體   English   中英

在 Python 中進行多處理以查找質數

[英]Multiprocessing in Python to find prime numbers

在 Python 3 我有這個任務,我需要使用多處理在區間[a,b]中找到質數。

讓我們以間隔 [0,30] 為例,使用 3 個進程,我有三個間隔[ai,bi][0.10][10,20][20,30]

這是我的代碼:

import multiprocessing
import time
def isprime(num):
  if num > 1:
       for i in range(2, num):
            if (num % i) != 0:
               pass
       else:
           return num

if __name__ == "__main__":
    pool = multiprocessing.Pool(3)
    start_time = time.perf_counter()
    result = pool.map(isprime, range(0,30))
    finish_time = time.perf_counter()
    print(f"Program finished in {finish_time-start_time} seconds")
    print(result)

   

這是預期的出口:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

這就是我得到的:

[None, None, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

你有三個問題:

  1. 您的isprime function 將隱式返回None for arguments <= 1 但否則將始終執行您的for語句的else子句並返回傳遞的參數。
  2. 假設isprime將返回傳遞的參數(如果它是素數)或None (如果不是),那么您需要從isprime中過濾掉None返回值。
  3. 您實際上並沒有像您指出的那樣通過將間隔分解為范圍來解決問題。 我將在代碼后的評論中解決這個問題。
import multiprocessing
import time

def isprime(num):
    if num < 2:
        return None
    for i in range(2, num):
         if (num % i) == 0:
            return None
    else:
        return num

if __name__ == "__main__":
    pool = multiprocessing.Pool(3)
    start_time = time.perf_counter()
    result = list(filter(lambda x: x is not None, pool.map(isprime, range(0,30))))
    finish_time = time.perf_counter()
    print(f"Program finished in {finish_time-start_time} seconds")
    print(result)

印刷:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

普通的留言

您的isprime function 可以大大改進(做一個更好的實施谷歌)。 例如:

def isprime(num):
    from math import sqrt, floor

    if num < 2: return None
    if num == 2: return num
    if num % 2 == 0: return None
    for d in range(3, floor(sqrt(num)) + 1, 2):
        if num % d == 0: return None
    return num

但是正如您所見,隨着參數n的增加,主循環需要進行更多次迭代才能證明傳遞的參數是素數。

處理這個問題的方法是實現某種版本的Eraosthenes算法,它可以有效地生成一系列素數,然后您將傳遞給這個 function 一個范圍內的數字,function 將返回所有的數字它在該范圍內找到的素數。 當然,你會把你的初始range(0, 30)分成 3 個子范圍的列表,即[range(0, 10), range(10, 20), range(20, 30)] ,這將是傳遞給您的map方法。

但是即使是標准的 Sieve 算法也必須開始生成以 2 開頭的素數,因此即使您將參數range(10, 20)傳遞給它,function 也必須重復在參數range(0, 10)為被通過。

因此,多次調用isprime方法對於查找一系列素數而言效率不高,但 Sieve 算法從多處理實現中沒有任何收獲(多處理實際上會損害性能)。 解決此問題的最佳方法是使用非多處理 Sieve。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM