JSはランダムなブール値を生成します


134

簡単な質問ですが、ここでニュアンスに興味があります。

私は自分で思いついた次の方法を使用してランダムなブール値を生成しています:

const rand = Boolean(Math.round(Math.random()));

random()現れるたびに、常に落とし穴があるようです-それは本当にランダムではなく、何か他のものによって危うくされています。それで、私は知りたいです:

a)上記はそれを行うための最良の方法ですか?

b)私は物事を考えすぎていますか?

c)私は物事を考えすぎていますか?

d)私が知らない、より良い/より速い/エレガントな方法はありますか?

(BとCが相互に排他的である場合にも多少関心があります。)

更新

違いがあれば、これをAIキャラクターの移動に使用しています。


25
const rand = Math.random() < 0.5同等で簡単です。
Hamms

3
真のランダム性ではなく、擬似ランダム性のみを達成できます。
Oriol

実際にはランダムなものはありません。目標は、できるだけランダムに近づけることです。
Adam Buchanan Smith

そして、もしあなたが50/50のチャンスを持っているmath.randomなら、十分であるべきです。シードにはミリ秒を使用してください。
Adam Buchanan Smith

ウェブサイトにアクセスするときはかなりランダムだと思います:Dだからこのアイデアを思いついたのです...Boolean(+Date.now()%2)
ロコC.ブルヤン

回答:


337

技術的には、コードは問題ないように見えますが、少し複雑すぎます。あなたは比較することができますMath.random()0.5の範囲として、直接的Math.random()である[0, 1)(この意味は「0を含む1の範囲0ではなく、1」)。範囲を[0, 0.5)およびに分割でき[0.5, 1)ます。

var random_boolean = Math.random() >= 0.5;

// Example
console.log(Math.random() >= 0.1) // %90 probability of get "true"
console.log(Math.random() >= 0.4) // %60 probability of get "true"
console.log(Math.random() >= 0.5) // %50 probability of get "true"
console.log(Math.random() >= 0.8) // %20 probability of get "true"
console.log(Math.random() >= 0.9) // %10 probability of get "true"


3
Iこの一つの解決策、それはあなたが真/偽の確率を微調整することを可能にするようのような
Evanion

たとえば、数値を0.5から0.9に変更した場合、これはfalseの確率を高めますか。
エージェントゼブラ

0.5から0.9に変更した場合。そうすると、確率が変わりそうです。10,000回の繰り返しなど、多数のランダムループを使用して試してみることができると思います。
ケルビン

最新のJavaScriptにはletie を使用する必要がありますlet randomBool = Math.random() >= 0.5;
Chris Halcrow

27

プロジェクトがある場合はlodash、次のことができます。

_.sample([true, false])

13

より暗号的に安全な値を得るにはcrypto.getRandomValues、最新のブラウザーで使用できます。

サンプル:

var randomBool = (function() {
  var a = new Uint8Array(1);
  return function() {
    crypto.getRandomValues(a);
    return a[0] > 127;
  };
})();

var trues = 0;
var falses = 0;
for (var i = 0; i < 255; i++) {
  if (randomBool()) {
    trues++;
  }
  else {
    falses++;
  }
}
document.body.innerText = 'true: ' + trues + ', false: ' + falses;

注ことcrypto、それはノードで利用できないのですが、そうオブジェクトは、DOMのAPIであるノードのための同様のAPIがあります


4
Math.random()多くの点で悪名高く、ランダムではない。偉大な代替案
Charles Harris

3
50 000 000回の実行後に平均で0.78%以上のゼロが生成されることがわかったので、ここで小さな修正を追加します。return a [0] <= 127; (その他127は含まれません)
Amund Midtskog

2
@AmundMidtskogよろしくお願いします。私が入力したはずです:a[0] > 127
アレクサンダーO'Mara

1
ちなみに、通常は、255よりもはるかに多くのサンプルを生成することをお勧めします。他のコメントで提案されているように、データのノイズを減らすために、100,000または数千万のようなものを削減する場合は、 0.78%程度のエラーを表示したいとします。
2017

8
!Math.round(Math.random());

­­­­­­­­­­­­­­


6
これをよりわかりやすくフォーマットし(stackoverflow.com/editing-help)、説明を追加してください。コードのみの回答はあまり評価されません。説明を追加すると、StackOverflowが無料のコード作成サービスであるという誤解を解消するのに役立ちます。
ユンノシュ

5

ケルビンの回答に非常に感銘を受けましたが、かなり似ていますが、少し強化されたソリューションを提案したいと思います。

var randomBoolean = Math.random() < 0.5;

の右側の数字は、<を取得するのtrueではなく、取得する確率を示しているため、このソリューションを読むともう少しわかりfalseやすくなります。また<、1シンボルは未満>=です。



-1

アレクサンダーオマラの答え

ノードコードスニペットを追加するだけ

const crypto = require('crypto');
const randomBool = (function () {
    let a = new Uint8Array(1);
    return function () {
        crypto.randomFillSync(a);
        return a[0] > 127;
    };
})();

let trues = 0;
let falses = 0;
for (let i = 0; i < 100; i++) {
    if (randomBool()) {
        trues++;
    }
    else {
        falses++;
    }
}

console.log('true: ' + trues + ', false: ' + falses);

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.