如果使用相同的种子,为什么 Erlang 会生成相同的随机数序列?

Why does Erlang generate the same sequence of random number if applying the same seed?

我将以下命令应用于两个 erlang 提示符,它们都生成相同的随机数序列,那么这是否意味着它是 Erlang 语言中的伪随机数?我很好奇其中的原理,因为在 Java 中,即使我为它提供两次相同的种子,序列也不会相同。非常感谢!

random:seed(6, 6, 6).
random:uniform(100).
random:uniform(100).
...

the generated sequence: 12, 27, 79, 58, 90, 25, ...

您所描述的通常是传统伪运行dom 数字生成器 (PRNG) 一直以来的工作方式,包括 Erlang 的 random 模块,我认为它实现了 Wichman-Hill, but today's PRNGs are necessarily more sophisticated. In Erlang 18 you'll find a new rand module不会遇到您描述的问题。

从下面复制的shell session可以看出,可以直接从不同的进程中调用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。如您所见,四个派生的进程每个 return 不同的值,所有这些值都不同于 shell 在它第一次 运行 rand:uniform/0.[=27= 时获得的值]

如果您想要 运行ge 中的数字不是 0-1,请将整数 N 传递给 rand:uniform/1,您将得到一个值 V在 运行ge 1 <= V <= 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