Compte tenu de Nombre Premier N, Calculer le Prochain Premier?
Un collègue m'a juste dit que le C# Dictionnaire de la collection redimensionne par des nombres premiers pour les arcanes des raisons liées à de hachage. Et ma question était: "comment sait-elle ce que le prochain premier est? font-ils l'histoire d'un géant de la table ou de la calculer à la volée? c'est un effrayant non-déterministe d'exécution sur la notice de causer un redimensionner"
Donc ma question est, étant donné N, qui est un nombre premier, ce qui est le moyen le plus efficace pour calculer le prochain nombre premier?
- Cela appartient vraiment sur mathoverflow.
- Peut-être que votre collègue est incorrecte, ou peut-être qu'il utilise un peu de pré-calculé les nombres premiers, plutôt que de trouver le prochain premier.
- Je suis en désaccord, c'est un algorithme de question, pas une question de mathématiques.
- Je ne suis pas sûr de ce que cela signifie - qu'est-ce que les mathématiques si ce n'est le raffinage des algorithmes, en particulier ceux qui impliquent des nombres premiers? C'est une programmation de site, pas un algorithme site. Efficacité & nombres premiers numéros à la fois cri de math pour moi.
- Tout cela relève de la théorie de l'informatique, qui est pour beaucoup dans le milieu de la programmation et les mathématiques. Donc honnêtement, je ne vois pas le problème de poster cette question sur le site.
- Pour le dictionnaire, la plus probable, il utilise le premier des numéros de séquence qui poussent exponentielle de garder l'heure d'insertion à O(N). Sinon, l'insertion doit échelle comme ~N^2 (qui devrait être légèrement plus rapide que O(N^2))
- Je ne comprends votre point, mais j'ai l'impression que l'affichage sur mathoverflow pourrait donner des plaintes similaires (bien que j'ai rarement visiter ce site). "Les plus efficaces" est difficile à déterminer avec les focales fixes, comme ce qui pourrait être plus efficace pour un P peut être très lent pour un autre.
- Cela n'a absolument pas sa place sur MathOverflow, ce qui est de la recherche au niveau des questions. Je suis également en désaccord qu'il doit être, sur math.stackexchange.com, mais il serait au moins convient-il ainsi.
- Par curiosité, quelle est la 'arcane, en raison de hachage'? J'ai tendance à simplement cultiver les tables de hachage par un facteur de 2 à 4 et de recalculer.
Vous devez vous connecter pour publier un commentaire.
La les écarts entre nombres premiers consécutifs est connu pour être assez petit, avec le premier écart de plus de 100 survenant pour le premier numéro de 370261. Cela signifie que même une simple force brute va être assez rapide dans la plupart des circonstances, en prenant en O(ln(p)*sqrt(p)) en moyenne.
Pour p=10 000 O(921) opérations. En gardant à l'esprit que nous jouerons ce une fois tous les O(ln(p)) insertion (grosso modo), c'est bien dans les limites de la plupart des problèmes en prenant sur l'ordre d'un millième de seconde sur la plupart du matériel moderne.
FILL_FACTOR * n
entrées pour le nouvel ensemble.Environ un an, j'ai été travailler ce domaine pour libc++ mise en œuvre de la
non ordonnée (hash) les conteneurs pour le C++11. Je pensais que je voudrais partager
mes expériences ici. Cette expérience prend en charge marcog accepté de répondre à pour un
raisonnable définition de "force brute".
J'ai développé plusieurs implémentations de
size_t next_prime(size_t n)
où l'spec de cette fonction est:
Chaque mise en œuvre de
next_prime
est accompagné par une fonction d'assistanceis_prime
.is_prime
devrait être considéré comme une mise en œuvre privée en détail; il ne doit pas être appelée directement par le client. Chacune de ces implémentations de cours a été testé pour la correction, mais aussitesté avec le test de performances suivants:
Je tiens à souligner que c'est un test de performance, et ne reflète pas typique
d'utilisation, qui ressemblerait plus à:
Tous les tests de performance ont été compilés avec:
Mise en œuvre 1
Il y a sept implémentations. Le but pour l'affichage de la première
la mise en œuvre est de démontrer que si vous ne parvenez pas à arrêter le test, le candidat
le premier
x
pour les facteurs àsqrt(x)
alors vous n'avez pas à même d'atteindre unla mise en œuvre qui pourraient être classés comme la force brute. Cette mise en œuvre est
brutalement lent.
Pour cette mise en œuvre seulement j'ai dû mettre
e
à 100 au lieu de 100000, juste pourobtenir un temps d'exécution raisonnable:
Mise en œuvre 2
Cette mise en œuvre est le plus lent de la force brute de mise en œuvre et le
seule différence par rapport à la mise en œuvre 1 est qu'il s'arrête de test pour primeness
lorsque le facteur dépasse
sqrt(x)
.Noter que
sqrt(x)
n'est pas calculée directement, mais déduit parq < i
. Cettede la vitesse par un facteur de milliers:
et valide marcog de prédiction:
Mise en œuvre 3
On peut presque le double de la vitesse (au moins sur le matériel que j'utilise) par
éviter l'utilisation de la
%
opérateur:Mise en œuvre 4
Jusqu'à présent, je n'ai même pas utilisé la connaissance commune que le 2 est le seul à même le premier.
Cette application intègre des connaissances, près de doubler la vitesse
nouveau:
Mise en œuvre 4 est probablement ce que la plupart des gens ont à l'esprit lorsqu'ils pensent à
"force brute".
Mise en œuvre 5
À l'aide de la formule suivante, vous pouvez choisir facilement tous les numéros qui sont
divisible ni par 2, ni 3:
où k >= 1. La suite de la mise en œuvre utilise cette formule, mais mis en œuvre
avec un mignon xor astuce:
Cela signifie que l'algorithme doit vérifier seulement 1/3 de l'
entiers pour primeness au lieu de 1/2 des nombres et le test de performance
affiche la vitesse attendue en hausse de près de 50%:
La mise en œuvre 6
Cette application est une extension logique de la mise en œuvre 5: Il utilise le
formule suivante pour calculer tous les nombres qui ne sont pas divisibles par 2, 3 et 5:
Il a également déroule la boucle interne au sein de is_prime, et crée une liste de "petit
les nombres premiers", qui est utile pour traiter avec les numéros de moins de 30.
C'est sans doute aller au-delà des "force brute" et c'est bon pour stimuler la
la vitesse de l'autre de 27,5% pour:
Mise en œuvre 7
C'est pratique pour jouer la partie pour une itération, le développement d'une
formule pour les nombres non divisible par 2, 3, 5 et 7:
Le code source n'est pas montré ici, mais il est très similaire à la mise en œuvre 6.
C'est la mise en œuvre, j'ai choisi d'utiliser effectivement pour les contenants non ordonnée
de libc++, et que le code source est open source (qui se trouve sur le lien).
Cette dernière itération est bon pour un autre de 14,6% boost de vitesse pour:
Utilisation de cet algorithme assure que les clients de libc++'s tables de hachage pouvez choisir
un premier ils décident qui est le plus bénéfique à leur situation, et de la performance
pour cette application est tout à fait acceptable.
return false
cas est le plus probable, alors, il vaut la peine de commutation pour cette seule raison (1 % de la vitesse-up).Juste au cas où quelqu'un est curieux:
À l'aide de réflecteurs j'ai déterminé qu' .Net utilise une classe statique qui contient une liste codée en dur de ~72 primes allant jusqu'à 7199369 qui est des scans pour les plus petits, le premier qui est au moins deux fois la taille actuelle, et pour les tailles plus grand que celui qu'elle calcule le prochain premier par la division de première instance de tous les nombres impairs jusqu'à la racine carrée du nombre potentiel. Cette classe est immuable et thread-safe (c'est à dire de plus grands nombres premiers ne sont pas stockées pour une utilisation future).
Une belle astuce consiste à utiliser partielle d'un tamis. Par exemple, quel est le prochain premier qui suit le nombre N = 2534536543556?
Vérifier le module de N par rapport à une liste de petits nombres premiers. Donc...
Nous savons que le prochain premier à la suite du N doit être un nombre impair, et nous pouvons jeter immédiatement tous les multiples impairs de cette liste de petits nombres premiers. Ces modules nous permettent de tamis de sortir des multiples de ces petits nombres premiers. Nous avons été d'utiliser les petits nombres premiers inférieurs à 200, on peut utiliser ce dispositif pour jeter immédiatement plus de potentiel nombre premier plus grand que N, sauf pour une petite liste.
Plus explicitement, si nous sommes à la recherche pour un nombre premier au-delà de 2534536543556, il ne peut pas être divisible par 2, donc nous avons besoin d'examiner que les nombres impairs au-delà de cette valeur. Les modules ci-dessus montrent que 2534536543556 est congru à 2 mod 3, donc 2534536543556+1 est congru à 0 mod 3, tout comme doit l'être 2534536543556+7, 2534536543556+13, etc. Effectivement, nous pouvons tamis de plusieurs des numéros sans qu'il soit besoin de les tester pour de primalité et sans aucun procès divisions.
De même, le fait que
nous dit que 2534536543556+4 est congru à 0 mod 7. Bien sûr, ce nombre est pair, donc nous ne pouvons l'ignorer. Mais 2534536543556+11 est un nombre impair est divisible par 7, comme c'est 2534536543556+25, etc. Encore une fois, nous pouvons exclure ces numéros clairement composite (parce qu'ils sont divisibles par 7) et n'est donc pas premier.
En utilisant seulement une petite liste des nombres premiers jusqu'à 37, nous pouvons exclure la plupart des numéros qui suivent immédiatement le point de départ de 2534536543556, uniquement à l'exception de quelques-uns:
De ces chiffres, sont-ils en premier?
J'ai fait l'effort de fournir le premier factorisations des deux premiers numéros de la liste. Voir qu'ils sont en composite, mais les facteurs premiers sont grands. Bien sûr, cela a du sens, puisque nous avons d'ores et déjà assuré qu'aucun nombre qui reste peut avoir de petits facteurs premiers. Le troisième dans notre courte liste (2534536543597) est en fait le premier nombre premier au-delà de N. Le tamisage schéma que je viens de décrire ont tendance à entraîner des nombres qui sont soit premier, ou sont composés généralement de grands facteurs premiers. Nous avons donc fait un test explicite de primalité à seulement quelques numéros avant de trouver le prochain premier.
Un régime similaire rapidement les rendements que le prochain premier dépassant N = 1000000000000000000000000000, comme 1000000000000000000000000103.
Juste un peu d'expériences avec les nombres premiers de la distance.
Ce n'est qu'un complément pour visualiser d'autres réponses.
J'ai eu les nombres premiers de la 100.000 ème (=1,299,709) pour le 200.000 ème (=2,750,159)
Quelques données:
Interprime distance tracé de fréquence:
Interprime Distance vs Nombre Premier
Juste pour voir c'est "aléatoire". Cependant ...
Il n'y a pas de fonction f(n) pour calculer le prochain nombre premier. Au lieu de cela, un certain nombre doit être testé pour la primalité.
Il est également très utile lors de la recherche de la n-ième nombre premier, à la connaissez déjà tous les nombres premiers à partir de la 1ère jusqu'à (n-1)ème, parce que ce sont les seuls nombres qui doivent être testés en tant que facteurs.
En raison de ces raisons, je ne serais pas surpris si il y a un pré-calculées ensemble de grands nombres premiers. Il n'a pas vraiment de sens pour moi si certaines focales fixes nécessaires pour être recalculé à plusieurs reprises.
Comme d'autres l'ont déjà noté, un moyen de trouver le prochain nombre premier donné l'actuel premier n'a pas encore été trouvé. Par conséquent, la plupart des algorithmes de se concentrer plus sur l'utilisation des moyens rapides de vérification de primalité depuis que vous avez à vérifier n/2 les chiffres entre votre premier et le suivant.
En fonction de l'application, vous pouvez aussi sortir avec juste de coder en dur une look-up table), comme l'a noté Paul Wheeler.
Pour de la pure nouveauté, il y a toujours cette approche:
qui produit naturellement
Tous les amusement et jeux de côté, c'est bien connu, la meilleure table de hachage de taille est rigoureusement prouvable un nombre premier de la forme
4N−1
. Donc juste de trouver le prochain premier est insuffisante. Vous avez à faire, les autres aussi.Aussi loin que je me souvienne, il utilise le premier numéro à côté du double de la taille actuelle. Il ne parvient pas à calculer que le premier numéro - là table avec préchargé nombres jusqu'à certains de grande valeur (ne pas exactement, quelque chose autour de 10 000 000). Lorsque ce nombre est atteint, il utilise certains naïfs algorithme pour obtenir la prochaine nombre (comme curNum=curNum+1) et valider à l'aide de certaines de ces méthodes: http://en.wikipedia.org/wiki/Prime_number#Verifying_primality
next_prime = prime + 2
. Vous avez peut-être raison, et personne ne peut prouver qu'une fois que vous obtenez assez élevé, vous aurez toujours tort. Alors, allez pour elle. 🙂