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

C++ 如何使用std::rand生成非重复的随机数序列,c++,c++11,random,C++,C++11,Random,在最后一个示例中,生成的序列是: 1 1 6 5 2 2 5 5 6 2 我如何保证生成的所有数字在它们之间是不同的?如果这是可能的,如果我们生成的数字超过了游侠的大小,那么我们的预期行为是什么 我之所以需要它,是因为我必须在cv::Mat中随机选择少量行(比如10行),其中有数十万行(甚至数百万行)。当然。对于真正的生成器,获取数字的可能性不依赖于以前的任何数字。伪随机数生成器试图很好地模拟这种特性 如果您希望生成不重复的数字,那么最好的办法是围绕std::shuffle:即定义所需的数字,

在最后一个示例中,生成的序列是:

1 1 6 5 2 2 5 5 6 2
我如何保证生成的所有数字在它们之间是不同的?如果这是可能的,如果我们生成的数字超过了游侠的大小,那么我们的预期行为是什么

我之所以需要它,是因为我必须在
cv::Mat
中随机选择少量行(比如10行),其中有数十万行(甚至数百万行)。

当然。对于真正的生成器,获取数字的可能性不依赖于以前的任何数字。伪随机数生成器试图很好地模拟这种特性

如果您希望生成不重复的数字,那么最好的办法是围绕
std::shuffle
:即定义所需的数字,然后将其洗牌。

当然。对于真正的生成器,获取数字的可能性不依赖于以前的任何数字。伪随机数生成器试图很好地模拟这种特性

如果您希望生成不重复的数字,那么最好的解决方案是围绕
std::shuffle
:即定义所需的数字,然后对其进行shuffle

我之所以需要它,是因为我必须在
cv::Mat
中随机选择一小部分行(比如10行),其中包含数十万(甚至数百万)行

模板
标准::向量选取部分(标准::大小计数,标准::大小最大值,生成器和g){
ASSERT(count*2最大值)抛出标准::超出范围(“计数”);
ASSERT(count<1000);//O(n^2)实现,对于较大的count来说速度较慢
std::选择载体;
均匀分布(0,最大值);
while(selected.size()
这假设max与count相比相当大,count很小

对于较大的计数,您可以使用
std::unordered_集
或类似的集替换
selected
(删除线性查找)

对于小计数,线性查找将更快

当计数接近最大值时,您可以找到不选择的元素。然后倒过来

但这两个都超出了你的问题范围,所以我只是提出了主张

我之所以需要它,是因为我必须在
cv::Mat
中随机选择一小部分行(比如10行),其中包含数十万(甚至数百万)行

模板
标准::向量选取部分(标准::大小计数,标准::大小最大值,生成器和g){
ASSERT(count*2最大值)抛出标准::超出范围(“计数”);
ASSERT(count<1000);//O(n^2)实现,对于较大的count来说速度较慢
std::选择载体;
均匀分布(0,最大值);
while(selected.size()
这假设max与count相比相当大,count很小

对于较大的计数,您可以使用
std::unordered_集
或类似的集替换
selected
(删除线性查找)

对于小计数,线性查找将更快

当计数接近最大值时,您可以找到不选择的元素。然后倒过来



但这两个问题都超出了您的问题范围,所以我只是提出了断言。

是的,这是可能发生的。另外,必须说明的是:如果所有的数字都不同,它们现在就不一样了,不是吗。与实数不同,只有有限数量的
double
s…“如果所有的数字都不同,它们现在就不一样了,是吗?”我整个周末都在考虑这个问题。直到@KerrekSB提到这一点之前,我一直在考虑这个问题。我妻子今晚出去了。带着一瓶好酒,我将着手写一份证明。是的,这是可能发生的。另外,必须说明的是:如果所有的数字都不同,它们现在就不一样了,不是吗。与实数不同,只有有限数量的doubles…“如果所有的数字都不同,它们现在就不一样了,是吗?”我整个周末都在考虑这个问题。直到@KerrekSB提到这一点之前,我一直在考虑这个问题。我妻子今晚出去了。带着一瓶好酒,我将开始写一个证明。谢谢你的回答,
std::shuffle
绝对是个好主意。如果我有数百万个元素呢?创建和洗牌一个向量(如)可能会耗费大量内存和时间,你不认为吗?你可能会得到一个1d Sobol序列。Sobol序列是均匀分布的一个很好的近似值,从数学上讲,它不会产生重复。您可能可以对其输出的各个部分进行随机播放。感谢您的回答,
std::shuffle
绝对是个好主意。如果我有数百万元素呢?创建和洗牌一个向量(如)可能会耗费大量内存和时间,你不认为吗?你可能会得到一个1d Sobol序列。Sobol序列是均匀分布的一个很好的近似值,从数学上讲,它不会产生重复。你可能可以洗牌它的输出部分。所以如果我理解正确,你只需随机选择一个数字,如果它已经被选中,你只需丢弃它。在我的问题中,
count
在10到50之间,但是
max
是高度可变的。为了让您了解,在一些非常罕见的情况下(1/5k),我们有
count>max
,我必须选择所有行。这有点不可预测,因为矩阵行是图像中“感兴趣点”的数量(根据算法)。@justHelloWorld您的问题说明您想要一个解决方案,从1000行、数百万行或r中选择少量行
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;
}