【发布时间】:2016-04-26 16:12:07
【问题描述】:
在 C++ 中是否有一种无需替换的良好且高效的采样算法,可以轻松应用于以下函数?
它需要两个向量,new 和 old,并通过从前者重复采样将后者填充到一个循环中(rng.i0 是一个随机数生成器函数,我使用它返回一个介于 0 和给定值)。
void diluationexpansionstep(std::vector<long> &oldpopulation,
std::vector<long> &newpopulation,
long newpopsize)
{
for (int i = 1; i <= newpopsize;i++) {
int index_a = rng.i0(oldpopulation.size());
newpopulation.push_back(oldpopulation[index_a]);
}
}
更新::
感谢您提供有用的回复。因为我想使用我自己的 RNG 而不是 C++ 中的内置 RNG,所以我最终构建了以下基于 Fisher Yates 的函数,其中 rng.i0 是一个返回 0 和整数参数之间的随机整数的函数。
void FisherYatesShuffle(vector<long> &indices){
for (int k = 0; k < indices.size(); k++) {
int r = k + rng.i0(indices.size()-k);
swap(indices[k], indices[r]);
}
}
void diluationexpansionstep(std::vector<long> &oldpopulation,
std::vector<long> &newpopulation,
long newpopsize){
vector<long> indices(oldpopulation.size());
std::iota(std::begin(indices),std::end(indices),0);
FisherYatesShuffle(indices);
for (int i = 0; i <= newpopsize-1;i++){
newpopulation.push_back(oldpopulation[indices[i]]);
}
}
据我所知,这项工作可以准确而合理地快速完成。
【问题讨论】:
-
不是您的示例采样 with 替换,因为您没有从
oldpopulation中删除任何内容,并且您没有确保您选择的索引不是t dups(除非那是rng.i0在做什么,我不认识)? -
我不确定你想在这里问什么。您能否澄清“无需替换”,您能否提供 rng.i0(...) 因为您要求“可以轻松应用于以下功能”。你的问题到底是什么?
-
@Elyasin - 我假设“没有替换”意味着从源中选择一个随机元素,然后从减少的源中选择一个后续元素(删除第一个元素),等等。换句话说,选择“无替换”与选择“有替换”的标准定义。
-
用“不重复”来形容不是更准确吗?