随机数生成及其在统计模拟中的应用

随机数生成及其在统计模拟中的应用
随机数生成及其在统计模拟中的应用

随机数生成及其在统计模拟中的应用

黄湘云

关键词:随机数; 统计检验; 模拟

审稿:郎大为、边蓓蕾;编辑:吴佳萍

揭秘统计软件如 R,Octave,Matlab 等使用的随机数发生器,然后做一些统计检验,再将其应用到独立随机变量和的模拟中,最后与符号计算得到的精确结果比较。除特别说明外,文中涉及到的随机数都是指伪随机数,发生器都是指随机数发生器。

背景

随机数的产生和检验方法是蒙特卡罗方法的重要部分,另外两个是概率分布抽样方法和降低方差提高效率方法。在 20 世纪 40 年代中期,当时为了原子弹的研制,乌拉姆(S.Ulam)、冯诺依曼(J.von Neumann)和梅特罗波利斯(N. Metropolis)在美国核武器研究实验室创立蒙特卡罗方法。当时出于保密的需要,与随机模拟相关的技术就代号“蒙特卡罗”。早期取得的成果有产生随机数的平方取中方法,取舍算法和逆变换法等。这两个算法的内容见统计之都王夜笙的文章。

随机数生成

讲随机数发生器,不得不提及一个名为 Mersenne Twister(简称 MT)的发生器,它的周期长达219937?1,现在是R 、Octave 和 Matlab等软件(较新版本)

的默认随机数发生器。

Matlab通过内置的rng函数指定不同的发生器,其中包括1995年Matlab采用George Marsaglia 在1991年提出的借位减(subtract with borrow,简称SWB)发生器。在Matlab中,设置如下命令可指定发生器及其状态,其中1234是随机数种子,指定发生器的状态,目的是重复实验结果,v5uniform是发生器的名字。

rng(1234, 'v5uniform') Octave 通过内置的rand函数指定发生器的不同状态,为获取相同的两组随机数,state 参数得设置一样,如1234(你也可以设置为

别的值)。Octave已经放弃了老版本内置的发生器,找不到命令去指定早期的

发生器,这个和 Matlab 不一样。

rand ('state',1234)

rand(1,5)

0.9664535 0.4407326 0.0074915 0.9109760 0.9392690

rand ('state',1234)

rand(1,5)

0.9664535 0.4407326 0.0074915 0.9109760 0.9392690

Python的numpy模块也采用MT发生器,类似地,通过如下方式获得相同的两组随机数

import numpy as np

a = np.random.RandomState(1234)

a.rand(5)

array([ 0.19151945, 0.62210877, 0.43772774, 0.78535858,

0.77997581])

a = np.random.RandomState(1234)

a.rand(5)

array([ 0.19151945, 0.62210877, 0.43772774, 0.78535858,

0.77997581])

R的默认发生器也是 MT 发生器,除了设置随机数种子的 seed 参数,还可以通过kind参数指定其他发生器,normal.kind参数指定产生正态分布随机数的发生器,下面也使用类似的方式产生两组完全一样的随机数。

set.seed(seed, kind = NULL, normal.kind = NULL)

set.seed(1234,kind = "Mersenne-Twister", normal.kind = "Inversion") # 默认参数设置

runif(5)

[1] 0.1137034 0.6222994 0.6092747 0.6233794 0.8609154

set.seed(1234,kind = "Mersenne-Twister", normal.kind = "Inversion") # 默认参数设置

runif(5)

[1] 0.1137034 0.6222994 0.6092747 0.6233794 0.8609154

SWB发生器中“借位相减”步骤是指序列的第i个随机数z i要依据如下递推关

系产生,z i=z i+20?z i+5?b下标i,i+20,i+5都是对32取模的结果,z i+20与z i+5做减法运算,b是借位,其取值与前一步有关,当z i是正值时,下一步

将b置为0,如果计算的z i是负值,在保存z i之前,将其值加1,并在下一步,将b的值设为2?53。

下面关于随机数生成的效率和后面的统计检验,都以生成224个为基准,是1600

多万个,取这么多,一方面为了比较编程语言实现的发生器产生随机数的效率,另一方面是后面的游程检验需要比较大的样本量。

