2010-07-01 13 views
8

gcc 4.4.4 c89mit Rand zum Generieren von Zufallszahlen

Ich verwende den folgenden Code. Allerdings bekomme ich immer die gleiche Nummer:

size_t i = 0; 

    for(i = 0; i < 3; i++) { 
     /* Initialize random number */ 
     srand((unsigned int)time(NULL)); 
     /* Added random number (simulate seconds) */ 
     add((rand() % 30) + 1); 
    } 

Ich möchte 0 bis 30 zurückgegeben werden. Aber das letzte Mal, als ich das Rennen gemacht habe, habe ich 17 Mal drei Mal bekommen.

Vielen Dank,

+2

möglich Duplikat [Zufallszahlenfunktion Zündaussetzer] (http: // Stackoverflow.com/questions/1068350/random-number-function-is-misfiring) –

Antwort

22

Sie innerhalb die Schleife (mit dem gleichen Wert, weil, wie schnell die Schleife ausgeführt wird) Impfen, die die Zufallszahl verursacht erzeugte das gleiche jedes Mal zu sein.

Sie benötigen Samen Funktion außerhalb die Schleife bewegen:

/* Initialize random number */ 
srand((unsigned int)time(NULL)); 

for(i = 0; i < 3; i++) { 
    /* Added random number (simulate seconds) */ 
    add((rand() % 30) + 1); 
} 
9

Sie müssen srand nur einmal zu Beginn des Programms, nennen.

srand initialisiert den Pseudozufallszahlengenerator mit der Zeit in Sekunden. Wenn Sie es mit einer bestimmten Nummer initialisieren, erhalten Sie immer die gleiche Zahlenfolge. Aus diesem Grund möchten Sie es normalerweise am Anfang mit der Zeit initialisieren (so dass der Startwert jedes Mal anders ist, wenn Sie das Programm ausführen) und dann nur rand verwenden, um Zahlen zu generieren, die zufällig erscheinen.

In Ihrem Fall ändert sich die Zeit nicht von Iteration zu Iteration, da ihre Auflösung nur 1 Sekunde beträgt, Sie erhalten also immer die erste Zahl der Pseudozufallsfolge, die immer gleich ist.

+1

Ist es wirklich wahr, dass 'srund nur einmal am Anfang Ihres Programms aufrufen muss? Ich meine, ich denke, wenn man braucht, sollten sie 'srand' aufrufen, wann immer sie den Samen des Zufallszahlengenerators ändern müssen und um eine andere Folge von Zufallszahlen zu erhalten. –

+0

Es ist wahr für dieses bestimmte Stück Code;). Natürlich können Sie es jederzeit aufrufen, wenn Sie aus irgendeinem Grund den Samen ändern möchten; es ist nicht verboten. –

+0

@skwllsp und das ist normalerweise nur einmal _per request_! – alexanderpas

4

Sie müssen srand((unsigned int)time(NULL)) nur einmal vor der Schleife tun.

2

Es ist durchaus möglich, dass die 3 mal 17 immer noch völlig zufällig sind.

Es besteht eine Wahrscheinlichkeit von 1 zu 10, dass zwei Zahlen gleich sind, wenn ein Bereich von 1-30 und drei Picks verwendet wird. (Dies ist aufgrund der birthday problem)

Nun, drei gleiche Ergebnisse zu erhalten hat immer noch eine Wahrscheinlichkeit von 1 in 900 mit dem gleichen Bereich.

Sie mehr Hintergrund lesen auf den analysis page of random.org

+0

In diesem Fall (auch wenn es kein Codierungsfehler war) zwei 17s bekommen Eine Zeile hat nichts mit dem Geburtstagsproblem zu tun. Die Annahme, dass jede Zufallszahl unabhängig ist, um die Wahrscheinlichkeit zu berechnen, zwei 17 hintereinander zu erhalten, wäre 1/30 * 1/30 oder 1/900. Für drei wäre es 1/30 * 1/30 * 1/30 oder 1/27000. – MarkD

+0

aber Sie vergessen, es gibt 30 verschiedene Möglichkeiten, drei gleiche Zahlen zu bekommen. 1/27000 * 30 = 1/900 – alexanderpas

+0

Jetzt, für die beiden gleich ... gibt es eigentlich drei Kombinationen XYX, XXY und YXY mit je 30 Möglichkeiten. 1/900 * 30 = 1/30 * 3 = 3/30 = 1/10 – alexanderpas

1

Seed an den Pseudo-Zufallszahlengenerator sollte nur einmal aufgerufen werden außerhalb der Schleife interessiert sein könnten. Zeit als Samen zu verwenden, ist eine gute Sache. Es besteht jedoch immer noch die Möglichkeit, die gleiche Zufallszahl zu erhalten.

1

Ich schlage vor, sondern auch gettimeofday() Systemaufruf mit dem Samen abrufen zu verwendenden srand zu füttern().

So etwas wie

 

struct timeval tv; 
... 
gettimeofday(&tv, NULL); 
srand(tv.tv_usec); 
... 
 

Dieser Ansatz kann mehr Entropie in Ihrer Pseudonummer Generation Code hinzuzufügen. IMHO natürlich

Ciao ciao

Verwandte Themen