Ist Random doch nicht Random?
Ich glaub ich raff das net richtig. Wenn du jedesmal die gleichen Zahlen haben willst, warum generierst du sie dann überhaupt jedesmal neu?
Einmal generieren und dann in einer Tabelle speichern.
Einmal generieren und dann in einer Tabelle speichern.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!

womit wir dann exakt bei meiner ursprünglichen frage wären, da diese methode das Zackenmuster produziertZeHa hat geschrieben:Das heißt, Du willst einfach nur 'ne Kurve, die krass aussieht, aber reproduzierbar ist?
Dann müßte es doch folgendermaßen funktionieren:Jetzt kannst Du in Zeile 1 jedesmal einen anderen Wert einsetzen, und bekommst auch jedesmal die passende Kurve. Die Kurve für 666 sieht aber immer gleich aus, und die Kurve für 667 sieht auch immer gleich aus. Ist es das, was Du brauchst?Code: Alles auswählen
RandomSeed(666) Dim y(100) For x = 0 to 100 y(x) = Random(10) Next x
Ok, jetzt verstehe ich was das Problem ist... du hast nicht begriffen, dass ein bestimmter Randomseed immer die selbe Reihenfolge von Zufallszahlen Produziert
Wenn du 1* RandomSeed ausführst auf eine Bestimmte Zahl, sagen wir mit seedwert 5, dann kommt immer die selbe Reihenfolge von Zufallszahlen beim Aufruf der Random Funktion.
Also du rufst 1* Randomseed(5) auf und die nächsten 10 000 000 Aufrufe von Random geben dir jedes mal die selben 10 000 000 Zufallszahlen zurück.

