Erlang Central

Difference between revisions of "Random Numbers"

From ErlangCentral Wiki

 
m (random:uniform/1 never returns 0)
(2 intermediate revisions by 2 users not shown)
Line 5:Line 5:
 
== Solution ==
 
== Solution ==
  
Use random:uniform function from the standard Erlang distribution. It has two forms: (1) a no-argument version that returns a random float value in the range of 0.0 to 1.0, and (2) an version that takes a single integer (N) and returns a random integer in the range of 1 to N.  
+
Use random:uniform/0 and random:uniform/1 ; the first returns a random float uniformly distributed between [0.0,1.1], and the second returns a random integer uniformly distributed between [1,N].
 
<code>
 
<code>
 
1> random:uniform().
 
1> random:uniform().
9.23009e-2
+
0.159112
 
2> random:uniform(150).
 
2> random:uniform(150).
 
67
 
67
 
</code>
 
</code>
  
This code generates and prints a random integer between 25 and 75, inclusive:
+
To select random integers from [N,M], can use N+random:uniform(M-N).
<code>
+
3> io:fwrite("Random = ~B\n", [random:uniform(51) + 24]).
+
Random = 74
+
ok
+
</code>
+
 
+
In the example, we want to limit the range to 25 to 75, so we add 24 to the result of the random:uniform function. This means we really want a random number between 1 and 51, so we give the random:uniform function the argument 51 (since the generated number is always from 1 to N).
+
 
+
The canonical application for this kind of number generation is the random selection of an element from a vector:
+
<code>
+
4> Dict = dict:from_list([{1,$a}, {2,$b}, {3,$c}, {4,$d}, {5,$1},
+
4>  {6,$2}, {7,$3}]).                                           
+
{dict,7,
+
      16,
+
      16,
+
      8,
+
      80,
+
      48,
+
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
+
      {{[],
+
        [[3|99]],
+
        [[6|50]],
+
        [],
+
        [],
+
        [],
+
        [[2|98]],
+
        [[5|49]],
+
        [],
+
        [],
+
        [],
+
        [[1|97]],
+
        [[4|100]],
+
        [[7|51]],
+
        [],
+
        []}}}
+
5> dict:fetch(random:uniform(7), Dict).
+
100
+
6> io:fwrite("~c\n", [100]).
+
d
+
ok
+
</code>
+
  
Another common example is generating a random password:  
+
A common example is generating a random password:  
 
<code>
 
<code>
generate_8_password() ->
+
generate_password(N) ->
     lists:flatten(lists:foldl(fun(X,AccIn) ->
+
     lists:map(fun (_) -> random:uniform(90)+$\s+1 end, lists:seq(1,N)).
        [random:uniform(90) + 32|AccIn] end,
+
        [], lists:seq(1,8))).
+
  
7> generate_8_password().
+
3> generate_password(8).
"]VD'hEa;"
+
"l?8j#$&&"
8> generate_8_password().
+
4> generate_password(8).
"Zju!W9'Z"
+
"V<bFi(EW"
9> generate_8_password().
+
5> generate_password(8).
"uw6uX\"JF"
+
"irp^DXTz"
10> generate_8_password().
+
"-)3Ue=8n"
+
 
</code>
 
</code>
  
Line 77:Line 32:
 
It can support bigint values, so no special recipe is required for extremely large random numbers.  
 
It can support bigint values, so no special recipe is required for extremely large random numbers.  
  
[[Category:CookBook]]
+
[[Category:CookBook]][[Category:NumberRecipes]]

Revision as of 07:32, 24 March 2009

Problem

You want a random number from a given range. For example, you wish to randomly select one element from an array, simulate rolling a die in a game of chance, or generate a random password.

Solution

Use random:uniform/0 and random:uniform/1 ; the first returns a random float uniformly distributed between [0.0,1.1], and the second returns a random integer uniformly distributed between [1,N].

1> random:uniform().
0.159112
2> random:uniform(150).
67

To select random integers from [N,M], can use N+random:uniform(M-N).

A common example is generating a random password:

generate_password(N) ->
    lists:map(fun (_) -> random:uniform(90)+$\s+1 end, lists:seq(1,N)).

3> generate_password(8).
"l?8j#$&&"
4> generate_password(8).
"V<bFi(EW"
5> generate_password(8).
"irp^DXTz"

The Erlang random number generator is attributed to B.A. Wichmann and I.D.Hill, in 'An efficient and portable pseudo-random number generator', Journal of Applied Statistics. AS183. 1982. Also Byte March 1987.

It can support bigint values, so no special recipe is required for extremely large random numbers.