Quel est le meilleur algorithme pour vérifier si un nombre est premier?

juste un exemple de ce que je cherche: je pourrais représenter chaque nombre impair avec un peu par exemple pour la gamme donnée de nombres( 1, 10), commence à 3:

1110

le dictionnaire suivant peut être pressé plus à droite? Je pourrais former des multiples de cinq avec un peu de travail, mais les nombres qui se terminent par 1, 3, 7 ou 9 doivent être là dans la rangée de bits. J'espère que ça clarifiera ce que je veux.

je cherche le meilleur algorithme, pour vérifier si un nombre est premier c'est à dire une fonction booléenne:

bool isprime(number);

je voudrais connaître le meilleur algorithme pour mettre en œuvre cette fonctionnalité. Naturellement, il y aurait une structure de données que je pourrais interroger. J' définir le meilleur algorithme , à l'algorithme qui produit une structure de données avec la plus faible consommation de mémoire pour le range (1, N], où N est une constante.

112
demandé sur BoltClock 2009-11-26 06:30:49

19 réponses

il y a plusieurs façons de faire le " test de primalité .

il n'y a pas vraiment de structure de données à interroger. Si vous avez beaucoup de nombres à tester, vous devriez probablement exécuter un test probabiliste puisque ceux-ci sont plus rapides, puis le suivre avec un test déterministe pour s'assurer que le nombre est premier.

vous devez savoir que les mathématiques derrière les algorithmes les plus rapides est pas pour les faibles de cœur.

61
répondu Ben S 2009-11-26 03:37:02

l'algorithme le plus rapide pour les tests de prime générale est AKS . L'article de Wikipedia le décrit en long et en lien avec le papier original.

si vous voulez trouver de grands nombres, regardez dans les nombres premiers qui ont des formes spéciales comme Mersenne nombres premiers .

l'algorithme que j'implémente habituellement (facile à comprendre et à coder) est le suivant (en Python):

def isprime(n):
    """Returns True if n is prime."""
    if n == 2:
        return True
    if n == 3:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False

    i = 5
    w = 2

    while i * i <= n:
        if n % i == 0:
            return False

        i += w
        w = 6 - w

    return True

c'est une variante de l'algorithme classique O(sqrt(N)) . Il utilise le fait qu'un premier (sauf 2 et 3) est de la forme 6k - 1 ou 6k + 1 et ne regarde que les diviseurs de cette forme.

parfois , si je veux vraiment de la vitesse et la portée est limitée , je mets en œuvre un pseudo-premier test basé sur Fermat'S little theorem . Si je veux vraiment plus de vitesse (c.-à-d. éviter o(sqrt (N)) algorithme tout à fait), je précalculer les faux positifs (voir Carmichael ) et faire une recherche binaire. C'est de loin le test le plus rapide que j'ai jamais mis en place, le seul inconvénient est que la portée est limitée.

168
répondu Alexandru 2018-03-10 11:12:54

La meilleure méthode, à mon avis, est d'utiliser ce qui est passé avant.

Il y a des listes de la première N nombres premiers sur internet avec N qui s'étend jusqu'à au moins cinquante millions de . Téléchargez les fichiers et utilisez-les, il est probable d'être beaucoup plus rapide que toute autre méthode que vous trouverez.

si vous voulez un algorithme réel pour faire vos propres nombres premiers, Wikipedia a toutes sortes de bonnes choses sur les nombres premiers ici , incluant des liens vers les différentes méthodes pour le faire , et" prime testing ici , à la fois des méthodes basées sur la probabilité et des méthodes déterministes rapides.

il devrait y avoir un effort concerté pour trouver le premier milliard (ou même plus) de nombres premiers et les faire publier sur le net quelque part afin que les gens puissent arrêter de faire ce même travail encore et encore et encore ... :- )

22
répondu paxdiablo 2009-11-26 03:52:03

