Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Zufallszahlen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
09.12.2010, 00:51 Uhr
wanne



Ich versuche gerade C++ zu lernen. Und komme bei etwas absolut nicht weiter:
Ich würde gerne Zufallszahlen erzeugen. Überall wo ich lese wird dazu die Funktion rand(); bzw. srand(); benutzt.
Ich suche aber ein Äquivalent zu der Funktion Funktion Math.random() in Java. Sprich wenn ich das Programm aufrufe sollen jedes mal 5 zufällige Zahlenfolgen herauskommen.
ich habe das jetzt so versucht:

C++:
#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
     srand(time(NULL));
     for(short int n=0; n<5;n++)
     {
         for (unsigned short int u = 0; u < 20; u++)
             cout << 1 + rand() % 6;
         cout << endl;
     }
    return 0;
}

Jetzt mein Problem:

Bash:
$ ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test
$ ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test
$ ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test
$ ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test
$ ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test
$ ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test
$ ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test
$ ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test
$ ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test
$ sort ~/Dokumente/tmp/test
12323224126211315613
12323224126211315613
12645151563313445353
12645151563313445353
12656346211114463561
12656346211114463561
13312642466631251626
13344435156456154641
13354644435433246333
13354644435433246333
14532466343661535651
14532466343661535651
14653642153115663143
22612413334316444144
23551332416423663135
23551332416423663135
24264615652142214652
31455146131342662634
31455146131342662634
32423315131254661245
32423315131254661245
33361641363636352533
35252534651624211641
35252534651624211641
36122514521566534315
42244356121114132632
45244112121654423244
46243153521564245543
46243153521564245543
53661162461343156533
54263225354615241531
54263225354615241531
54554633316455664624
54644555124455322241
56141454611443666166
61452641146161552366
61452641146161552366
62221155214421433654
62221155214421433654
65163525466256612324
65163525466256612324
66113544315224165644
66113544315224165644
66234515311124543161
66316213161261256563

Wie ihr seht ist fast jedes Ergebnis Doppelt. Die Wahrscheinlichkeit für einen Doppelgänger sollte aber in der Größenordnung 10^-14 liegen. Wenn sie stattdessen bei 10^-10 währe, (das 10.000 fache) währe das für mich kein Problem. Aber so kann ich das echt nicht gebrauchen. Kann mir jemand helfen?

Dieser Post wurde am 09.12.2010 um 01:00 Uhr von wanne editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
09.12.2010, 02:39 Uhr
Hans
Library Walker
(Operator)


Hi,

ich kenne zwar die Java Funktion nicht, würde aber anstelle von time (NULL) in der Klammer von srand eher clock() einsetzen, also
C++:
srand(clock());


schreiben. Ein weiteres generelles Problem bei dieser Konstruktion ist, das sich der Zeitwert, mit dem der Zufallsgenerator initialisiert wird, in dem eher kurzen Zeitraum zwischen zwei Aufrufen des Programms nicht ändert. Wenn Du das Programm also häufig neu starten willst, wäre zu überlegen, ob es wirklich Sinnvoll ist, den Zufallsgenerator jedesmal neu zu initialisieren, also srand zu benutzen.
Wenn dir das immer noch nicht reicht, dann wäre noch die Möglichkeit, einen anderen Zufallsgenerator einzubauen, beispielsweise einen Mersenne Twister; - Code findet man unter dem Link.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
09.12.2010, 08:24 Uhr
ao

(Operator)


Na ja, der Zahlengenerator liefert, wenn er zweimal mit derselben Zahl initialisiert wird, zweimal dieselbe Zahlenfolge. Es sind eben keine echt zufälligen Zahlen, sondern jede neue Zahl ergibt sich eindeutig aus der Vorgeschichte, und die Folge hängt nur vom Startwert ab. Der Name "rand" ist so gesehen eine Mogelpackung.

Manchmal ist es erwünscht, so eine Art "reproduzierbaren Zufall" zu haben, aber in deinem Fall bedeutet es, wenn du dein Programm zweimal in derselben Sekunde startest, bekommst du zweimal dasselbe Ergebnis.

Die Frage ist, ob dein Testfall (Programm 10mal starten) so brauchbar ist oder ob du nicht besser alle benötigten Zahlen hintereinander ziehst, ohne zwischendurch neu zu initialisieren.

Dieser Post wurde am 09.12.2010 um 08:25 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
09.12.2010, 11:40 Uhr
wanne



OK, hatte nicht damit gerechnet, das der time Befehl nur sekundengenau ist.
So gibt es keine Probleme:

Bash:
while [ 1 = 1 ]; do ~/cworkspace/Test/Debug/Test >> ~/Dokumente/tmp/test; sleep 2;done

clock() gibt bei mir allerdings immer 10000 zurück und eignet sich dementsprechend wenig.
Da es im normalen Einsatz tatsächlich recht unwahrscheinlich ist, dass das Programm 2 mal zur gleichen Sekunde aufgerufen wird ist das Problem für mich erstmal erledigt. (Auch wenn die Menge der möglichen Zufallsreihen damit weit unter 10^10 sinkt.)
=> Ihr habt mich davon überzeugt, das ich gar kein Problem habe auch OK, danke.

PS: Aber wenn ich das richtig verstanden habe, hilft mir für wirklich zufällige Zahlen der Mersenne-Twister da auch nicht weiter, da er, wie rand(), auch erstmal einen wirklich zufälligen Initialisierungswert braucht.

Dieser Post wurde am 09.12.2010 um 11:42 Uhr von wanne editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
09.12.2010, 13:03 Uhr
ao

(Operator)


Ich hab nicht genau verstanden, wie der Mersenne-Twister funktioniert, aber soweit ich gesehen habe, ist auch das eine voll deterministische Formel. Also nein, nicht wirklich zufällig.

Für echte Zufallswerte muss man irgendwelche physikalischen Vorgänge auswerten, z.B. würfeln oder radioaktive Zerfälle zählen oder das thermische Rauschen von elektronischen Bauteilen abtasten. Oder die Schneeflocken zählen, die in einer Sekunde am Fenster vorbeifallen ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
13.12.2010, 11:18 Uhr
0xdeadbeef
Gott
(Operator)


Denkbar:

C++:
#include <sys/time.h>

/* ... */

struct timeval tv;

gettimeofday(&tv, NULL);
srand(tv.tv_sec + tv.tv_usec);


Womöglich gibt es bessere Verrechnungsmethoden, ich sähe aber von tv.tv_sec * 1000000 + tv.tv_usec ab, weil die Systemuhr nicht überall so genau sein muss.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 13.12.2010 um 11:21 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: