非常教程

Erlang 20参考手册

stdlib

rand

模块

模块摘要

伪随机数生成

描述

该模块提供了一个伪随机数发生器。该模块包含许多算法 xoroshiro116+ and xorshift1024* algorithms by Sebastiano Vigna. Ziggurat Method by Marsaglia and Tsang 。均匀分布算法使用正态分布算法使用均匀分布算法的顶层。

对于某些算法,为并行计算提供了生成不重叠序列的跳变函数.。跳转函数执行等效于执行大量重复调用计算新状态的计算。

提供了下列算法:

exrop

Xoroshiro116 +,58位精度和2 ^ 116-1的周期

跳转函数:相当于2^64次调用

exs1024s

Xorshift1024 *,64位精度和2 ^ 1024-1的周期

跳转功能:相当于2 ^ 512个调用

exsp

Xorshift116 +,精度为58位,周期为2 ^ 116-1

跳转功能:相当于2 ^ 64个调用

这是以前默认算法的修正版本,现在已被Xoroshiro116 +(exrop)取代。由于没有原生的58位旋转指令,这个算法执行的速度比(比如<15%)要快一些exrop。看到了algorithms' homepage

默认算法是exrop(Xoroshiro116 +)。如果需要特定算法,请确保始终用于seed/1初始化状态。

未记录(旧)算法已被弃用,但仍旧实施,因此依赖它们的旧代码将产生与以前相同的伪随机序列。

在实现现在未公开的算法时存在许多问题,这就是为什么它们被弃用的原因。新算法有点慢,但没有这些问题:

统一的整数范围在概率分布上有一个偏差,对于小范围来说这是不明显的,但对于大范围小于发生器的精度,产生一个低数字的概率可能是一个高概率的两倍。

统一整数范围大于或等于发生器的精度时,使用浮点回退,该回退仅使用小于请求范围的52位进行计算,因此并非所有请求范围内的数字都可能产生。

均匀的浮体具有不均匀的密度,因此小的值(即小于0.5)具有较小的间隔,随着生成的值接近0.0而减小,尽管对于足够大的子范围仍然均匀分布。新算法生成N * 2.0 ^( - 53)形式的均匀分布的浮体,因此具有相同的间距。

每次请求一个随机数时,将使用一个状态来计算它并产生一个新状态。该状态可以是隐式的,也可以是明确的参数和返回值。

具有隐式状态的函数使用进程字典变量rand_seed来记住当前状态。

如果进程调用uniform/0或者uniform/1不先设置种子,seed/1则会使用默认算法自动调用并创建非常量种子。

具有显式状态的函数从不使用进程字典。

例子:

简单的使用;如果尚未完成,则使用非常量种子创建并种子默认算法:

R0 = rand:uniform(),
R1 = rand:uniform(),

使用指定的算法:

_ = rand:seed(exs1024s),
R2 = rand:uniform(),

使用具有常量种子的指定算法:

_ = rand:seed(exs1024s, {123, 123534, 345345}),
R3 = rand:uniform(),

使用带有非常数种子的FunctionalAPI:

S0 = rand:seed_s(exrop),
{R4, S1} = rand:uniform_s(S0),

创建一个标准的正常偏差:

{SND0, S2} = rand:normal_s(S1),

创建一个平均值为3和方差为0.5的正常偏差:

{ND0, S3} = rand:normal_s(-3, 0.5, S2),

内置的随机数生成器算法不具有密码强度。如果需要密码强的随机数生成器,请使用类似的东西crypto:rand_seed/0

对于所有这些生成器,最低位(s)的随机行为比所有其他位少一些。exrop(和exsp)1位,以及3位exs1024s。例如,请参阅生成器源代码中的说明: Xoroshiro128+

除了通过BigCrush之外,该生成器还通过了PractRand测试套件
直至(并包括)16TB,除二进制等级测试外,
由于最低位是LFSR而失败; 所有其他位都通过
试验。我们建议使用符号测试来提取一个随机布尔值。

如果这是一个问题;生成一个布尔类型,如下所示:

(rand:uniform(16) > 8)

对于一般范围,N = 1用于exropN = 3exs1024s

(((rand:uniform(Range bsl N) - 1) bsr N) + 1)

当从一个整数转换时,这个模块中的浮点生成函数浪费最小的位,所以它们避免了这个障碍。

数据类型

builtin_alg() =

exs64 | exsplus | exsp | exs1024 | exs1024s | exrop

alg() =builtin_alg()| atom()

alg_handler() =

#{type :=alg(),

bits => integer() >= 0,

weak_low_bits => integer() >= 0,

max => integer() >= 0,

next :=

fun((alg_state()) -> {integer() >= 0,alg_state()}),

uniform => fun((state()) -> {float(),state()}),

uniform_n =>

