相关疑难解决方法(0)

如何简洁,便携,彻底地播种mt19937 PRNG?

我似乎看到很多答案,有人建议使用它<random>来生成随机数,通常伴随着这样的代码:

std::random_device rd;  
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 5);
dis(gen);
Run Code Online (Sandbox Code Playgroud)

通常这会取代某种"邪恶的憎恶",例如:

srand(time(NULL));
rand()%6;
Run Code Online (Sandbox Code Playgroud)

我们可能会批评旧的方式,认为time(NULL)提供低熵,time(NULL)可预测,最终结果是不均匀的.

但所有这一切都适用于新的方式:它只有一个更光亮的贴面.

  • rd()返回一个unsigned int.这至少有16位,可能是32位.这还不足以为MT的19937位状态提供种子.

  • 使用std::mt19937 gen(rd());gen()(以32位播种并查看第一个输出)不能提供良好的输出分布.7和13永远不会是第一个输出.两粒种子产生0.十二粒种子产生1226181350.(链接)

  • std::random_device可以(有时是)实现为具有固定种子的简单PRNG.因此,它可能在每次运行时产生相同的序列.(链接)这甚至比time(NULL).

更糟糕的是,尽管存在它们包含的问题,但复制和粘贴上述代码片段非常容易.对此的一些解决方案需要获得可能不适合每个人的大型 .

鉴于此,我的问题是如何在C++中简洁,便携,彻底地播种mt19937 PRNG?

鉴于上述问题,一个很好的答案:

  • 必须完全播种mt19937/mt19937_64.
  • 不能单独依赖std::random_devicetime(NULL)作为熵的来源.
  • 不应该依赖Boost或其他图书馆.
  • 应该适合少量的线条,这样看起来很好,可以复制粘贴到答案中.

思考

  • 我目前的想法是,输出来自std::random_device(可能通过XOR)time(NULL),从地址空间随机化得到的值,以及硬编码常量(可以在分配期间设置)以获得熵的最佳努力.

  • std::random_device::entropy() 没有很好地说明std::random_device可能做什么或不做什么.

c++ random c++11

106
推荐指数
4
解决办法
7189
查看次数

使用"<random>"的不可重现的随机数

我正在尝试创建一个为多个发行版生成随机数的类,同时保持它们的可重现性(通过设置初始种子).

代码似乎工作,直到我开始使用正态分布和奇怪的错误表面.这些主要是:

  • 如果我取消注释double a = rnd.rnorm(0.0, 1.0);-line(第40行)(即如果我rnorm在设置种子之前调用),则正态分布的第一个随机数不再匹配,随后的随机数再次匹配
  • 如果我从正态分布中检索奇数个随机数,则将正常随机数移一(例如,通过将第39行设置为int n = 3;)
  • 如果我一起做这两件事,随机数在另一个方向上移一个(领先)

现在我的问题是,是什么导致了这种奇怪的行为?我RNG是以错误的方式实施的吗?最重要的是,我该如何解决?

如果您想自己测试结果,可以使用此http://cpp.sh/9phre

或这个

#include <stdio.h>
#include <random>

// Class to create random numbers 
// Main functions to set the seed: setseed()
// create uniformly distributed values: runif()
// and normally distributed values: rnorm()
class RNG {
public:
    RNG(int seed = (int) time(0)) {
        setseed(seed);
    };
    ~RNG() {};
    void setseed(int newSeed) {
        re.seed(newSeed);
    };

    double runif(double minNum, double maxNum) …
Run Code Online (Sandbox Code Playgroud)

c++ random

8
推荐指数
1
解决办法
204
查看次数

如果我们在不同的机器上将c ++ 11 mt19937作为相同的种子,我们将获得相同的随机数序列

从灵感和类似的问题,我想学习如何做在C++ 11周的行为mt19937伪随机数生成器,当两个单独的机器,它与相同的输入种子.

换句话说,我们有以下代码;

std::mt19937 gen{ourSeed};
std::uniform_int_distribution<int> dest{0, 10000};
int randNumber = dist(gen);
Run Code Online (Sandbox Code Playgroud)

如果我们在不同的时间在不同的机器上尝试这个代码,我们每次都会获得相同的randNumber值序列或不同的序列吗?

在任何一种情况下,为什么会这样呢?

还有一个问题:

无论种子如何,这段代码会无限地随机生成数字吗?我的意思是,例如,如果我们在一个运行数月但没有停止的程序中使用这个代码块,那么数字的生成或数字的一致性会有问题吗?

c++ random c++11

6
推荐指数
1
解决办法
1188
查看次数

实现之间的随机输出不同

我用libstdc ++,libc ++和dinkumware尝试过这个程序:

#include <iostream>
#include <algorithm>
#include <vector>
#include <random>
#include <functional>
#include <limits>

int main()
{
    std::vector<int> v(10);

    std::mt19937 rand{0};
    std::uniform_int_distribution<> dist(
        1, 10
    );

    std::generate_n(v.begin(), v.size(),
        std::bind(dist, rand));

    for (auto i : v)
        std::cout << i << " ";
}
Run Code Online (Sandbox Code Playgroud)

输出分别是:

6 6 8 9 7 9 6 9 5 7 

6 1 4 4 8 10 4 6 3 5 

5 10 4 1 4 10 8 4 8 4 
Run Code Online (Sandbox Code Playgroud)

每次运行的输出都是一致的,但正如您所看到的,它们是不同的.说明?

c++ random c++11

5
推荐指数
1
解决办法
217
查看次数

标签 统计

c++ ×4

random ×4

c++11 ×3