我有一个使用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);
}

但是我得到一个模板错误,用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);
}

可能是因为它是一个实际的函数调用。但显然这并没有使国家不受最初的mersenne twister影响。是什么赋予了?有没有办法在没有全局变量的情况下做我想做的事情?

有帮助吗?

解决方案

在C ++ 03中,您无法基于函数本地类型实例化模板。如果你将rand类移出函数,它应该可以正常工作(免责声明:未经测试,可能存在其他恶意错误)。

此要求已在C ++ 0x中放宽,但我不知道该更改是否已在GCC的C ++ 0x模式中实现,并且我会非常惊讶地发现它存在于任何其他编译器中。

其他提示

在评论中,罗伯特古尔德要求后人的工作版本:

#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);
}

我在这里使用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);

我认为值得指出的是,现在只使用标准库,这在C ++ 11中非常简单:

#include <random>
#include <algorithm>

std::random_device rd;
std::mt19937 randEng(rd());
std::shuffle(vec.begin(), vec.end(), randEng);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top