簡體   English   中英

10,000 項復合的斐波那契式序列

[英]Fibonacci-like sequence that is composite for 10,000 terms

請教我如何優化我的代碼...

我正在尋找方程a*Xn-1 - (c*c)Xn-2斐波那契數列。 我正在尋找 GCD 為 1 的a, c值,這將導致從第10th項到第10,000th項的復合斐波那契數列。 但是,對於序列中的每個術語,我還希望term + 1的值和term - 1的值也是復合的。

隨着數字變得非常大,代碼需要非常長的時間才能完成。 為了測試素數,我使用了from sympy.ntheory import isprime函數。 我沒有使用列表,而是使用兩個變量來表示我的斐波那契數列。 我正在使用遞歸來分析較小的間隔並逐漸向上移動到最大值。 打印語句應該有助於理解代碼在運行時正在做什么。

這是我的代碼:

from math import gcd
from sympy.ntheory import isprime


def check_pairs(a_c_pairs, start_checking_from, increment, max):
    end_checking_at = start_checking_from + increment
    pairs_that_passed_the_composite_test = []  # list of the successful pairs

    print()
    print(f"{a_c_pairs = }")
    print(f"{start_checking_from = }, {end_checking_at = }, {increment = }, {max = }")
    print()
    print(f"Number of terms to check: {len(a_c_pairs)}")

    count = 1
    for a, c in a_c_pairs:  # checking for each of the provided pairs
        print(f"{count}/{len(a_c_pairs)}: {a=}, {c=}, result=", end="")
        count += 1

        first_term = 0
        second_term = 1

        fail = False
        # iterating through each term in the sequence without using a list
        for i in range(end_checking_at):
            third_term = a*second_term - (c*c)*first_term

            if not i < start_checking_from:  # if the term is in our targeted range, check if that term is prime
                if isprime(third_term) or isprime(third_term + 1) or isprime(third_term - 1):
                    fail = True
                    print("FAIL")
                    break

            # set values for the loop to calculate the next term in the sequence
            first_term = second_term
            second_term = third_term

        if not fail:  # after the entire sequence has been analyzed, if none of the terms were prime
            print("pass")
            pairs_that_passed_the_composite_test.append([a, c])

    if not end_checking_at == max:
        check_pairs(pairs_that_passed_the_composite_test,
                    start_checking_from + increment, increment, max)
    else:
        print()
        print("FINAL LIST OF PAIRS:")
        for a, c in pairs_that_passed_the_composite_test:
            print(a, c)

        return


# these pairs have passed up to 3000 terms
a_c_pairs = [
    [11, 3],
    [34, 3],
    [37, 3],
    [38, 3],
    [40, 3],
    [41, 3],
    [53, 3],
    [56, 3],
    [59, 3],
    [61, 3],
    [65, 3],
    [71, 3],
    [77, 3],
    [82, 3],
    [89, 3],
    [94, 3],
    [95, 3],
    [98, 3],
    [37, 5],
    [39, 5],
    [42, 5],
    [43, 5],
    [46, 5],
    [51, 5],
    [54, 5],
    [57, 5],
    [64, 5],
    [73, 5],
    [74, 5],
    [77, 5],
    [86, 5],
    [89, 5],
    [91, 5],
    [98, 5],
    [53, 7],
    [55, 7],
    [64, 7],
    [71, 7],
    [75, 7],
    [79, 7],
    [81, 7],
    [83, 7],
    [87, 7],
    [92, 7],
    [99, 7],
    [100, 7],
    [86, 9],
    [89, 9],
    [94, 9],
    [97, 9],
    [98, 9]
]

check_pairs(a_c_pairs, 2000, 500, 3000)

檢查一個數是否為質數對於大數來說是昂貴的。 雖然有像 AKS 這樣具有多項式復雜度的算法來做到這一點,但多項式的 很大(即O(n^7)其中n是測試數字 N 的大小,以位為單位)。 非確定性算法的多項式復雜度較低,但這仍然相當大。 例如,Miller Rabin 檢驗可以在O(n^4)做到這一點,假設未經證實的廣義黎曼假設為真(目前看來確實如此)。 對於像 64 位擬合這樣的中等大數,您只能檢查少數幾個鹼基,從而進行快速素性測試。 對於龐大的數字,研究人員正在積極致力於設計更好的算法(尤其是確定性通才無條件測試)並尋找此類算法的理論算法復雜度界限。 不幸的是,AFAIK O(n^4)接近於最知名的復雜性(沒有任何巨大的隱藏常數)來測試一個數字是否是合數。

問題是斐波那契數列增長得非常快。 對於標准版本,表示第 i 個元素的位數接近2 i / 3 因此,對於i = 10 000 ,計算時間將非常大,因為它需要處理大約 6700 位的數字,在最壞的情況下需要數百萬次迭代(即質數)。 目前還沒有主流計算機可以快速做到這一點(而且可能在未來 20 年內不會)。

解決這個問題的唯一可能解決方案是設計一個特定的素性測試您生成的數字,乍一看似乎是一項非常艱巨的任務。 如果素數和斐波那契數之間沒有關系,那么沒有比使用最先進的算法(在您的情況下太慢)更好的解決方案。 否則,如果有任何關系,這樣的問題是堆棧溢出的題外話,但您可以在math.stackexchange.com上提出這個問題。

third_term-1 如果third_term-1是偶數,那么只需要檢查third_term (因為其他都不是素數)。 如果third_term-1是奇數,則third_term不是質數並且third_term-1third_term+1不是質數。 此外,請注意 GCD 和斐波那契數之間存在關系,GCD 和素數之間也存在關系,因此斐波那契數和素數之間可能存在關系。

暫無
暫無

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

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