关于随机数分布器的问题

今天看C++Primer介绍的随机数,准备使用一下,结果出现点小问题,就是每次运行程序获得的首个随机数都是一样的。

(已使用time作为随机数种子,按理说应该至少每秒产生的随机数都是不一样的)

int main()
{
    default_random_engine e(time(0));
    uniform_int_distribution<unsigned> u(0,99);
    cout<<u(e)<<endl;

}

如果直接输出e()那么会产生0-2147483646之间的随机数,程序每次运行,至少每秒运行产生的随机数都不一样。

但是用了分布器之后,u(e)输出的第一个值总是一样的。通过手动传入种子,可以知道相近的种子产生的第一个随机值

也是相近的,那分布器到底对原始值做了怎样的压缩呢?

int main()
{
    default_random_engine e;
    uniform_int_distribution<unsigned> u(0,99);
    for(size_t i = 0; i < 100000; ++i)
    {
        e.seed(i);
        if(u(e) != 0)
        {
            cout<<i<<endl;
            break;
        }
    }

    cout<<"0-9:"<<12778.0/60.0<<endl;
    cout<<"0-99:"<<1278.0/60.0<<endl;
    cout<<"0-999:"<<128.0/60.0<<endl;
}

程序输出i的值为1278,也就是说种子0-1277产生的随机数经过u(0,99)压缩后得到的都是0,呃,那么也就是说

如果用time(0)作为种子,产生0-99之间的随机数,可能程序最多在1277秒内产生的第一个随机值都是一样的。

如果程序运行一次,关掉,再运行一次,结果却一样。。。

其它测试:0-9 12777秒; 0-999 127秒

这应该是生成器算法的问题吧,相近的种子产生相近的随机值,分布器对一定范围的随机值压缩成一个值。。。

结果就是一段时间内的首个随机值都一样。。。真杯具

解决办法,丢掉第一个值,呃。那么换个生成器试试

int main()
{
    mt19937 e(time(0));
    uniform_int_distribution<unsigned> u(0,99);
    cout<<u(e);
}

这次的结果还算可以接受,每次都不一样了,搜了一下mt19937的介绍,结果msdn上有

typedef mersenne_twister_engine<unsigned int, 32, 624, 397,
    31, 0x9908b0df,
    11, 0xffffffff,
    7, 0x9d2c5680,
    15, 0xefc60000,
    18, 1812433253> mt19937;

typedef mersenne_twister_engine<unsigned long long, 64, 312, 156,
    31, 0xb5026f5aa96619e9ULL,
    29, 0x5555555555555555ULL,
    17, 0x71d67fffeda60000ULL,
    37, 0xfff7eee000000000ULL,
    43, 6364136223846793005ULL> mt19937_64;

噢,原来是梅森螺旋算法啊~,当时想用的时候不知道尖括号里都该填什么,这下有两个现成的可用了。

时间: 2024-10-03 21:03:45

关于随机数分布器的问题的相关文章

RNG—随机数产生器

RNG 随机数产生器 RNG g_rng(12345); /******************************************************************************************************/ 用OpenCV做算法的朋友们肯定为随机数烦恼过,新版本一直支持随机数产生器啦,而且还继续支持之前版本的c格式的函数,不过与时俱进,我这里介绍C++的RNG类.它可以压缩一个64位的i整数并可以得到scalar和array的随机数.目

通过均匀分布随机数产生器获得一个高斯分布随机数产生器

一.Box-Muller Transfrom 对于给定一个能产生(0,1)之间的均匀分布的随机数产生器,可以利用Box-Muller transform来获得一个产生标准高斯分布随机数的随机数产生器. Box-Muller transform可以描述如下: 假设U1和U2是两个独立的随机变量,并且其分布为(0,1)之间的均匀分布,可以得到 Z1和Z2是两个互相独立的随机变量,并且这两个随机变量的分布为标准高斯分布. 二.Matlab实验 代码 %% clear clc; clear; %% un

OpenCV笔记(六)——随机数产生器、绘制文字

