Reputation: 35
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?
Upvotes: 1
Views: 6409
Reputation: 104
May I suggest using std::vector instead of an array. If you use the std::rand function, you can seed it with time with srand(time(NULL));
. Of course you will need to include time.h for this. You can fill the vector with generate(a.begin(), a.end(), rand);
without using a loop. This will give you a new random number sequence every time.
Upvotes: -1
Reputation: 69854
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);
}
Upvotes: 2
Reputation: 12749
Even if you use std::random_device
there's no guarantee to obtain a different sequence every time:
std::random_device may be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation. In this case each std::random_device object may generate the same number sequence.
That happened, for example, with older g++ implentation of stdlibc++ on Windows.
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
).
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.
Upvotes: 5
Reputation: 2307
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;
}
Upvotes: -2