问题
Version 3 Moved generator into a class. Is my new random number generation technique correct this time?
template<typename T = int>
class MyRandomGenerator
{
public:
MyRandomGenerator()
{
std::random_device rd;
gen = std::mt19937{rd()};
}
T getNumber(const T& From, const T& To)
{
std::uniform_int_distribution<T> dist(From, To);
return dist(gen);
}
private:
std::mt19937 gen;
};
And here my new position calculators:
auto calculate_x_position = [&]() ->sf::Uint32 {return RandGen.getNumber(0, W - 1); };
auto calculate_y_position = [&]() ->sf::Uint32 {return RandGen.getNumber(0, H - 1); };
Same pattern/problem as before:

Version 2 Creating ~3 maps per second of 10.000 stars per map. The outcome is still the same. Moreover, it gets even more clear that there is a pivot to the top of the maps. Example:

Original Question: i went into trying to draw a simple star map. For this i first calculate the x and y position for the stars. X and Y are within the range of width and height of the window.
This is my random number generating function:
template<typename T>
T getRandomNumberBetween(const T& Min, const T& Max)
{
static std::random_device rd;
static std::uniform_int_distribution<T> dist{Min, Max};
return dist(rd);
}
And i use it like this:
auto calculate_x_position = std::bind(inc::getRandomNumberBetween<sf::Uint32>, 0, Width-1);
auto calculate_y_position = std::bind(inc::getRandomNumberBetween<sf::Uint32>, 0, Height-1);
x = calculate_x_position(); //...
But as i draw my map over and over again it seems to me that there is a pivot to where most stars tend to be. E.g. the majority of stars are in the upper half of my window.
Example:

Am i using it wrong or having a wrong expectation here?... Because here it says:
This distribution produces random integers in a range [a,b] where each possible value has an equal likelihood of being produced.
Kind Regards
回答1:
Uniform distribution does not specifically mean that you will get an equal amount in each quadrant of the screen; It means that there is an equal chance of each point appearing. So if you do a simple 50:50 trial, it does not mean you will get 50:50 results.
However if you did a test with say 1,000,000 stars it is very likely that they will be nearly uniformly distributed. To me this seems like an error in sample size
回答2:
There are a couple of ways you could improve your code. An engine is only meant to be created once, not everytime you want a random number. And you usually don't want to use std::default_random_engine
because it may default to std::rand
. A better default is std::mt19937
. My example is pulled from The bell has tolled for rand():
#include <random>
std::mt19937& prng_engine()
{
thread_local static std::random_device rd{};
thread_local static std::mt19937 engine{rd()};
// Or you can replace the two previous lines with:
//thread_local static std::mt19937
// prng{std::random_device{}()};
return engine;
}
template<typename T>
T getRandomNumberBetween(T Min, T Max)
{
thread_local static std::uniform_int_distribution<T> dist{Min, Max};
return dist(prng_engine());
}
来源:https://stackoverflow.com/questions/29183501/uniform-int-distribution-used-wrong-here-my-results-seem-not-equally-distribut