我将以下命令应用于两个erlang提示,它们都生成相同的随机数序列,这是否意味着它在Erlang语言中是伪随机的?我对基本原理感到好奇,因为在Java中,即使我为它提供相同的种子两次,序列也不会相同。非常感谢!
random:seed(6, 6, 6).
random:uniform(100).
random:uniform(100).
...
the generated sequence: 12, 27, 79, 58, 90, 25, ...
答案 0 :(得分:6)
您所描述的通常是传统的伪随机数生成器(PRNG)一直有效,包括Erlang的random
模块,我认为它实现Wichman-Hill,但今天的PRNG必然更复杂。在Erlang 18中,你会找到一个新的rand
module,它不会遇到你所描述的问题。
正如您在下面复制的shell会话中看到的那样,您可以在不播种的情况下从不同进程调用rand:uniform/0,1
函数,并且各个进程中的初始数字将不同:
1> rand:uniform().
0.10584199892675317
2> Self = self().
<0.1573.0>
3> f(R), spawn(fun() -> Self ! rand:uniform() end), receive R -> R end.
0.9124422823012622
4> f(R), spawn(fun() -> Self ! rand:uniform() end), receive R -> R end.
0.9476479571869831
5> f(R), spawn(fun() -> Self ! rand:uniform() end), receive R -> R end.
0.037189460750910064
6> f(R), spawn(fun() -> Self ! rand:uniform() end), receive R -> R end.
0.17698653918897836
第一个调用直接在shell进程中运行。然后我们获取shell的pid,将其存储到Self
中,并连续生成四个进程,每个进程将rand:uniform/0
的结果发送回shell,然后将其接收到R
。如您所见,四个衍生进程各自返回不同的值,所有这些值都与shell在首次运行rand:uniform/0
时获得的值不同。
如果您想要一个0-1以外范围的数字,请将整数N
传递给rand:uniform/1
,并且您将获得范围为1&lt; =的值V
V
&lt; = N
:
7> f(R), spawn(fun() -> Self ! rand:uniform(1234567) end), receive R -> R end.
510226
8> f(R), spawn(fun() -> Self ! rand:uniform(1234567) end), receive R -> R end.
562646
9> f(R), spawn(fun() -> Self ! rand:uniform(1234567) end), receive R -> R end.
250637
10> f(R), spawn(fun() -> Self ! rand:uniform(1234567) end), receive R -> R end.
820871
11> f(R), spawn(fun() -> Self ! rand:uniform(1234567) end), receive R -> R end.
121252