根据给定的概率分布从集合中提取值

时间:2017-07-22 16:28:48

标签: c++ algorithm c++11 boost statistics

我必须解决这个问题:

vector<int> myset={1,2,3,4};
vector<double> distribution ={0.01,0.1,0.3,0.59};

我必须根据给定的发行版 myset 中选择一些值。实际上,发布 myset 并未修复。它们具有相同的尺寸,但是这个尺寸可以改变并且也很大。我可以统一提取范围[0 100]中的数字,并且这样做:

int extracted_numb;
int numb = rand(0,100);
if(numb<1)
  extracted_numb=myset[0];
else if(numb<11)
  extracted_numb=myset[1];
else if(numb<41)
  extracted_numb=myset[2];
else
  extracted_numb=myset[3];

但我再说一遍,我不知道在实际案例中发布 myset 的维度(因为是用户参数),因此我不知道 if 要做多少。

我问是否有一个很好的算法来解决这个问题,也许是C ++的一些原生库或已经完成它的Boost

(我正在使用Boost 1.63和C ++ 11)

1 个答案:

答案 0 :(得分:4)

使用C ++ 11,使用random::discrete_distribution选择myset的索引。 (Boost有类似的功能。)

示例(改编自cppreference链接):

#include <iostream>
#include <map>
#include <random>
#include <vector>

int main()
{
    std::vector<int> myset = {10,22,35,47};
    std::vector<double> distribution = {0.01,0.1,0.3,0.59};
    std::random_device rd;
    std::mt19937 gen(rd());
    std::discrete_distribution<> d(distribution.begin(), distribution.end());
    std::map<int, int> m;
    for(int n=0; n<10000; ++n) {
        ++m[myset[d(gen)]];
    }
    for(auto p : m) {
        std::cout << p.first << " generated " << p.second << " times\n";
    }
}

Live on coliru