Matlab内置的发生器及大部分的函数,底层实现都是 C 或者 Fortran,MathWorks创始人Cleve B. Moler是数值分析领域著名的LINPACK和EISPACK 包的作者之一,他当年做了很多优化和封装,进而推出Matlab,只要是调用内置函数,效率不会比C差,自己写的含有循环、判断等语句的代码,性能就因人而异了,对大多数人来说,性能要比C低。这里比较Matlab内置SWB发生器(就当作是C语言实现的好了和用Matlab重写的SWB发生器的效率,代码如下:

% matlab code

tic % 大约几秒

rng(1234, 'v5uniform') % 调用SWB发生器

x = rand(1,2^24);

toc

% octave code

id = tic % 时间耗费大约一小时

randtx('state',0)

x = randtx(1,2^24);

toc (id)

randtx不是Matlab和Octave内置的函数,而是Cleve B.Moler基于Matlab实现的SWB发生器,也是100多行包含嵌套循环等语句的Matlab代码打包的函数,上面的代码运行时间差异之大也就不难理解了,为了能在Octave上跑,我做了少量修改,Octave软件版本为4.2.1,安装Octave时,Blas选择OpenBlas,为了后续检验,在获得随机数后,将其保存到磁盘文件random_number.matsave -mat random_number.mat x R,Octave,Matlab和Python内置的发生器都是MT 发生器,与之实现有关的数学库,也是Blas,虽然有开源和进一步优化的商业版本之分,但是矩阵乘法,向量乘法之类运算的效率也就半斤八两,Julia语言官网给出了一个标准测试2。

不同语言的性能表现(C语言在算法中的表现为基准,时间记为1.0)

这里再给出用C语言实现的MT发生器,产生同样多的随机数,只需要10秒左右,

其中包含编译和写随机数到文件的时间,实际产生随机数的时间应该远小于这个

时间。(程序运行环境环境Dev-C++ 5.11,用64位的GCC编译)。

统计检验

随机数的检验是有一套标准的,如George Marsaglia开发的DieHard检验程序,

检验的内容很丰富。这篇文章只能算初窥门径,R内产生真随机数的包是Dirk

Eddelbuettel开发的random包,它是连接产生真随机数网站的接口。

相关性检验

先来一个简单的,就用R产生的两个独立同均匀分布样本,调用cor.test做相

关性检验,看看这两组数是不是足够独立同分布,通过眼球验证,随着样本量增

大,相关性趋于0,相关性弱到可以视为独立。如下图所示

library(ggplot2)

library(viridisLite)

library(viridis)

set.seed(1234)

corr<- rep(0, 1000)

for(i in seq(from = 1000, to = 1000000, by = 1000)) {

corr[i/1000] <- cor.test(runif(i, min = 0, max = 1), runif(i, min = 0, max = 1))$estimate}

ggplot(data.frame(x = seq(1000), y = corr), aes(x = x, y = y)) +

geom_hex(show.legend = FALSE) +

scale_fill_viridis(direction = -1) + xlab("Sample size *10^3")

+ ylab("Correlation")

分布检验

检验产生的随机数是否服从指定的分布:原假设是样本来自指定的分布,计算的P值比较大,就不能拒绝原假设。

ks.test(runif(1000), "punif") #分布检验

##

## One-sample Kolmogorov-Smirnov test

##

## data: runif(1000)

## D = 0.022302, p-value = 0.7025

## alternative hypothesis: two-sided

检验两样本是否来自同一分布:原假设是两样本来自同一分布,计算的P值比较小,就表示两样本不是来自同一分布。

ks.test(runif(1000), runif(1000)) #同分布检验

##

## Two-sample Kolmogorov-Smirnov test

##

## data: runif(1000) and runif(1000)

## D = 0.04, p-value = 0.4005

## alternative hypothesis: two-sided

从结果来看,R内置的随机数发生器通过了检验(嘿嘿,这是肯定的!!)。游程检验

游程检验对随机数序列的随机性检验,不对序列做任何分布假设,不同于上面的相关性检验和省略没讲的特征统计量(如均值和方差)的检验。先对随机性略作解释,简单起见,我们考虑0-1序列,抛掷均匀的硬币1000次,正面向上记为1,反面向上记为0,这是一个离散的均匀分布,每一次抛掷硬币都无法准确地判断出现的是正面还是反面,若记录的序列中0和1相对集中的出现,不是随机,0和1交替出现,呈现周期性也不是随机,除了这两种情况基本就是随机了。

游程检验的原假设是序列满足随机性,序列一旦生成,就是有序的,因为游程检验需要固定位置,再数上升(下降)的游程数,当计算的P值比较大时,不能拒绝原假设,即不能否认这个序列是随机的。对上述0-1序列进行模拟,然后检验,如下所示

library(tseries)

x <- sample(c(0, 1), 1000, replace = TRUE, prob = c(1/2, 1/2))

runs.test(factor(x))

##

## Runs Test

##

## data: factor(x)

## Standard Normal = 0.45116, p-value = 0.6519

## alternative hypothesis: two.sided

现在用游程检验比较SWB发生器(Octave/Matlab版)、MT发生器(R语言版)和MT发生器(C语言版)。对于一般的实数序列,得先指定一个阈值,记为delta,然后比较序列中的值和delta的大小关系,这里类似数上升或下降的游程长度(runs length),基于这样一个事实:如果序列表现随机,则序列中两个小于delta的值,间隔越远出现的次数越少。可以这样理解,还是以上面抛硬币的例子来说,出现了很多次正面,那么下一次抛掷倾向于出现反面,这是一条人人可接受的经验。

为了把这条经验可视化出来,对序列做如下操作:先给定阈值delta为0.01(也可以取别的值),取出序列中的值小于delta的位置,位置序列前面添加0,再差分,然后每个值减1,得到新序列,新序列中的值为0,表明原序列连续两个值小于delta,新序列中的值为1,表明间隔1个数小于delta,新序列中的值为2,表明间隔2个数小于delta,依次类推….. 统计所有的情况,用直方图显示,这就获得游程长度与间隔的关系图(间隔数取到100足可示意)。

library(gridExtra)

library(R.matlab)

# 游程频数直方图

run_test_fun<- function(x, string, delta) {

n <- length(x)

len<- diff(c(0, which(x < delta), n + 1)) - 1

ggplot(data.frame(x = len[len< 101]), aes(x, fill = ..count..)) + scale_fill_viridis(direction = -1) +

geom_histogram(binwidth = 1, show.legend = FALSE) +

xlab(string) + ylab("")

}

set.seed(1234) # R默认采用Mersenne Twister发生器

r_data<- runif(2^24, 0, 1); # R内生成均匀分布随机数

matlabv5_data <- readMat("random_number.mat") # 读取Octave生成的均匀分布随机数

temp <- read.table(file = "random_number.txt") # 读取C语言生成的均匀分布随机数

c_data<- c(as.matrix(t(temp)))

p1 <- run_test_fun(x = r_data, string = "R", delta = 0.01)

p2 <- run_test_fun(x = matlabv5_data$x, string = "Matlab v5", delta = 0.01)

p3 <- run_test_fun(x = c_data, string = "C", delta = 0.01)

grid.arrange(p1, p2, p3, ncol=3)

从图中可以看出MT发生器通过了检验,SWT发生器没有通过,在间隔数为27的位置,有一条沟,按规律游程长度不应该减少这么多,这是因为SWB发生器“借位减”步骤,取模32的运算和5一起消耗了间隔为27的数量(读者可以按借位减的递推关系思考是如何消耗的),导致不符合随机性的要求,该算法细节参见Cleve B. Moler的书《Numerical Computing with MATLAB》第9章第267页。

应用

两个均匀分布的统计模拟

随机变量X1,X2iid~

某分布(比如二项分布,泊松分布,正态分布,指数分布,卡方分布,伽马分布),则X1+X2也服从该分布。常见的均匀分布是否具有这样的可加性?具体地说,就是X1,X2iid~U(0,1),X1+X2是否服从U(0,2)?如果有一台电脑在旁边,我首

先想到的就是敲三五行代码,画个散点图、直方图,看图说话。

set.seed(1234)

x <- runif(10000, min = 0, max = 1)

y <- runif(10000, min = 0, max = 1)

z <- x + y

plot(z) # 散点图

hist(z) # 直方图

为美观起见,从viridis包调用viridis调色板,颜色越深的地方,相应的数值越大,不管是此处geom_hex绘制的六角形热图,还是geom_histogram绘制的直方图,都遵循这个规律。

ggplot(data.frame(x = seq(10000), y = z), aes(x = x, y = y)) + geom_hex(show.legend = FALSE) +

scale_fill_viridis(direction = -1) + xlab("") + ylab("")

显然这不是均匀分布,在z=1

处,散点比较集中,看起来有点像正态分布。如果往中心极限定理上靠,将作如

下标准化Y?2=X1+X2?2?121+X2?1)则Y?2的期望为0,

方差为1。

p4 <- ggplot(data.frame(x = z), aes(x, fill = ..count..)) + scale_fill_viridis(direction = -1) +

geom_histogram(bins=20, show.legend = FALSE) + xlab("") +

ylab("")

p5 <- ggplot(data.frame(x = sqrt(6)*(z-1)), aes(x, fill = ..count..)) + scale_fill_viridis(direction = -1) +

geom_histogram(bins = 20, show.legend = FALSE) + xlab("") +

ylab("")

grid.arrange(p4, p5, ncol=2)

只是变换后的图像和之前基本一致,那么现在看来眼球检验不好使了,那就上P

值呗!

ks.test(sqrt(6)*(z-1), "pnorm") # 分布检验

##

## One-sample Kolmogorov-Smirnov test

##

## data: sqrt(6) * (z - 1)

## D = 0.025778, p-value = 3.381e-06

## alternative hypothesis: two-sided

也不是正态分布,既然如此,那就在两个随机变量的情况下,把精确分布推导出

来。

精确分布的推导及计算

课本如《概率论与数理统计教程》采用卷积的方法求分布函数,这种方法实行

起来比较繁琐,也不利于后续编程,下面考虑用特征函数的方法求。我们知道标

准均匀分布的特征函数φ(t)=e it?1it

考虑X1和X2相互独立,它们的和用S2表示,则随机变量S2的特征函数为

