Wie funktioniert SeedRnd?

Übersicht BlitzBasic Allgemein

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

 

Apocalyptic

Betreff: Wie funktioniert SeedRnd?

BeitragMo, März 15, 2004 19:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi,

erstmal vorne weg: Natürlich weiß ich, wie man SeedRnd anwendet, aber mich interessiert, wie die Pseudozufallszahlen berechnet werden. Dh. was macht Blitz mit RndSeed() und der Information, wie oft Rand() aufgerufen wurde? Gibts da einen nachvollziehbaren mathematischen Zusammenhang? (Den muss es ja geben, oder?)
Suum cuique

[ www.ffs-net.de.vu ] [ Raycaster ]
 

Absoluter Beginner

BeitragMo, März 15, 2004 20:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Schau dir mal Kongruenzgeneratoren an, das sind die die am häufigsten verwendet werden um PseudoZufallszahlen zu berechnen.
http://www.informatik.hu-berli...eferat.pdf

Mit SeedRnd gibt man dem Generator einen Startwert und auf Basis des Startwerts wird dann die 1. Zufallszahle berechnet, die 2. dann auf Basis der 1. usw., d.h. gleicher Startwert => gleiche Zufallszahlenfolge.
Error Inside!
 

Apocalyptic

BeitragDi, März 16, 2004 21:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke schonmal für die Antwort Very Happy

Absoluter Beginner hat Folgendes geschrieben:
Schau dir mal Kongruenzgeneratoren an, das sind die die am häufigsten verwendet werden um PseudoZufallszahlen zu berechnen.


Wird dieser Generator auch bei Blitz verwendet? (Das werd ich Mark wohl persönlich fragen müssen, als ob der nicht schon genug zu tun hat Rolling Eyes Wink )

Absoluter Beginner hat Folgendes geschrieben:
Mit SeedRnd gibt man dem Generator einen Startwert und auf Basis des Startwerts wird dann die 1. Zufallszahle berechnet, die 2. dann auf Basis der 1. usw., d.h. gleicher Startwert => gleiche Zufallszahlenfolge.

Ja, so hab ich mir das vorgestellt... Nur wie kommt man von Zahl1 auf Zahl2? Naja, ich werd mir gleich mal die Seite zu Gemüte führen Wink
Suum cuique

[ www.ffs-net.de.vu ] [ Raycaster ]

TheShadow

Moderator

BeitragDi, März 16, 2004 21:57
Antworten mit Zitat
Benutzer-Profile anzeigen
da werden einfach bits irgendwie rumgetauscht - das wirkt dann zufällig

Ein Virus (der früher mal MS-Server attakiert hat) brauchte IP-Adressen - diese wurden zufällig bestimmt. Um dann keine Zeit zu verschwenden wurden einfach Bits des Zufallwerts getauscht oder umgeschaltet (irgendwie). Natürlich war alles in Maschinencode Smile (wurde doch so ein böses Buffer-Overflow ausgenutzt). So hat es sich in Minuten verbreitet...
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2
 

Absoluter Beginner

BeitragFr, März 19, 2004 14:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Nehmen wir mal so einen Generator

x(n+1) = (a * x(n) + c) mod m

Man sieht schonmal das nur Zahlen von 0 bis m-1 erzeugt werden.
Außerdem das die neue Zufallszahl x(n+1) auf der alten basiert x(n)

Damit man möglichst viele gut verteilte Zufallszahlen erzeugt, sollten noch einige Bedinungen erfüllt sein (irgendwo abgeschrieben)
    - c und m sind teilerfremd
    - a-1 ist ein vielfaches jedes Primteilers von m
    - mit m ist auch a-1 ein Vielfaches von 4


Also SeedRnd setzt die 1. Zufallszahl x(n) a,c und m müßen vom Programmierer gewählt werden, und zwar so das "gute" Zufallszahlen enstehen, und der Pc übernimmt dann den Rest Smile
Error Inside!
 

Apocalyptic

BeitragFr, März 19, 2004 18:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Jo, Danke Very Happy

Wie schwer ist es eigentlich bei dieser Berechnung, die Zufallsverteilung nachzuvollziehen?

Noch eine Frage:

Bei dem Beispiel hier kommt immer 0 raus. Das zu verhindern ist ja nicht schwer, aber gibts noch ähnliche Zahlen, außer dem Maximum, bei denen sowas ähnliches rauskommt? Beim Minimum gibts keine Probleme.

