Gre*_*ers 11 c++ stl boost-random
我有一个程序使用boost :: random的mt19937随机数生成器.我需要做一个random_shuffle,并希望为此生成的随机数来自这个共享状态,这样它们就可以确定为mersenne twister之前生成的数字.
我试过这样的事情:
void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
struct bar {
boost::mt19937 &_state;
unsigned operator()(unsigned i) {
boost::uniform_int<> rng(0, i - 1);
return rng(_state);
}
bar(boost::mt19937 &state) : _state(state) {}
} rand(state);
std::random_shuffle(vec.begin(), vec.end(), rand);
}
Run Code Online (Sandbox Code Playgroud)
但是我得到一个模板错误,用rand调用random_shuffle.但是这有效:
unsigned bar(unsigned i)
{
boost::mt19937 no_state;
boost::uniform_int<> rng(0, i - 1);
return rng(no_state);
}
void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
std::random_shuffle(vec.begin(), vec.end(), bar);
}
Run Code Online (Sandbox Code Playgroud)
可能是因为它是一个实际的函数调用.但显然这并没有使国家不受最初的mersenne twister影响.是什么赋予了?有没有办法在没有全局变量的情况下做我想做的事情?
Chr*_*ung 13
在评论中,罗伯特古尔德要求后人的工作版本:
#include <algorithm>
#include <functional>
#include <vector>
#include <boost/random.hpp>
struct bar : std::unary_function<unsigned, unsigned> {
boost::mt19937 &_state;
unsigned operator()(unsigned i) {
boost::uniform_int<> rng(0, i - 1);
return rng(_state);
}
bar(boost::mt19937 &state) : _state(state) {}
};
void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
bar rand(state);
std::random_shuffle(vec.begin(), vec.end(), rand);
}
Run Code Online (Sandbox Code Playgroud)
cop*_*pro 11
在C++ 03中,您无法基于函数本地类型实例化模板.如果你将rand类移出函数,它应该可以正常工作(免责声明:未经测试,可能存在其他恶意错误).
这个要求已经在C++ 0x中放宽了,但是我不知道这个改变是否已经在GCC的C++ 0x模式中实现了,而且我会惊讶地发现它存在于任何其他编译器中.
我在这里使用tr1而不是boost :: random,但不应该太重要.
以下是有点棘手,但它的工作原理.
#include <algorithm>
#include <tr1/random>
std::tr1::mt19937 engine;
std::tr1::uniform_int<> unigen;
std::tr1::variate_generator<std::tr1::mt19937,
std::tr1::uniform_int<> >gen(engine, unigen);
std::random_shuffle(vec.begin(), vec.end(), gen);
Run Code Online (Sandbox Code Playgroud)