selon wikipedia, le tamis D'Eratosthène a complexité O(n * (log n) * (log log n)) et nécessite O(n) mémoire - donc c'est un assez bon endroit pour commencer si vous ne testez pas pour des nombres particulièrement grands.

6
répondu matt b 2009-11-26 03:36:25
bool isPrime(int n)
{
    // Corner cases
    if (n <= 1)  return false;
    if (n <= 3)  return true;

    // This is checked so that we can skip 
    // middle five numbers in below loop
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}
this is just c++ implementation of above  AKS algorithm

https://en.wikipedia.org/wiki/AKS_primality_test

6
répondu saurabh kumar 2017-05-17 05:31:53

En Python 3:

def is_prime(a):
if a < 2:
    return False
elif a!=2 and a % 2 == 0:
    return False
else:
    return all (a % i for i in range(3, int(a**0.5)+1) )

explication: Un nombre premier est un nombre divisible par lui-même et 1. Ex: 2,3,5 et 7...

1) si a<2: si " a " est inférieur à 2 ce n'est pas une prime.

2) elif a!= 2 et a % 2 = = 0: si "a" est divisible par 2 alors ce n'est certainement pas un prime. Mais si a=2 nous ne voulons pas évaluer cela comme c'est un nombre premier. D'où la condition d'un!= 2

3) retourner tous (a % i pour i dans la gamme (3, int(a 0.5)+1) ):** regardez D'abord ce que fait all() command en python. À partir de 3 Nous divisons "a" jusqu'à sa racine carrée (a**0.5). Si " a " est divisible, le résultat sera faux. Pourquoi racine carrée? Disons que a=16. La racine carrée de 16 = 4. On n'a pas besoin d'évaluer avant 15 ans. On a juste besoin de vérifier jusqu'à 4 h pour dire que ce n'est pas une prime.

Supplémentaire: Une boucle pour trouver tous les nombres premiers dans une gamme.

for i in range(1,100):
if is_prime(i):
    print("{} is a prime number".format(i) )
2
répondu Deep grewal 2018-02-25 07:33:14

Python 3:

def is_prime(a):
    return a > 1 and all(a % i for i in range(2, int(a**0.5) + 1))
1
répondu Oleksandr Shmyheliuk 2017-06-27 16:37:37

bien trop tard pour la fête, mais espérons que cela aide. Ceci est pertinent si vous cherchez de grands nombres premiers:

pour tester de grands nombres impairs, vous devez utiliser le test de Fermat et/ou le test de Miller-Rabin.

ces tests utilisent exponentiation modulaire qui est assez cher, pour n bits exponentiation dont vous avez besoin au moins n grande multiplication int et n grande division int. Ce qui signifie la complexité de l'exponentiation modulaire is O (n3).

donc avant d'utiliser les gros canons, vous devez faire pas mal de divisions d'essai. Mais ne le faites pas naïvement, il y a un moyen de les faire jeûner. D'abord multiplier autant de nombres premiers, ensemble, autant s'inscrit dans une les mots que vous utilisez pour les grands entiers. Si vous utilisez des mots de 32 bits, multipliez 3*5*7*11*13*17*19*23*29=3234846615 et calcule le plus grand diviseur commun avec le nombre que vous testez en utilisant L'algorithme euclidien. Après la première étape, le nombre est réduit en dessous de la taille de mot et continuer l'algorithme sans effectuer de remplir grande division entière. Si le GCD != 1, cela signifie qu'un des nombres premiers que vous avez multipliés ensemble divise le nombre, donc vous avez une preuve que ce n'est pas premier. Puis continuer avec 31*37*41*43*47 = 95041567, et ainsi de suite.

une fois que vous avez testé plusieurs centaines (ou milliers) de nombres premiers de cette façon, vous pouvez faire 40 tours de test Miller-Rabin pour confirmer le nombre est premier, après 40 tours, vous pouvez être certain que le nombre est premier il n'y a que 2^-80 il est plus probable que votre matériel fonctionne mal...).