fun((integer() >= 1,state()) -> {integer() >= 1,state()}),

jump => fun((state()) ->state())}

alg_state() =

exs64_state()|

exsplus_state()|

exs1024_state()|

exrop_state()|

term()

state() = {alg_handler(),alg_state()}

算法依赖状态。

export_state() = {alg(),alg_state()}

算法依赖状态,可以打印或保存到文件中。

exs64_state()

算法特定内部状态

exsplus_state()

算法特定内部状态

exs1024_state()

算法特定内部状态

exrop_state()

算法特定内部状态

出口

export_seed() -> undefined | export_state()

以外部格式返回随机数字状态。与...一起使用seed/1

export_seed_s(State :: state()) -> export_state()

以外部格式返回随机数生成器状态。与...一起使用seed/1

jump() -> NewState :: state()

在执行跳转计算到流程字典中的状态之后,返回状态。

如果not_implemented没有为流程字典中的状态指定的算法实施跳转功能,则此函数会生成错误异常。

jump(State :: state()) -> NewState :: state()

返回执行跳转计算到给定状态后的状态。

not_implemented当在该状态下指定的算法没有实现跳转功能时,该函数会生成一个错误异常。

normal() -> float()

返回标准的正常偏差浮点数(即平均值为0,标准偏差为1),并更新过程字典中的状态。

normal(Mean :: number(), Variance :: number()) -> float()

返回一个正常的N(Mean,Variance)偏离浮点数并更新流程字典中的状态。

normal_s(State :: state()) -> {float(), NewState :: state()}

对于指定的状态,返回标准正常偏离的浮点数(即平均值为0,标准偏差为1)和新状态。

normal_s(Mean :: number(),

Variance :: number(),

State0 :: state()) ->

{float(), NewS :: state()}

对于指定的状态,返回正常的N(平均值,方差)偏差浮动值和新的状态值。

seed(AlgOrStateOrExpState ::

builtin_alg() | state() | export_state()) ->

state()

如果AlgOrStateOrExpState是算法,则使用指定的算法和随时间变化的数据来生成随机数生成。

否则在流程字典中重新创建导出的种子,并返回状态。另见export_seed/0

seed(Alg :: builtin_alg(),

Seed :: {integer(), integer(), integer()}) ->

state()

使用指定的算法和进程字典中的整数种子随机数生成并返回状态。

seed_s(AlgOrStateOrExpState ::

builtin_alg() | state() | export_state()) ->

state()

如果AlgOrStateOrExpState是算法,则使用指定的算法和随时间变化的数据来生成随机数生成。

否则,重新创建导出的种子并返回状态。另见export_seed/0

seed_s(Alg :: builtin_alg(),

Seed :: {integer(), integer(), integer()}) ->

state()

用指定的算法和整数种子随机数生成并返回状态。

uniform() -> X :: float()

返回均匀分布在值范围内的随机float,0.0 =< X < 1.0并更新进程字典中的状态。

生成的数字形式为N * 2.0 ^( - 53),即; 在间隔中等间隔。

警告

这个函数可能会返回0.0到某些应用程序可能致命的地方。如果这是不希望的,你可以用它(1.0 - rand:uniform())来获得间隔0.0 < X =< 1.0

如果两个端点都不需要,您可以测试并重新尝试,如下所示:

my_uniform() ->
    case rand:uniform() of
        0.0 -> my_uniform();
	X -> X
    end
end.

uniform(N :: integer() >= 1) -> X :: integer() >= 1

对于指定的整数N >= 1,返回一个均匀分布在值范围内的随机整数,1 =< X =< N并更新流程字典中的状态。

uniform_s(State :: state()) -> {X :: float(), NewState :: state()}

对于指定状态,返回均匀分布在值范围0.0 =< X < 1.0和新状态中的随机float 。

生成的数字形式为N * 2.0 ^( - 53),即;在间隔中等间隔。

警告

这个函数可能会返回0.0到某些应用程序可能致命的地方。如果这是不希望的,你可以用它(1.0 - rand:uniform(State))来获得间隔0.0 < X =< 1.0

如果两个端点都不需要,您可以测试并重新尝试,如下所示:

my_uniform(State) ->
    case rand:uniform(State) of
        {0.0, NewState} -> my_uniform(NewState);
	Result -> Result
    end
end.

uniform_s(N :: integer() >= 1, State :: state()) ->

{X :: integer() >= 1, NewState :: state()}

对于指定的整数N >= 1和状态,返回一个在值范围内均匀分布的随机整数1 =< X =< N和一个新状态。

Erlang 20

Erlang 是一种通用的面向并发的编程语言,可应付大规模开发活动的程序设计语言和运行环境。

主页 https://www.erlang.org/
源码 https://github.com/erlang/otp
版本 20
发布版本 20.1