2009-05-19 3 views
1

Im Moment habe ichHaben Sie eine bessere Idee, Münzwurf zu simulieren?

return 'Heads' if Math.random() < 0.5 

Gibt es einen besseren Weg, dies zu tun?

Dank

bearbeiten: bitte den Rückgabewert ignorieren und „besser“ bedeutet genau 50-50 Wahrscheinlichkeit.

+0

Welche Sprache? Und warum eine Saite zurückgeben? –

+0

"besser" in welcher Weise? Unter der Annahme, dass random() einen Float generiert, der 0 <= Num <1 ist, haben Sie eine genaue 50-50 Chance. –

+2

Wie wäre es mit einer "Randmünze"? ;) – DisgruntledGoat

Antwort

-4

Versuchen

return 'Heads' if Math.random() * 100 mod 2 = 0 

Ich weiß nicht wirklich, welche Sprache Sie verwenden, aber wenn die Zufallszahl durch zwei teilbare ist, dann ist es Köpfe, wenn es nicht so ist es Schwanz ist.

+1

Das funktioniert möglicherweise nicht. Die äußersten linken Bits einiger Zufallszahlengeneratoren sind zufälliger als die ganz rechten Bits. –

+0

Wenn Sie eine solche Technik verwenden, stellen Sie sicher, dass random() bei den Bits niedrigerer Ordnung genauso zufällig ist wie bei Bits höherer Ordnung. Siehe die Anmerkungen zu rand (3) linux.die.net/man/3/rand – Stephan202

+0

Deshalb habe ich mod 2 verwendet, weil 98 genauso gültig ist wie 52 und genauso gültig wie 02. Weil dann tendenziell bestimmte Zahlen bevorzugt werden, oder Bereiche von Zahlen, aber wenn Sie Mod 2 verwenden, sollten Sie eine ziemlich gerade Pause zwischen gerade und ungerade erhalten. –

9

gibt es immer die Toten einfach

Münze = rand (1);

In vielen Skriptsprachen erhalten Sie ein zufälliges int zwischen 0 und Ihrem Argument, so dass Sie 1 oder 0 (Kopf oder Zahl) erhalten, wenn Sie 1 übergeben.

+1

Garantiert dies, dass die Wahrscheinlichkeit 50% beträgt? – unj2

+4

Ich glaube nicht, dass du das je garantieren kannst. – ChristianLinnell

+0

Tal Pressman sagte, dass ich "eine genaue 50-50 Chance" bekommen kann. Ist das falsch? – unj2

0

Versuchen Sie, zwischen ungeraden und geraden Zahlen zu unterscheiden. Geben Sie außerdem einen Enumerationswert (oder einen booleschen Wert) statt einer Zeichenfolge zurück.

4

Was Sie haben, ist die Art, wie ich es tun würde. Wenn 0,0 < = Math.random() < 1.0, standardmäßig ist, dann (Math.random() < 0,5) wird Ihnen Köpfe geben, wenn Math.random() zwischen 0,0 und 0,4999 ..., und Schwanz, wenn es liegt zwischen 0,5 und 0,999 ... Das ist so fair wie ein Münzwurf.

Natürlich nehme ich eine gute Umsetzung von Math.random().

+0

wird <= einen Unterschied machen? – unj2

+2

Ja, <= würde eine leichte Verzerrung zugunsten der einen oder anderen Seite machen (je nachdem, was Sie zuweisen, in diesem Fall Köpfe). 0,0 - 0,5 ist ein etwas größerer Bereich als 0,5000001 - 0,9999999. –

+0

Erinnern Sie sich an Ungenauigkeiten beim Vergleichen und Floaten. – strager

7

Numerical Recipes in C sagt nicht, die eingebauten Zufallszahlengeneratoren zu vertrauen, wenn es darauf ankommt. Sie könnten wahrscheinlich den Algorithmus in dem Buch als Funktion RAN1() gezeigt implementieren, die es alle bekannten statistischen Tests der Zufälligkeit behauptet geht (1992) für weniger als etwa 10 Anrufe.

Die Grundidee hinter dem RAN1 (Algorithmus) ist ein Shuffle mit dem Ausgang des Zufallszahlengenerators hinzufügen niederwertigen serielle Korrelationen zu reduzieren. Sie verwenden den Bays-Durham Shuffle aus Abschnitt 3.2-3.3 in The Art of Computer Programming Volume 2, aber ich schätze, Sie könnten auch den Fisher-Yates shuffle verwenden.

Wenn Sie mehr zufällige Werte als die benötigen, bietet das gleiche Dokument auch einen Generator (RAN2), die für mindestens 10 Werte sollte gut sein (meine Vermutung auf einem Zeitraum von 2,3 x 10-basiert) . Sie stellen auch eine Funktion (ran3) zur Verfügung, die eine andere Methode zur Erzeugung von Zufallszahlen verwendet, sollten lineare Kongruenzgeneratoren Ihnen ein Problem bereiten.