Code: [AUSKLAPPEN]
SeedRnd 2147483647

For i=0 To 20
   Print Rand(0,5)
Next

WaitKey()
Suum cuique

[ www.ffs-net.de.vu ] [ Raycaster ]
 

Absoluter Beginner

BeitragMi, März 24, 2004 12:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Jo, Danke Very Happy

Wie schwer ist es eigentlich bei dieser Berechnung, die Zufallsverteilung nachzuvollziehen?

Naja, je nachdem wie man a,c und m wählt kann man die zufallsverteilung beinflussen, bei guten werten kann man halt 1000000 Zufallszahlen erstellen, bis sie sich dann genau so wiederholen bei schlechten nur 100.

Zitat:
Noch eine Frage:

Bei dem Beispiel hier kommt immer 0 raus. Das zu verhindern ist ja nicht schwer, aber gibts noch ähnliche Zahlen, außer dem Maximum, bei denen sowas ähnliches rauskommt? Beim Minimum gibts keine Probleme.

Code: [AUSKLAPPEN]
SeedRnd 2147483647

For i=0 To 20
   Print Rand(0,5)
Next

WaitKey()
Also ich kenn keine, hab aber auch noch keine gesucht Rolling Eyes
Error Inside!

diceman

BeitragSo, Aug 13, 2017 17:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry für's Ausgraben eines alten Threads, aber da schonmal jemand die Frage gestellt hat, die momentan auch mich bewegt, warum dann einen neuen Thread aufmachen? Smile
Wie wahrscheinlich vielen hier bekannt, ist 2147483647 die höchste Zahl, welche in Blitzbasic dargestellt werden kann. -2147483648 ist die niedrigste. Darüber (bzw. darunter) geschieht ein Überlauf in den positiven/negativen Zahlenbereich.
Ich habe letztens ein bißchen mit dem SeedRnd-Befehl experimentiert - wenn ich immer dieselben Zahlenfolgen generieren möchte, kann ich auch fixe Zahlen vorgeben (bietet sich an, wenn man prozedural erstellte Welten/Dungeons Speichern und Wiederherstellen möchte).
Dies funktioniert auch mit der Zahl 0 oder negativen Zahlen (eine gängige Praxis ist das initiale Seeden über den aktuellen Stand der Millisekunden, welche nach Booten des PCs verstrichen sind = SeedRnd Millisecs() ).

Allerdings:

Benutzt man die Zahl -1 oder die Zahl 2147483647 zum Seeden, erhält man keine Zufallszahlen, sondern immer die niedrigste des gewünschten Spektrums:

Code: [AUSKLAPPEN]
SeedRnd 2147483647

For z = 1 To 20
   Print Rand(1,9)
Next

WaitKey()


Hierbei kommt 20 mal die Zahl 1 heraus. Ebenso, wenn ich als SeedRnd -1 verwende.
Ich wiederhole hier an dieser Stelle nochmal die Frage meines Vorgängers, ob sich mittlerweile jemand findet, der mehr über diesen Algorithmus weiß, bzw. ob diese beiden Zahlen (-1 und 2147483647) die einzigen sind, bei denen diese Anomalie auftritt.

Vielen Dank! Smile
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.

diceman

BeitragSo, Aug 13, 2017 18:08
Antworten mit Zitat
Benutzer-Profile anzeigen
So, ich beantworte mir meine Frage dann mal selbst (allein das Ausformulieren hier im Forum hat mich auf die Idee gebracht) ... Very Happy

Zuerst mal eine weitere Anomalie der Zahl 2147483647:
Code: [AUSKLAPPEN]

Print 2147483647
WaitKey()
End

Funktioniert wie erwartet: Es wird die Zahl 2147483647 ausgegeben.

Versucht man allerdings eine For...Next-Schleife von 2147483646 bis 2147483647 zu durchlaufen, hört diese nicht bei 2147483647 auf, sondern schlägt in den negativen Zahlenbereich um und zählt von dort aus weiter nach oben:
Code: [AUSKLAPPEN]

For a = 2147483646 To 2147483647
   Print a
Next
WaitKey()
End


Dagegen:

Code: [AUSKLAPPEN]
For a = -2147483648 To -2147483647
   Print a
Next
WaitKey()
End

Funktioniert problemlos.