φ2(t)=φ(t)?φ(t)=(e it?1it)2=2(1?cos(t))e it t2只要满足条件

∫+∞?∞|φ2(t)|dt<∞S2的密度函数就可以表示为p2(x)=12π∫+∞?∞e ?itxφ2(t)dt经计算∫+∞?∞

|φ2(t)|dt=4∫+∞01cos(t)t2dt=4∫+∞0(sin(x)x)2dx=2π

那么p2(x)=12π∫+∞?∞e?itxφ2(t)dt=2π∫+∞0(1?

cos(t))cos(t(1?x))t2dt=2π∫+∞0cos(2(1?x)t)(sin(t)t)2dt

一般地,n个独立随机变量的和φn(t)=(e it?1it)n=(sin(t/2)e it2t/2)n 那么,同理p n(x)=2π∫+∞0cos(2(n/2?x)t)(sin(t)t)n dt

要说数值计算一个p(x)近似值,是一点问题没有!且看

integrate(function(t,x,n) 2/pi*cos((n-2*x)*t)*(sin(t)/t)^n ,x = 1,n = 2,lower = 0,upper = Inf,subdivisions = 1000)

## 0.9999846 with absolute error<6.6e-05那如果要把上面的积分积出来,获得一个精确的表达式,在n=2的时候还可以手动计算,主要使用分部积分,余弦积化和差公式和一个狄利克雷积分公式∫+∞0sin(ax)x dx=π2sgn(a),过程略,最后算得p2(x)=12((2?x)sgn(2?x)?xsgn(?x))?(1?x)sgn(1?x)=12(|x|+|x?2|)?|x?1|,0

p2(x)的密度函数图象如下:

fun_p2_1 <- function(x) { 1 / 2 * (abs(x - 2) - 2 * abs(x - 1) + abs(x)) } fun_p2_2 <- function(x) {

x <- as.matrix(x)

tempfun<- function(x) {

integrate(function(t, x, n) 2 / pi * cos((n - 2 * x) * t) * (sin(t) / t) ^ n,

x=x, n= 2,lower = 0, upper = Inf, subdivisions = 1000)$value

}

return( sapply(x,tempfun) )

}

ggplot(data.frame(x = c(0, 2)), aes(x = x)) +

stat_function(fun = fun_p2_2, geom = "point", colour = "#2A768EFF") + stat_function(fun = fun_p2_1, geom = "line", colour = "#78D152FF")

从图中可以看出,两种形式的密度函数在数值计算的结果上很一致,当

n=100,1000时,含参量积分的表示形式就很方便啦!任意给定一个n,符号

计算上面的含参量积分,这个时候还是用软件计算比较合适,R的符号计算仅限于求导,积分运算需要借助Ryacas,rSymPy,可惜的是,这些包更新缓慢,即使∫+∞0sin(at)t dt

也算不出来,果断直接使用Python的sympy模块

from sympy import *

a=symbols('a', real = True)

t=symbols('t', real = True, positive = True)

print(integrate(sin(a*t)/t, (t, 0, oo)))

## Piecewise((pi/2, Eq(Abs(periodic_argument(polar_lift(a)**2, oo)), 0)), (Integral(sin(a*t)/t, (t, 0, oo)), True))

初次见到这样的结果,是不是一脸mb,翻译一下,就是

π2for∣∣periodic argument(polar_lift2(a),∞)∣∣=0∞∫01t sin( at)dtotherwise稍为好点,但是还是有一大块看不懂,那个绝对值里是什么

3?还是不要纠结了,路远坑多,慢走不送啊!话说要是计算p2(x)密度函数里的积分,

from sympy import *

x=symbols('x', real=True)

t=symbols('t', real=True,positive=True)

print(integrate(2/pi*cos(2*t*(1-x))*(sin(t)/t)**2,(t,0,oo)))

## Piecewise((Piecewise((2*x, (2*x - 2)**2/4 < 1), (0, 4/(2*x - 2)**2 < 1), (meijerg(((1/2,), (1, 1, 3/2)), ((1/2, 1, 0), (1/2,)),

polar_lift(-2*x + 2)**2/4), True))/2,

Eq(Abs(periodic_argument(polar_lift(-2*x + 2)**2, oo)), 0)), (Integral(2*sin(t)**2*cos(2*t*(-x + 1))/(pi*t**2), (t, 0, oo)), True))

那就更长了。。。

2xfor14(2x?2)2<10for4(2x?2)2<1G3,14,4(121,1,3212,1,012∣∣

∣∣14polar_lift2(?2x+2))otherwisefor∣∣

periodic argument(polar_lift2(?2x+2),∞)∣∣

=0∞∫02πt2sin2(t)cos(2t(?x+1))dtotherwise

