如何对0,1,..中的k个随机数进行采样..,n-1,而不缓存到数组

How to sample k random numbers in 0, 1, ..., n-1 without caching to an array

本文关键字:n-1 采样 缓存 数组 随机数 中的      更新时间:2023-10-16

我想对0、1、2、…中的k个不同的随机数进行采样(无需替换(。。。,n-1.

在我看来,我在网上找到的大多数解决方案都需要一个数组来存储所有数字,然后以某种方式打乱数组。然而,它需要O(n(空间。我想知道在C++中是否有任何不生成数组的方法。

确定

它被称为储层取样。基本上,你假装你得到的值是0,1,2。。。,从流中抽取n-1,对随机数进行采样并与储层进行交换。

曾经是一个伪代码,调试过它,现在它应该只工作

#include <iostream>
#include <random>
#include <vector>
static int N = 0;
static int s = 0;
int next_item() { // emulate incoming with the stream
if (s == N) // all values are streamed
return -1;
return s++;
}
std::vector<int> RS(int k) {
std::vector<int> result;
std::mt19937 rng(987654321);
int sp = 0; // position in the stream
for (;; ) {
int v = next_item();
if (v < 0)
break;
if (sp < k)
result.push_back(v);
else
{
std::uniform_int_distribution<int> uni(0, sp);
int idx = uni(rng);
if (idx < k)
result[idx] = v;
}
++sp;
}
return result;
}
int main() {
s = 0;
N = 10000;
auto v = RS(10);
for (auto e : v) {
std::cout << e << "n";
}
return 0;
}