是否有可能在JavaScript中播种随机数生成器(Math.random) ?


当前回答

如今,许多需要Javascript中可种子随机数生成器的人都在使用David Bau的seedrandom模块。

其他回答

我写了一个函数,返回一个种子随机数,它使用数学。罪恶有一个很长的随机数,并使用种子从其中挑选数字。

使用:

seedRandom("k9]:2@", 15)

它将返回您的种子号码 第一个参数是任意字符串值;你的种子。 第二个参数是返回多少位数字。

     function seedRandom(inputSeed, lengthOfNumber){

           var output = "";
           var seed = inputSeed.toString();
           var newSeed = 0;
           var characterArray = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','y','x','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','U','R','S','T','U','V','W','X','Y','Z','!','@','#','$','%','^','&','*','(',')',' ','[','{',']','}','|',';',':',"'",',','<','.','>','/','?','`','~','-','_','=','+'];
           var longNum = "";
           var counter = 0;
           var accumulator = 0;

           for(var i = 0; i < seed.length; i++){
                var a = seed.length - (i+1);
                for(var x = 0; x < characterArray.length; x++){
                     var tempX = x.toString();
                     var lastDigit = tempX.charAt(tempX.length-1);
                     var xOutput = parseInt(lastDigit);
                     addToSeed(characterArray[x], xOutput, a, i); 
                }                  
           }

                function addToSeed(character, value, a, i){
                     if(seed.charAt(i) === character){newSeed = newSeed + value * Math.pow(10, a)}
                }
                newSeed = newSeed.toString();

                var copy = newSeed;
           for(var i=0; i<lengthOfNumber*9; i++){
                newSeed = newSeed + copy;
                var x = Math.sin(20982+(i)) * 10000;
                var y = Math.floor((x - Math.floor(x))*10);
                longNum = longNum + y.toString()
           }

           for(var i=0; i<lengthOfNumber; i++){
                output = output + longNum.charAt(accumulator);
                counter++;
                accumulator = accumulator + parseInt(newSeed.charAt(counter));
           }
           return(output)
      }

注意:尽管(或者说,因为)简洁和明显的优雅,这个算法在随机性方面绝不是一个高质量的算法。看看这个答案中列出的例子,会有更好的结果。

(最初改编自另一个答案的评论中提出的一个聪明的想法。)

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

您可以将seed设置为任何数字,只是避免为零(或Math.PI的任何倍数)。

在我看来,这个解决方案的优雅之处在于没有任何“神奇”数字(除了10000,它代表了您必须丢弃的最小数字数量,以避免奇怪的模式-请参阅值为10,100,1000的结果)。简洁也很好。

它比Math.random()稍微慢一点(2或3倍),但我相信它与任何其他用JavaScript编写的解决方案一样快。

编写自己的伪随机生成器非常简单。

戴夫·斯科塞斯的建议是有用的,但正如其他人指出的那样,它并不是完全均匀分布的。

然而,这并不是因为sin的整数参数。这只是因为sin的范围,恰好是一个圆的一维投影。如果取圆的角度,它就会是均匀的。

所以用arg(exp(i * x)) / (2 * PI)代替sin(x)

如果你不喜欢线性顺序,可以把它和异或混合一下。实际因素也没有那么重要。

要生成n个伪随机数,可以使用以下代码:

function psora(k, n) {
  var r = Math.PI * (k ^ n)
  return r - Math.floor(r)
}
n = 42; for(k = 0; k < n; k++) console.log(psora(k, n))

还请注意,当需要真实熵时,不能使用伪随机序列。

SIN(id + seed)是一个非常有趣的替代RANDOM函数,不能像SQLite一样播种:

https://stackoverflow.com/a/75089040/7776828

Antti Sykäri的算法很好,很短。我最初做了一个变种来取代JavaScript的Math。当你调用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没有的另一个功能:多个独立的随机生成器。如果您希望同时运行多个可重复的模拟,这一点尤其重要。