sympy模块还是比较强的,化简可能比较弱,感觉是我的条件声明没有充分利用,要看懂,得知道一些复变函数的知识,这个时候,可以试试Maple或者Mathematica,面对高昂的费用,我们可以使用在线的免费计算WolframAlph (https://www.360docs.net/doc/dd9149691.html,/),输入integrate

2/pi*cos(2*t*(1-x))*(sin(t)/t)^2,t,0,oo即可得p2(x)=12(|x?2|?2|x ?1|+|x|),n取任意值都是可以算的,由于式子比较复杂,就不展示了。

小结

作者的一些经验感悟:

因为看论文的原因(感觉MCMC好像哪都有),接着从随机数生成开始自学MCMC,一次偶然的机会,去年在北京计算科学研究中心听清华喻文健教授的报告,提到均匀分布的随机数检验,中间也出现了这个图,现在已经记不得是喻教授因为时间原因,没细讲背后的原因,还是自己没听懂,总之只觉得挺有意思的(涉及统计中的游程检验,周围基本都是工科学生,我想我听的更明白些),就记下来,

在听报告之前,囫囵地看了康崇禄写的《蒙特卡罗方法理论和应用》的前两章(前两章故事比较多因此看完了),这本书没讲那个例子,却把背后的原因讲明白了(后来细看才知道的)。错位相减算法曾出现在Matlab,自然就去读Cleve B. Moler 写的《Numerical Computing with MATLAB》(Revised in 2013),这本书在文中有出现,也介绍了Matlab这么多年内置的随机数发生器的变化史。其实还是推荐看康崇禄那本,不仅因为故事多,而且内容全面和透彻,可以挑自己需要和感兴趣的部分读,也不拘泥于Matlab。

关于应用部分的举例,源于面试,陷于教材,钟于符号计算。这部分涉及一本广为人知的教材《概率论与数理统计教程》(第二版)茆诗松、程依明和濮晓龙著,这本书给了用卷积求独立随机变量和的例子,后面讲特征函数,说它在求独立随机变量和有优势,但是没有举例,所以正好是补充,而且意外地简洁和统一。符号计算获得精确结果是为了和数值计算的结果比较,之前在统计之都的投名状就是符号计算与R语言,但是没有提及python的sympy,这下也正好合体了。

随机数生成算法的研究

随机数生成算法的研究 [日期:2006-05-23] 来源:作者:[字体:大中小] 张敬新 摘要:本文通过流程图和实际例程,较详细地阐述了随机数生成的算法和具体的程序设计,分析了其符合算法特征的特性。 关键词:随机数;算法;算法特征;程序设计 1 引言 在数据结构、算法分析与设计、科学模拟等方面都需要用到随机数。由于在数学上,整数是离散型的,实数是连续型的,而在某一具体的工程技术应用中,可能还有数据值的范围性和是否可重复性的要求。因此,我们就整数随机数和实数随机数,以及它们的数据值的范围性和是否可重复性,分别对其算法加以分析和设计。以下以Visual Basic 语言为工具,对整数随机数生成问题加以阐述,而对于实数随机数生成问题,只要稍加修改就可转化为整数随机数生成问题。 根据整数随机数范围性和是否可重复性,可分为: (1)某范围内可重复。 (2)某范围内不可重复。 (3)枚举可重复。 (4)枚举不可重复。 所谓范围,是指在两个数n1和n2之间。例如,在100和200之间这个范围,那么,只要产生的整数随机数n满足100≤n≤200,都符合要求。所谓枚举,是指有限的、已知的、若干个不连续的整数。例如,34、20、123、5、800这5个整数就是一种枚举数,也就是单独可以一个个确定下来。 2 某范围内可重复 在Visual Basic 语言中,有一个随机数函数Rnd。 语法:Rnd[(number)]。 参数number 可选,number 的值决定了Rnd 生成随机数的方式。Rnd 函数返回小于1 但大于或等于0 的值。

在调用Rnd 之前,先使用无参数的Randomize 语句初始化随机数生成器,该生成器具有一个基于系统计时器的种子。 若要生成某给定范围内的随机整数,可使用以下公式: Int((upperbound - lowerbound + 1) * Rnd + lowerbound) 这里,upperbound 是此范围的上限,而lowerbound 是范围的下限。 程序流程图: 程序例程:下面是一个生成10个10~20之间随机数的例子。 运行结果:12 10 20 20 17 17 18 14 12 20 3 某范围内不可重复

随机数生成器

随机数生成器 一、随机数 1.1随机数的概念 数学上是这样定义随机数的:在连续型随机变量的分布中,最简单而且最基本的分布是单位均匀分布。由该分布抽取的简单子样称为随机数序列,其中每一个体称为随机数。单位均匀分布即[0,1]上的均匀分布。由随机数序列的定义可知,ξ1,ξ2,…是相互独立且具有相同单位均匀分布的随机数序列。也就是说,独立性、均匀性是随机数必备的两个特点。 1.2随机数的分类 随机数一般分为伪随机数和真随机数。利用数学算法产生的随机数属于伪随机数。利用物理方法选取自然随机性产生的随机数可以看作真随机数。实用中是使用随机数所组成的序列,根据所产生的方式,随机数序列再可以分为两类: 1.伪随机数序列 伪随机数序列由数学公式计算所产生。实质上,伪随机数并不随机,序列本身也必然会重复,但由于它可以通过不同的设计产生满足不同要求的序列且可以复现(相同的种子数将产生相同的序列),因而得到广泛的应用。由伪随机数发生器所产生的伪随机数序列,只要它的周期足够长并能通过一系列检验,就可以在一定的范围内将它当作真随机数序列来使用。 2.真随机数序列 真随机数序列是不可预计的,因而也不可能出现周期性重复的真正的随机数序列。它只能由随机的物理过程所产生,如电路的热噪声、宇宙噪声、放射性衰变等。 按照不同的分类标准,随机数还可分为均匀随机数和非均匀随机数,例如正态随机数。 1.3随机数的衡量标准 在实际模拟过程中,我们一般只需要产生区间[0,1]上的均匀分布随机数,因为其他分布的随机数都是由均匀分布的随机数转化来的。 实用中的均匀随机数主要通过以下三个方面来衡量其随机性能的高低。 1.周期性 伪随机数序列是由具有周期性的数学公式计算产生,其本身也必然会表现出周期性,即序列中的一段子序列与另一段子序列相同。它的周期必须足够长,才能为应用提供足够多的可用数据。只有真随机数序列才能提供真正的、永不重复的随机数序列。 2.相关性 随机数发生器所产生的一个随机数序列中的各个随机数应该不相关,所产生的各个随机数序列中的随机数也应该不相关。真随机数序列自然地满足这种不相关性。对于伪随机数发生器,应该仔细地设计所用的数学公式,以尽量满足不相关的要求。 3.分布均匀性 包括蒙特卡洛计算在内的大多数应用都要求所采用的随机数序列服从均匀分布,即同一范围内的任一个数出现的概率相同。从均匀分布的随机数序列也很容易导出其它类型分布的

MATLAB随机数生成

2009年03月20日星期五 03:25 P.M. rand(n):生成0到1之间的n阶随机数方阵 rand(m,n):生成0到1之间的m×n 的随机数矩阵 (现成的函数) 另外: Matlab随机数生成函数 betarnd 贝塔分布的随机数生成器 binornd 二项分布的随机数生成器 chi2rnd 卡方分布的随机数生成器 exprnd 指数分布的随机数生成器 frnd f分布的随机数生成器 gamrnd 伽玛分布的随机数生成器 geornd 几何分布的随机数生成器 hygernd 超几何分布的随机数生成器 lognrnd 对数正态分布的随机数生成器 nbinrnd 负二项分布的随机数生成器 ncfrnd 非中心f分布的随机数生成器 nctrnd 非中心t分布的随机数生成器 ncx2rnd 非中心卡方分布的随机数生成器 normrnd 正态(高斯)分布的随机数生成器 poissrnd 泊松分布的随机数生成器 raylrnd 瑞利分布的随机数生成器 trnd 学生氏t分布的随机数生成器 unidrnd 离散均匀分布的随机数生成器 unifrnd 连续均匀分布的随机数生成器 weibrnd 威布尔分布的随机数生成器 (From:https://www.360docs.net/doc/dd9149691.html,/question/30033707.html) matlab生成随机数据 matlab本身提供很多的函数来生成各种各样的随机数据: normrnd 可以生成一定均值和标准差的正态分布 gamrnd 可以生成gamma分布的伪随机数矩阵 chi2rnd 可以生成卡方分布的伪随机数矩阵 trnd 可以生成t分布的伪随机数矩阵 frnd 可以生成f分布的伪随机数矩阵 raylrnd 可以生成rayleigh分布的伪随机数矩阵

随机数生成方法

University of Sydney School of Information Technologies Generating Random Variables Pseudo-Random Numbers Definition : A sequence of pseudo-random numbers ()i U is a deterministic sequence of numbers in []1,0 having the same relevant statistical properties as a sequence of random numbers. The most widely used method of generating pseudo-random numbers are the congruential generators: ()M X U M c aX X i i i i =+=?mod 1 for a multiplier a , shift c , and modulus M , all integers. The sequence is clearly periodic, with maximum period M . The values of a and c must be carefully chosen to maximise the period of the generator, and to ensure that the generator has good statistical properties. Some examples: M a c 259 1313 0 232 69069 1 231-1 630360016 0 232 2147001325 715136305 Reference: Ripley, Stochastic Simulation , Chapter 2

随 机 数 生 成 器

使用python实现伪随机数生成器 在前两天学习了使用python实现伪随机数的方法,今天是时候来做一个总结了。 首先要说明的是什么是随机数,真正的随机数是使用物理现象产生的:比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等等。产生这些随机数的方法有很多种,而这些产生随机数的方法就称为随机数生成器。像前面说的由物理现象所产生的随机数发生器叫做物理性随机数发生器,它们的缺点是技术要求比较高。 但是在我们的实际生活中广泛应用的是伪随机数生成器,所谓的“伪”就是假的的意思,也就是说并不是真正的随机数。那么这些随机数是怎么实现的呢?这些数字是由固定的算法实现的,是有规律可循的,并不能实现真正的“随机”,但是它们具有类似于随机数的统计特征。这样的发生器叫做伪随机数发生器。 实现伪随机数的方法有很多种,如:平方取中法,线性同余法等方法。 下面主要介绍的是线性同余法,如C的rand函数和JAVA的java.util.Random类就是使用该方法实现的,其公式为:rNew = (a*rOld + b) % (end-start) 其中, a称为乘数,b称为增量,(end-start)称为模数,它们均为常数。 然后设置rOld = rNew,一般要求用户指定种子数rOld(也称为

seed),当然也可以自由选择a和b,但是两个数如果选择不好,可能会影响数字的随机性,所以一般令: a=32310901 这样使得生成的随机数最均匀。下面我是用的将种子自定义设为999999999。代码如下: def myrandint( start,end,seed=999999999 ): a=32310901 #产生出的随机数最均匀 rOld=seed m=end-start while True: #每调用一次这个myrandint函数,才生成一次随机数所以要惰性求值 rNew = (a*rOld+b)%m yield rNew rOld=rNew #模拟使用20个不同的种子来生成随机数 for i in range(20): r = myrandint(1,10000, i) #每个种子生成10个随机数 print('种子',i,'生成随机数') for j in range(10): print( next(r),end=',' ) 运行结果是使用20个不同的种子生成的随机数。

matlab产生随机数的方法

matlab 产生随机数的方法 第一种方法是用 random 语句,其一般形式为 y = random (' 分布的英文名 ',A1,A2,A3,m,n ) , 表示生成m 行n 列的m x n 个参数为(A1 , A2 , A3 ) 的该分 布的随机数。 例如: (1) R = random ('Normal',0,1,2,4): 生成期 望为 0, 标准差为 1 的(2 行 4 列)2 x 4个正态随机数 (2) R = random ('Poisson',1:6,1,6): 依次 生成参数为 1 到 6 的(1 行 6 列 )6 个 Poisson 随机数 第二种方法是针对特殊的分布的语句: 一. 几何分布随机数 R = geornd(P) R = geornd(P,m) (下面的 P , m 都可以是矩阵) (生成参数为 P 的几何随机数) (生成参数为 P 的 x m 个几何随机数) 1 R = geornd (P,m,n ) (生成参数为 P 的 m 行 n 列的 m x n 个几何随 机数) 例如 ⑴ R = geornd (1./ 2八(1:6))(生成参数依次为 1/2,1/2A 2,至U 1/2A 6 的 6 个几 何随机数 ) ⑵ R = geornd (0.01,[1 5])( 生成参数为0.01的(1行5列)5个几何随 机数). 二. Beta 分布随机数 R = betarnd(A,B) R = betarnd(A,B,m) 生成 m 行 n 列的 m x n 个数为 A,B 的 Beta 随 三.正态随机数 R = normrnd (MU, SIGMA ) (生成均值为 MU,标准差为SIGMA 的正态随机数) R = normrnd (MU , SIGMA,m ) (生成 1x m 个正态随机数) R = normrnd(MU , SIGMA,m,n) (生成 m 行 n 列的 m x n 个正态随机数) 例如 (1) R = normrnd(0,1,[1 5]) 生成 5 个正态 (0,1) 随机数 (2) R = normrnd([1 2 3;4 5 6],0.1,2,3) 生成期望依次为 [1,2,3;4,5,6], 方 差为 0.1 的 2x 3 个正态随机数. 生成参数为 A,B 的 Beta (生成 x m 个数为 A,B 随机数) 的 Beta 随机数) R = betarnd(A,B,m,n) 机数) .