Jetzt zu meinem Testprogramm:
Code: [AUSKLAPPEN]
Dim zahl(3)
For seed = -2147483648 To 2147483646
   SeedRnd seed
   For z = 1 To 3
      zahl(z) = Rand(1,1000)
   Next
   If zahl(1) = 1 And zahl(2) = 1 And zahl(3) = 1 Then Print seed
Next
Print "Finished"
WaitKey()
End

In einer Schleife laufe ich alle Zahlen von der niedrigsten bis zur höchsten darstellbaren durch, und erzeuge in jedem Durchlauf einen Seed mit dem aktuellen Schleifen-Index, auf dessen Basis 3 Zufallszahlen von 1 bis 1000 erzeugt werden. Falls diese drei Zahlen alle 1 ausgeben, wird der Seed notiert.

Nach ca. 5 Minuten war das Programm beendet, und ich hatte 5 Zahlen:
-2137324080
-1863896853
-1
10159568
283586795
Diese 5 Zahlen habe ich jetzt nochmal seperat auf Herz und Nieren getestet, indem ich sie als Seed einsetzte und damit 20 Zufallszahlen von 1 bis x erzeugte. Tatsächlich gilt die oben beobachtete Anomalie nur für die Zahl -1 und die Zahl 2147483647 (die ich in der obigen Testschleife absichtlich nicht angesteuert habe, sondern eine Ziffer davor abgebrochen habe, da sich das Programm ansonsten endlos verfangen hätte).
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.

Thunder

