javascript代码实例教程-Javascript 随机数函数 学习之二:产生服从正态分布随机数

发布时间:2019-01-23 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-Javascript 随机数函数 学习之二:产生服从正态分布随机数脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 一、为什么需要服从正态分布的随机函数

 

一般我们经常使用的随机数函数 Math.random() 产生的是服从均匀分布的随机数,能够模拟等概率出现的情况,例如 扔一个骰子,1到6点的概率应该相等,但现实生活中更多的随机现象是符合正态分布的,例如20岁成年人的体重分布等。

 

 

 

假如我们在制作一个游戏,要随机设定许许多多 NPC 的身高,如果还用Math.random(),生成从140 到 220 之间的数字,就会发现每个身高段的人数是一样多的,这是比较无趣的,这样的世界也与我们习惯不同,现实应该是特别高和特别矮的都很少,处于中间的人数最多,这就要求随机函数符合正态分布。

 

 

 

二、正态分布复习

 

 

 

图片来自:https://zh.wikiPEdia.org/zh-cn/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83

 

具体性质也请查阅上面链接,描述正态分布的主要特征是均值和方差,如上图,最左的倒钟形图的均值为-2, 其余为0 ;

 

 

 

方差越大,钟形越扁平,方差越小越陡;

 

密度函数图像关于均值对称。

在x=μ±σ处,曲线有拐点。

函数曲线下68.26%的面积在平均数左右的一个标准差σ的区间内。

95.44%的面积在平均数左右两个标准差2σ的区间内。

99.74%的面积在平均数左右三个标准差3σ的区间内。

当均值为0, 方差为 1 时称为标准正态分布;

 

 

 

 

 

三、由均匀分布经 “Box-Muller法” 转换为正态分布

 

 

 

通过查阅文献可知(请参见:https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform),有一个称为 Box-Muller (1958) 转换的算法能够将两个在区间(0,1] 的均匀分布转化为标准正态分布,其公式为:

 

y1 = sqrt( - 2 ln(u) ) cos( 2 pi v )

 

y2 = sqrt( - 2 ln(u) ) sin( 2 pi v )

 

 

 

 

 

因为三角函数计算较慢,我们可以通过上述公式的一个 polar form(极坐标形式)能够简化计算,

 

算法描述如下:

 

复制代码

function getNumberInNormalDistribution(mean,std_dev){

    return mean+(randomNormalDistribution()*std_dev);

}

 

function randomNormalDistribution(){

    VAR u=0.0, v=0.0, w=0.0, c=0.0;

    do{

        //获得两个(-1,1)的独立随机变量

        u=Math.random()*2-1.0;

        v=Math.random()*2-1.0;

        w=u*u+v*v;

    }while(w==0.0||w>=1.0)

    //这里就是 Box-Muller转换

    c=Math.sqrt((-2*Math.LOG(w))/w);

    //返回2个标准正态分布的随机数,封装进一个数组返回

    //当然,因为这个函数运行较快,也可以扔掉一个

    //return [u*c,v*c];

    return u*c;

}

复制代码

 

 

因此,假如我们要获得均值为180,要68.26%左右的NPC身高都在[170,190]之内,即1个标准差范围内,因此标准差为10, 可以通过getNumberInNormalDistribution(180,10) 调用,我们实验1000000词,得到结果如下:

 

 

 

复制代码

// 身高:频率

128:1

132:1

133:1

134:1

135:1

136:2

137:4

138:8

139:11

140:14

141:19

142:28

143:41

144:54

145:80

146:133

147:153

148:235

149:333

150:429

151:598

152:764

153:1059

154:1314

155:1776

156:2290

157:2835

158:3503

159:4373

160:5513

161:6475

162:7809

163:9437

164:11189

165:13282

166:15020

167:17239

168:19215

169:21597

170:24336

171:26684

172:29000

173:31413

174:33179

175:35027

176:37084

177:38047

178:38968

179:39635

180:39700

181:39548

182:38960

183:38674

184:36948

185:35220

186:33224

187:31038

188:29198

189:26668

190:23893

191:21662

192:19476

193:16898

194:15056

195:13046

196:10971

197:9456

198:7928

199:6697

200:5370

201:4334

202:3548

203:2810

204:2330

205:1765

206:1350

207:1093

208:797

209:595

210:371

211:328

212:255

213:165

214:121

215:91

216:71

217:29

218:32

219:28

220:20

221:6

222:7

223:7

224:3

225:2

228:1

复制代码

 

 

绘制成柱状图如下:

 

 

 

 

 

可见,这是有着非常明显的正态分布图像特征。

 

 

 

 

 

四、由均匀分布叠加获得正态分布

 

 

 

我们需要祭出万能的中心极限定理。

 

 

 

根据独立同分布的中心极限定理:设随机变量X1,X2,...Xn,...相互独立,服从同一分布,且数学期望为μ,标准差为σ (σ>0),则随机变量之和的标准化变量:

 

Y=((X1+X2+...+Xn)-nμ)/(sqrt(n)*sqrt(σ)) 近似服从标准正态分布 N(0,1)

 

 

 

如果我们将足够多个均匀分布随机变量相加,相加之和将服从正态分布。但是,我们需要累加多少个均匀分布才能较好低近似正态分布呢?

 

由于 X~U(0, 1) , 可得 μ=1/2, σ=sqrt(1/12),代入上面的式子即可近似模拟随机变量之和的概率密度函数(p.d.f).

 

 

 

下图是由2个服从 U(0,1) 分布的随机变量相加得到的 p.d.f 图像:

 

 

 

如果我们增加累加的均匀分布的数量会怎样呢?

 

 

 

上图是 n=3 时的图像,可以看到正态分布的形状出来了,但顶端还略为平缓。

 

 

 

特别低,当n=12时 (随机变量(X1+X2+...+Xn)的均值为6,方差为1)  这时有一个很好的特点,公式 Y=((X1+X2+...+Xn)-nμ)/(sqrt(n)*sqrt(σ)) 的分母正好为1,因此简化成了 Y=((X1+X2+...+Xn)-nμ),非常便于编程计算,并且已经非常接近于标准正态分布,请见下图:

 

 

 

 

 

也就是说均值为μ,标准差为σ 的独立同分布变量 X1,X2, ..., Xn 的算数平均数  T=(X1+X2+ ...+ Xn)/n,当n充分大时,近似地服从均值为μ,方差为σ*σ/n 的正态分布。

 

 

 

最后,代码如下:

 

复制代码

function getNumberInNormalDistribution(mean,std_dev){    

    return mean+(uniform2NormalDistribution()*std_dev);

}

 

function uniform2NormalDistribution(){

    var sum=0.0;

    for(var i=0; i<12; i++){

        sum=sum+Math.random();

    }

    return sum-6.0;

}

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-Javascript 随机数函数 学习之二:产生服从正态分布随机数全部内容,希望文章能够帮你解决javascript代码实例教程-Javascript 随机数函数 学习之二:产生服从正态分布随机数所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。