是否有 C++/C 的高效构建功能可以快速均匀地对 b 条目进行采样,而无需替换 n 个条目?
Any efficient building function in C++/C to fast uniformly sample b entries without replacement from n entries?
似乎,在获取第一个b
条目之前使用shuffle(Index, Index+n, g)
仍然效率不高,因为n
非常大但b
非常小,其中 Index 是存储0 ... (n-1)
的向量/数组。
您可以采用标准的随机播放算法并将其修改为在仅随机播放前b
个条目后停止。
这是一个与 sh1 建议的不同的想法。 与之前的答案不同,它在数学上是合理的。没有 % BS。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <ostream>
#include <random>
#include <set>
#include <vector>
int main()
{
// Configuration.
auto constexpr n = 100;
auto constexpr b = 10;
// Building blocks for randomness.
auto const seed = std::mt19937::result_type{ std::random_device{}() };
std::cout << "seed = " << seed << std::endl;
auto engine = std::mt19937{ seed };
auto distribution = std::uniform_int_distribution<>{};
// Creating the data source. Not part of the solution.
auto reservoir = std::vector<int>{};
std::generate_n(std::back_inserter(reservoir), n,
[i = 0]() mutable { return i++; });
// Creating the sample.
// Idea attributed to Bob Floyd by Jon Bentley in Programming Pearls 2nd Edition.
auto sample = std::set<int>{};
for (auto i = n - b; i != n; ++i)
{
auto const param = std::uniform_int_distribution<>::param_type(0, i);
auto const j = distribution(engine, param);
(sample.find(j) == sample.cend())
? sample.insert(j)
: sample.insert(i);
}
// Converting the sample to an output vector and shuffle it, if necessary.
auto output = std::vector<int>(std::cbegin(sample), std::cend(sample));
std::shuffle(std::begin(output), std::end(output), engine);
// Print out the result.
for (auto const x : output) { std::cout << x << " "; }
std::cout << std::endl;
return 0;
}
相关文章:
- 模板参数替换失败,并且未完成隐式转换
- 如何用转义符替换字符串中的所有特殊字符
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- 如何用RISC-V GD32VF103CBT6开发板卸载精确的ADC过采样
- 在一个读写器队列中,我可以用volatile替换原子吗
- 用符号版本替换对函数的所有调用
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- 替换基于地图的所有引用
- 按平均值替换数组中的元素
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 如何将字节数组元素替换为修改的十六进制 ASCII 符号?
- 初始化 std::vector 替换为单大括号而不是双大括号
- 删除/替换C++字符串中的多字符 (ÿû)
- 将 malloc 替换为数组
- 如何替换此示例代码片段中已弃用的handler_type_t或 boost::asio::handler_type?
- 如何在C++中用'\'替换''来处理转义序列?
- 替换密码:哪一个?
- 替换 C++17 中移除的绑定 1st
- 是否有 C++/C 的高效构建功能可以快速均匀地对 b 条目进行采样,而无需替换 n 个条目?
- 如何使用c++uniform_int_distribution在不替换的情况下进行采样