1
répondu Calmarius 2018-04-27 09:16:00

j'ai une fonction première qui fonctionne jusqu'à (2^61)-1 ici:

from math import sqrt
def isprime(num): num > 1 and return all(num % x for x in range(2, int(sqrt(num)+1)))

explication:

la fonction all() peut être redéfinie comme suit:

def all(variables):
    for element in variables:
        if not element: return False
    return True

la fonction all() passe simplement par une série de bools / nombres et renvoie False si elle voit 0 ou False .

la fonction sqrt() ne fait que racine carrée d'un nombre.

par exemple:

>>> from math import sqrt
>>> sqrt(9)
>>> 3
>>> sqrt(100)
>>> 10

la partie num % x renvoie le reste de num / X.

enfin, range(2, int(sqrt(num))) signifie qu'il va créer une liste qui commence à 2 et se termine à int(sqrt(num)+1)

pour plus d'informations sur la gamme, consultez ce site web !

la partie num > 1 ne fait que vérifier si la variable num est plus grande que 1, parce que 1 et 0 ne sont pas considérés des nombres premiers.

j'espère que cela a aidé :)

1
répondu WhyAreYouReadingThis 2018-05-11 08:52:34

En Python:

def is_prime(n):
    return not any(n % p == 0 for p in range(2, int(math.sqrt(n)) + 1))

une conversion plus directe du formalisme mathématique en Python utiliserait tout(n % p != 0... ) , mais cela exige une évaluation stricte de toutes les valeurs de P. La version pas n'importe quelle version peut se terminer tôt si une valeur vraie est trouvée.

1
répondu Vlad Bezden 2018-05-22 14:54:48

meilleur algorithme pour nombres premiers javascript

 function isPrime(num) {
      if (num <= 1) return false;
      else if (num <= 3) return true;
      else if (num % 2 == 0 || num % 3 == 0) return false;
      var i = 5;
      while (i * i <= num) {
        if (num % i == 0 || num % (i + 2) == 0) return false;
        i += 6;
      }
      return true
    }
1
répondu Mahdi Pourrostam 2018-06-23 05:01:15

idée similaire à l'algorithme AKS qui a été mentionnée""

public static boolean isPrime(int n) {

    if(n == 2 || n == 3) return true;
    if((n & 1 ) == 0 || n % 3 == 0) return false;
    int limit = (int)Math.sqrt(n) + 1;
    for(int i = 5, w = 2; i <= limit; i += w, w = 6 - w) {
        if(n % i == 0) return false;
        numChecks++;
    }
    return true;
}
0
répondu Derri Leahy 2017-08-14 19:30:14

pour déterminer si le ou les nombres dans une plage sont/sont premiers.

#!usr/bin/python3

