笔者近期使用了随机数做抽样,本来是一个简单的应用,但是我想要探究一下随机数的生成原理,就看了一些网上的相关文章,总结如下。
首先贴一段是用c# 的random 产生随机数的代码,这是应用层面。
var rand = new Random();
int value1 = rand.Next(1, maxids + 1) # 取1-maxids的id int类型随机
double value2 = rand.NextDouble() #取0-1的double类型的随机
下面说原理层面。
抽样过程中,怎样在大量的样本集合中抽取定量样本呢,肯定要用到随机数.
如果要给随机数下一个定义, 那就是可以循环计数的序列。使用递归的方法,下一个数的生成是基于上一个随机数的结果,还要保证生成数的均匀分布。
随机数->计时器->递归.
在数学层面上讲,随机数就是一种按照某种计算方法生成数而保证随机性的方法.
例子
中央随机数生成器
种子: 随机序列初始化的值.
rnd.today=new Date();
rnd.seed=rnd.today.getTime();
function rnd() {
rnd.seed = (rnd.seed*9301+49297) % 233280;
return rnd.seed/(233280.0);
};
function rand(number) {
return Math.ceil(rnd()*number);
};
注意,被乘的数往往是质数,用来保证自我重复循环空间的最大化.
平方取中法
产生0/1均匀分布的随机数; 伪随机数.
此法开始取一个2s位的整数[10-100以内的整数],称为种子,将其平方,得4s位整数(不足4s位时高位补0),然后取此4s位的中间2s位作为下一个种子数,并对此数规范化(即化成小于1的2s位的实数值),即为第一个(0,1)上的随机数。以此类推,即可得到一系列随机数。
若取种子r =11,那么 取r的平方 r^2 = 121, 不足4s位高位补0,就是0121, 中间2s位为12,规范化后为0.12,取round(0.12) 即为0.,下一个就从12算起.【笔者理解】
如果一般生成的是均匀分布,那么如何变成高斯分布呢?
这是笔者从一篇博客中借鉴的如何从均匀分布变成高斯分布的方法,可供参考,理论证明忽略。^_^. 如果大家感兴趣,可以自己试着推导证明过程,但我认为是需要一定的数学功底的。
#include <stdlib.h>
#include <stdio.h>
#define PI 3.141592654double
double gaussrand( )
{
static double U, V;
static int phase = 0;
double z;
if(phase == 0)
{
U = rand() / (RAND_MAX + 1.0);
V = rand() / (RAND_MAX + 1.0);
Z = sqrt(-2.0 * log(U))* sin(2.0 * PI * V);
}
else
{
Z = sqrt(-2.0 * log(U)) * cos(2.0 * PI * V);
}
phase = 1 - phase;
return Z;