Dies ist der beste Algorithmus, den ich entwickeln konnte.
def get_primes(n):
numbers = set(range(n, 1, -1))
primes = []
while numbers:
p = numbers.pop()
primes.append(p)
numbers.difference_update(set(range(p*2, n+1, p)))
return primes
>>> timeit.Timer(stmt='get_primes.get_primes(1000000)', setup='import get_primes').timeit(1)
1.1499958793645562
Kann er noch schneller gemacht werden?
Dieser Code hat ein Problem: Da numbers
eine ungeordnete Menge ist, gibt es keine Garantie dafür, dass numbers.pop()
die niedrigste Zahl aus der Menge entfernt. Trotzdem funktioniert es (zumindest für mich) für einige Eingabelnummern:
>>> sum(get_primes(2000000))
142913828922L
#Das ist die korrekte Summe aller Zahlen unter 2 Millionen
>>> 529 in get_primes(1000)
False
>>> 529 in get_primes(530)
True
0 Stimmen
Der Code-Schnipsel ist viel schneller, wenn Zahlen wie Zahlen = set(range(n, 2, -2)) deklariert werden. Aber kann sundaram3 nicht schlagen. Danke für die Frage.
4 Stimmen
Es wäre schön, wenn es Python 3-Versionen der Funktionen in den Antworten geben könnte.
0 Stimmen
Sicher gibt es eine Bibliothek, um dies zu tun, damit wir nicht selbst programmieren müssen. Xkcd versprach, dass Python so einfach ist wie
import antigravity
. Gibt es nicht so etwas wierequire 'prime'; Prime.take(10)
(Ruby)?0 Stimmen
Beachten Sie, dass Sie kein Set als Argument an
difference_update
übergeben müssen. Sie können einfachnumbers.difference_update(xrange(p*2, N+1, p))
tun. Das wird zumindest ein paar Millisekunden von Ihrer Zeit abziehen.2 Stimmen
Ich vermute, dass eine Python-Anbindung an die C++-Bibliothek primesieve um Größenordnungen schneller wäre als all diese.
4 Stimmen
@ColonelPanic Wie es sich herausstellt, habe ich github.com/jaredks/pyprimesieve für Py3 aktualisiert und zu PyPi hinzugefügt. Es ist sicherlich schneller als diese, aber nicht um Größenordnungen - eher etwa ~5x schneller als die besten numpy-Versionen.
0 Stimmen
Ich kenne den Geschwindigkeitsvergleich zu den bereits hier aufgelisteten Antworten nicht, ich würde jedoch empfehlen, sich sagemath.org anzusehen. Es handelt sich um ein Python-Krypto-Framework, das viele integrierte Funktionen hat, um die Dinge zu tun, nach denen Sie suchen.
4 Stimmen
@ColonelPanic: Ich denke, es ist angemessen, alte Antworten zu bearbeiten, um anzugeben, dass sie gealtert sind, da dies sie zu einer nützlicheren Ressource macht. Wenn die "akzeptierte" Antwort nicht mehr die beste ist, könnte man vielleicht eine Notiz in die Frage einfügen mit einem Update von 2015, um die Leute auf die aktuell beste Methode hinzuweisen.
0 Stimmen
Ich kann nicht glauben, dass kein Moderator diese Frage gelöscht hat. Sie bittet um Verbesserung in der Geschwindigkeit eines Algorithmus, der zugegebenermaßen nicht korrekt ist. Grüße, Albert
0 Stimmen
from sympy import sieve; sieve.extend(N);
0 Stimmen
Hey, das ist wirklich schneller Code. Du hast recht, der Code funktioniert für
n =10000
nicht, danumber.pop()
nicht das kleinste Element als ungeordnetes auslöst. Thread