485

Math.randomJavaScript で乱数ジェネレーター ( ) をシードすることは可能ですか?

4

16 に答える 16

232

いいえ、シードすることはできませんが、Math.random()独自のジェネレーターを作成するのはかなり簡単です。さらに良いのは、既存のジェネレーターを使用することです。

チェックアウト:この関連する質問.

また、シードの詳細については、David Bau のブログを参照してください。

于 2009-02-06T17:42:35.143 に答える
187

注: 簡潔さと見た目の優雅さにもかかわらず (というか、そのために)、このアルゴリズムはランダム性の点で決して高品質なものではありません。より良い結果を得るには、たとえばこの回答にリストされているものを探してください。

(元々は、コメントで提示された巧妙なアイデアを別の回答に適応させたものです。)

var seed = 1;
function random() {
    var x = Math.sin(seed++) * 10000;
    return x - Math.floor(x);
}

任意の数値に設定できますがseed、ゼロ (または Math.PI の任意の倍数) は避けてください。

私の意見では、このソリューションの優雅さは、「魔法の」数字がないことから来ています(奇妙なパターンを避けるために捨てなければならない最小桁数を表す 10000 以外に - 値101001000の結果を参照してください)。簡潔さもいいです。

Math.random() よりは少し遅いですが (2 倍または 3 倍)、JavaScript で記述された他のソリューションと同じくらい高速だと思います。

于 2013-10-10T18:42:59.607 に答える
47

いいえ、しかし、これは単純な疑似乱数ジェネレーターであり、ウィキペディアから採用したMultiply-with-carryの実装です(その後削除されました)。

var m_w = 123456789;
var m_z = 987654321;
var mask = 0xffffffff;

// Takes any integer
function seed(i) {
    m_w = (123456789 + i) & mask;
    m_z = (987654321 - i) & mask;
}

// Returns number between 0 (inclusive) and 1.0 (exclusive),
// just like Math.random().
function random()
{
    m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;
    m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;
    var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
    result /= 4294967296;
    return result;
}
于 2013-10-10T16:29:45.507 に答える
31

Antti Sykäri のアルゴリズムは素晴らしく、短いものです。Math.randomを呼び出すときに JavaScript を置き換えるバリエーションを最初に作成しましたMath.seed(s)が、Jason は、関数を返す方が良いとコメントしました。

Math.seed = function(s) {
    return function() {
        s = Math.sin(s) * 10000; return s - Math.floor(s);
    };
};

// usage:
var random1 = Math.seed(42);
var random2 = Math.seed(random1());
Math.random = Math.seed(random2());

これにより、JavaScript にない別の機能が提供されます: 複数の独立したランダム ジェネレーターです。複数の再現可能なシミュレーションを同時に実行したい場合、これは特に重要です。

于 2014-04-25T22:34:46.097 に答える
6

以前の回答のいくつかを組み合わせると、これはあなたが探しているシード可能なランダム関数です:

Math.seed = function(s) {
    var mask = 0xffffffff;
    var m_w  = (123456789 + s) & mask;
    var m_z  = (987654321 - s) & mask;

    return function() {
      m_z = (36969 * (m_z & 65535) + (m_z >>> 16)) & mask;
      m_w = (18000 * (m_w & 65535) + (m_w >>> 16)) & mask;

      var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
      result /= 4294967296;
      return result;
    }
}

var myRandomFunction = Math.seed(1234);
var randomNumber = myRandomFunction();
于 2015-04-04T19:32:14.333 に答える