如何使用std :: rand生成一个非重复的随机数序列

时间:2017-01-20 18:21:59

标签: c++ c++11 random

在最后一个例子中阅读std::uniform_int_distribution生成的序列是:

1 1 6 5 2 2 5 5 6 2

我如何保证所有生成的数字在它们之间有所不同?如果可能的话,如果我们生成的数字多于游侠大小,那么预期的行为是什么?

我需要这个,因为我必须在cv::Mat中随机选择少量行(比如说10个),行数十万(甚至数百万)。

2 个答案:

答案 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。