簡體   English   中英

快速素數分解算法

[英]Fast Prime Factorization Algorithm

我正在用 C 編寫一個代碼,它返回一個正整數可以表示為兩個正整數的完全平方和的次數。

R(n) is the number of couples (x,y) such that x² + y² = n where x, y, n are all 
non negative integers.

為了計算 R(n),我需要首先找到 n 的質因數分解。

問題是我已經嘗試了很多可以在 C 上使用的素數分解算法,但我需要我的代碼盡可能快,所以如果有人能給我他/她認為是計算大到2147483742.的數的質因數分解的最快算法2147483742.

多么奇怪的限制; 2147483742 = 2^31 + 94。

正如其他人指出的那樣,對於一個數字,這個由素數進行的小試除很可能足夠快。 如果不是,您可以嘗試 Pollard 的 rho 方法:

/* WARNING! UNTESTED CODE! */
long rho(n, c) {
    long t = 2;
    long h = 2;
    long d = 1;

    while (d == 1) {
        t = (t*t + c) % n;
        h = (h*h + c) % n;
        h = (h*h + c) % n;
        d = gcd(t-h, n); }

    if (d == n)
        return rho(n, c+1);
    return d;
}

稱為rho(n,1)此函數返回n的(可能是復合)因子; 如果您想找到n 的所有因子,請將其放入循環中並重復調用它。 你還需要一個素數檢查器; 對於您的極限,以 2、7 和 61 為基數的 Rabin-Miller 測試被證明是准確且相當快的。 您可以在我的博客上閱讀更多關於使用質數編程的信息。

但無論如何,鑒於如此小的限制,我認為您最好使用素數試除。 其他任何東西都可能漸近地更快,但實際上更慢。

編輯:這個答案最近收到了幾個贊成票,所以我添加了一個簡單的程序,用 2、3、5 輪進行輪分解 該程序稱為wheel(n) ,按遞增順序打印n的因子。

long wheel(long n) {
    long ws[] = {1,2,2,4,2,4,2,4,6,2,6};
    long f = 2; int w = 0;

    while (f * f <= n) {
        if (n % f == 0) {
            printf("%ld\n", f);
            n /= f;
        } else {
            f += ws[w];
            w = (w == 10) ? 3 : (w+1);
        }
    }
    printf("%ld\n", n);

    return 0;
}

我在 我的博客中討論了輪子分解; 解釋很長,所以我不會在這里重復。 對於適合long整數,您不太可能顯着改善上面給出的wheel函數。

有一種快速的方法可以減少候選人的數量。 此例程嘗試 2,然后是 3,然后是所有不能被 3 整除的奇數。

long mediumFactor(n)
{
    if ((n % 2) == 0) return 2;
    if ((n % 3) == 0) return 3;
    try = 5;
    inc = 2;
    lim = sqrt(n);
    while (try <= lim)
    {
       if ((n % try) == 0) return try;
       try += inc;
       inc = 6 - inc;  // flip from 2 -> 4 -> 2
    }
    return 1;  // n is prime
}

inc 在 2 和 4 之間的交替經過仔細對齊,以便跳過所有偶數和可被 3 整除的數。對於這種情況: 5 (+2) 7 (+4) 11 (+2) 13 (+4) 17

試驗在 sqrt(n) 處停止,因為至少有一個因子必須等於或低於平方根。 (如果兩個因子都 > sqrt(n),那么因子的乘積將大於 n。)

嘗試次數為 sqrt(m)/3,其中 m 是系列中可能的最高數字。 對於 2147483647 的限制,最壞情況下(對於 2147483647 附近的素數)最多產生 15,448 個除法,包括 2 和 3 測試。

如果數字是合數,則划分的總數通常要少得多,很少會更多; 甚至考慮到重復調用例程來獲取所有因素。

暫無
暫無

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

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