Reputation: 31070
Why do I get a list of identical numbers when I run randy:spawner()
below? I was expecting a list of random numbers. How could I change the code to achieve this?
-module(randy).
-export([randlister/2,spawner/0]).
-import(lists,[map/2]).
spawner() ->
[spawn(fun() -> randlister(X,random:uniform()) end) || X <- lists:seq(1,3)].
randlister(X, Randomnumber) ->
io:format("~p, ~p~n",[X,Randomnumber]).
Example output:
18> randy:spawner().
1, 0.4435846174457203
2, 0.4435846174457203
3, 0.4435846174457203
Upvotes: 0
Views: 584
Reputation: 4269
randy:spawner()
below?You must seed before generating random numbers. Random number sequences generated from the same seed will be exactly the same.
If a process calls uniform/0
or uniform/1
without setting a seed first, seed/0
is called automatically.
seed/0
will seed random number generation with a default (fixed) value,
which can be accessed through seed0/0
. On my laptop it always returns {3172,9814,20125}
with a default process dictionary.
In the simplest case, the solution from @EmilVikström is sufficient. However, I do recommend to keep track of the random number generation state so you can have a easier life when you're debugging.
A random number generation state is just a 3-tuple of integers, as returned by now()
. The seed is just the first state. Then you can use uniform_s/1
or uniform_s/2
to generate random numbers from specified states.
By using these functions with states, you can specify random number seeds outside your Erlang code, e.g. passing a seed through command-line options or environment variables.
Upvotes: 2
Reputation: 91983
You must seed the random number generator in each process:
spawner() ->
[spawn(fun() ->
random:seed(now()),
randlister(X,random:uniform())
end) || X <- lists:seq(1,3)].
Upvotes: 5