Zufälle gibt's?! - Funktionen rund um rand, Random und den Zufall
-
Hast du eine konkrete Frage?
Der allgemeine Aufbau eines linearen Kongruenzgenerators wird in einem anderen Artikel erläutert.
-
Marc++us schrieb:
#include <iostream> using namespace std; int main() { for (unsigned u = 0; u <= RAND_MAX; u++) { cout << u << "\t" << u % 3 << endl; } return 0; }
Am Anfang geht's noch sauber los:
0 0 1 1 2 2 3 0 ...
aber am Ende ist ein kleines Problem vorhanden:
32762 2 32763 0 32764 1 32765 2 32766 0 32767 1
Es geht nicht auf! Der größtmögliche Wert 32767 – der Zufallszahlengenerator schneidet wegen
&0xffff
alles darüber ab – wird durch das Modulo 3 auf 1 gesetzt. Sie können sich das wie das Ablegen von Kugeln vorstellen, man legt immer reihum in die drei Töpfe; zählt man am Ende die Kugeln in den drei Töpfen 0, 1 und 2, so liegt diese Anzahl von Kugeln pro Topf vor:Topf 0: 10923 33,33435% Topf 1: 10923 33,33435% Topf 2: 10922 33,33130%
Problem gelöst...
Bei den Modulo-Rechnungen mit nicht 2er Potenzen einfach in der for den Maximalwert - in dem Fall RAND_MAX - mit dem selben Modulo berechnen und addieren:#include <iostream> using namespace std; int main() { for (unsigned u = 0; u <= RAND_MAX + (RAND_MAX % 3); u++) // <- { cout << u << "\t" << u % 3 << endl; } cin>>ende; return 0; }
Oder RAND_MAX mit dem selben Modulo berechnen, +1 und dann subtrahieren:
#include <iostream> using namespace std; int main() { for (unsigned u = 0; u <= RAND_MAX - ((RAND_MAX % 3)+1); u++) // <- { cout << u << "\t" << u % 3 << endl; } return 0; }
Damit sind alle "Töpfe" gleich voll und man schließt eine ungleiche "Prozentuale Zieh-Chance" aus.
Jedoch wird die häufigkeit der wiederholung damit beeinflusst.
Ergibt das überhaupt Sinn?
MfG
C++ Newbe, Zitro
-
Zitro schrieb:
Ergibt das überhaupt Sinn?
Nein. RAND_MAX kannst Du nicht ändern.
-
@Marc-us sagte in Zufälle gibt's?! - Funktionen rund um rand, Random und den Zufall:
srand(static_cast<int>(time(NULL))); // <-- Neu
Der cast sollte imho nach
unsigned
lauten.
-
@Zitro
Nö das ergibt keinen Sinn.Was man dagegen machen kann...
Wenn man die Zahlen von 0...RAND_MAX auf N Töpfe aufteilen will, dann kann manauto const x = (RAND_MAX - N + 1) / N; // Annahme: RAND_MAX >= N - 1
rechnen, dann alle Zufallszahlen
r < x
verwerfen, und bei den übrigbleibendenr % N
als Topfnummer verwenden.Abgesehen davon... dieser Thread ist von 2007 und durch die neuen RNG Klassen von C++11 auch eindeutig veraltet. Also wozu ausgraben?
-
@hustbaer für Zeh ist es nicht veraltet.
-
@Swordfish Zeh?
-
-
@Swordfish Lol, OK.
Wobei, wenn das erste Codebeispiel gleich mal mit#include <iostream>
anfängt...
-
@hustbaer rauschen