在excel中产生随机数

用excel产生随机数 统计软件提供的随机数发生器可以使我们对抽样分布进行计算机模拟,对抽样分布有更加直观的理解。Excel的分析工具库中有一个“随机数发生器”模块,可以产生服从大部分常用分布的模拟数据,但没有提供直接产生随机数的函数。在SPSS中产生随机数的函数在“Randomnumbers”类别中,相应的函数都是以Rv 开头的。 1 样本均值抽样分布的随机模拟 假总体的均值为μ,标准差为σ,则统计理论表明,不论总体的分布如何,只要样本容量n足够大,样本均值的分布总会趋向于正态分布,且均值为μ,标 准差为。 例题:假设总体为均匀分布,模拟样本均值的抽样分布。 假设总体的分布为0-1区间上的均匀分布,则总体的均值为0.5,方差等于 1/12,标准差等于0.288675。现在,我们从总体中抽取1000个样本容量为2的样本(有放回抽样),计算每个样本的样本均值,然后观察样本均值的分布状况。 新建一个Excel工作簿,单击“工具”“数据分析”“随机数发生器”,在弹出的对话框中把变量个数设为2,随机数个数为1000,选择0-1区间的均匀分布,结果放在新工作表中(图1)。把输出结果的每一行看作一个容量为2的样本,共有1000个样本。在C列中计算每个样本的均值。接下来我们就可以分析这1000个样本均值的分布状况了。由于SPSS的直方图工具更为方便,我们把相应的数据复制到SPSS中作直方图,结果如图2,抽样分布的均值为0.5097,标准差为 0.20345,理论值等于0.288675/ 2 =0.20412,两者差异不大。 图1 随机数发生器对话框

图2 样本均值的抽样分布,样本容量=2 2 样本比例抽样分布的随机模拟 样本比例实质上就是指标数值只能取0和1时的样本均值。由于在这种情况下总体的分布为0-1分布,因此在重复抽样的条件下样本均值抽样分布的理论分布是二项分布。中心极限定理表明当样本用量足够大(能够保证np≥5,nq≥5)时二项分布可以用正态分布来近似。 [例] 假设有大批零件,不合格率p为0.2。随机模拟从总体中抽取样本容量分别为5,20,50的2000个样本,分析样本比例p? 的抽样分布。 新建一个工作表,在单元格中输入图5-10左上角所示的信息作为总体:总体中取值为1(不合格)的概率为0.2,取值为0(合格)的概率为0.8。 图3 二项分布的随机模拟

随机数生成器功能:1,产生一个随机概率,.doc

随机数生成器功能:1,产生一个随机概率, 2产生一个a到b之间的随机整数 3,产生一个指定长度的随机数组,里面存放随机的布尔值,表示染色体 package edu.zsu.zouang.util;//java.util中的Random使用指定的伪随机原随即更改指定列表的序列 import java.util.Random;//import导入,导入random类,用于产生伪随机数流 public class Randomizer { private int lower; private int upper; private static Random random = new Random();//生成random实例 public Randomizer(int lower, int upper){ if(upper <= lower){ throw new IllegalStateException("Upper is smaller than lower!"); } this.lower = lower; this.upper = upper; } public Double nextDouble(){//返回概率 return Double. (upper - lower) * random.nextDouble()); }//Random中double nextDouble()返回下一个伪随机数,它是从伪随机数生成器的序列中取出的在0.0到1.0之间的double值 //double.valueof(str)说明把str转化成double类型的对象,相当于强制转换 public Integer nextInteger(){//返回整数lower到upper之间 return Integer.valueOf(lower +random.nextInt(upper - lower)); }//Random(int)返回0到int之间的整数随机值 public char[] nextBitArray(int length){//生成指定长度的字符数组,存放基因系列 if(length <= 0){ throw new IllegalStateException("Length is less than ZERO!"); } char[] temp = new char[length]; for(int i = 0; i < length ; i++){ temp[i] = random.nextBoolean() ? '1' : '0'; }//Random.nextBoolean()返回随机的bool值

