Primzahlen
Übersicht

![]() |
LordArtusBetreff: Primzahlen |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo ,
hab ein Prog. in Bmax geschrieben , welches Primzahlen berechnet. Code: [AUSKLAPPEN] z=1 bis=100000000 counter=0 Type MyType Field prim Function Create:MyType(zzz) Local e:MyType=New MyType e.prim=zzz Return e End Function End Type Local PrimList:TList=New TList PrimList.AddLast(MyType.Create(2)) memvar=GCMemAlloced() time=MilliSecs() For t=0 To bis zz=Sqr(z) For a:MyType=EachIn PrimList If (z Mod a.prim)=0 PrimList.RemoveLast() Exit ElseIf a.prim>=zz counter=counter+1 Print z 'An der Stelle ist z=PRIM Exit EndIf Next z=z+1 PrimList.AddLast(MyType.Create(z)) Next Print "Von 1 bis "+bis Print "Menge der Primzahlen: "+counter Print "Zeit : "+(MilliSecs()-time)/1000.0+" sek" Print "Mem.Anfang: "+memvar+" bytes" Print "Mem.Ende: "+GCMemAlloced()+" bytes" While Not KeyHit(KEY_ESCAPE) Wend End Problem an dem Code ist , dass die Liste immer grösser wird , bis 100.000.000 braucht das Prog. ca.280 MB an Arbeitsspeicher. Da in der Liste alle Primzahlen enthalten sind , aber zur Berechnung der Primzahlen nur die Wurzel der grössten Primzahl in der Liste benötigt wird , ist der Rest in der Liste zur Laufzeit eigentlich überflüssig (reine RAM Verschwendung). Nun , meine Frage: hätte jemand nee Idee , wie ich die Liste kleiner halten könnte , ohne grösseren Performanceeinbrüchen , oder gibts schnellere Methoden um Primzahlen auszurechnen ? Wäre sehr dankbar für Antworten. MfG LordArtus |
||
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also jetzt ohen den Code genauer angeschaut zu haben, und ohen das ich mich mit Primzahlberechnungen auskenne:
Wenn du doch eh nur die größte, also auch die letzte berechnete Primzahl brauchst, warum nimmst du dann überhaupt eine Liste? Eine einzigste Variable dürfte da doch reichen, oder? ![]() Und schau mal in der Suche, gibt schon viele Threads zu dem Thema, dürften für dich dann auch interessant sein ![]() |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
![]() |
Smily |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: Wenn du doch eh nur die größte, also auch die letzte berechnete Primzahl brauchst, warum nimmst du dann überhaupt eine Liste? Eine einzigste Variable dürfte da doch reichen, oder?
Das wort einzige ist nicht steigerbar! |
||
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets "Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!" stummi.org |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
der elementarste fehler in dem algo ist das du 1 steps machst. Ab 3 kannst du jedoch garantieren dass der step mindestens 3 ist! (weil gerade kanns nie mehr werden). Damit halbiert sich der speicherbedarf schonma ![]() Deswegen würde ich von der For schleife abraten und ne while oder repeat nehmen. In diese schleife gehst du dann rein, wenn die gesuchte zahl > 2 ist und benutzt fortan einfach nur noch + 2 dort kannst du dann auch weitere step optimierungen vornehmen solltest du das wünschen oder welche kennen. Solltest du je speedprobleme haben: Nimm die Print raus und ersetz sie durch Filebefehle ... das geschreibsel ist eine der grössten speedbremsen weil die konsole nie dafür gedacht war sie so zuzuschreiben. PS: ganz oben noch strict oder super strict rein, sonst sind local wertlos und der ganze code leidet drunter |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Smily0412 hat Folgendes geschrieben: Zitat:
Wenn du doch eh nur die größte, also auch die letzte berechnete Primzahl brauchst, warum nimmst du dann überhaupt eine Liste? Eine einzigste Variable dürfte da doch reichen, oder?
Das wort einzige ist nicht steigerbar! Ot? :O (Nja, sorry jetzt für weiteres OT): Einzige, mehr Einzigste, am Einzigsten ![]() ![]() War keine Steigerung, kommt wohl eher von der Aussprache her ![]() ![]() ![]() (Tjaja, Akzente ![]() @Dreamora: Wenn ab 3 der Step 3 ist, käme man doch direkt zur Zahl 6, welche ja doch gerade ist..? Oder verstehe ich deine Aussage falsch..? |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
![]() |
mahe |
![]() Antworten mit Zitat ![]() |
---|---|---|
Der Step ist natürlich 2, was er in späterer Folge auch richtig geschrieben hat. | ||
ʇɹǝıdɯnɹɹoʞ ɹnʇɐuƃıs - ǝpoɥʇǝɯ-ɹoɹɹıɯ ɹǝp uı ,ɹoɹɹǝ, |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Zitat: z=z+1
Vielleicht missinterpretier ich das 1 auch einfach falsch ![]() Er prüft ob z prim ist, nicht ob t prim ist. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
LordArtus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Guten Morgen,
erstmal Danke für die Antworten. Als erstes sage ich einfach : um die grösste Primzahl zu berechnen , brauche ich eh eine Liste mit Primzahlen von 2 bis zu der Wurzel der Zahl die ich berechnen will , und genau mit dem Prog. wird so eine Liste gemacht , bloss nicht bis zu der Wurzel (was ich mir eigentlich wünsche und das ist gerade das Prob.) , sondern bis zu der Zahl die ich berechnen will.(Und weil alle Primzahlen bis zu der berechneter Zahl in der Liste vorhanden sind ist auch der Arbeitsspeicher schon bei 280MB bei der "kleinen" Zahl von 100.000.000.Theoretisch könnte ich schon mit derzeitiger Liste bis 100.000.000^2 berechnen) @Dreamora Stimmt , der Printbefehl ist langsam , mit dauerts bei mir bis 100.000.000 ca. 739 sek. ohne Print (d.h. ohne jeglicher Ausgabe) ca. 449 sek. (AMD 64 4000). Stimmt , mit z=z+2 und kleinen Eingriff müsste es viel schneller laufen ![]() MfG LordArtus p.s. Sorry für grammatische und orthographische Fehler und dass ich eventuell etwas vergessen habe zu schreiben , aber bin grad aufgestanden und noch kein Kaffee intus ![]() p.p.s eventuell wüsste vielleicht jemand wie ich die Variable "MyType.prim" kleinstmöglich in der Liste abspeichern kann ? (Es muss nicht ein Type sein) |
||
![]() |
LordArtus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi , nochmal ich.
Code: [AUSKLAPPEN] z=1 bis=100 ' bis=Bis zur welcher Zahl sollen Primzahlen berechnet werden bis=bis/2 ' Wegen z=z+2 Type MyType Field prim Function Create:MyType(zzz) Local e:MyType=New MyType e.prim=zzz Return e End Function End Type Local PrimList:TList=New TList PrimList.AddLast(MyType.Create(3)) ' Ist der Anfangswert der Liste memvar=GCMemAlloced() time=MilliSecs() For t=0 To bis zz=Sqr(z) For a:MyType=EachIn PrimList If (z Mod a.prim)=0 PrimList.RemoveLast() Exit ElseIf a.prim>=zz Print z 'An der Stelle ist z=PRIM Exit EndIf Next z=z+2 PrimList.AddLast(MyType.Create(z)) Next Print "Von 1 bis "+bis*2 Print "Menge der Primzahlen: "+(PrimList.Count()+1) Print "Zeit : "+(MilliSecs()-time)/1000.0+" sek" Print "Mem.Anfang: "+memvar+" bytes" Print "Mem.Ende: "+GCMemAlloced()+" bytes" While Not KeyHit(KEY_ESCAPE) Wend End Änderungen an dem Code : -Schrittweite erhöht von z=z+1 auf z=z+2 -Rechnet jetzt ab 3 , da 2 sinnlos ist , weil keine geraden Zahlen überprüft werden (wegen z=z+2) -Variable counter entfern , da die Menge der Primzahlen der Grösse der Liste entspricht (+1 weil , 1 und 2 nicht in der Liste enthalten sind und zum Schluss noch eine unnötige Zahl reingeschrieben wird) Was sich geändert hat : -Rechnet etwas schneller , (AMD 64 4000) bis 100.000.000 mit Print ca. 724sek. , ohne jeglicher Ausgabe ca. 384sek. (Thx Dreamora) -Das allerbeste ist , die Liste ist jetzt satte 100MB kleiner , sprich ca.185MB wird jetzt an Arbeitsspeicher benötigt , und das allerbeste ist , ich verstehe nicht warum jetzt das so ist , da die alte Liste die gleichen Werte enthalten hat , hmmm (Nochmal Thx an Dreamora) So , wie ich oben erwähnt habe , bekomme es nicht hin die Liste noch kleiner zu machen (d.h. für die Berechnungen , wird nur die Wurzel der grössten Zahl in der Liste benötigt , sprich noch viel weniger Arbeitsspeicher nötig). Damit wären Zahlen bis ca. 100.000.000^2*10 ohne grösserer Probleme in akzeptabler Geschwindigkeit(hoffe ist die schnellste Lösung ![]() Wenn jemand eine Idee hat , bitte posten. MfG LordArtus p.s. Aso , 2 und 3 wird nicht ausgegeben , bitte nicht wundern , rechnet trotzdem alles richtig ![]() |
||
klepto2 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also ich habe mal kurz das 'Sieb des Eratosthenes' umgesetzt und was soll ich sagen es ist unbedeutend schneller.
bis 100.000.000 braucht das ganze ca. 8sek ohne ausgabe. Code: [AUSKLAPPEN] Const Anzahl = 100000000 Function Prim:Byte[](Zahl:Int = 10000,Ausgabe:Byte = True ) Local PrimZahlen:Byte[Zahl] Local I:Int For I = 2 To Zahl PrimZahlen[I] = False Next Primzahlen[0] = True Primzahlen[1] = True I = 2 While I*I <= Zahl If Primzahlen[I] = False Then Local J = (I*I) While J <= Zahl Primzahlen[j] = True J:+i Wend EndIf I:+1 Wend If Ausgabe = True Then For I = 0 To Zahl If Primzahlen[I] = False Then Print I Next EndIf Return Primzahlen End Function Local T:Int = MilliSecs() Prim(Anzahl,False) Local TT:Int = MilliSecs() Delay 2000 Local T2:Int = MilliSecs() 'Prim(Anzahl) 'Auskommentiert da bei 100.000.000 etwas lange ;) Local TT2:Int = MilliSecs() Print "Range : " + Anzahl Print "Zeit ohne Ausgabe : " + (TT-T) Print "Zeit mit Ausgabe : " + (TT2-T2) |
||
Matrix Screensaver
Console Modul für BlitzMax KLPacker Modul für BlitzMax HomePage : http://www.brsoftware.de.vu |
![]() |
LordArtus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Thx klepto2 , mein Fehler , hab mich zu wenig über Primzahlberechnung informiert.
Da ist mein Code totaler Müll ![]() Hast den Code von Wiki kopiert ![]() MfG LordArtus p.s. Sieb des Atkin soll noch schneller sein. |
||
![]() |
LordArtus |
![]() Antworten mit Zitat ![]() |
---|---|---|
'Sieb des Atkin' falls es jemanden interresiert:
Code: [AUSKLAPPEN] limit = 100000000 hFactor = Int(Sqr(limit))-1 Local isprim:Byte[limit] n:Int=0 time=MilliSecs() For i=5 To limit isprim[i]=False Next For i=1 To hFactor For j=1 To hFactor n=4*i*i+j*j If (n<=limit And ((n Mod 12=1) Or (n Mod 12=5))) isprim[n]=Not isprim[n] EndIf n=3*i*i+j*j If (n<=limit And (n Mod 12=7)) isprim[n]=Not isprim[n] EndIf n=3*i*i-j*j If (n<=limit And (i>j) And (n Mod 12=11)) isprim[n]=Not isprim[n] EndIf Next Next For i=5 To hFactor If isprim[i]=True j=i*i While j<limit isprim[j]=False j=j+i*i Wend EndIf Next time=MilliSecs()-time isprim[1]=True isprim[2]=True isprim[3]=True Rem For i=1 To limit If isprim[i]=True Print i Next EndRem Print "Zeit: "+time+" ms" While Not KeyHit(KEY_ESCAPE) Wend Leider ist es etwas langsamer als die Umsetzung von klepto2. Für die 100.000.000 braucht es 5127 ms , die Umsetzung von klepto2 3572 ms auf meinen Komp. MfG LordArtus |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Versuchs ma indem du isPrim nicht als Byte Array sondern als Int Array implementierst ... heutige Systeme habens net so mit Byte. Sieht gut aus im Source, kommt meistens bei performance checks aber bedeutend mieser raus, weil auf 32bit OS nix mit 8bit adressiert wird sondern mit 32bit und sub adress.
darüber hinaus kannst du von kleptos code vielleicht noch etwas über sinnvolle verwendung von Const etc lernen ![]() Und solange du deine "Optimierungen" in form der Modulos drin hast wird das mit der geschwindigkeit nix fürcht ich. Modulo ist nicht umbedingt die billigste operation ... |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
LordArtus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi ,
- "Versuchs ma indem du isPrim nicht als Byte Array sondern als Int Array implementierst ... heutige Systeme habens net so mit Byte" , (Bit wäre natürlich das optimalste) , aber egal , hier der Gegenbeweis was Byte angeht: Code: [AUSKLAPPEN] limit=100000000 mem=GCMemAlloced() Local test:Byte[limit] mem=GCMemAlloced()-mem Print "bytemem:"+mem time=MilliSecs() For i=0 To limit test[i]=False Next time=MilliSecs()-time Print "bytespeed:"+time Delay 5000 mem1=GCMemAlloced() Local test1:Int[limit] mem1=GCMemAlloced()-mem1 Print "intmem:"+mem1 time1=MilliSecs() For i=0 To limit test1[i]=False Next time1=MilliSecs()-time1 Print "intspeed:"+time1 - das mit Const sollte jeder wissen ![]() - 'Sieb des Atkin' ohne Modulo umzusetzen wäre nicht so toll ![]() Komischerweise in c++ und c# ist 'Sieb des Atkin' um ca. 30-35% schneller als 'Sieb des Erathostenes'. Was mir aufgefallen ist , dass das Invertieren in Bmax ziemlich langsam ist , ausserdem könnte Modulo auch langsamer funtzen. MfG LordArtus |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das Problem ist das für Modulo und andere Operationen seit MingW 3.1 drastische Verbesserungen entwickelt wurden.
Deswegen ist C++ und C# soviel schneller. Das war auch das was mich damals geschockt hat nach dem Wechsel auf den aktuellen MingW, dass Mathe Operationen bis zu 100% schneller liefen und ^ zb nimmer das massive Float Ungenauigkeitsproblem hat trotz allem Und wenn du das mit Const weisst, warum missachtest du es dann aktiv bei Limit zb ![]() |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
LordArtus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi ,
Bei den mini-beispiel-test-progrämmchen sehe ich es nicht als notwendig Const zu benutzen (Wird ja hauptsächlich dazu benutzt um nicht aus Versehen eine Variable zu überschreiben bei grösseren Progs..): -bei meinen Beispielen hat Const überhaupt keinen Einfluss auf die Geschwindigkeit , wenn schon wäre der Vorteil im Nanosek. Bereich (mir gehts fast immer nur um die Geschwindigkeit des Ganzen , nicht darum ob der Code 'schön' aussieht.Ich denke , man kann einiges über einen Menschen erfahren , wenn man seine QuellCodes liest ![]() ![]() ![]() -die Codes sind ja ziemlich klein und ausserdem wird Limit nicht so oft verwendet. MfG LordArtus p.s. ok gebe zu , mit programmieren habe ich nicht so viel zu tun , aber hat mich schon immer faszieniert , wie ein Computer funktioniert und um ehrlich zu sein ist es noch immer mein Traum ein eigenes Spiel zu proggen , wahrscheinlich bin ich auch hier gelandet ![]() (Ob die KI irgenwann mal uns überholt ??? naja , so ein Zwischengedanke ![]() |
||
Sebe |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Zitat: Ob die KI irgenwann mal uns überholt ??? naja , so ein Zwischengedanke
Nein. |
||
![]() |
LordArtus |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi ,
Sebe , das klingt , als ob Du ziemlich sicher wärst. Hast Du keine Begründung dafür ??? MfG LordArtus |
||
Sebe |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Naja, mal ganz abgesehen von den Speicherplatzproblemen die eine sich selbst weiterentwickelnde, kreative AI hätte würde - da bin ich ziemlich sicher - jemand rechtzeitig den Stecker ziehen. | ||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group