2016-12-08 1 views
0

Ich habe vor kurzem ausgeführt und den folgenden Code getestet, um auf einer Webseite auszuführen. Für jede Person, die meine Website besucht, sollte dieser Code ausgeführt werden, bevor sie die Seite anzeigen, um 50% zufällig auf eine andere Webseite zu leiten. Der von mir erstellte Code (siehe unten) generiert, basierend auf meinem Verständnis (und Testen), eine Zufallszahl zwischen 1 und 10. Nachdem ich ihn kompiliert und 1000 Mal ausgeführt habe, habe ich bestätigt, dass 1, 2, 3, 4, 5 generiert werden ungefähr 50% der Zeit und 6, 7, 8, 9, 10 werden zu 50% generiert. Daher würde ich erwarten, dass basierend auf meinem Code jeder mit einer 1, 2, 3, 4 oder 5 die Kriterien der if-Anweisung erfüllen würde.Zufallsgenerator erzeugt voreingenommene Ergebnisse - kein klarer Grund, warum

var rando = Math.floor((Math.random() * 10) + 1); 
if(rando < 6){ 
    //execute unrelated jquery code here to modify webpage 
} 

Leider hat die Ausführung auf der Webseite nicht wie geplant funktioniert. Von 250 eindeutigen Besuchern meiner Webseite lösten 100 die if-Anweisung und 150 nicht. Während dies offensichtlich das Ergebnis einer zufälligen Chance sein könnte, ist es wahrscheinlich eher die Quelle eines Fehlers, den ich vermisse. Wie oben erwähnt, habe ich diesen Code getestet und festgestellt, dass er die erwartete Verteilung generiert hat. Ich habe dieses spezielle Problem beim Stack-Austausch untersucht, und obwohl es in einigen Fällen eine Verzerrung im Zufallsgenerator gibt, denke ich nicht Code führt zu diesem Problem. Jede Hilfe oder Einsicht würde sehr geschätzt werden!

+2

-Test es 250-mal. Was sind die Ergebnisse? – rassar

+2

Einige Leute, Browser, Bots können JavaScript deaktiviert haben, so dass die Vorgabe nicht wäre, das if zu tun. Das könnte etwas für den Skew/Bias erklären. – Muskie

Antwort

1

Vereinfachen Sie die Dinge .. erzeugen Sie eine Zufallszahl zwischen 0 und 1. Sehen Sie sich diesen Code an. Hit run und es wird jedes Mal etwa 50% sein.

var count = 0; 
 
var numTimes = 10000; 
 

 
for(var i = 0; i < numTimes; i++) 
 
{ 
 
var rando = Math.floor((Math.random() * 2)); 
 
    if(rando === 1){ 
 
    count++; 
 
    } 
 
} 
 

 
console.log(count/numTimes);

1

Wie Sie diesen Code ausführen, werden Sie feststellen Verteilung von Zufallswerten pseudo variiert. Der Unterschied ist möglicherweise deutlicher, wenn die Anzahl der Proben niedrig ist. Als die Ausgabe von Math.random depends of browser's JavaScript engine implementation könnte es nicht zufriedenstellende Verteilung für Ihren Fall ergeben.

Sie könnten auch cryptographically random values verwenden - schwieriger zu implementieren, aber sollten Sie eine gleichmäßigere Verteilung geben. random-js scheint diese API zu implementieren.

function test(times) { 
 
    var t = times; 
 
    var a = 0; 
 
    var b = 0; 
 

 
    while(t --> 0) { 
 
    var rando = Math.floor((Math.random() * 10) + 1); 
 
    if(rando < 6){ 
 
     a++; 
 
    } 
 
    else { 
 
     b++; 
 
    } 
 
    } 
 

 
    console.log("TEST FOR " + times); 
 
    console.log(a); 
 
    console.log(b); 
 

 
    console.log("DISTRIBUTION"); 
 
    console.log((100 * a/(a + b)).toFixed(2) + "%"); 
 
} 
 

 
test(250); 
 
test(250); 
 
test(250); 
 

 
test(1024); 
 
test(2048); 
 
test(4096); 
 
test(8192); 
 
test(32768);


unten Down crypto.getRandomValues Implementierung sehen kann. Die Verteilung für 1000+ Proben ist fast garantiert, dass sie sehr nahe bei 50% liegt.

function test(times) { 
 
    var t = times; 
 
    var a = 0; 
 
    var b = 0; 
 
    
 
    var array = new Uint32Array(times/32); 
 
    window.crypto.getRandomValues(array); 
 

 
    for (var i = 0; i < array.length; i++) { 
 
    var bitString = array[i].toString(2); 
 
    for (var j = 0; j < 32; j++) { 
 
     if(j < bitString.length && bitString[j] === '1') 
 
     a++; 
 
     else 
 
     b++; 
 
    } 
 
    } 
 

 
    console.log("TEST FOR " + times); 
 
    console.log(a); 
 
    console.log(b); 
 
    
 
    console.log("DISTRIBUTION"); 
 
    console.log((100 * a/(a + b)).toFixed(2) + "%"); 
 
} 
 

 
test(256); 
 
test(256); 
 
test(256); 
 

 
test(1024); 
 
test(2048); 
 
test(4096); 
 
test(8192); 
 
test(32768);

Verwandte Themen