c++ - 如何生成升序随机整数列表

标签 c++ algorithm sorting random

我有一个包含 n 个元素的外部集合,我想随机选择其中的一些 (k) 个元素,将这些元素的索引输出到某个序列化数据文件。我希望索引按严格的升序输出,并且没有重复项。 n 和 k 都可能很大,简单地将整个数组存储在该大小的内存中通常是不可行的。

我想出的第一个算法是从 1 到 n-k 中选择一个随机数 r[0]... 然后从 r[i-1]+1 到 n- 中选择一个连续的随机数 r[i] k+i,一次只需要为'r'存储两个条目。然而,一个相当简单的分析表明,选择小数字的概率与整个集合均匀分布时的概率不一致。例如,如果 n 是十亿,k 是十亿分之一,那么使用我刚才描述的方法选择第一个条目的概率非常小(十亿分之一),实际上,因为一半的条目是被选中时,第一个应该被选中的概率为 50%。即使我使用外部排序对 k 个随机数进行排序,我也必须丢弃所有重复项,然后重试。随着 k 接近 n,重试次数将继续增加,并且无法保证终止。

如果可能的话,我想找到一个 O(k) 或 O(k log k) 的算法来执行此操作。我将使用的实现语言是 C++11,但伪代码中的描述可能仍有帮助。

最佳答案

如果在实践中 k 与 n 具有相同的数量级,也许非常简单的 O(n) 算法就足够了:

assert(k <= n);
std::uniform_real_distribution rnd;
for (int i = 0; i < n; i++) {
    if (rnd(engine) * (n - i) < k) {
        std::cout << i << std::endl;
        k--;
    }
}

它以相等的概率生成所有升序序列。

关于c++ - 如何生成升序随机整数列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37690539/

相关文章:

c++ - 为什么在循环之前将 const 标量值分配给 const 会有所帮助?

c++ - 指针运算符的正式名称

java - 偏序比较器

c++ - 在 linux 终端中只编译编辑过的文件

python - 即使基本情况是完美的,递归也不会终止

performance - 计算数字的归一化和工程科学记数法的最快算法

algorithm - 计算德州扑克或奥马哈手牌对抗 8 只随机对手手牌的获胜概率的软件如何工作?

python - 在 Python 3 中按字典顺序对混合数据类型的深度嵌套列表进行排序

linux - 如何使用 'sort' 按第一列文本排序,然后按第二列数字排序?

具有内存位置的 C++ 删除运算符