P5.js: randomSeed() with similar values produces similar sequences

Created on 10 Apr 2019  路  3Comments  路  Source: processing/p5.js

The first value returned from random() after a call to randomSeed(n) is often very similar to the first value returned from random() after a call to randomSeed(n+1). This sketch demonstrates the problem:

0 62 89 84 64 18
1 62 98 52 68 85
2 62 7 21 72 51
3 62 16 89 75 18
4 62 25 58 79 84
5 62 34 26 83 51
6 62 43 95 86 18
7 62 52 63 90 84
8 62 61 32 94 51
9 62 70 0 98 18
10 62 79 69 1 84
11 62 88 37 5 51
12 62 98 5 9 18

The first column is the value passed to randomSeed(), the second column is the first value returned from int(random(100)), the third column is the next value returned from int(random(100)), etc. You can see that the first value returned from random() after seeding rounds to the same number. The second value for similar random seeds is also very similar (i.e., randomSeed(n); random(); console.log(random()) will always display a number roughly 0.9 more than randomSeed(n+1); random(); console.log(random()), taking into account the "wrap-around" when the value exceeds 1). This behavior, as far as I can tell, is not typical for pseudorandom number generators.

This behavior becomes a problem when you want to use randomSeed() to produce stable random numbers over time and space; i.e., this sketch sets the random seed for each position in a 2D grid, and should have rectangles of uniformly distributed sizes; instead, it has a noticeable pattern. Likewise, this sketch, which seeds the random number generator with the frame count (source code reproduced below) should probably show the ellipse moving to uniformly distributed positions on the screen; instead, the ellipse moves slowly across the screen as the first value returned from random() increases with the value passed to randomSeed():

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(40);
  noStroke();
  fill(255);
  randomSeed(frameCount);
  ellipse(random(width), height/2, 50, 50);
}

Nature of issue?

  • [x] Found a bug

Most appropriate sub-area of p5.js?

  • [x] Math

Details about the bug:

  • p5.js version: 0.7.3

All 3 comments

Yes, I can reproduce this!! :stuck_out_tongue_closed_eyes:
@lmccart this is because of parameter (m, a and c) used to generate random numbers. we can replace it with values used by other librarys.

This is a sketch that uses the same parameter values used in p5 currently. that generates mostly the same values with continues seed.

And here is a sketch that uses glibc's parameter values and generates more random numbers with continues seeds.

After a bit more research, I guess this problem is typical of linear congruential generators. So maybe this issue is less a bug and more of a feature request! For the reasons I mentioned, it would be nice if the seed didn't have such an out-sized effect on the sequence of numbers. One solution might be to hash the value passed to randomSeed() (with a fast hashing algorithm e.g. xxhash) before using it in the random number generator.

@aparrish As you have found, this is a "feature" (or rather limitation) of this particular type of pseudo random number generator. It has the name "pseudo" in it because it doesn't actually generate random numbers which in this case shows up as similar values on initial numbers with similar seeds.

Using a hashing algorithm to get around this is rather overkill. You can achieve the same result by just seeding with regular unseeded random number (A good hashing algorithm is also a good PRNG) and not using similar seeds.

Also in most cases I don't think it will be a big problem in most sketches that would be using seeded random numbers.

Was this page helpful?
0 / 5 - 0 ratings