简体   繁体   English

Python 使用 Lucas-Lehmer 序列查找梅森素数并存储它们

[英]Python Finding Mersenne primes with Lucas-Lehmer sequence and storing them

I am trying to calculate big primes (for fun) on my computer.我正在尝试在我的计算机上计算大素数(为了好玩)。 So far, I have got to a point where it can calculate the primes.到目前为止,我已经到了可以计算素数的地步。 However, I am wondering how I can store them and make it so that when the code restarts it continues where it left off.但是,我想知道如何存储它们并使其在代码重新启动时从停止的地方继续。 Here is my code:这是我的代码:

lucas_lehmer = [4]

def mersenne(n):
    return (2 ** n) - 1

def ll(n):
    global lucas_lehmer
    if len(lucas_lehmer) < n:
        for num in range(n-1):
            lucas_lehmer.append(lucas_lehmer[-1] ** 2 - 2)
    return lucas_lehmer[n-1]

def check_prime(n):
    m = mersenne(n)
    if ll(n - 1) % m == 0:
        return m
    else:
        return -1

It calculates primes using the Lucas-Lehmer seqence.它使用 Lucas-Lehmer 序列计算素数。 The sequence starts with 4 and the next number is the number squared, minus 2. Also, the input to the check_prime function must also be a prime number.序列从 4 开始,下一个数字是数字的平方,即负 2。此外, check_prime函数的输入也必须是素数。

You're algorithm is suffiently slow that storing and restarting won't be of much value as it bottoms out quickly.你的算法足够慢,存储和重新启动不会有太大价值,因为它很快就会触底。 However, it's still a good exercise.然而,这仍然是一个很好的练习。

First, this line in your code isn't optimal:首先,代码中的这一行不是最佳的:

for num in range(n-1):

As it can cause you to add more items to the lucas_lehmer array than you need to answer the immediate question.因为它可能会导致您向lucas_lehmer数组添加比您需要回答的直接问题更多的项目。 It should be more like:它应该更像是:

while len(lucas_lehmer) < n:

or the difference between the length of the array and the number you're testing.或数组长度与您要测试的数字之间的差异。

What you need to store, in my understanding of this code, is not the primes but your lucas_lehmer array so that you don't have to build it up again upon restart of the code.根据我对这段代码的理解,您需要存储的不是素数,而是您的lucas_lehmer数组,这样您就不必在重新启动代码时再次构建它。 That's the approach I take below:这就是我在下面采取的方法:

library lucas_lehmer.py库 lucas_lehmer.py

import pickle

PICKLE_FILE = "lucas_lehmer.pickle"

lucas_lehmer = None

def ll(n):
    global lucas_lehmer

    if lucas_lehmer is None:
        try:
            with open(PICKLE_FILE, 'rb') as file:
                lucas_lehmer = pickle.load(file)
        except FileNotFoundError:
            lucas_lehmer = [4]

    if len(lucas_lehmer) < n:
        while len(lucas_lehmer) < n:
            lucas_lehmer.append(lucas_lehmer[-1] ** 2 - 2)

        with open(PICKLE_FILE, 'wb') as file:
            pickle.dump(lucas_lehmer, file)

    return lucas_lehmer[n - 1]

def check_prime(n):
    mersenne = (2 ** n) - 1

    if ll(n - 1) % mersenne == 0:
        return mersenne

    return -1

This code will create the lucas_lehmer.pickle file for you if it doesn't exist.如果它不存在,此代码将为您创建 lucas_lehmer.pickle 文件。 I tried this with JSON but it got slower slightly sooner with large integers than did Pickle.我用 JSON 尝试过这个,但它比 Pickle 用大整数稍微慢一点。 Now, you also need test code that you start, stop and restart:现在,您还需要启动、停止和重新启动的测试代码:

from lucas_lehmer import check_prime

def is_prime(n):
    if n < 2:
        return False

    if n % 2 == 0:
        return n == 2

    for divisor in range(3, int(n ** 0.5) + 1, 2):
        if n % divisor == 0:
            return False

    return True

while True:
    number = int(input("Enter a number: "))

    if number < 0:
        break

    if is_prime(number):
        print(number, check_prime(number))
    else:
        print(number, "not prime!")

The key to this is you need to instrument your library to make sure that it's initializing, loading and dumping correctly.关键是您需要检测您的库以确保它正确初始化、加载和转储。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM