热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

erlang的随机数及random:uniform()函数

每次调用会更新进程字典里的random_seed变量,这样在同一个进程内每次调用random:uniform()时,随机数种子都不同,所以生成的随机数都不一样(调用完random:uniform(

  每次调用会更新进程字典里的random_seed变量,这样在同一个进程内每次调用random:uniform()时,随机数种子都不同,所以生成的随机数都不一样(调用完random:uniform()后,可以用get(random_seed)查看更新后的种子值)。

但是如果是不同的进程分别调用random:uniform(),因为随机种子更新的算法是一样的,所以每次各进程的随机数种子也是相同的,从而生成的随机数也是一样的,要想让不同进程生成的随机数不同,要手动为每个进程设置不同的种子,常用的是用erlang:now,比如:

random:seed(erlang:now()),random:uniform().

不过如果每个进程调用random:seed(erlang:now())太接近,种子值会比较接近,生成的随机数也会比较接近,更好的方法是用一个单独的进程来生成种子,保证每次的种子值相差比较大

Seed = {random:uniform(99999), random:uniform(999999), random:uniform(999999)}

然后每次调用random:uniform()前从该种子生成进程获取最新的种子值,seed()之。

 

下面为random.erl 的源码:

  1 %%
2 %% %CopyrightBegin%
3 %%
4 %% Copyright Ericsson AB 1996-2011. All Rights Reserved.
5 %%
6 %% The contents of this file are subject to the Erlang Public License,
7 %% Version 1.1, (the "License"); you may not use this file except in
8 %% compliance with the License. You should have received a copy of the
9 %% Erlang Public License along with this software. If not, it can be
10 %% retrieved online at http://www.erlang.org/.
11 %%
12 %% Software distributed under the License is distributed on an "AS IS"
13 %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14 %% the License for the specific language governing rights and limitations
15 %% under the License.
16 %%
17 %% %CopyrightEnd%
18 %%
19 -module(random).
20
21 %% Reasonable random number generator.
22 %% The method is attributed to B. A. Wichmann and I. D. Hill
23 %% See "An efficient and portable pseudo-random number generator",
24 %% Journal of Applied Statistics. AS183. 1982. Also Byte March 1987.
25
26 -export([seed/0, seed/1, seed/3, uniform/0, uniform/1,
27 uniform_s/1, uniform_s/2, seed0/0]).
28
29 -define(PRIME1, 30269).
30 -define(PRIME2, 30307).
31 -define(PRIME3, 30323).
32
33 %%-----------------------------------------------------------------------
34 %% The type of the state
35
36 -type ran() :: {integer(), integer(), integer()}.
37
38 %%-----------------------------------------------------------------------
39
40 -spec seed0() -> ran().
41
42 seed0() ->
43 {3172, 9814, 20125}.
44
45 %% seed()
46 %% Seed random number generation with default values
47
48 -spec seed() -> ran().
49
50 seed() ->
51 case seed_put(seed0()) of
52 undefined -> seed0();
53 {_,_,_} = Tuple -> Tuple
54 end.
55
56
57 %% seed({A1, A2, A3})
58 %% Seed random number generation
59
60 -spec seed({A1, A2, A3}) -> 'undefined' | ran() when
61 A1 :: integer(),
62 A2 :: integer(),
63 A3 :: integer().
64
65 seed({A1, A2, A3}) ->
66 seed(A1, A2, A3).
67
68 %% seed(A1, A2, A3)
69 %% Seed random number generation
70
71 -spec seed(A1, A2, A3) -> 'undefined' | ran() when
72 A1 :: integer(),
73 A2 :: integer(),
74 A3 :: integer().
75
76 seed(A1, A2, A3) ->
77 seed_put({(abs(A1) rem (?PRIME1-1)) + 1, % Avoid seed numbers that are
78 (abs(A2) rem (?PRIME2-1)) + 1, % even divisors of the
79 (abs(A3) rem (?PRIME3-1)) + 1}). % corresponding primes.
80
81
82 -spec seed_put(ran()) -> 'undefined' | ran().
83
84 seed_put(Seed) ->
85 put(random_seed, Seed).
86
87 %% uniform()
88 %% Returns a random float between 0 and 1.
89
90 -spec uniform() -> float().
91
92 uniform() ->
93 {A1, A2, A3} = case get(random_seed) of
94 undefined -> seed0();
95 Tuple -> Tuple
96 end,
97 B1 = (A1*171) rem ?PRIME1,
98 B2 = (A2*172) rem ?PRIME2,
99 B3 = (A3*170) rem ?PRIME3,
100 put(random_seed, {B1,B2,B3}),
101 R = B1/?PRIME1 + B2/?PRIME2 + B3/?PRIME3,
102 R - trunc(R).
103
104 %% uniform(N) -> I
105 %% Given an integer N >= 1, uniform(N) returns a random integer
106 %% between 1 and N.
107
108 -spec uniform(N) -> pos_integer() when
109 N :: pos_integer().
110
111 uniform(N) when is_integer(N), N >= 1 ->
112 trunc(uniform() * N) + 1.
113
114
115 %%% Functional versions
116
117 %% uniform_s(State) -> {F, NewState}
118 %% Returns a random float between 0 and 1.
119
120 -spec uniform_s(State0) -> {float(), State1} when
121 State0 :: ran(),
122 State1 :: ran().
123
124 uniform_s({A1, A2, A3}) ->
125 B1 = (A1*171) rem ?PRIME1,
126 B2 = (A2*172) rem ?PRIME2,
127 B3 = (A3*170) rem ?PRIME3,
128 R = B1/?PRIME1 + B2/?PRIME2 + B3/?PRIME3,
129 {R - trunc(R), {B1,B2,B3}}.
130
131 %% uniform_s(N, State) -> {I, NewState}
132 %% Given an integer N >= 1, uniform(N) returns a random integer
133 %% between 1 and N.
134
135 -spec uniform_s(N, State0) -> {integer(), State1} when
136 N :: pos_integer(),
137 State0 :: ran(),
138 State1 :: ran().
139
140 uniform_s(N, State0) when is_integer(N), N >= 1 ->
141 {F, State1} = uniform_s(State0),
142 {trunc(F * N) + 1, State1}.
View Code

 random:seed 由进程字典put存了随机数,random:uniform则get取了随机数,而它同时又put了新的随机数.

 

如果一开始直接调用,random:uniform/0,  则一开始 get(random_seed)为undefined,后面每次生产的种子的规则都是根据其业务规则生成。 但如果是 先调用random:seed/1 ,则它先生成了随机种子,put到random_seed 的进程字典中,后面依次调用random:uniform/0的时候,则从random_seed的进程字典中取出随机种子,则不是undefined,后面根据其业务规则,生成随机数.


推荐阅读
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • ubuntu用sqoop将数据从hive导入mysql时,命令: ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
author-avatar
幸福的小兔子3
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有