2016-12-08 4 views
0

私は最近、Webページで実行する次のコードを実行してテストしました。私のウェブページにアクセスする人それぞれについて、このコードはページを見る前に実行され、その50%がランダムに別のウェブページを見ることができます。コンパイルして1000回実行した後、1,2,3,4,5が生成されていることを確認しました(下の図を参照してください)。約50%の時間と6,7,8,9,10が50%生成される。したがって、私のコードに基づいて、1,2,3,4、または5のいずれかを持つ人は、ifステートメントの基準を満たすことが期待されます。乱数ジェネレータがバイアスのある結果を生成する - 明確な理由がない

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

残念ながら、ウェブページ上の実行は計画通りに機能しませんでした。私のウェブページに250人のユニークビジターのうち、100人がifステートメントを起動し、150人がそうしなかった。これは明らかにランダムチャンスの結果である可能性がありますが、おそらく私が紛失しているエラーの原因になりそうです。上で述べたように、このコードをテストしたところ、この特定の問題をスタック交換で研究していると予想されていたディストリビューションが生成されていて、乱数ジェネレータに偏りがあるように見えますが、コードがその問題にぶつかる。どのような助けや洞察力があれば幸いです。

+2

テストその250倍。結果は何ですか? – rassar

+2

一部の人、ブラウザ、ボットがJavaScriptを無効にしている可能性がありますので、デフォルトではifを実行できません。これはスキュー/バイアスの一部を説明することができます。 – Muskie

答えて

1

単純化すると、0と1の間の乱数が生成されます。このコードを確認してください。ヒットラン、それは毎回約50%になります。

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

あなたはこのコードを実行するとして、あなたは、擬似乱数値の変化分布に気づくでしょう。この差は、サンプル数が少ない場合に顕著になります。 Math.randomの出力としてdepends of browser's JavaScript engine implementationは、あなたのケースでは満足な分布ではないかもしれません。

cryptographically random valuesを実装するのは難しいかもしれませんが、より均一な配布を提供する必要があります。 random-jsはこのAPIを実装しているようです。

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);


あなたはcrypto.getRandomValues実装を見ることができ、以下のダウン。 1000以上のサンプルの分布はほぼ50%に非常に近いことが保証されています。

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);

関連する問題