第3章 随机数的产生与模拟

第三章随机数的产生与模拟目录 ?随机数的产生与模拟 ?§3.1均匀随机数的产生 ? 3.1.1线性同余法(LCG)的递推公式 ? 3.1.2反馈位移寄存器法(FSR) ? 3.1.3组合发生器 ?§3.2非均匀随机数的产生 ?§3.3 Monte Carlo方法在解确定性问题中的应用 ? 3.3.1计算定积分 ? 3.3.1.1随机投点法 ? 3.3.1.2平均值估计法 ? 3.3.1.3重要抽样法 ? 3.3.1.4分层抽样法 ? 3.3.2 计算多重积分 ? 3.3.2.1 随机投点法 ? 3.3.2.2 平均值估计法 ? 3.3.3应用实例 ?§3.4 随机模拟方法在随机服务系统中的应用 ?§3.5 随机模拟方法在理论研究中的应用

随机数的产生与模拟 用随机模拟方法解决实际问题时,首先要解决的是随机数的产生方法,或称随机变量的抽样方法。

随机数的产生与模拟 伪随机数: 在计算机上用数学方法产生均匀随机数是指按照一定的计算方法而产生的数列,它们具有类似于均匀随机变量的独立抽样序列的性质,这些数既然是依照确定算法产生的,便不可能是真正的随机数,因此常把用数学方法产生的随机数称为伪随机数。

