简体   繁体   English

C ++-如何使用 <random> 填充std :: array

[英]c++ - How to use <random> to fill std::array

I am trying new ways to generate random numbers and fill them in an array. 我正在尝试生成随机数并将其填充到数组中的新方法。 So far I have done. 到目前为止,我已经完成了。

template<size_t SIZE>
void fill_array(array<int, SIZE>& a)
{
    default_random_engine dre;
    uniform_int_distribution<int> uid1(0, 1000);

    for (int i = 0; i < a.size(); i++)
    {
        a[i] = uid1(dre);

    }

}

My main file is very simply and looks like this 我的主文件非常简单,看起来像这样

    array<int, 10> a;

    Array3 a1;

    a1.fill_array(a);
    a1.print_array(a);

I thought I managed to get random numbers everytime I debug but I get the same numbers everytime. 我以为每次调试都能设法获得随机数,但是每次都能获得相同的数。 Weird enough sometimes I do get different numbers but then it's the same thing where I have to debug multiple times to get new numbers. 有时候我确实得到了不同的数字,这很奇怪,但是同样,我不得不多次调试才能获得新的数字。 What did I do wrong? 我做错了什么?

Even if you use std::random_device there's no guarantee to obtain a different sequence every time: 即使您使用std::random_device也不能保证每次都获得不同的序列:

std::random_device may be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (eg a hardware device) is not available to the implementation. 如果不确定性源(例如,硬件设备)不可用于实现,则可以根据实现定义的伪随机数引擎来实现std :: random_device。 In this case each std::random_device object may generate the same number sequence. 在这种情况下,每个std :: random_device对象都可以生成相同的数字序列。

That happened, for example, with older g++ implentation of stdlibc++ on Windows. 例如,在Windows上使用较旧的g ++实现stdlibc ++时就发生了这种情况。

Moreover, due to performace issues, random_device is generally only used (once) to seed a pseudo random bit generator such as the Mersenne twister engine ( std::mt19937 ). 而且,由于性能问题,通常只(一次)使用random_device来播种伪随机位生成器,例如梅森扭曲器引擎( std::mt19937 )。

Your fill function could be implemented like this: 您的填充功能可以这样实现:

#include <iostream>
#include <array>
#include <iterator>
#include <random>
#include <algorithm>

template< class Iter >
void fill_with_random_int_values( Iter start, Iter end, int min, int max)
{
    static std::random_device rd;    // you only need to initialize it once
    static std::mt19937 mte(rd());   // this is a relative big object to create

    std::uniform_int_distribution<int> dist(min, max);

    std::generate(start, end, [&] () { return dist(mte); });
}

int main()
{
    std::array<int, 10> a;

    fill_with_random_int_values(a.begin(), a.end(), 0, 1000);

    for ( int i : a ) std::cout << i << ' ';
    std::cout << '\n';
}

live demo HERE . 现场演示在这里

something along these lines: 遵循以下原则:

#include <random>
#include <array>
#include <algorithm>

template<class Engine, class Integer, size_t SIZE>
void fill_array(Engine& eng, std::array<Integer, SIZE>& a, Integer lower = 0, Integer upper = 1000)
{
    std::uniform_int_distribution<Integer> uid1(lower, upper);

    std::generate(a.begin(), a.end(), [&]
    {
        return uid1(eng);
    });
}

int main()
{
    std::random_device rnd;  // a source of machine-wide entropy
    std::default_random_engine eng(rnd()); // use it to initialise the psuedo-random engine

    std::array<int, 100> arr;
    fill_array(eng, arr);
}

May I suggest using std::vector instead of an array. 我可以建议使用std :: vector而不是数组。 If you use the std::rand function, you can seed it with time with srand(time(NULL)); 如果使用std :: rand函数,则可以使用srand(time(NULL));随时间播种它srand(time(NULL)); . Of course you will need to include time.h for this. 当然,您需要为此添加time.h。 You can fill the vector with generate(a.begin(), a.end(), rand); 您可以用generate(a.begin(), a.end(), rand);填充矢量generate(a.begin(), a.end(), rand); without using a loop. 不使用循环。 This will give you a new random number sequence every time. 每次都会为您提供一个新的随机数序列。

You aren't initializing the seed to a random value. 您没有将种子初始化为随机值。 So your random generator always starts from the same position. 因此,您的随机生成器始终从同一位置开始。

Here's an example of how to initialize your seed to start from some place. 这是一个如何初始化种子以从某个地方开始的示例。 Essentially you need some source that isn't always the same so your generator produces random results, time is the most common value used. 本质上,您需要一些并不总是相同的来源,因此您的生成器会产生随机结果,时间是最常用的值。

#include <iostream>
#include <chrono>
#include <random>

int main ()
{
  typedef std::chrono::high_resolution_clock clock;


  std::default_random_engine generator(clock::now().time_since_epoch().count());
  std::uniform_int_distribution<int> rand(0,1000);

  for(int i = 0;i < 10;i++)
 {
    std::cout << rand(generator) << std::endl;
 }

  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM