通过采样填充新矢量而无需替换旧矢量

时间:2016-04-26 16:12:07

标签: c++ c++11 vector shuffle

C ++中是否有一个优秀而有效的算法,无需替换就可以轻松应用于以下函数?

它需要两个向量newold,并通过从前者重复采样在循环中填充后者(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]);
    }
}

更新::

感谢您提供有用的回复。因为我想在C ++中使用我自己的RNG而不是内置的RNG,所以我结束了构造以下基于Fisher Yates的函数,其中rng.i0是一个函数,它返回0和整数参数之间的随机intiger。

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]]);
        }
    }

就我能准确而合理地快速地说出这项工作而言。

1 个答案:

答案 0 :(得分:0)

A&#34;优质高效&#34;使用std::random_shuffle中的<algorithm>

来最小化开发人员时间和最大化正确性的算法
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

using namespace std;

vector<long> random_sample_without_replacement(const vector<long>& source, int newpopsize)
{
    assert(newpopsize >= 0 && newpopsize <= source.size());
    auto result { source };
    std::random_shuffle(result.begin(), result.end());
    result.resize(newpopsize);
    return result;
}

int main() {
    vector<long> test { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    auto result { random_sample_without_replacement(test, 5) };
    for (auto& e : result) cout << e << " ";
    cout << endl;
    return 0;
}

Working example here.