在最后一个例子中阅读std::uniform_int_distribution生成的序列是:
1 1 6 5 2 2 5 5 6 2
我如何保证所有生成的数字在它们之间有所不同?如果可能的话,如果我们生成的数字多于游侠大小,那么预期的行为是什么?
我需要这个,因为我必须在cv::Mat
中随机选择少量行(比如说10个),行数十万(甚至数百万)。
答案 0 :(得分:5)
当然。对于 true 生成器,获取数字的可能性不依赖于任何先前的数字。伪随机数生成器试图非常好地模拟这个属性。
如果您想生成没有重复的数字,那么最好的办法是围绕--verbosity=debug
建立解决方案:即定义您想要的数字,然后将它们随机播放。
答案 1 :(得分:0)
我需要这个,因为我必须在
cv::Mat
中随机选择少量行(比如说10个),行数十万(甚至数百万)。
template<class Generator>
std::vector<std::size_t> pick_some( std::size_t count, std::size_t max, Generator& g ) {
ASSERT(count*2 < max); // massively slow if count is close to max
if (count > max) throw std::out_of_range("count");
ASSERT(count < 1000); // O(n^2) implementation, slow for large count
std::vector<std::size_t> selected;
uniform_int_distribution<std::size_t> distribution(0,max);
while (selected.size() < count) {
auto v = distribution(g);
if (std::find( begin(selected), end(selected), v ) != end(selected))
continue;
selected.push_back(v);
}
return selected;
}
这假设与计数相比最大值非常大,而且计数很小。
对于较大的计数,您可以将selected
替换为std::unordered_set
或某些(取消线性查找)。
对于小计数,线性查找会更快。
当计数接近最大值时,您可以找到而不是选择的元素。然后反转。
但是这两个都在你的问题域之外,所以我只是放入ASSERT。