BeitragSo, Aug 13, 2017 18:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Da BB open source ist kannst du dir den Code anschauen. Unten siehst du den Randomgenerator von Blitz3D (Quelle: https://github.com/blitz-resea...bbmath.cpp)

Code: [AUSKLAPPEN]
static int rnd_state;
static const int RND_A=48271;
static const int RND_M=2147483647;
static const int RND_Q=44488;
static const int RND_R=3399;


static inline float rnd(){
        rnd_state=RND_A*(rnd_state%RND_Q)-RND_R*(rnd_state/RND_Q);
        if( rnd_state<0 ) rnd_state+=RND_M;
        return (rnd_state&65535)/65536.0f+(.5f/65536.0f);
}

float bbRnd( float from,float to ){
        return rnd()*(to-from)+from;
}

int bbRand( int from,int to ){
        if( to<from ) std::swap( from,to );
        return int(rnd()*(to-from+1))+from;
}

void bbSeedRnd( int seed ){
        seed&=0x7fffffff;
        rnd_state=seed ? seed : 1;
}

int  bbRndSeed(){
        return rnd_state;
}


die erste Zeile in bbSeedRnd löscht das höchste bit der verwendeten Zahl. das erklärt, warum du für -1 (binär* 11111111111111111111111111111111) und 2147483647 (binär* 01111111111111111111111111111111) die gleichen zahlen bekommst. Es bedeutet, dass die Eingabemenge für diese Funktion eigentlich halbiert wird.
* Zweierkomplement-Darstellung um genau zu sein

Die zweite Zeile setzt außerdem die seed auf 1 falls du 0 übergeben hast. Also bekommst du für 1 und 0 auch gleiche ergebnisse.

So, jetzt zu 2147483647 bzw. -1: Ich habe die rnd()-Funktion mit Debug-Ausgaben geschmückt:
Code: [AUSKLAPPEN]
#include <cmath>
#include <iostream>
#include <algorithm>
#include <utility>

static int rnd_state;
static const int RND_A=48271;
static const int RND_M=2147483647;
static const int RND_Q=44488;
static const int RND_R=3399;

static const float dtor=0.0174532925199432957692369076848861f;
static const float rtod=57.2957795130823208767981548141052f;

float bbSin( float n ){ return (float)sin(n*dtor); }
float bbCos( float n ){ return (float)cos(n*dtor); }
float bbTan( float n ){ return (float)tan(n*dtor); }
float bbASin( float n ){ return (float)asin(n)*rtod; }
float bbACos( float n ){ return (float)acos(n)*rtod; }
float bbATan( float n ){ return (float)atan(n)*rtod; }
float bbATan2( float n,float t ){ return (float)atan2(n,t)*rtod; }
float bbSqr( float n ){ return (float)sqrt(n); }
float bbFloor( float n ){ return (float)floor(n); }
float bbCeil( float n ){ return (float)ceil(n); }
float bbExp( float n ){ return (float)exp(n); }
float bbLog( float n ){ return (float)log(n); }
float bbLog10( float n ){ return (float)log10(n); }


using namespace std;

//return rand float from 0...1
static inline float rnd(){
   std::cout << "1 rnd_state: " << rnd_state << endl;
   rnd_state=RND_A*(rnd_state%RND_Q)-RND_R*(rnd_state/RND_Q);
   std::cout << "2 rnd_state: " << rnd_state << endl;
   if( rnd_state<0 ) rnd_state+=RND_M;
   std::cout << "3 rnd_state: " << rnd_state << endl;
   std::cout << "4 return: " << (rnd_state&65535)/65536.0f+(.5f/65536.0f) << endl;
   return (rnd_state&65535)/65536.0f+(.5f/65536.0f);
}

float bbRnd( float from,float to ){
   return rnd()*(to-from)+from;
}

int bbRand( int from,int to ){
   if( to<from ) std::swap( from,to );
   return int(rnd()*(to-from+1))+from;
}

void bbSeedRnd( int seed ){
   seed&=0x7fffffff;
   rnd_state=seed ? seed : 1;
}

int  bbRndSeed(){
   return rnd_state;
}


int main()
{
   bbSeedRnd(-1);
   for(int i = 0; i < 5; i++){
      cout << i << ".: " << bbRand(1,1000) << endl;
   }
   return 0;
}


Da sieht man recht schnell, dass nach dem ersten Aufruf von rnd die Variable rnd_state auf 0 geht und dort bleibt, deswegen bleiben die Ausgaben gleich. Ich schätze Mal, dass das ein Fehler in der Implementierung ist. Man hätte eine Ausnahme in bbSeedRnd machen müssen (wie für 0).

Bezüglich deiner Tests: Dein Testprogramm ist leider unzureichend, um eindeutig zu bestimmen ob du wirklich eine Seed gefunden hast, die zu gleichen Outputs führt:
Code: [AUSKLAPPEN]
   For z = 1 To 3
      zahl(z) = Rand(1,1000)
   Next
   If zahl(1) = 1 And zahl(2) = 1 And zahl(3) = 1 Then Print seed

du testest nur die ersten 3 Zahlen der Folge mit Zufallszahlen von 1-1000. Die Wahrscheinlichkeit, dass du dreimal eine 1 bekommst, ist 1 zu einer Milliarde. Aber wir haben eine Eingabemenge von 4 milliarden. Liegt also im Bereich des Wahrscheinlichen. Z.B. bei Seed -1863896853 sind nur die ersten 3 Zahlen 1 und danach ändert es sich.

Also du musst entweder mehr testen (weil du den inneren State des zu testenden "Objekts" nicht kennst, musst du auf statistische Relevanz schauen) oder den Code nehmen und wie ich den Inneren State ausgeben. Wenn sich der nicht mehr ändert, "hängt" der Algorithmus.
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

diceman

BeitragMo, Aug 14, 2017 8:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielen Dank für deine Ausführungen. Du steckst da doch weitaus tiefer in der Materie als ich; ich habe lediglich beobachtet, keine Schlüsse gezogen. Wink
Generell scheinen die Zahlen nahe an den beiden Enden der Skala "verbuggt" zu sein. Beziehungsweise zeigen sich hier die wahren Defizite eines Computers, Zufallszahlen zu erzeugen. Zum Beispiel
Code: [AUSKLAPPEN]
SeedRnd MilliSecs()
Print Rand(-2147483647,2147483646)
WaitKey()

scheint ausschließlich die beiden Zahlen -2147483647 und -2147483648(!) zu erzeugen, egal wie oft man das Programm restarted. Ist jedenfalls ein faszinierendes Thema, das Erzeugen von Zufallszahlen. Die Konsequenz, die ich draus gezogen habe: 10-stellige Zahlen vermeiden! Very Happy
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.

Thunder

BeitragMo, Aug 14, 2017 12:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, du hast Blackbox-Testing gemacht und ich hab mir einfach den Sourcecode genommen und geschaut.. gewissermaßen unfair Razz

Wenn du dich für Zufallsgeneratoren interessierst, würde ich dir den Mersenne-Twister (MT 19937) ans Herz legen (für nicht-kryptographische Zwecke). Der Code ist etwas länger als der in BB inkludierte Zufallsgenerator, dafür hat der Mersenne-Twister eine Periodenlänge von (2^19937-1). Es gibt auch eine kleinere Variante davon, den TT800, der hat eine Periodenlänge von 2^800-1, was ich auch noch ausreichend finde. Der deutsche Wikipedia-Artikel dazu (https://de.wikipedia.org/wiki/Mersenne-Twister) ist recht gut.

Ich habe den TT800 in BlitzMax implementiert: https://github.com/chtisgit/bl..._tt800.bmx
sollte man auch in BB hinkriegen können. Oder du baust dir aus dem C quelltext eine DLL und verwendest die.

Wenn du eine Funktion brauchst, die über die gesamte Menge von Int Zufallszahlen erzeugt, musst du sie fast selber schreiben, weil die Funktion Rand() bei der du eine Range vorgeben kannst, meistens intern rnd() verwendet, was du nicht sinnvoll über die ganze Menge von Ints skalieren kannst. In meiner Implementierung des TT800 gibt es so eine Methode (RndInt()).
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

Lobby

BeitragMo, Aug 14, 2017 16:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für die Informationen, finde ich auch sehr interessant und die genannten Algorithmen scheinen nicht so schwer zu implementieren zu sein.
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux

diceman

BeitragMo, Aug 14, 2017 16:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier gibt es anscheinend eine mit Blitz3D/Blitz Plus kompatible Mersenne Twister userlib:
http://www.socoder.net/?showcase=14860

Bin grad auf der Arbeit, konnte sie daher noch nicht testen. Smile

Zitat:
[...] Functions available are mtSeedRnd(), mtRand(), mtRnd(), and mtRawRand().

mtSeedRnd(seed) works as expected.
mtRand(min, max) works as Rand(), but both min and max must be specified.
mtRandMod(min, max) is mtRand() from the previous version. Its distribution is not quite as good, and it barfs if min > max, but it is minutely faster (about 5ms over 50000 calls).
mtRnd() is the oddball - it always returns a result in the range [0, 1]. To simulate Blitz's Rnd() behavior, try (min + mtRnd() * Float(max-min)).
mtRawRand() returns a random number in [-2,147,483,648, 2,147,483,647].
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
 

Mrokmirider

BeitragDi, Aug 15, 2017 6:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Das sind ja alles Pseudozufallszahlen? Oder?
Weil hatten das mal in einer Vorlesung, das echte Zufallszahlen sehr schwer zu implementieren sind.

BladeRunner

Moderator

BeitragDi, Aug 15, 2017 8:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Jap. Eine Maschine welche auf Grundlage einer Abfolge definierter Zustände arbeitet ist nicht sonderlich geeignet "wahren" Zufall zu erzeugen. Daher behilft man sich mit möglichst chaotischen Zahlenreihen, die aber bei genauer Betrachtung auch wieder in sich Definiert (und ab einer gewissen Stelle sich wiederholend) sind.
Wenn Du nicht grade die Möglichkeit hast auf eine analoge Komponente des Systems zuzugreifen (bei heutigen PC in der Regel schwer bis unmöglich, zumindest beim System von der Stange, für welches man ja schreibt) wirst Du immer einen Pseudozufall erhalten.

Auf dem C64 zB konnte man zumindest zur Initialisierung des Pseudozufalls auf eine analoge Schaltung zurückgreifen, der SID (Soundchip) konnte Rauschen erzeugen und das konnte abgefragt werden. Man konnte (theoretisch) auch die Paddleeingänge prüfen, wenn da kein Paddle angeschlossen war schwangen die auch mehr oder weniger zufällig. Richtig befriedigend war aber auch das nicht.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

diceman

BeitragDi, Aug 15, 2017 9:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich habe die oben verlinkte Mersenne Twister-userlib mal getestet ...
Das Einbinden der Befehle klappt soweit super, allerdings ist der mtRand(min,max) Befehl verbuggt! Wenn man lange genug Zufallszahlen hintereinander erzeugt, gibt die Funktion irgendwann max+1 als Ergebnis zurück. Dagegen mtRandMod(min,max) scheint problemlos zu funktionieren (Black Box-Testing) ...
Bin jetzt trotzdem 'n bißchen skeptisch, ob ich das wirklich benutzen möchte. Confused
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
  • Zuletzt bearbeitet von diceman am Di, Aug 15, 2017 11:58, insgesamt einmal bearbeitet

DAK

BeitragDi, Aug 15, 2017 9:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Es gibt auch unter modernen Betriebssystemen echte Zufallszahlengeneratoren. So gibt es unter Linux das Device /dev/random, welches echte Zufallswerte liefert. /dev/random sammelt dafür Entropie (=in diesem Kontext echte Zufälligkeit) aus dem Umgebungsrauschen von verschiedenen Gerätetreibern. Hat allerdings den Nachteil, dass nur vergleichsweise geringe Mengen an Zufallszahlen aus dem Umgebungsrauschen anfallen, und wenn der Zufallscache leer ist, weil zu viele Zufallszahlen abgefragt wurden, dann blockiert die Abfrage an /dev/random, bis wieder genug Zufall da ist.

Echter Zufall ist allerdings nur bei kryptografischen Anwendungen wirklich wichtig. Da kann ein Angreifer z.B. wenn er weiß, welcher Pseudozufallszahlengenerator verwendet wird, die Anzahl an möglichen Schlüsseln, die er durchprobieren muss, verringern, da viele Zahlenfolgen von dem Generator gar nicht erzeugt werden. Oder wenn er einen Teil des Schlüssels kennt, kann er leichter den Rest erraten.

Bei Spielen und ähnlichem ist ein gut initialisierter (=möglichst echt zufälliger Seed) Pseudozufallszahlengenerator oft besser, da er wesentlich schneller neue Zufallszahlen liefert und mehr Zufallszahlen pro Sekunde schafft. Und hier genügt es absolut, dass das Ergebnis zufällig aussieht (=für den Nutzer nicht mehr nachvollziehbare Reihenfolge).
Gewinner der 6. und der 68. BlitzCodeCompo

Thunder

BeitragMi, Aug 16, 2017 1:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Habe gerade aus dem Quellcode von Wikipedia und meinem BlitzMax-Code eine DLL für BB gebastelt. Das ist der TT800, also nicht der große Mersenne-Twister (weil ich finde dass er völlig ausreicht).
https://www.blitzforum.de/upload/file.php?id=13305 (Edit: update, alte Version war schrott)
Falls du den testen willst, wäre ich sehr an den Ergebnissen interessiert. Das Problem mit Rand(-2147483647,2147483646) gibt es hier auch, aufgrund der Art wie ttRand() implementiert ist (über Rnd, so wie das in BB gemacht wird).

mtRandMod klingt sehr nach einsatz von Modulo, was immer zu schlechter Verteilung von Pseudozufallszahlen führt.
Dazu kann ich einen sehr guten 30-minütigen Vortrag von der GoingNative 2013 empfehlen https://www.youtube.com/watch?v=8hREcJ4CFKI er benutzt zwar C++ code, aber die gleichen Probleme gibt es auch in anderen Sprachen.
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit
  • Zuletzt bearbeitet von Thunder am Do, Aug 17, 2017 2:04, insgesamt einmal bearbeitet

diceman

BeitragMi, Aug 16, 2017 2:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, danke! Smile
Werde gleich morgen mal in deine .dll reingucken - das Thema Zufallszahlen beschäftigt mich nämlich nach wie vor, wenngleich ich selbst nicht über die Höheren Mathe/C-Skills verfüge, mir selbst was zurechtzubasteln.
Noch eine Frage: was genau versteht man unter "schlechter Verteilung von Pseudozufallszahlen"? Ich nehme mal an, daß mit wachsender min-max-Spanne die Wahrscheinlichkeit für einige Zahlen wächst, und für andere sinkt - von was für einem Verhältnis sprechen wir hier? Welche Zahlen werden bevorzugt, große oder kleine?
Ich habe die Blitz-interne-Randfunktion weiter auf Herz und Nieren getestet: wenn die Spanne zwischen min-max sehr groß wird a.k.a. 6 Stellen überschreitet, werden kleine Zahlen anscheinend nicht mehr produziert - d.h. Rand(1,9999999) ist nicht mehr in der Lage, einstellige Zahlen zu erzeugen; Rand(1,99999999) schafft keine ein- und keine zweistelligen Zahlen mehr, usw. Mit dem Mersenne-Twister dagegen kein Problem (auch wenn die Wahrscheinlichkeit hierfür entsprechend gering ist - logisch).
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group