开发者

(P)RNG - Array of Random Numbers Created with a Seed

开发者 https://www.devze.com 2023-02-18 14:17 出处:网络
I want to create an array of random/pseudo-random numbers using a seed. I want the very same array to be created when the sa开发者_如何学编程me seed is used and I want to have little or no visible pat

I want to create an array of random/pseudo-random numbers using a seed. I want the very same array to be created when the sa开发者_如何学编程me seed is used and I want to have little or no visible pattern in the array. I'm working in JavaScript.

This is the random function I'm using, which I'm quite happy with (sorry, I forgot who the original author is):

function random(seed) {
    if (!seed) seed = new Date().getTime();
    seed = (seed*9301+49297) % 233280;
    return seed/(233280.0);
}

This is the array generation:

var superSeed = random();
var nRandom = 100;
var randomArray = new Array();
for (var i = 0 ; i < nRandom ; i++){
    randomArray.push(random((superSeed*10)+ (i)));
}

Somehow the pattern seems to be quite similar, no matter how often I run it. This question seems to be similar, but since it's about matrixes, I don't understand what's being said.

Thanks!


Having worked on similar things before I think we can use a fairly simple series, which takes two initial values and then you can get a lot more.

var a1,b1;

function InitSequence(v1, v2) {
    a1 = Math.pow(v1, 5) / Math.pow(v1, 3);
    b1 = Math.pow(v2, 8);
    lastrand = (a1 + b1) & 0x7fffffff;
}

function SequenceNext() {
    var alast = a1;
    var nextVal = (a1 + b1) & 0x7fffffff;
    b1 = alast;
    a1 = nextVal;
    return nextVal;
}

Then use it like this:

InitSequence(75, 21);
for (var i = 0; i < 99; i++) {
    v = SequenceNext();
}

I tested it like this:

var used = new Array();

InitSequence(75, 21); // any two values will do.

// fill 10k into array.

for (var i = 0; i < 9999; i++) {
    v = SequenceNext();
    if (undefined != used[v]) {
        used[v]++;
    } else used[v] = 1;

    //document.write(i+": "+v+"<br>");
}

// see if there any duplicates.
var tdup = 0;
for (xx in used) {
    ndup = used[xx];
    if (ndup > 1) {
        document.write("duplicated " + xx + " :" + ndup + "<br>");
        tdup += ndup;
    }
}
document.write("Total dups " + tdup + "<br>");

This is using the Fibonacci series, which in mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation

(P)RNG - Array of Random Numbers Created with a Seed

. I'm starting with different values - (v1^5) / (v1^3) and v2 ^ 8; otherwise it would only ever be identical.


I like the "Super 7" PRNG. It is simple, fast (although the other answer with the fib. sequence is fast as well), and has the interesting property:

  • In the entire range -- albeit of a meager of 32k -- there are no duplicates using the "Super 7" PRNG.

Multiple 7's can be joined to increase the number of bits and/or provide multiple seeds. This non-duplication property can exposed or folded.

(The sequence of a PRNG is always the same given a starting seed: it's the distribution and cycle lengths that are interesting -- it is these properties that may make them ideal in different cases where "true randomness" isn't desired).

Happy coding.


Maybe you should try this

function s_random() {
  s_random.m = 71402523; s_random.a = 409647; s_random.c = 1508892;
  s_random.seed = (s_random.seed*s_random.a + s_random.c) % s_random.m;
  return s_random.seed / s_random.m;
}
/* 
generate IV
s_random.seed = Math.floor((new Date).getTime()/10000);
*/
s_random.seed = 130324232; 

var CheckRandom = 4999999; var PrintSamples = 100; var used = new Array();

for (var i = 0; i < CheckRandom; i++) { v = (Math.ceil(Math.sqrt(s_random())* 1000000000) * 8); if (undefined != used[v]) { used[v]++; } else used[v] = 1; if ( i< PrintSamples) document.write(i+": "+v+"
"); } /* see if there are any duplicates. */ var tdup = 0; for (xx in used) { ndup = used[xx]; if (ndup > 1) { if (ndup < PrintSamples) document.write("duplicated " + xx + " :" + ndup + "
"); tdup += ndup; } } document.write("Total generated " + CheckRandom + "
"); document.write("Total duplicates " + tdup + "
");

Just got 5 million seeded, repeatable random numbers and no duplicates. Tested several times on Mac OS X with Safari.

Cheers, Karl

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号