2012-12-18 7 views
5

Ich arbeite in C und ich versuche (verzweifelt), einen Zufallsgenerator zu erzeugen, der nicht nur eine andere Zahl generiert, jedes Mal wenn ich den Generator aber auch eine andere Reihenfolge jedes Mal i Führen Sie das Programm aus. Ich habe fast alles getestet, was ich online gefunden habe. Ich habe 2 gute Möglichkeiten gefunden, einen guten Zufallsgenerator zu erstellen. Die erste ist, jedes Mal einen anderen Samen zu verwenden. Das bedeutet, dass ich jedes Mal einen anderen Zufallssamen verwenden muss, eine Sache, die ich zuerst nicht gelöst habe. Hier ist, was ich jetzt versuche, aber es ist nicht wirklich zufällig, wie ich will:Ich suche einen voll-zufälligen Zahlengenerator

int myrand(int random_seed){ 
    random_seed = random_seed * 1103515245 +12345; 
    return (unsigned int)(random_seed/65536) % 32768; 
          } 

Jedes Mal, wenn ich die Funktion aufrufen, erhöhe ich die Samen von 1.

Der zweite Weg time.time Änderungen zu verwenden ist, und dies ist randomness.I auch viele Möglichkeiten ausprobiert um dies zu implementieren.Mein letzter Versuch ist hier: Compiler error-Possible IDE error"undefined reference to gettimeofday error" aber ich konnte nicht die Funktion gettimeofday verwenden, weil ich in Windows arbeite.Auch in dieser Frage habe ich keine Antworten erhalten.

Könnte jemand mir helfen, wie ich einen Zufallsgenerator (wahrscheinlich mit Zeit) in C arbeiten in Windows oder könnte ich Unix verwenden?

+2

Stimmt etwas nicht mit 'srand()'? Du kannst es wie folgt säen: 'srand (time (NULL));' –

+0

Ich habe auch srand versucht (time (NULL)), aber ich musste Verzögerungen machen, um die Zeit zu warten, um den Grund zu ändern Ich möchte eine große Menge von Zufallszahlen in einmal generieren und ich möchte nicht warten 2 Minuten für das Programm, um sie zu generieren.Ich habe auch versucht, Millisekunden zu verwenden, aber ohne Erfolg.Vielleicht Millisekunden ist die Antwort, aber ich konnte nicht implementieren Sie es richtig, wieder war das Problem, dass ich Windows verwende. – Dchris

+2

@Dchris: seed Ihren Pseudo-Zufallszahlengenerator (PRNG) mit der Zeit * einmal *, am Anfang des Programms. Dann müssen Sie vielleicht sicherstellen, dass Sie Ihr Programm nicht mehr als einmal pro Sekunde ausführen (und die Einführung von Millisekunden würde dabei helfen), aber Sie müssen nicht jedes Mal eine Sekunde warten, wenn Sie eine Zahl von Ihrem PRNG lesen. –

Antwort

4

Seed Ihren RNG mit einer guten Quelle der Entropie.

Verwenden Sie unter Unix/dev/random.

Unter Windows verwenden Sie so etwas wie CryptoAPI - Windows equivalent of /dev/random

+1

Dies ist nur für wichtige Zufälligkeit. Das Lesen von/dev/random wird das System der Entropie entleeren, was zu einer Blockierung führen wird, wenn es schließlich leer ist, bis das System mehr Entropie gesammelt hat. Natürlich gab das OP nicht an, ob das Problem, das er zu lösen versucht, sicherheitsrelevant ist oder nicht. Ich vermute es ist nicht. –

+0

geändert, um festzustellen, dass Sie das Rng so einfach säen können. –

+1