Wenn du 1* RandomSeed ausführst auf eine Bestimmte Zahl, sagen wir mit seedwert 5, dann kommt immer die selbe Reihenfolge von Zufallszahlen beim Aufruf der Random Funktion.
Also du rufst 1* Randomseed(5) auf und die nächsten 10 000 000 Aufrufe von Random geben dir jedes mal die selben 10 000 000 Zufallszahlen zurück.
- Froggerprogger
- Badmin
- Beiträge: 855
- Registriert: 08.09.2004 20:02
Mir fallen 2 Sachen dazu ein:
1) Aus dem was Zaphod meint folgt auch, dass jedes Programm, welches zu Beginn den RandomSeed auf immer denselben Wert, z.B. 666 oder immer dieselben Werte, z.B. nach einem bestimmten Muster in einer for-Schleife setzt, sich bei jedem Durchlauf immer gleich verhält. Ich kann mir nicht vorstellen, dass das von dir gewünscht ist. Setze daher lieber sowas wie.
2) Fast alle Programmiersprachen (und garantiert auch PBs) haben als eingebauten Zufallszahlengenerator einen sogenannten linearen Kongruenzgenerator: http://de.wikipedia.org/wiki/Kongruenzgenerator
Diese sind schnell, aber haben ein paar unschöne Eigenschaften, insbesondere können sie bei geeigneter Darstellung oder Verwendung Muster verursachen, die echte Zufallszahlen nicht haben, z.B. Schräglinien in Punktwolken, etc. Es kann durchaus sein, dass genau dieses Verhalten für die Muster in deinem Problem verantwortlich ist. Gerade für zu niedrige Startwerte (Seeds) ist dieses extrem (z.B. sind die ersten Zufallswerte dann meist monoton steigend), daher sollte man lieber große Seeds nehmen (wie auch von ElapsedMilliseconds() oder sowas wie 100000 + 12345*i) geliefert). Für wissenschaftliche Anwendungen, oder generell welche, wo 'besserer Zufall' gewünscht ist, sollte man andere Zufallsgeneratoren nutzen, z.B. den Mersenne-Twister. Diese sind weit 'zufälliger' als der lineare, brauchen aber etwas mehr Rechenzeit.
1) Aus dem was Zaphod meint folgt auch, dass jedes Programm, welches zu Beginn den RandomSeed auf immer denselben Wert, z.B. 666 oder immer dieselben Werte, z.B. nach einem bestimmten Muster in einer for-Schleife setzt, sich bei jedem Durchlauf immer gleich verhält. Ich kann mir nicht vorstellen, dass das von dir gewünscht ist. Setze daher lieber sowas wie
Code: Alles auswählen
RandomSeed(ElapsedMilliseconds())
2) Fast alle Programmiersprachen (und garantiert auch PBs) haben als eingebauten Zufallszahlengenerator einen sogenannten linearen Kongruenzgenerator: http://de.wikipedia.org/wiki/Kongruenzgenerator
Diese sind schnell, aber haben ein paar unschöne Eigenschaften, insbesondere können sie bei geeigneter Darstellung oder Verwendung Muster verursachen, die echte Zufallszahlen nicht haben, z.B. Schräglinien in Punktwolken, etc. Es kann durchaus sein, dass genau dieses Verhalten für die Muster in deinem Problem verantwortlich ist. Gerade für zu niedrige Startwerte (Seeds) ist dieses extrem (z.B. sind die ersten Zufallswerte dann meist monoton steigend), daher sollte man lieber große Seeds nehmen (wie auch von ElapsedMilliseconds() oder sowas wie 100000 + 12345*i) geliefert). Für wissenschaftliche Anwendungen, oder generell welche, wo 'besserer Zufall' gewünscht ist, sollte man andere Zufallsgeneratoren nutzen, z.B. den Mersenne-Twister. Diese sind weit 'zufälliger' als der lineare, brauchen aber etwas mehr Rechenzeit.
!UD2
- dllfreak2001
- Beiträge: 2925
- Registriert: 07.09.2004 23:44
- Wohnort: Bayern
Ich weiß ja net obs interessiert, hab mal in ner älteren Version von PB mit Randomseed rumgemacht. Da fiel mir auf, dass nur der Randomseed benutzt wurde der zuerst aufgerufen wurde egal wieviel man dannach ausführte. So musste ich um den Randomseed zu ändern das Programm neustarten.
Sollte ne Verschlüsselungsroutine werden und hab mich dann gewundert
als ich mit dem Passwort 1234 und auch dem paswort 195762 die Datei korrekt öffnen konnte.
Falls es interessiert...
Sollte ne Verschlüsselungsroutine werden und hab mich dann gewundert
als ich mit dem Passwort 1234 und auch dem paswort 195762 die Datei korrekt öffnen konnte.
Falls es interessiert...
I´a dllfreak2001
@dllfreak
scheinbar gibt's das problem nicht mehr, insofern es mal existiert hat.
@Zaphod
das hatte er schon verstanden, und wollte es ja auch nutzten.
das problem ist einfach der Random-algo von PB, bzw das was FroggerProgger erklärt hat.
man kann das nur etwas verwischen, aber weg bekommt man es nicht.
hab Gubbie's code mal verändert. statt ordinalen seeds werden jetzt vorberechnete zufällige seeds berwendet.
um eine andere formation zu erzuegen, den seedwert am anfang ändern.
komplett:
scheinbar gibt's das problem nicht mehr, insofern es mal existiert hat.
@Zaphod
das hatte er schon verstanden, und wollte es ja auch nutzten.
das problem ist einfach der Random-algo von PB, bzw das was FroggerProgger erklärt hat.
man kann das nur etwas verwischen, aber weg bekommt man es nicht.
hab Gubbie's code mal verändert. statt ordinalen seeds werden jetzt vorberechnete zufällige seeds berwendet.
Code: Alles auswählen
RandomSeed(1)
Global Dim rands.l(#bh*400)
For y=0 To #bh*400
rands(y) = Random(#bh*400)
Next
;...
Procedure.f ran(x,y)
;RandomSeed(9999+rands(y))
;RandomSeed(Random(10000)+x)
RandomSeed(rands(y)+x) : Random(1)
;For i = 0 To x
l.f=-1+Random(2000)/1000
;Next
ProcedureReturn l
EndProcedure
komplett:
Code: Alles auswählen
InitSprite()
InitKeyboard()
InitMouse()
;#bb=1280 : #bh=800 : OpenScreen(#bb,#bh,32,"")
#bb=600 : #bh=400 : OpenWindow(0,100,100,#bb,#bh,"") : OpenWindowedScreen(WindowID(0),0,0,#bb,#bh,0,0,0)
RandomSeed(1)
Global Dim rands.l(#bh*400)
For y=0 To #bh*400
rands(y) = Random(#bh*400)
Next
Procedure.f Cosine_Interpolate(a.f, b.f, x.f)
ft.f = x * #PI
f.f = (1 - Cos(ft)) * 0.5
ProcedureReturn (a*(1-f) + b*f)
EndProcedure
Procedure.f ran(x,y)
;RandomSeed(9999+rands(y))
;RandomSeed(Random(10000)+x)
RandomSeed(rands(y)+x) : Random(1)
;For i = 0 To x
l.f=-1+Random(2000)/1000
;Next
ProcedureReturn l
EndProcedure
Procedure.f noise(x.f,y.f)
rand1.f=ran(Int(x),Int(y))
rand2.f=ran(Int(x)+1,Int(y))
rand3.f=ran(Int(x),Int(y+1))
rand4.f=ran(Int(x)+1,Int(y+1))
ProcedureReturn Cosine_Interpolate(Cosine_Interpolate(rand1 ,rand2,x-Int(x)),Cosine_Interpolate(rand3 ,rand4,x-Int(x)),y-Int(y))
EndProcedure
Procedure.f perlin(x.f,y.f,order)
res.f=0
For i = 1 To order
res + noise(x*Pow(2,i),y*Pow(2,i))/Pow(2,i)
Next
ProcedureReturn res;noise(x,y)/2 + noise(x*2,y*2)/4 + noise(x*4,y*4)/8
EndProcedure
#Step=5
w=1
amp=100
CreateSprite(0,#bb,#bh)
CreateSprite(1,#bb,#bh)
StartDrawing(SpriteOutput(0))
For x = 1 To #bb-1
; Debug x
Next
StopDrawing()
Repeat
ExamineKeyboard()
ExamineMouse()
ClearScreen(RGB(0,0,0))
For i = 0 To 10
DisplaySprite(0,-1,0)
StartDrawing(ScreenOutput())
For y = 1 To #bh/2-1
farbe.f=(0.5+0.5*perlin(time*00.01,y*00.01,10))*255
If farbe>y
farbe-y
Plot(#bb-1,#bh-y*w,RGB(farbe,farbe,farbe))
EndIf
Next
time+1
StopDrawing()
GrabSprite(0,0,0,#bb,#bh)
Next
;DisplaySprite(1,0,0)
FlipBuffers()
Until KeyboardPushed(1)
- dllfreak2001
- Beiträge: 2925
- Registriert: 07.09.2004 23:44
- Wohnort: Bayern
vielen dank für deine mühe, aber das löst das problem leider nicht.#NULL hat geschrieben:@dllfreak
das problem ist einfach der Random-algo von PB, bzw das was FroggerProgger erklärt hat.
man kann das nur etwas verwischen, aber weg bekommt man es nicht.
hab Gubbie's code mal verändert. statt ordinalen seeds werden jetzt vorberechnete zufällige seeds berwendet.um eine andere formation zu erzuegen, den seedwert am anfang ändern.Code: Alles auswählen
...
komplett:Code: Alles auswählen
...
hier hatte doch mal jemand eine alternative randomfunktion geschrieben, die ich leider nicht mehr finde.
Ich habe mich jetzt etwas mit Perlin Noise beschäftigt, das ist ja sehr interessant! Gubbie247, vielen Dank dass Du das hier zur Sprache gebracht hast.
Ich glaube, ich verstehe jetzt auch einen Teil der Verwirrung die hier entstanden ist. Bei Perlin Noise geht es darum, reproduzierbares Rauschen zu erzeugen. Dafür braucht man eine Funktion, die scheinbar zufällige Werte liefert. Diese Funktion hat pro behandelter Dimension 1 Parameter, d.h. im 2-dimensionalen Fall sieht das so aus:
Das ist aber etwas ganz anderes als PureBasics Random()-Funktion. Wichtig für Perlin-Rauschen ist, dass solch eine PerlinNoise()-Funktion für die selben Parameter immer das selbe Ergebnis liefert! Das ist bei Random() aber nicht der Fall. Für RandomSeed() trifft das zwar zu, aber RandomSeed() liefert keine (Pseudo-)Zufallszahlen, sondern das macht Random().
Was ist eine Zufallszahl? Ist z.B. 3 eine Zufallszahl? Die Frage ist so falsch gestellt. Man kann immer nur Serien von Zahlen nehmen und untersuchen, ob die Zahlen in einer Serie (annähernd) so verteilt sind, wie es auch der Fall wäre, wenn sie durch Zufall zustande gekommen wären. Random() liefert Serien von Zufallszahlen. Die Qualität hängt davon ab, wie lang die Periode ist (wie lange es dauert, bis Random() wieder anfängt die selben Zahlen zu liefern), und wie gut die Gleichverteilung der produzierten Zahlen ist (lässt sich z.B. mit dem Chiquadrat-Anpassungstest statistisch prüfen). Ohne solche Prüfungen gemacht zu haben, würde ich nicht behaupten dass hier irgendwas bei PureBasic nicht gut funktioniert.
Gubbie247 nimmt RandomSeed(). Weil diese Funktion keine Zahl zurückliefert, muss man anschließend noch mindestens 1x Random() aufrufen, also z.B.:
Das entscheidende ist nun, dass (soweit ich weiß) niemand behauptet hat, dass die Werte die der wiederholte Aufruf solch einer Funktion Foo() zurückliefert, (pseudo)zufällig verteilt sind!
Am besten ist hier wohl -- wie oben auch schon vorgeschlagen wurde -- ein oder mehrere Arrays im Voraus zu berechnen, und diese dann im Programm zu verwenden. Der Erfinder, Prof. Perlin, macht es auch so.
Gruß, Little John
Ich glaube, ich verstehe jetzt auch einen Teil der Verwirrung die hier entstanden ist. Bei Perlin Noise geht es darum, reproduzierbares Rauschen zu erzeugen. Dafür braucht man eine Funktion, die scheinbar zufällige Werte liefert. Diese Funktion hat pro behandelter Dimension 1 Parameter, d.h. im 2-dimensionalen Fall sieht das so aus:
Code: Alles auswählen
Procedure.d PerlinNoise2D (x, y)
...
EndProcedure
Was ist eine Zufallszahl? Ist z.B. 3 eine Zufallszahl? Die Frage ist so falsch gestellt. Man kann immer nur Serien von Zahlen nehmen und untersuchen, ob die Zahlen in einer Serie (annähernd) so verteilt sind, wie es auch der Fall wäre, wenn sie durch Zufall zustande gekommen wären. Random() liefert Serien von Zufallszahlen. Die Qualität hängt davon ab, wie lang die Periode ist (wie lange es dauert, bis Random() wieder anfängt die selben Zahlen zu liefern), und wie gut die Gleichverteilung der produzierten Zahlen ist (lässt sich z.B. mit dem Chiquadrat-Anpassungstest statistisch prüfen). Ohne solche Prüfungen gemacht zu haben, würde ich nicht behaupten dass hier irgendwas bei PureBasic nicht gut funktioniert.
Gubbie247 nimmt RandomSeed(). Weil diese Funktion keine Zahl zurückliefert, muss man anschließend noch mindestens 1x Random() aufrufen, also z.B.:
Code: Alles auswählen
Procedure.l Foo (seed.l, range.l)
RandomSeed(seed)
ProcedureReturn Random(range)
EndProcedure
Am besten ist hier wohl -- wie oben auch schon vorgeschlagen wurde -- ein oder mehrere Arrays im Voraus zu berechnen, und diese dann im Programm zu verwenden. Der Erfinder, Prof. Perlin, macht es auch so.

Gruß, Little John
geh auf den ersten link in dem post, und lade dir dort so eine datei herunter:
http://www.purebasic.fr/german/viewtopi ... 220#111220
dann kannst du deine random-werte aus dieser datei beziehen, und FileSeeks als Seeds verwenden.
http://www.purebasic.fr/german/viewtopi ... 220#111220
dann kannst du deine random-werte aus dieser datei beziehen, und FileSeeks als Seeds verwenden.