我想從沒有更換的相對較大的人口中提取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);
也許我誤解了你的代碼。但是,使用範圍(0..1668)對容器進行混洗並取第一個(n)指數更容易嗎? – hetepeperfan
@hetepeperfan,對於1668年,我同意,是的。對於2e9來說更是如此。它適用於非常大的人羣,但這是失敗案例。 – chuck