随机数的产生与模拟 均匀分布随机数: 定理:设)(x F是连续且严格单调上升的分布函数,它的反函数存在,且记为)(1x F-, 1、若随机变量ξ的分布函数为)(x F,则)1,0(~)(U Fξ; 2、若随机变量)1,0(~U F-的分布函数为)(x F R,则)(1R

随机数的产生与模拟 均匀分布随机数: 该定理说明了任意分布的随机数均可由均匀分布的随机数变换得到。常简称的随机数为均匀分布随机数。 )1,0(U )1,0(U

随 机 数 生 成 器

利用泊松分布实现随机数生成器 不多说,直接上代码,这是在华师大算法课上做的实验代码,C++可运行。 #includeiostream #includetime.h #includecmath using namespace std; class Random { Random(bool pseudo = true); double random_real(); int random_integer(int low, int high); int poisson(double mean); void randomByAvg(double avg,int num); private: int reseed(); -- Re-randomize the seed. int seed,multiplier,add_on; -- constants for use in arithmetic operations Random::Random(bool pseudo) Post: The values of seed, add_on, and multiplier are initialized. The seed is initialized randomly only if pseudo == false.

if (pseudo) seed = 1; else seed = time(NULL) % INT_MAX; multiplier = 2743; add_on = 5923; int Random::reseed() Post: The seed is replaced by a pseudorandom successor. seed = seed * multiplier + add_on; return seed; double Random::random_real() Post: A random real number between 0 and 1 is returned. double max = INT_MAX + 1.0; --INT_MAX = (2)31 -1 double temp = reseed(); if (temp 0) temp = temp + max; return temp - max; int Random::random_integer(int low, int high) Post: A random integer between low and high is returned. if (low high) return random_integer(high, low); else return ((int) ((high - low) * random_real())) + low; int Random::poisson(double mean) Post: A random integer, reflecting a Poisson distribution with parameter mean, is returned. double limit = exp(-mean);

随机数生成器

湖北轻工职业技术学院 实验报告 题目:随机数生成器 专业:电子信息工程技术 姓名: 学号: 班级:10电信 指导老师: 2012年5月29日

目录 引言 (3) 一、总体方案的设计 (4) 二、单元电路的设计 (4) (一) NE555的引脚与功能 (4) (二) CD4017的引脚与功能 (5) (三)实物正反面图 (6) 三、使用元件 (7) 四、电路组装\调试过程中遇到的问题及解决办法 (7) 五、分析与心得 (8)

引言 随机数是专门的随机试验的结果。随机数最重要的特性是:它所生成的后面的那个数与前面的那个数毫无关系。首先需要声明的是,计算机不能生成绝对随机的随机数(“真随机数”),只能生成“伪随机数”。其实绝对随机的随机数只是一种理想的随机数,即使计算机怎样发展,它也不会生成一串绝对随机的随机数。计算机只能生成相对的随机数,即伪随机数。未来的量子计算机有可能生成基于自然规律的不可重现的“真随机数”。在统计学的不同技术中需要使用随机数。比如:1、在从统计总体中抽取有代表性的样本的时候2、在将实验动物分配到不同的试验组的过程中3、在进行蒙特卡罗模拟法计算的时候等等。实际生活中,这些随机数起着很大的作用,所以很多人会专门去寻找随机数生成器。比如:1、对银行来说,银行的ID和密码非常脆弱。如果有随机数表,就可以防备此类事件。随机数表是指为每个客户指定各不相同的数字列表,申请时将该随机数表分配给客户,而不是按照一定的规律给出,这就安全很多。2、要考察某公司的牛奶产品质量,想从800袋牛奶中抽取60袋,就可以在随机数表中选中一数,并用向上、下、左、右不同的读法组成60个数,并按牛奶的标号进行检测,虽然麻烦,但很常用。3、企业要调查消费者对某产品的需求量,要从很多消费者中抽选一定数量的样本调查。

matlab随机数生成方法

Matlab(https://www.360docs.net/doc/dd9149691.html,) 随机数生成方法(转自雅虎空间) 第一种方法是用random 语句,其一般形式为 y = random('分布的英文名',A1,A2,A3,m,n), 表示生成m 行n 列的m × n 个参数为( A1 , A2 , A3 ) 的该分布的随机数。例如: (1) R = random('Normal',0,1,2,4): 生成期望为0,标准差为1 的(2 行4 列)2× 4 个正态随机数 (2) R = random('Poisson',1:6,1,6):依次生成参数为 1 到 6 的(1 行 6 列)6 个Poisson 随机数 第二种方法是针对特殊的分布的语句: 一.几何分布随机数(下面的P,m 都可以是矩阵) R = geornd(P) (生成参数为P 的几何随机数) R = geornd(P,m)(生成参数为P 的× m 个几何随机数) 1 R = geornd(P,m,n)(生成参数为P 的m 行n 列的m × n 个几何随机数) 例如 (1)R = geornd(1./ 2.^(1:6)) ( 生成参数依次为1/2,1/2^2,到1/2^6 的6 个几何随机数) (2)R = geornd(0.01,[1 5]) (生成参数为0.01 的(1行5列)5 个几何随机数). 二.Beta 分布随机数 R = betarnd(A,B)(生成参数为A,B 的Beta 随机数) R = betarnd(A,B,m)(生成× m 个数为A,B 的Beta 随机数) 1 R = betarnd(A,B,m,n)(生成m 行n 列的m × n 个数为A,B 的Beta 随机数). 三.正态随机数 R = normrnd(MU,SIGMA)(生成均值为MU,标准差为SIGMA 的正态随机数) R = normrnd(MU,SIGMA,m)(生成1× m 个正态随机数) R = normrnd(MU,SIGMA,m,n) (生成m 行n 列的m × n 个正态随机数) 例如 (1) R = normrnd(0,1,[1 5]) 生成5 个正态(0,1) 随机数 (2) R = normrnd([1 2 3;4 5 6],0.1,2,3)生成期望依次为[1,2,3;4,5,6], 方差为0.1 的2× 3 个正态随机数. 四.二项随机数:类似地有 R = binornd(N,P)R = binornd(N,P,m) R = binornd(N,p,m,n) 例如 n = 10:10:60; r1 = binornd(n,1./n)或r2 = binornd(n,1./n,[1 6]) (都生成参数分别为 1 1 ), L, ( 60, ) 的6个二项随机数. (10, 10 60

随机数产生器设计报告

摘要 本次随机数产生器的编写主要采用汇编语言来编写的,在程序的编写中通过调用并运行子程序以及其他汇编指令的协调来实现所要达到的功能,程序主要分三大功能,1.随机数的产生,2.确定随机数的上下限,3.将产生的随机数用16进制的ASCII 表示出来,本程序主要有四大模块,1.随机数产生模块;2.数制转换模块;3.字符显示模块;4.运算模块,通过这次汇编语言的程序设计,让我们更加了解了汇编语言,扩展了我们在汇编邻域的知识,让我们掌握了编写实训报告的能力,汇编语言的长处在于编写高效且简单,易懂,需要对机器硬件精确控制的程序。汇编语言比机器语言易于读写、调试和修改,同时具有机器语言全部优点。本次编写的随机数产生器简单易懂,其中的上下线用编写者定义,更加的具有灵活性,此程序突出了汇编语言的简单,灵活,易读写,易修改的特点。 关键词:汇编语言;程序;随机数

目录 1 设计任务 (1) 2任务分析 (2) 2.1 程序功能说明 (2) 2.2 程序要点说明 (2) 3功能及程序设计 (3) 3.1主程序流程图及结构图 (3) 3.2程序说明 (4) 3.3 子程序功能说明 (5) 3.3.1 MACT子程序说明 (5) 3.3.2 RAND子程序说明 (7) 3.3.3 字符串显示子程序说明 (8) 4调试结果及分析 (10) 5心得体会 (12) 6参考文献 (13) 附录: (14) 源代码 (14)

1 设计任务 产生十六进制随机数并对其进行运算是相当多应用程序经常会涉及到的一种功能。实际上,十六进制数有个计数符号:0~9,A~F。4个二进制位共有16种组合状态,这样每个十六进制数的计数符号可对应4位二进制数的一种组合状态;反之,1个十六进制符号可以替代一种4位二进制数的组合状态。在阅读和编写汇编语言程序时,经常用十六进制数表示数据、存储单元地址或代码等。 本次课程设计研究的产生16进制随机数并运算的内容。本程序采用汇编语言编程,建立一个文件,显示任意两个16进制数的加法或减法表达式及其运算结果。在减法运算中,如果被减数小于减数,显示“Divider error”的提示信息。

MATLAB产生各种分布的随机数

MATLAB产生各种分布的随机数 1,均匀分布U(a,b): 产生m*n阶[a,b]均匀分布U(a,b)的随机数矩阵:unifrnd (a,b,m, n) 产生一个[a,b]均匀分布的随机数:unifrnd (a,b) 2,0-1分布U(0,1) 产生m*n阶[0,1]均匀分布的随机数矩阵:rand (m, n) 产生一个[0,1]均匀分布的随机数:rand 4,二类分布binornd(N,P,mm,nn) 如binornd(10,0.5,mm,nn) 即产生mm*nn均值为N*P的矩阵 binornd(N,p)则产生一个。而binornd(10,0.5,mm)则产生mm*mm的方阵,军阵为N*p。5,产生m*n阶离散均匀分布的随机数矩阵: unidrnd(N,mm,nn)产生一个数值在1-N区间的mm*nn矩阵 6,产生mm nn阶期望值为的指数分布的随机数矩阵: exprnd( ,mm, nn) 此外,常用逆累积分布函数表 函数名调用格式函数注释 norminv X=norminv(P,mu,sigma) 正态逆累积分布函数 expinv X=expinv(P,mu) 指数逆累积分布函数 weibinv X=weibinv(P,A,B) 威布尔逆累积分布函数 logninv X=logninv(P,mu,sigma) 对数正态逆累积分布函数 Chi2inv X=chi2inv(P,A,B) 卡方逆累积分布函数 Betainv X=betainv(P,A,B) β分布逆累积分布函数

4.1 随机数的产生 4.1.1 二项分布的随机数据的产生 命令参数为N,P的二项随机数据 函数 binornd 格式 R = binornd(N,P) %N、P为二项分布的两个参数,返回服从参数为N、P的二项分布的随机数,N、P大小相同。 R = binornd(N,P,m) %m指定随机数的个数,与R同维数。 R = binornd(N,P,m,n) %m,n分别表示R的行数和列数 例4-1 >> R=binornd(10,0.5) R = 3 >> R=binornd(10,0.5,1,6) R = 8 1 3 7 6 4 >> R=binornd(10,0.5,[1,10]) R = 6 8 4 6 7 5 3 5 6 2 >> R=binornd(10,0.5,[2,3]) R = 7 5 8 6 5 6 >>n = 10:10:60; >>r1 = binornd(n,1./n)

实验计算机模拟

实验:计算机模拟 一、实验目的和要求 1. 掌握计算机模拟的基本原理及方法; 2. 掌握利用随机数解决问题; 二、实验内容 1.已知零件C由零件A和零件B连接而成,已知零件A、B的长度为随机变量, aaa=[]; for i=1:10 a=rand; if a<=007 a1=5; elseif a>0.07&&a<=0.26 a1=6; elseif a>0.26&&a<=0.64 a1=7; elseif a>0.64&&a<=0.89 a1=8; elseif a>0.89&&a<=1 a1=9; end b=rand; if b<=0.23 b1=14; elseif a>0.23&&a<=0.64 b1=15; elseif a>0.64&&a<=0.91 b1=16; elseif a>0.91&&a<=1 b1=17; end c=a1+b1 aaa=[aaa a1+b1];

end 运行xxx得到以下结果 :xxx c = 21 c = 19 c = 20 c = 21 c = 20 c = 20 c = 21 c = 19 c = 19 c = 19 >> mean(aaa) ans = 19.9000 10个样本计算C的平均长度为19。 单件成本7 8 9 10 11 12 概率0.05 0.15 0.2 0.3 0.25 0.05 定价\概率\预计销售500 600 700 800 900 19 0.05 0.15 0.4 0.25 0.15 20 0.3 0.2 0.2 0.2 0.1 21 0.2 0.3 0.35 0.1 0.05 量时,每件以5元处理) 根据题设编写代码:a.m b=[500 600 700 800 900]; a=[19,20,21]; x1=rand; if x1<0.05 c=7; elseif x1>0.05&x2<0.20 c=8; elseif x1>0.20&x1<0.4 c=9;

C++随机数的生成

标准库(被包含于中)提供两个帮助生成伪随机数的函数: 函数一:int rand(void); 从srand (seed)中指定的seed开始,返回一个[seed, RAND_MAX(0x7fff))间的随机整数。 函数二:void srand(unsigned seed); 参数seed是rand()的种子,用来初始化rand()的起始值。 可以认为rand()在每次被调用的时候,它会查看: 1)如果用户在此之前调用过srand(seed),给seed指定了一个值,那么它会自动调用srand(seed)一次来初始化它的起始值。 2)如果用户在此之前没有调用过srand(seed),它会自动调用srand(1)一次。 根据上面的第一点我们可以得出: 1)如果希望rand()在每次程序运行时产生的值都不一样,必须给srand(seed)中的seed 一个变值,这个变值必须在每次程序运行时都不一样(比如到目前为止流逝的时间)。 2)否则,如果给seed指定的是一个定值,那么每次程序运行时rand()产生的值都会一样,虽然这个值会是[seed, RAND_MAX(0x7fff))之间的一个随机取得的值。 3)如果在调用rand()之前没有调用过srand(seed),效果将和调用了srand(1)再调用rand()一样(1也是一个定值)。 举几个例子,假设我们要取得0~6之间的随机整数(不含6本身): 例一,不指定seed: for(int i=0;i<10;i++){ ran_num=rand() % 6; cout<

计算机随机数模拟随机试验教学反思

《计算机随机数模拟随机试验》教学反思 1.教学内容分析 本节课是一节数学与信息技术的结合课。处于数学进入选择性必修二,讲完4.1节《条件概率与事件的独立性》4.2节《随机变量》中4.2.3《二项分布和超几何分布》。信息技术课讲完Excle的应用之后。随着计算机科学、人工智能的迅猛发展,人们获取数据和处理数据的能力都得到很大的提升。为了让我们的学生适应这种变化,计算机与学科的融合不容忽视。这节课我们主要要让学生熟悉用随机数模拟随机试验及对试验数据的理解处理。数学建模是对现实问题进行数学抽象数学建模是对现实问题进行数学抽象,用数学语言表达问题、用数学方法构建模型解决问题的素养。这节课我们以随机数模拟为载体在探究随机数模拟随机试验的过程中,锻炼学生在实际情境中从数学的视角发现问题、提出问题,分析问题、建立模型,确定参数、计算求解,检验结果、改进模型,最终解决实际问题的能力。发展学生数学抽象,数学建模的数学核心素养。 2.学习者分析 我校属于省级示范校,学生基础相对较好,具备一定的自主探究能力,同时在本学期的数学学习中刚刚学习过条件概率与事件的独立性,二项分布和超几何分布。信息技术课刚刚学习过Excle的应用。从而具备了探索建立适当模型去模拟随机试验,通过数据分析估计事件概率的可能性。学生的困难在于分析问题解决问题策略的选择,在现有数据基础上得出合理结果,实验结果与理论结果的差异分析。 3.学习目标确定 (1)会使用Excel中Rand()函数的若干功能; (2)通过“三门问题”的模拟实验了解计算机模拟的可行性和优越性; (3)通过小组合作探究提升学生在实际情境中从数学的视角发现问题、提出问题,分析问题、建立模型,确定参数、计算求解,检验结果、改进模型,最终解决 实际问题的能力,发展学生数学抽象,数学建模的数学核心素养。 4.教学重难点 教学重点:建立适当的模型模拟随机试验,实验得到的频率值与概率值的比较。 教学难点:分析问题解决问题策略的选择特色学习资源分析与技术手段应用说明 5教学过程 (1)随机模拟方法的基本思想是:为了求解数学、物理、工程技术以及生产管理等方面

伪随机数产生器

伪随机数产生器 ----------------------------------------------------------------------------- -- -- The following information has been generated by Exemplar Logic and -- may be freely distributed and modified. -- -- Design name : pseudorandom -- -- Purpose : This design is a pseudorandom number generator. This design -- will generate an 8-bit random number using the polynomial p(x) = x + 1. -- This system has a seed generator and will generate 2**8 - 1 unique -- vectors in pseudorandom order. These vectors are stored in a ram which -- samples the random number every 32 clock cycles. This variance of a -- priority encoded seed plus a fixed sampling frequency provides a

truely -- random number. -- -- This design used VHDL-1993 methods for coding VHDL. -- ---------------------------------------------------------------------------- Library IEEE ; use IEEE.std_logic_1164.all ; use IEEE.std_logic_arith.all ; entity divide_by_n is generic (data_width : natural := 8 ); port ( data_in : in UNSIGNED(data_width - 1 downto 0) ; load : in std_logic ; clk : in std_logic ; reset : in std_logic ; divide : out std_logic ); end divide_by_n ;

C怎样产生随机数

C怎样产生随机数 问:怎样产生随机数? 答:在计算机中并没有一个真正的随机数发生器,但是可以做到使产生的数字重复率很低,这样看起来好象是真正的随机数,实现这一功能的程序叫伪随机数发生器。 有关如何产生随机数的理论有许多,如果要详细地讨论,需要厚厚的一本书的篇幅。不管用什么方法实现随机数发生器,都必须给它提供一个名为“种子”的初始值。而且这个值最好是随机的,或者至少这个值是伪随机的。“种子”的值通常是用快速计数寄存器或移位寄存器来生成的。 下面讲一讲在C语言里所提供的随机数发生器的用法。现在的C编译器都提供了一个基于ANSI标准的伪随机数发生器函数,用来生成随机数。它们就是rand()和srand()函数。这二个函数的工作过程如下: 1) 首先给srand()提供一个种子,它是一个unsigned int类型,其取值范围从0~65535; 2) 然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0到32767之间) 3) 根据需要多次调用rand(),从而不间断地得到新的随机数; 4) 无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。 这个过程看起来很简单,问题是如果你每次调用srand()时都提供相同的种子值,那么,你将会得到相同的随机数序列,这时看到的现象是没有随机数,而每一次的数都是一样的了。例如,在以17为种子值调用srand()之后,在首次调用rand()时,得到随机数94。在第二次和第三次调用rand()时将分别得到26602和30017,这些数看上去是很随机的(尽管这只是一个很小的数据点集合),但是,在你再次以17为种子值调用srand()后,在对于rand()的前三次调用中,所得的返回值仍然是在对94,26602,30017,并且此后得到的返回值仍然是在对rand()的第一批调用中所得到的其余的返回值。因此只有再次给srand()提供一个随机的种子值,才能再次得到一个随机数。 下面的例子用一种简单而有效的方法来产生一个相当随机的“种子”值----当天的时间值:#include #include #include #include void main(void) { int i; unsigned int seedVal; struct timeb timeBuf; ftime(&timeBuf); seedVal=((((unsigned int)timeBuf.time&0xFFFF) (unsigned int)https://www.360docs.net/doc/dd9149691.html,litm)^ (unsigned int)https://www.360docs.net/doc/dd9149691.html,litm); srand((unsigned int)seedVal);

相关文档
最新文档