【问题标题】:How to generate a non-repetitive sequence of random numbers using std::rand如何使用 std::rand 生成非重复的随机数序列
【发布时间】:2017-01-20 18:21:58
【问题描述】:

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

1 1 6 5 2 2 5 5 6 2

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

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

【问题讨论】:

  • 是的,它可能会发生。另外,必填:dilbert.com/strip/2001-10-25
  • 如果所有数字都不同,他们现在就不会统一了,对吧。
  • 与实数不同,doubles...
  • “如果所有数字都不同,他们现在就不会统一了,不是吗。”我整个周末都会考虑这个问题。
  • 直到@KerrekSB 提到这一点,我才这样做。我妻子今晚出去了。带着一瓶漂亮的红葡萄酒,我将着手编写证明。

标签: c++ c++11 random


【解决方案1】:

当然。对于 true 生成器,获得数字的可能性不依赖于任何先前的数字。伪随机数生成器试图非常好地模拟这个属性。

如果您想生成没有重复的数字,那么最好的办法是基于std::shuffle 的解决方案:即定义您想要的数字,然后将它们随机排列。

【讨论】:

  • 感谢您的回答,std::shuffle 绝对是个好主意。如果我有数百万个元素怎么办?创建和改组向量(如 here )可能会非常耗费内存和时间,你不觉得吗?
  • 您可能会使用一维 Sobol 序列。
  • sobol 序列是均匀分布的良好近似,从数学上讲不会绘制重复。您也许可以随机播放其输出的各个部分。
【解决方案2】:

我需要这个,因为我必须在具有数十万(甚至数百万)行的 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;
}

这假设 max 与 count 相比相当大,而 count 很小。

对于更大的计数,您可以将 selected 替换为 std::unordered_set 或类似的(删除线性查找)。

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

随着计数接近最大值,您可以找到要选择的元素。然后反转。

但是这两个都在你的问题域之外,所以我只输入了 ASSERT。

【讨论】:

  • 所以如果我理解正确的话,你只是随机选择一个数字,如果它已经被选择,你只需丢弃它。在我的问题中,count 介于 10 和 50 之间,但 max 变化很大。只是为了让您理解,在一些非常罕见的情况下(1 超过 5k),我们有 count&gt;max,我必须选择所有行。这有点不可预测,因为矩阵行是图像中“有趣点”的数量(根据SIFT 算法)。
  • @justHelloWorld 您的问题表明您需要一种解决方案,用于从数千或数百万行中选择少量行。您的评论表明您的问题不是您要问的。如果您有一个不是上面所问的新问题,请随时单击上面的“提问”按钮,我相信也会有人解决这个问题。或者,您可以在我的回答中使用 cmets,我预计您的问题并勾勒出如何解决这些情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-27
  • 2020-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多