2013-05-10 40 views
6

我一直使用C#代碼(是的,我正在做與梅森素數的東西來計算完美的數字優化盧卡斯 - 萊默檢驗法。我想知道這是可能與當前的代碼,以進一步使在速度提升我使用System.Numerics.BigInteger類來保存這些數字,也許它不是最明智的,我們會看到它,然後盧卡斯萊默優化

這段代碼實際上是根據情報發現:http://en.wikipedia.org/wiki/Lucas%E2%80%93Lehmer_primality_test

此頁面(在時間戳)部分,一些證據是考慮到優化師了。

用於LucasTest的代碼是:

public bool LucasLehmerTest(int num) 
{ 
    if (num % 2 == 0) 
    return num == 2; 
    else 
    { 
    BigInteger ss = new BigInteger(4); 
    for (int i = 3; i <= num; i++) 
    { 
     ss = KaratsubaSquare(ss) - 2; 
     ss = LucasLehmerMod(ss, num); 
    } 
    return ss == BigInteger.Zero; 
    } 

}

編輯: 哪個比使用從BigInteger類ModPow通過下面Mare的無限極所建議的速度更快。這實現:

public bool LucasLehmerTest(int num) 
{ 
    if (num % 2 == 0) 
    return num == 2; 
    else 
    { 
    BigInteger m = (BigInteger.One << num) - 1; 
    BigInteger ss = new BigInteger(4); 
    for (int i = 3; i <= num; i++) 
     ss = (BigInteger.ModPow(ss, 2, m) - 2) % m; 
    return ss == BigInteger.Zero; 
    } 

}

的LucasLehmerMod方法實現如下:

public BigInteger LucasLehmerMod(BigInteger divident, int divisor) 
{ 
    BigInteger mask = (BigInteger.One << divisor) - 1; //Mask 
    BigInteger remainder = BigInteger.Zero; 
    BigInteger temporaryResult = divident; 

    do 
    { 
     remainder = temporaryResult & mask; 
     temporaryResult >>= divisor; 
     temporaryResult += remainder; 
    } while ((temporaryResult >> divisor) != 0); 

    return (temporaryResult == mask ? BigInteger.Zero : temporaryResult); 
} 

我擔心的是,使用.NET Framework中BigInteger類時,我我一定會對他們的計算。這是否意味着我必須創建自己的BigInteger類來改進它?或者,我可以通過使用KaratsubaSquare(從karatsuba算法得到的)這樣,維持了我對Optimizing Karatsuba Implementation發現:

public BigInteger KaratsubaSquare(BigInteger x) 
{ 
    int n = BitLength(x);         

    if (n <= LOW_DIGITS) return BigInteger.Pow(x,2);  //Standard square 

    BigInteger b = x >> n;         //Higher half 
    BigInteger a = x - (b << n);       //Lower half 
    BigInteger ac = KaratsubaSquare(a);      // lower half * lower half 
    BigInteger bd = KaratsubaSquare(b);      // higher half * higher half 
    BigInteger c = Karatsuba(a, b);       // lower half * higher half 

    return ac + (c << (n + 1)) + (bd << (2 * n));   
} 

所以基本上,我想看看它是否能夠提高盧卡斯 - 萊默測試方法通過優化for循環。但是,我有點卡在那裏...甚至有可能嗎?

當然歡迎任何想法。

一些額外的幾點思考:

我可以使用多個線程來加快在尋找完美的數量計算。但是,我還沒有經驗(尚未)具有良好的分區。 我會盡力解釋我的想法(無代碼):

首先,我將使用Erathostenes篩子生成一個可視表。大約需要25毫秒才能找到2-100萬單線程範圍內的素數。

#提供了什麼C是相當驚人的。與Parallel.For方法一起使用PLINQ,我可以幾乎同時運行幾個計算,但是,它會將primeTable數組分割成不受搜索限制的部分。

我已經想通了,線程的自動負載均衡是不夠的這項任務。因此,我需要嘗試一種不同的方法,通過根據mersenne數字劃分負載平衡來找到並使用它來計算完美數字。有沒有人有這方面的經驗?本頁面似乎有點幫助:http://www.drdobbs.com/windows/custom-parallel-partitioning-with-net-4/224600406

我會尋找到它進一步。

至於現在,我的結果如下。 我現在的算法(使用C#中的標準BigInteger類)可以在我的筆記本電腦(具有4個內核和8GB內存的Intel I5)的5秒鐘內找到前17個完美數字(請參見http://en.wikipedia.org/wiki/List_of_perfect_numbers)。但是,它會在10分鐘內卡住並且找不到任何東西。

這是我無法比擬的東西......我的直覺(和常識)告訴我,我應該研究LucasLehmer測試,因爲計算第18個完美數字(使用Mersenne Prime 3217)的for-loop會運行3214次。我猜...

Dinony在下面發佈的是一個建議,用C完全重寫它。我同意這會提高我的性能,但是我選擇C#來找出它的侷限性和優點。由於它被廣泛使用,並且能夠快速開發應用程序,所以我覺得值得嘗試。

不安全的代碼也可以在這裏提供好處嗎?

+1

你真的需要的BigInteger這裏?如果你回答是的,也許'ModPow'是你的朋友。 – 2013-05-11 11:58:22

+0

Mare Infinitus,這可能很有趣。是的,我需要一個BigInteger,因爲完美的數字有一個相當大的趨勢...第17個完美的數字由1373個數字組成。 我會看看我可以用ModPow做些什麼! – RvdV79 2013-05-11 12:07:40

+0

我很早以前就寫過一個測試,但是在C#和BigInteger中。 ModPow明確地做出了區別。認爲這是爲歐拉項目。問題是:你需要這種特殊的算法還是隻需要一個工作? – 2013-05-11 12:09:39

回答

2

一個可能的優化是使用BigInteger ModPow

這真的顯著提高性能。

+0

Mare Infinitus,我已經在原來的帖子中更新了你以前的建議。實現和使用ModPow實際上比我的優化慢,它可以消除分割......但是,加上一個建議! – RvdV79 2013-05-11 15:43:30

+0

到目前爲止我已經接受你的回答。在進入盧卡斯萊默測試之前測試素數是最好的建議! – RvdV79 2013-05-27 15:18:55

1

如何將代碼調整爲C?我不知道該算法的想法,但它不是多的代碼..所以最大的運行時間改善,可以適應C.

+0

是的,這似乎並不像是太難轉換。 C#比C更容易構建基礎設施。 – 2013-05-10 15:44:13

+0

這是我完全可以同意的@dinony。不過,我覺得喜歡用C#編程。如果這是真正的優化(我毫不懷疑),我必須進一步觀察。不知何故,它必須能夠加速算法。 我也注意到Karatsuba可以通過使用位掩碼來實現更高效。 – RvdV79 2013-05-11 11:24:17

+0

Yap我知道,在C#編程是非常誘人和有趣的,但是當我聽到優化時我認爲C/C++ :) ..我知道這不是你想要的答案,也許有人知道算法可以給你C#優化提示 – dinony 2013-05-11 11:54:39

2

只是記下信息... 在Python中,這

ss = KaratsubaSquare(ss) - 2 

有比這更糟糕的表現:

ss = ss*ss - 2 
+1

如果任何庫實現大整數操作,那麼我會假設它以最快的方式執行它。因此,Python將使用Karatsuba方法本身,但會進行高度優化和調整,或者它將使用更快的方法,如Karatsuba方法的泛化或FFT方法。 – gnasher729 2014-03-22 01:27:16