Is there a limit in your design on how low the lowest random number should be, and how high the highest random number generated should be?
The first way was along the lines of what I was looking for. I want a number less than 10 OR greater than 20.
|
Indeed, my first post can do that
custom_random_number(10, 20);
You should note though that the implementation in my first post has nondeterministic runtime -- technically, there's an astronomically small chance that the generator could keep generate 5 for an hour of running inside the while loop.
Here's an implementation that has a deterministic runtime, and is bounded between -100 and 100, inclusive.
https://ideone.com/JpWMYK
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
#include <iostream>
#include <random>
#include <map>
#include <iomanip>
int keep_out_of_range(int low, int high, int number)
{
if (number >= low && number <= high)
{
int halfway = (low + high) / 2;
int halfrange = (high - low) / 2;
if (number > halfway)
number += halfrange;
else
{
number -= halfrange + 1;
}
}
return number;
}
int main()
{
const int MinGen = -100;
const int MaxGen = 100;
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(MinGen, MaxGen);
const int nrolls = 10000; // number of experiments
// generate numbers, make a histogram of distribution
std::map<int, int> histogram;
for (int i = 0; i < nrolls; i++) {
int random_number = distribution(generator); // here's where # is generated
random_number = keep_out_of_range(10, 20, random_number);
++histogram[random_number];
}
// print the histogram
for (auto p : histogram) {
std::cout << std::fixed << std::setprecision(1) << std::setw(2)
<< p.first << ' ' << std::string(p.second/(nrolls/(10*(MaxGen-MinGen))), '*') << '\n';
}
return 0;
}
| |
Not that it still isn't uniform, because they way we "pushed" numbers in the [10, 20] range out will make numbers surrounding the [10, 20] range more likely to be hit.
-6 ********
-5 ***********
-4 **********
-3 **********
-2 ************
-1 **********
0 *********
1 **********
2 ************
3 **************
4 **********************
5 ***********************
6 ***************
7 *****************
8 *******************
9 ***********************
21 **********************
22 ******************
23 ********************
24 **********************
25 *****************
26 **********
27 ********
28 *********
29 **********
30 ***********
31 ***********
32 *********
33 ********
34 *********
|
Note: You could have unbounded + deterministic runtime as well, change uniform_int_distribution to normal_distribution.
_______________________________________________
Anyway.... all of this is complicated, and it's begging the question: What do you want to do with your random numbers after you generate them?
Usually, for things such as games, people want a
bounded output, usually with a uniform distribution. Ex: Bounding between 0 and 100, or bounding between the coordinates of the player map.
My first post has a generating method that is unbounded, meaning that there's a chance of the number 1 million being generated. If, in your program, you generate 1 million, what are you planning on doing with it?