如何实现奖品获奖机会的相对比例?

时间:2015-04-30 06:40:05

标签: c++

例如,我有一个奖品列表,并且对于每个奖品,相对比率常数代表获得它的机会,如下面的代码所示:

vector<pair<string,int> > prizeBox;
prizeBox.push_back(make_pair("toy car",100));
prizeBox.push_back(make_pair("football",50));
prizeBox.push_back(make_pair("book",50));
prizeBox.push_back(make_pair("cash 1000",10));
prizeBox.push_back(make_pair("cash 5000",5));
prizeBox.push_back(make_pair("free expensive lunch",2));
prizeBox.push_back(make_pair("free expensive dinner",2));
prizeBox.push_back(make_pair("special big price",1));

在上面的代码中,“玩具车”有100 /(100 + 50 + 50 + 10 + 5 + 2 + 2 + 1)的机会获得。我知道rand()可以用来获取一个随机数,但在这种情况下如何使用呢?

(另外我不相信我需要一个新的矢量,增加100“玩具车”,50“足球”等等......)

3 个答案:

答案 0 :(得分:2)

您可以轻松地使用std::discrete_distribution来代替创建自己的发布:

int main()
{
    //create vector and fill it
    std::vector<std::tuple<std::string,int> > prizeBox { {"toy car",100}, {"football",50}, {"book",50}, {"cash 1000",10} };

    //create a vector of the second entries of vector-elements of prizeBox
    std::vector<int> chance;
    std::transform(std::begin(prizeBox), std::end(prizeBox), std::back_inserter(chance), [](auto p){return std::get<1>(p);});

    //set up the distribution and the random number generator
    auto dist = std::discrete_distribution<int>(std::begin(chance), std::end(chance));
    std::mt19937_64 rng;

    //draws ten time from the prize box
    for(int i=0;i<10;++i)
    {
        std::cout<<std::get<0>(prizeBox[dist(rng)])<<std::endl;
    }
}

DEMO

编辑:上述解决方案的唯一问题是将元组的第一个条目复制到新的向量中。 Here你可以找到直接在元组向量上工作的方法。

答案 1 :(得分:0)

如果你想用权重概率进行索引,我想我会这样做

srand(time(NULL));

vector<pair<string,int> > prizeBox; 

int total = 100+50+50+10+5+2+2+1;

int random = rand()%(total);
if(random < 100){
    // acces to prizeBox[0];
}
else if(random < 150){
    //acces to prizeBox[1];
}
else if (random < 200)
    // and so on 

PS:您可以使用初始化程序列表来执行标签(它比几个push_back更漂亮

    vector<pair<string,int> > prizeBox  = { {"toy car",100} , {"football",50} };

答案 2 :(得分:0)

这是一个根据您想要的机会抽取随机奖品的功能。我们的想法是首先通过向量迭代并获得机会的总和。然后,生成从1到该总和的随机数并再次迭代,从随机数中减去当前机会。当随机数小于当前机会时,您将获得分类奖金。下面的代码显示了实现。

#include <vector>
#include <string>
#include <stdlib.h>
#include <time.h>

using namespace std;

string drawPrize (vector<pair<string, int> > prizeBox) {
    //iterate through vector to get the sum of the weigths.
    int total = 0;
    for (vector<pair<string,int> >::iterator it = prizeBox.begin() ; it != prizeBox.end(); ++it)
        total += it->second;

    // getting a random number
    srand(time(NULL));
    int r = rand() % total + 1; // a number from 1 to total

    // finding the prize
    vector<pair<string,int> >::iterator it = prizeBox.begin();
    while (r > it->second && it != prizeBox.end()) {
        r -= it->second;
        it++;
    }

    // returning the sorted prize
    return it->first;
}