Setting up a Discrete Distribution in C++

大兔子大兔子 提交于 2021-02-07 09:53:42

问题


After hours of struggling with this issue, I cannot find any explanations for my error.

I want the computer to pick a random number (weighted) between 0 and 120 (inclusive). I have an array, interval[], which holds the numbers from 0 to 120 (inclusive). I have another array, weights[], which holds the probabilities for choosing the ith element in the array. I want to define a probability distribution function for these data.

Here is what I tried. I get an error saying that no instance of constructor matches the argument list.

Snippet of my code:

std::vector< int> weights(121);
for (int i = 0; i < 121; i++)
{
    weights[i] = (teamData[i]).S();
}
discrete_distribution<> dist(weights.begin(), weights.end());

回答1:


From your linked page (emphasis mine)

std::piecewise_constant_distribution produces random floating-point numbers, which are uniformly distributed within each of the several subintervals [bi, bi+1), each with its own weight wi. The set of interval boundaries and the set of weights are the parameters of this distribution.

It expects floating point weights and boundaries, and one less weight than boundaries. It will also not output integers between 0-120, but floats.

You're passing it integer weights and boundaries so it fails to compile. But even when you fix that you're still going to get floating point values out of it...

Instead as you've discovered you want the disrete_distribution which you can set up like this: (modified from the linked pages documentation)

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

int main()
{
    // Setup the random bits
    std::random_device rd;
    std::mt19937 gen(rd());

    // Setup the weights (in this case linearly weighted)
    std::vector<int> weights;
    for(int i=0; i<120; ++i) {
        weights.push_back(i);
    }

    // Create the distribution with those weights
    std::discrete_distribution<> d(weights.begin(), weights.end());

    // use the distribution and print the results.
    std::map<int, int> m;
    for(int n=0; n<10000; ++n) {
        ++m[d(gen)/10];
    }
    for(auto p : m) {
        std::cout << p.first*10 << " - "<<p.first*10+9 << " generated " << p.second << " times\n";
    }
}



回答2:


Try this piece of code and see if you get the same problem.

 // piecewise_constant_distribution
#include <iostream>
#include <array>
#include <random>

int main()
{
  const int nrolls = 10000; // number of experiments
  const int nstars = 100;   // maximum number of stars to distribute

  std::default_random_engine generator;
  std::array<double,6> intervals {0.0, 2.0, 4.0, 6.0, 8.0, 10.0};
  std::array<double,5> weights {2.0, 1.0, 2.0, 1.0, 2.0};
  std::piecewise_constant_distribution<double>
    distribution (intervals.begin(),intervals.end(),weights.begin());

  int p[10]={};

  for (int i=0; i<nrolls; ++i) {
    int number = distribution(generator);
    ++p[number];
  }

  std::cout << "a piecewise_constant_distribution:" << std::endl;
  for (int i=0; i<10; ++i) {
    std::cout << i << "-" << i+1 << ": ";
    std::cout << std::string(p[i]*nstars/nrolls,'*') << std::endl;
  }
  return 0;
}


来源:https://stackoverflow.com/questions/31153610/setting-up-a-discrete-distribution-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!