0

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
Lee
  • 29,398
  • 28
  • 117
  • 170

2 Answers2

5

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)].
Emil Vikström
  • 90,431
  • 16
  • 141
  • 175
  • 1
    See also [this question](http://stackoverflow.com/questions/10318156/how-to-create-a-list-of-1000-random-number-in-erlang/10319823#10319823) – Tilman Nov 14 '12 at 07:46
2

Why do I get a list of identical numbers when I run 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.

How could I change the code to achieve this?

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.

  • When you are testing/debugging, fix the seed so that each time you run your program will give the same result.
  • When you are satisfied, change the seed in order to (probably) continue debugging :-)
  • When you are ready for production, just pass the current time (or whatever) as the seed, so you can have some randomness.
Xiao Jia
  • 4,169
  • 2
  • 29
  • 47