Sie können jede dieser Funktionen mit Ihrem < 0.5-Test verwenden, um sicherer zu sein, dass Sie eine gleichmäßige Verteilung erhalten.

+0

Ich hoffe, dass ran1 Code nicht von Numerical Recipes ist, weil die Numerical Recipes Lizenz (in den Büchern enthalten und auf der nrbook.com Website veröffentlicht) verbietet ausdrücklich Umverteilung von jedem ihrer Quellcode: http: // www. nr.com/licenses/redistribute.html – las3rjock

+1

Guter Gott, das habe ich noch nie gesehen. Ein Buch voller Code-Leute, die nicht in Open-Source-Projekten verwendet werden dürfen ... wow. – fenomas

+0

Ja tatsächlich. Ich habe meine Übersetzung entfernt. Wenn Sie eine Zufallszahlengenerierung benötigen, müssen Sie eine Kopie ihres Buches kaufen und die Übersetzung selbst durchführen. – garethm

0

Ich kann nicht auf Menschen Beiträge kommentieren, weil ich den Ruf nicht haben, sondern nur ein FYI über die ganze < = vs.< Thema in Bill adressiert Der Kommentar der Eidechse: Weil es effektiv angenommen werden kann, dass zufällige eine Zahl zwischen 0-1 generiert (was technisch nicht der Fall ist aufgrund der Beschränkungen für die Größe einer Gleitkommazahl, aber mehr oder weniger) wahr in der Praxis) wird es keinen Unterschied in num < = .5 oder num < .5 geben, weil die Wahrscheinlichkeit, irgendeine Zahl in einem kontinuierlichen Bereich zu erhalten, 0 ist. IE: P (X = .5) = 0 wenn X = eine Zufallsvariable zwischen 0 und 1

+1

Ah, bei Fließkommazahlen liegt man falsch, als .5 ist ein Wert, der genau dargestellt werden kann. Also wird <.5 einen Wert kleiner als <= .5 haben, der wahr ergibt. Mathematisch sind Sie jedoch richtig, aber für Gleitkommazahl mit <=. 5 wird eine Verzerrung von etwa 2^-24 oder 2^-53 eingeführt, je nachdem, ob Sie einfach oder doppelt verwenden :) – Joey

+0

.5 kann genau sein dargestellt, und wie ich sagte, arbeitete ich unter der Annahme, dass die Anzahl der Werte, die der Computer zwischen 0 und 1 darstellen kann, unendlich ist. In diesem Fall ist die Wahrscheinlichkeit, eine diskrete Zahl zu erhalten, 0. Ich weiß, dass die Annahme technisch nicht ist True aufgrund der Einschränkungen von IEEE und nur in der Lage, Zahlen zu etwa 1^-36 oder so zu repräsentieren, aber wenn Sie Hunderte von Millionen von Versuchen laufen, ist es eine ziemlich faire Annahme, oder? –

7

ein winziges Hommage an xkcd:

string getHeadsOrTails { 
     return "heads"; //chosen by fair coin toss, 
         //guaranteed to be random 
    } 
2

auf einem linux-System, das Sie Bits in von/dev/random lesen konnten "bessere" Zufallsdaten zu bekommen, aber ein fast rand om-Methode wie Math.Random() wird für fast jede Anwendung in Ordnung sein, die Sie sich vorstellen können, abgesehen von ernsthaften Kryptografiearbeiten.

+0

/dev/random wird blockiert, wenn Sie den Entropiepool erschöpft haben. Darüber hinaus ist es als eine Quelle von nicht-aussagefähigen Zufallsdaten mit sehr geringer Ausbeute gedacht (um einen kryptografisch sicheren PRNG zu erzeugen oder Schlüssel zu erzeugen), nicht als eine allgemeine Quelle von Zufallsdaten. Auch können Sie keine 50% ige Chance garantieren, da das Generieren völlig unvoreingenommener Entropie wirklich schwierig und wahrscheinlich unmöglich ist. – Joey

+0

Wenn Blockieren ein Problem ist, gibt es immer/dev/urandom ... aber ich denke nicht, dass dies einen Vorteil gegenüber Math.Random() bietet. – DrStalker

+0

ist es kryptographisch sicher. Aber wenn du etwas mit Krypto willst, denkst du wahrscheinlich nicht über Münzen nach :) – Joey

0

Die einzige wirkliche Antwort auf diese Frage ist, dass Sie keine Wahrscheinlichkeit "garantieren" können. Wenn Sie darüber nachdenken, ist ein echter Münzwurf keine garantierte 50/50-Wahrscheinlichkeit, sondern hängt von der Münze, der Person, die sie dreht, und wenn die Münze fallengelassen wird und über den Boden rollt. ;)

Der Punkt ist, dass es "zufällig genug" ist. Wenn Sie einen Münzwurf simulieren, ist der Code, den Sie gepostet haben, mehr als gut.

Verwandte Themen