ALERT!
Click here to register with a few steps and explore all our cool stuff we have to offer!
Home
Upgrade
Credits
Help
Search
Awards
Achievements
 3916

Populating a std::vector with random 64-bit integers

by bitm0de - 01-11-2016 - 02:45 AM
#1
Here's an example snippet I put together which uses a fair seeded RNG to populate a std::vector with random 64-bit integers using std::generate_n() from the STL:
Code:
#pragma warning(disable: 4996)
#pragma warning(default: 4555)

#include <iostream>
#include <algorithm>
#include <random>
#include <numeric>
#include <cstdint>
#include <vector>

typedef std::linear_congruential_engine
< uint64_t, 0x5851F42D4C957F2DU, 0x14057B7EF767814FU, 0U >
klcg;

int main()
{
  std::random_device rd;
  uint64_t rng_seed = (uint64_t(rd()) << 32) | rd();
  klcg rng { rng_seed };

  int i = 0;
  const size_t N = 10;
  std::vector<uint64_t> v(N);
  std::generate_n(v.begin(), N, rng);
  for (const auto &n : v)
  {
    std::cout << "v[" << i++ << "]" << " - " << n << std::endl;
  }
}

This is much better than the alternative that I see with most people using a single 32-bit seed for the Mersenne Twister's RNG... std::random_device is much better if the hardware supports it, and the implementation. The problem with seeding std::mt19937 RNG with a single 32-bit integer is that the internal state uses 624 32-bit integers, in addition to a few more for maintenance. At that point you've completely destroyed entropy...

Example output:
[Image: qBXdM31.png]

The numbers I've used in the above LCG are Knuth's preferred values in hex form. Note, that for this to work you must reserve (in this case) for N elements because begin() and end() are not used from the std::vector<T>::iterator, it's blindly using the ++ operator to point to the next element via an iterator for each iteration up to N values. If space is not reserved internally for these elements you'll go out of bound of the allocated space and the program will probably crash and segfault. If using an older standard of C++, the way to do this would be to call reserve().

Btw, I'm not sure if it has been fixed yet for GCC, but they have not yet implemented a non-deterministic way for Windows on generating a new random using std::random_device, therefore, it uses an internal hardcoded value and the results will yield the same sequence for the same seed. If you compile this using Microsoft's compiler, it acts the way it should because they have implemented it to use the host system to allow for a non-deterministic RNG.
Reply

Users browsing: 2 Guest(s)