3

I'd like to use the std::mt19937 random number generator to produce a list of numbers between 0 and 255. "Once a number has been chosen, it should not appear again in the set." - it's this bit I don't know how to do. The mathematical term for this escapes me(!)

std::mt19937 twister; std::uniform_int_distribution<int> distribution; twister.seed(91210); distribution = std::uniform_int_distribution<int>(0,255); std::vector vNumbers; vNumbers.resize(256); for( int n = 0; n < 256; ++ n ) vNumbers[n] = distribution(twister); 
6
  • 1
    Do you need to retain the order in which they are produced? Commented Jul 30, 2013 at 9:04
  • 1
    No, order doesn't matter; I want random order :) Commented Jul 30, 2013 at 9:06
  • 1
    What I mean is, if you use std::set to get uniqueness, your numbers get sorted. I.e. if you generate 57 1 9 44 102 1 and store it in a std::set, you get back 1 9 44 57 102. Is this acceptable? (And you keep generating until mySet.size()==255). Commented Jul 30, 2013 at 9:08
  • 1
    Oh I see. You want exactly the integer 0-255 inclusive, in some random order, correct? If so, you could fill the std::vector with 0 1 ... 255 with std::iota, then get random order with std::random_shuffle. Commented Jul 30, 2013 at 9:09
  • 1
    @fishfood Why do you shout your requirements "I want [this particular thing]" when you just said "order doesn't matter"? Clearly, it does matter, then? Commented Jul 30, 2013 at 9:09

2 Answers 2

10

There's algorithms for that:

// fill a vector ith [0..255]: std::vector<int> vNumbers(256); std::iota(vNumbers.begin(), vNumbers.end(), 0); // shuffle it std::random_shuffle(vNumbers.begin(), vNumbers.end()); // done 

With C++11 you can pass in your own generator for the RNG: (see also comments)

std::shuffle(vNumbers.begin(), vNumbers.end(), twister); 

Or you could roll your own (google Fisher-Yates, or see Knuth)


Of course the iota can be replaced by te following

for (int i=0; i<256; ++i) vNumbers[i] = i; 
Sign up to request clarification or add additional context in comments.

15 Comments

And you can even use a random engine to shuffle the numbers!
@delnan It's a bit ludicrous to mention only that :/ But yeah: the background for that: eternallyconfuzzled.com/arts/jsw_art_rand.aspx
@sehe My comment was about the sample you added, which is incorrect.
@interjay Except that it's not incorrect: coliru.stacked-crooked.com/… or ideone.com/elp3IF
@sehe It's UB because the program violates the constraints given by the standard on how the function is supposed to behave: "the call rand(n) shall return a randomly chosen value in the interval [0,n)".
|
2

You could use std::set instead of std::vector, as it will ensure you have no duplicates. Just loop until the size of the set is the number of value you want.


Since it seems you want one of each number in just a random order, you don't really need to generate random numbers, just generate a sequence from 0 to 255, and then randomly shuffle them.

This can easily be done with some standard algorithms, like std::iota and std::random_shuffle:

std::vector<int> values{256}; std::iota(values.begin(), values.end(), 0); std::random_shuffle(values.begin(), values.end()); 

6 Comments

what about the case where the RNG generates a repeat and it's inserted into the set. if the set rejects it, I'm left with < 255 numbers in my set. I'm looking for a way to instruct the random number generator not to issue any repeating data.
I should also point out that I'm copying this data into a texture for use in a shader program, so using a vector is also desirable for ease of copying the data to the gfx card.
@fishfood Continue until the size of the set is the number of values you want. And it's easy to copy a set to a vector when needed.
I know that's one way to pluck the turkey, but I'd like to find a way to instruct the random number generator not to issue any repeating data. I'm sure it exists :)
@fishfood The thing about random numbers is that they are random, even a series of ten of the same number can be considered random. See e.g. xkcd.com/221 for a humorous (but valid) take on it.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.