From 1e3db41373c00e0aac68984fb52dbf0b115c5bcb Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 12 Aug 2020 14:57:16 -0700 Subject: [PATCH] Add deterministic LCG. --- README.md | 2 +- src/lcg.js | 9 +++++++++ src/simulation.js | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 src/lcg.js diff --git a/README.md b/README.md index eed3b26..0832339 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ Returns the node closest to the position ⟨*x*,*y*⟩ with the given search *ra # simulation.randomSource([source]) [<>](https://github.com/d3/d3-force/blob/master/src/simulation.js "Source")) -If *source* is specified, sets the function used to generate random numbers; this should be a function that returns a number between 0 (inclusive) and 1 (exclusive). If *source* is not specified, returns this simulation’s current random source which defaults to Math.random. A custom random source can be used to guarantee deterministic behavior. See also [*random*.source](https://github.com/d3/d3-random/blob/master/README.md#random_source). +If *source* is specified, sets the function used to generate random numbers; this should be a function that returns a number between 0 (inclusive) and 1 (exclusive). If *source* is not specified, returns this simulation’s current random source which defaults to a fixed-seed [linear congruential generator](https://en.wikipedia.org/wiki/Linear_congruential_generator). See also [*random*.source](https://github.com/d3/d3-random/blob/master/README.md#random_source). # simulation.on(typenames, [listener]) [<>](https://github.com/d3/d3-force/blob/master/src/simulation.js#L145 "Source") diff --git a/src/lcg.js b/src/lcg.js new file mode 100644 index 0000000..a13cf79 --- /dev/null +++ b/src/lcg.js @@ -0,0 +1,9 @@ +// https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use +const a = 1664525; +const c = 1013904223; +const m = 4294967296; // 2^32 + +export default function() { + let s = 1; + return () => (s = (a * s + c) % m) / m; +} diff --git a/src/simulation.js b/src/simulation.js index b47b4bd..7a1ff82 100644 --- a/src/simulation.js +++ b/src/simulation.js @@ -1,5 +1,6 @@ import {dispatch} from "d3-dispatch"; import {timer} from "d3-timer"; +import lcg from "./lcg.js"; export function x(d) { return d.x; @@ -22,7 +23,7 @@ export default function(nodes) { forces = new Map(), stepper = timer(step), event = dispatch("tick", "end"), - random = Math.random; + random = lcg(); if (nodes == null) nodes = [];