Adding new types of random number generators: 1. shuffle a list non-deterministic (not the default shuffle) 2. get random numbers of a range 3. get random numbers of a range, without duplicates (the latest based on floty's idea). Note that the existing random number works quite well, the new approach uses boost::random and is more flexible if other distributions are needed for the AI.
The code is currently disabled due to link problems on debian/ubuntu (boost::random seems to be missing there).
This commit is contained in:
@@ -23,10 +23,77 @@
|
|||||||
#include <core/loghelper.h>
|
#include <core/loghelper.h>
|
||||||
#include <core/openssl_wrapper.h>
|
#include <core/openssl_wrapper.h>
|
||||||
|
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
#include <boost/nondet_random.hpp>
|
||||||
|
#include <boost/random/uniform_int.hpp>
|
||||||
|
#include <boost/random/variate_generator.hpp>
|
||||||
|
#include <set>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
#if 0 // TODO temporarily disabled until build problems are solved
|
||||||
|
boost::thread_specific_ptr<boost::random_device> g_rand_state;
|
||||||
|
|
||||||
|
struct nondet_rng : std::unary_function<unsigned, unsigned> {
|
||||||
|
boost::random_device &_state;
|
||||||
|
unsigned operator()(unsigned i) {
|
||||||
|
boost::uniform_int<> rng(0, i - 1);
|
||||||
|
return rng(_state);
|
||||||
|
}
|
||||||
|
nondet_rng(boost::random_device &state) : _state(state) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void InitRandState() {
|
||||||
|
if (!g_rand_state.get()) {
|
||||||
|
g_rand_state.reset(new boost::random_device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tools::ShuffleArrayNonDeterministic(int *inout, unsigned count)
|
||||||
|
{
|
||||||
|
InitRandState();
|
||||||
|
nondet_rng rand(*g_rand_state);
|
||||||
|
std::random_shuffle(&inout[0], &inout[count], rand);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tools::GetRand(int minValue, int maxValue, unsigned count, int *out)
|
||||||
|
{
|
||||||
|
InitRandState();
|
||||||
|
boost::uniform_int<> dist(minValue, maxValue);
|
||||||
|
boost::variate_generator<boost::random_device&, boost::uniform_int<> > gen(*g_rand_state, dist);
|
||||||
|
int *startPtr = out;
|
||||||
|
for (unsigned i = 0; i < count; i++) {
|
||||||
|
*startPtr++ = gen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tools::GetRandUnique(int minValue, int maxValue, unsigned count, int *out)
|
||||||
|
{
|
||||||
|
InitRandState();
|
||||||
|
unsigned numCreated = 0;
|
||||||
|
int *startPtr = out;
|
||||||
|
std::set<int> tmpSet;
|
||||||
|
for (unsigned i = 0; i < count; i++) {
|
||||||
|
boost::uniform_int<> dist(minValue, maxValue - numCreated);
|
||||||
|
boost::variate_generator<boost::random_device&, boost::uniform_int<> > gen(*g_rand_state, dist);
|
||||||
|
*startPtr = gen();
|
||||||
|
std::set<int>::const_iterator v = tmpSet.begin();
|
||||||
|
std::set<int>::const_iterator end = tmpSet.end();
|
||||||
|
while (v != end) {
|
||||||
|
if (*v <= *startPtr) {
|
||||||
|
(*startPtr)++;
|
||||||
|
}
|
||||||
|
++v;
|
||||||
|
}
|
||||||
|
tmpSet.insert(*startPtr);
|
||||||
|
startPtr++;
|
||||||
|
numCreated++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Tools::getRandNumber(int start, int end, int howMany, int* randArray, bool different, int* bad, int countBad)
|
void Tools::getRandNumber(int start, int end, int howMany, int* randArray, bool different, int* bad, int countBad)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,11 @@
|
|||||||
class Tools
|
class Tools
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static void ShuffleArrayNonDeterministic(int *inout, unsigned count);
|
||||||
|
static void GetRand(int minValue, int maxValue, unsigned count, int *out);
|
||||||
|
static void GetRandUnique(int minValue, int maxValue, unsigned count, int *out);
|
||||||
|
|
||||||
static void getRandNumber(int, int, int, int*, bool, int* = 0, int = 0);
|
static void getRandNumber(int, int, int, int*, bool, int* = 0, int = 0);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user