我想从相对较大的总体中抽取n个样本,而不进行替换。因此,我绘制随机数并跟踪以前的选择,因此每当绘制两次数字时都可以重新采样:

boost::mt19937 generator;
boost::uniform_int<> distribution(0, 1669 - 1);
boost::variate_generator<boost::mt19937, boost::uniform_int<> >
        gen(generator, distribution);
int n = 100;

std::vector<int> idxs;
while(static_cast<int>(idxs.size()) < n)
{
    // get random samples
    std::generate_n(std::back_inserter(idxs), n - idxs.size(),
                    gen);
    // remove duplicates
    // keep everything that's not duplicates to save time
    std::sort(idxs.begin(), idxs.end());
    std::vector<int>::iterator it = std::unique(idxs.begin(), idxs.end());
    idxs.resize(std::distance(idxs.begin(), it));
}

不幸的是,我遇到了上面使用的常量的无限循环。

我添加了一些输出(表明它一直选择相同的数字),并在尝试显示问题10次后停止:
boost::mt19937 generator;
boost::uniform_int<> distribution(0, 1669 - 1);
boost::variate_generator<boost::mt19937, boost::uniform_int<> >
        gen(generator, distribution);
int n = 100;

int repeat = 0;
std::vector<int> idxs;
while(static_cast<int>(idxs.size()) < n)
{
    if(repeat++ > 10) break;
    cout << "repeat " << repeat <<
            ", " << idxs.size() << " elements" << endl;
    std::generate_n(std::back_inserter(idxs), n - idxs.size(),
                    gen);
    cout << "last " << idxs.back() << endl;
    std::sort(idxs.begin(), idxs.end());
    std::vector<int>::iterator it = std::unique(idxs.begin(), idxs.end());
    idxs.resize(std::distance(idxs.begin(), it));
}

代码打印
repeat 1, 0 elements
last 1347
repeat 2, 99 elements
last 1359
repeat 3, 99 elements
last 1359

依此类推,如果我不终止程序,这似乎永远循环。这不应该发生,对吧?我只是不幸吗?还是我做错了什么?

简短解决方案
感谢@jxh!使用引用有助于:
boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
        gen(generator, distribution);

最佳答案

问题是generate_n创建了您创建的生成器gen的副本。因此,在对generate_n的调用结束时,gen的状态不变。因此,每次重新循环时,都会再次生成相同的序列。

解决此问题的一种方法是在variate_generator中使用对您的随机数生成器对象的引用:*

boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
        gen(generator, distribution);

*由于我在Boost方面的经验有限,因此我最初的建议相当笨拙。在此答案中,我采用了问询者实现的解决方案。

关于c++ - 来自大量种群的随机样本陷入无限循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18323661/

10-17 02:36