def prime_check(*args):
    for arg in args:
        if arg > 1:     # prime numbers are greater than 1
            for i in range(2,arg):   # check for factors
                if(arg % i) == 0:
                    print(arg,"is not Prime")
                    print(i,"times",arg//i,"is",arg)
                    break
            else:
                print(arg,"is Prime")

            # if input number is less than
            # or equal to 1, it is not prime
        else:
            print(arg,"is not Prime")
    return

# Calling Now
prime_check(*list(range(101)))  # This will check all the numbers in range 0 to 100 
prime_check(#anynumber)         # Put any number while calling it will check.
0
répondu Harsh Singh 2018-03-23 11:38:43
myInp=int(input("Enter a number: "))
if myInp==1:
    print("The number {} is neither a prime not composite no".format(myInp))
elif myInp>1:
    for i in range(2,myInp//2+1):
        if myInp%i==0:
            print("The Number {} is not a prime no".format(myInp))
            print("Because",i,"times",myInp//i,"is",myInp)
            break
    else:
        print("The Number {} is a prime no".format(myInp))
else:
    print("Alas the no {} is a not a prime no".format(myInp))
0
répondu DKB 2018-03-28 14:48:06

on peut utiliser sympy .

import sympy

sympy.ntheory.primetest.isprime(33393939393929292929292911111111)

True

D'après sympy docs. La première étape consiste à rechercher des facteurs triviaux qui, s'ils sont trouvés, permettent un retour rapide. Ensuite, si le tamis est assez grand, l'utilisation non-bloquante de recherche sur le tamis. Pour de petits nombres, une série de tests déterministes de Miller-Rabin est effectuée avec des bases qui sont connues pour n'avoir aucun contre-échantillon dans leur gamme. Enfin, si le nombre est supérieur à 2 ^ 64, un test BPSW fort est effectuer. Bien qu'il s'agisse d'un premier test probable et nous croyons qu'il existe des contre-exemples, il n'existe pas de contre-exemples connus "151970920

0
répondu LetzerWille 2018-08-26 13:52:05

vous pourriez essayer quelque chose comme ça.

def main():
    try:
        user_in = int(input("Enter a number to determine whether the number is prime or not: "))
    except ValueError:
        print()
        print("You must enter a number!")
        print()
        return
    list_range = list(range(2,user_in+1))
    divisor_list = []
    for number in list_range:
        if user_in%number==0:
            divisor_list.append(number)
    if len(divisor_list) < 2:
        print(user_in, "is a prime number!")
        return
    else:
        print(user_in, "is not a prime number!")
        return
main()
0
répondu Patrick Jane 2018-09-30 01:14:17

plus petit souvenir? Ce n'est pas le moindre, mais c'est un pas dans la bonne direction.

class PrimeDictionary {
    BitArray bits;

    public PrimeDictionary(int n) {
        bits = new BitArray(n + 1);
        for (int i = 0; 2 * i + 3 <= n; i++) {
            bits.Set(i, CheckPrimality(2 * i + 3));
        }
    }

    public PrimeDictionary(IEnumerable<int> primes) {
        bits = new BitArray(primes.Max());
        foreach(var prime in primes.Where(p => p != 2)) {
            bits.Set((prime - 3) / 2, true);
        }
    }

    public bool IsPrime(int k) {
        if (k == 2) {
            return true;
        }
        if (k % 2 == 0) {
            return false;
        }
        return bits[(k - 3) / 2];
    }
}

bien sûr, vous devez spécifier la définition de CheckPrimality .

-1
répondu jason 2009-11-26 03:54:16

je pense que l'un des plus rapides est ma méthode que j'ai faite.

void prime(long long int number) {
    // Establishing Variables
    long long int i = 5;
    int w = 2;
    const long long int lim = sqrt(number);

    // Gets 2 and 3 out of the way
    if (number == 1) { cout << number << " is hard to classify. \n";  return; }
    if (number == 2) { cout << number << " is Prime. \n";  return; }
    if (number == 3) { cout << number << " is Prime. \n";  return; }

    // Tests Odd Ball Factors
    if (number % 2 == 0) { cout << number << " is not Prime. \n";  return; }
    if (number % 3 == 0) { cout << number << " is not Prime. \n";  return; }

    while (i <= lim) {
        if (number % i == 0) { cout << number << " is not Prime. \n";  return; }
        // Tests Number
        i = i + w; // Increments number
        w = 6 - i; // We already tested 2 and 3
        // So this removes testing multepules of this
    }
    cout << number << " is Prime. \n"; return;
}
-1
répondu Spl1ce 2017-08-01 00:46:40
public static boolean isPrime(int number) {
 if(number < 2)
   return false;
 else if(number == 2 || number == 3)
        return true;
      else {
        for(int i=2;i<=number/2;i++)
           if(number%i == 0)
             return false;
           else if(i==number/2)
                return true;
      }
    return false;
}
-1
répondu gaurav 2018-04-19 17:18:33