当前位置:  开发笔记 > IOS > 正文

C++ 11:如何使用<random>设置种子

如何解决《C++11:如何使用<random>设置种子》经验,为你挑选了2个好方法。



1> g24l..:

具有a的要点seed_seq是增加所生成序列的熵.如果您的系统上有random_device,则可以使用该随机设备中的多个数字进行初始化.在具有伪随机数生成器的系统上,我认为随机性没有增加,即生成的序列熵.

建立在你的方法基础上:

如果您的系统确实提供了随机设备,那么您可以像这样使用它:

  std::random_device r;
  // std::seed_seq ssq{r()};
  // and then passing it to the engine does the same
  default_random_engine eng{r()};
  uniform_real_distribution urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);

如果您的系统没有随机设备,那么您可以将其time(0)用作random_engine的种子

  default_random_engine eng{static_cast(time(0))};
  uniform_real_distribution urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);

如果您有多个随机源,您实际上可以这样做(例如2)

std::seed_seq seed{ r1(), r2() };
  default_random_engine eng{seed};
  uniform_real_distribution urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);

其中r1,r2是不同的随机设备,例如热噪声量子源.

当然你可以混合搭配

std::seed_seq seed{ r1(), static_cast(time(0)) };
  default_random_engine eng{seed};
  uniform_real_distribution urd(0, 1);
  cout << "Uniform [0, 1): " << urd(eng);

最后,我想用一个衬垫初始化:

  auto rand = std::bind(std::uniform_real_distribution{0,1},
              std::default_random_engine{std::random_device()()});
  std::cout << "Uniform [0,1): " << rand();

如果您担心time(0)具有第二精度,您可以high_resolution_clock通过请求以下bames23首先指定的纪元以来的时间来解决这个问题:

static_cast(std::chrono::high_resolution_clock::now().time_since_epoch().count()) 

或者只是玩CPU随机性

long unsigned int getseed(int const K)
{

    typedef std::chrono::high_resolution_clock hiclock;

    auto gett= [](std::chrono::time_point t0)
    {
        auto tn = hiclock::now();
        return static_cast(std::chrono::duration_cast(tn-t0).count());
    };

    long unsigned int diffs[10];
    diffs[0] = gett(hiclock::now());
    for(int i=1; i!=10; i++)
    {
        auto last = hiclock::now();
        for(int k=K; k!=0; k--)
        {
            diffs[i]= gett(last);
        }
    }

    return *std::max_element(&diffs[1],&diffs[9]);
}



2> bames53..:
#include 
#include 

using namespace std;

int main() {
    std::random_device r;                                       // 1
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; // 2
    std::mt19937 eng(seed);                                     // 3

    uniform_real_distribution urd(0, 1);

    cout << "Uniform [0, 1): " << urd(eng);
}

为了从伪随机数生成器获得不可预测的结果,我们需要不可预测的种子数据源.在1我们创建一个 std::random_device为此目的.在 2上,我们使用a std::seed_seq将由此产生的几个值组合random_device成适合于播种伪随机数发生器的形式.输入的数据越不可预测,seed_seq种子引擎的结果就越不可预测.在3我们创建一个随机数引擎,使用它seed_seq来播种引擎的初始状态.

A seed_seq可用于初始化多个随机数引擎; seed_seq每次使用时都会生成相同的种子数据.

注意:并非所有实现都提供非确定性数据的来源.检查您的实施文档std::random_device.


如果您的平台没有提供非确定性,random_device则可以使用其他一些来源进行播种.文章Simple Portable C++ Seed Entropy提出了许多替代资源:

高分辨率时钟,例如std::chrono::high_resolution_clock(time()通常分辨率为1秒,通常太低)

由于地址空间布局随机化(ASLR),现代操作系统上的内存配置会有所不同

CPU计数器或随机数生成器.C++不提供对这些的标准化访问,因此我不会使用它们.

线程ID

一个简单的计数器(只有你不止一次种子才有意义)

例如:

#include 
#include 
#include 
#include 
#include 

using namespace std;

// we only use the address of this function
static void seed_function() {}

int main() {
    // Variables used in seeding
    static long long seed_counter = 0;
    int var;
    void *x = std::malloc(sizeof(int));
    free(x);

    std::seed_seq seed{
        // Time
        static_cast(std::chrono::high_resolution_clock::now()
                                   .time_since_epoch()
                                   .count()),
        // ASLR
        static_cast(reinterpret_cast(&seed_counter)),
        static_cast(reinterpret_cast(&var)),
        static_cast(reinterpret_cast(x)),
        static_cast(reinterpret_cast(&seed_function)),
        static_cast(reinterpret_cast(&_Exit)),
        // Thread id
        static_cast(
            std::hash()(std::this_thread::get_id())),
        // counter
        ++seed_counter};

    std::mt19937 eng(seed);

    uniform_real_distribution urd(0, 1);

    cout << "Uniform [0, 1): " << urd(eng);
}

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有