一.随机数产生器 在OpenCV中,我们主要使用RNG类(即Random Number Generator)来产生随机数. RNG rng(); // 默认以0xffffffff作为随机数产生器的种子 我们也可以以系统的当前时间作为随机数产生器的种子.这也是常用的手段. #include <time.h> RNG rng( (unsigned int)time(NULL) ); 另外,我们可以产生一定范围内的均匀分布或者高斯分布(均值为零)的随机数 rng.uniform(0, 10); //

使用均匀分布随机数产生器构造任意分布的随机数产生器

一.算法原理 在概率论中,有下面重要的结论:设随机变量Y的概率分布函数F(y)为连续函数,而X是在(0,1)上均匀分布的随机变量,设,则Z与Y有相同的分布. 因此,理论上,我们可以用(0,1)上的均匀分布来得到任意分布的随机数 设随机变量Y的概率密度函数为f(y),则,我们可以按照下面的步骤来获得满足其分布的随机数: 1.根据给定的概率密度函数(PDF)f(y),通过积分算出概率分布函数F(y): 2.计算概率分布函数F(y)的反函数, 3.生成一个(0,1)上均匀分布的随机数变量X, 4.那么

nump中的为随机数产生器的seed

在python的程序中,发现了如下的伪随机数产生的代码 rng = numpy.random.RandomState(23355) arrayA = rng.uniform(0,1,(2,3)) 该段代码的目的是产生一个2行3列的assarray,其中的每个元素都是[0,1]区间的均匀分布的随机数 这里看以看到,有一个23355这个数字,其实,它是伪随机数产生器的种子,也就是“the starting point for a sequence of pseudorandom number” 对于

Boost程序库完全开发指南——深入C++“准”标准库(第3版)

内容简介  · · · · · · Boost 是一个功能强大.构造精巧.跨平台.开源并且完全免费的C++程序库,有着“C++‘准’标准库”的美誉. Boost 由C++标准委员会部分成员所设立的Boost 社区开发并维护,使用了许多现代C++编程技术,内容涵盖字符串处理.正则表达式.容器与数据结构.并发编程.函数式编程.泛型编程.设计模式实现等许多领域,极大地丰富了C++的功能和表现力,能够使C++软件开发更加简捷.优雅.灵活和高效. <Boost程序库完全开发指南——深入C++“准”标准库(

【转】ns2 随机数

随机数产生器(Random Number Generator) [前言] 随机数产生器在NS2中是非常重要的,举凡网络节点在NAM中的位置或者是应用程序在何时开始传送或结束数据传输,都会用到随机数产生器.因此,在本节中,笔者将介绍如何在NS2中使用随机数产生器. [种子(seed)和分布(distribution)] 随机数产生器所产生的数值是由种子和分布所控制的,不同的种子或者是分布就会产生出不同的随机数.我们可以这样思考,当一个种子和分布决定之后,随机数产生器会产生出一个表格,表格内是由一长

【C++11】随机数函数库random

1.随机数由生成器和分布器结合产生 生成器generator:能够产生离散的等可能分布数值 分布器distributions: 能够把generator产生的均匀分布值映射到其他常见分布,如均匀分布uniform,正态分布normal,二项分布binomial,泊松分布poisson 2.分布器利用运算符()产生随机数,要传入一个generator对象作为参数 std::default_random_engine generator; std::uniform_int_distribution<

shell实例浅谈之三产生随机数七种方法

一.问题 Shell下有时需要使用随机数,在此总结产生随机数的方法.计算机产生的的只是"伪随机数",不会产生绝对的随机数(是一种理想随机数).伪随机数在大量重现时也并不一定保持唯一,但一个好的伪随机产生算法将可以产生一个非常长的不重复的序列. 二.随机数 1.生成随机数的七种方法 (1)通过内部系统变量($RANDOM) echo $RANDOM 生成0-32767之间的整数随机数,若超过5位可以加个固定10位整数,然后进行求余. 生成400000~500000的随机数: #!/bin