In C++ 11 können Sie ['std :: random_device'] (http://en.cppreference.com/w/cpp/numeric/random/random_device) verwenden, das vermutlich die Quelle von wirklich zufälligen Daten verwenden wird das System. –

3

Was für Sie fragen nicht ein Zufallszahlengenerator ist, aber wie der Zufallszahlengenerator verwenden, bereits in der C-Standardbibliothek enthalten.

Alles, was Sie tun müssen, ist Samen es einmal beim Programmstart:

srand(time(NULL)); 

Das ist alles. Es ist portabel und wird Ihnen jedes Mal, wenn Sie das Programm ausführen, eine andere Reihenfolge geben, vorausgesetzt, dass mindestens eine Sekunde seit der letzten Ausführung vergangen ist.

Es ist nicht schaden, es später wieder zu säen, aber auch keinen Sinn darin.

+0

Nachsaat sollte nicht leicht genommen werden. Abhängig vom PRNG-Algorithmus kann eine Neubildung wünschenswert sein, um die Entropie zu erhöhen, aber es gibt definitiv richtige und falsche Wege zum Resedieren und kryptografische Angriffe, die auf schlechtem Neuansatz basieren. Wie Sie gesagt haben, ist das Nachsetzen für einfache PRNG-Anwendungsfälle normalerweise nicht notwendig. Zum Beispiel kann der MT-Algorithmus erstaunliche 2^19937-1-Zahlen erzeugen, bevor er sich wiederholt. Andere sind gut bis 2^32 Nummern vor dem Radfahren. – bot403

1

Die C-Standardbibliothek hat den Header time.h (oder ctime, wenn Sie C++ verwenden) (reference). Die Funktionen dort werden in Windows und Unix unterstützt.

Ich würde time() oder clock() als Startwert für Ihren Zufallszahlengenerator empfehlen.

Eine andere Möglichkeit, völlig zufällig zu bekommen Eingabe ist die Verwendung der Mausposition oder andere Dinge von außen beeinflusst.

0

Es gibt viele Möglichkeiten, prng zu implementieren, aber leider ist keiner von ihnen ein echter Zufallszahlengenerator. Zeit (NULL) ist ein guter Ansatz, aber ich verwende "Blum blum shub". Es erzeugt eine Bit-Zufallszahl

0

Da Sie explizit für eine Windows-Lösung sind gefragt würde ich vorschlagen, für srand()time(NULL) oder clock() als Saatgut zu vermeiden, da ihre Granularität sehr begrenzt ist (ms).Stattdessen könnten Sie das Ergebnis des Leistungsindikatoren verwenden:

LARGE_INTEGER PerformanceCount; 
QueryPerformanceCounter(&PerformanceCount); 
srand(PerformanceCount.LowPart); 

Die Schrittrate der Frequenz von QueryPerformanceCounter() kann durch einen Aufruf QueryPerformanceFrequency() erhalten werden. Dies erhöht sich typischerweise um mindestens 1 MHz und manchmal sogar bis in den GHz-Bereich. Daher bietet es eine schnell wechselnde Quelle für den Samen.

Bearbeiten: Wie von Ihrem earlier question auch eine gettimeofday() ähnliche Implementierung verstanden wird keine feine Granularität geben. Es kann das Wort tv_usec in seinem Argument zeigen, aber auf Windows wird es Mikrosekunden Granularität nicht bereitstellen, wie es auf Linux-Systemen tut.

0

Zitat:

to make a random generator that not only generates a different number every time i run the generator

Definitionen von Zufall nicht enthalten dieses Konzept. Die Idee ist vielmehr, dass Sie die gleiche Chance haben, eine beliebige Zahl auszuwählen, unabhängig von der zuvor gewählten Anzahl. Das heißt, es ist theoretisch möglich, dieselbe Nummer zweimal zu wählen.

Wenn Sie ein Kartenspiel haben, dann erfüllt das Ihr Kriterium, dass es keine Duplikate gibt. Die Verwendung des Deck-Handels-Ansatzes bedeutet, die "gebrauchten" Nummern im Auge zu behalten.

Sie sollten auch beachten, dass PNRGs (Pseudozufallszahlengeneratoren) zyklisch (periodisch) sind. Nachdem Sie Nummern generiert haben, meist eine große Zahl, beginnen Sie von vorne und wiederholen die Namensfolge der Zahlen. Die UNIX rand() Funktion ganze Zahlen ganze Zahlen im Bereich erzeugt [0, {RAND_MAX}] und hat eine Periode von 2^32

betrachten wirklich diese kurze Seite zu lesen:

See: http://pubs.opengroup.org/onlinepubs/009695399/functions/rand.html

Verwandte Themen