2021年7月5日 星期一

多機率分佈

 這個小程式方便產生不同機率分佈的亂數,建構函數接受 vector<double> 含陣列各位置的機率分佈權值,實際運作時會傳回命中的陣列的索引

#include <chrono>
#include <random>
#include <iostream>
#include <vector>

using namespace std;

// 多機率分佈
class Multi_probability_distribution
{  
  size_t Max;
  vector<double> m_Probability_accumulation;
public:
  // Constructor
  Multi_probability_distribution(const vector<double> &Probability_distribution)
    :Max(Probability_distribution.size()-1),
    m_Probability_accumulation(Probability_distribution.size())
  {
    m_Probability_accumulation[0] = Probability_distribution[0];
    for (size_t i = 1; i <= Max; ++i)
      m_Probability_accumulation[i] = m_Probability_accumulation[i - 1] +
      Probability_distribution[i];

    double Max_v = m_Probability_accumulation[Max];

    for (double& v : m_Probability_accumulation)
      v /= Max_v;
  }

  size_t operator()()
  {
    static minstd_rand0 Generator((unsigned)
      chrono::system_clock::now().time_since_epoch().count());
    static uniform_real_distribution<double> Distribution(0.0, 1.0);
    double number = Distribution(Generator);

    size_t Start = 0, End = Max;

    // 二分搜尋加快速度
    while (Start != End)
    {
      size_t Sel = (Start + End)/2;
      if (number < m_Probability_accumulation[Sel])
        End = Sel;
      else
        Start = Sel + 1;
    }

    return Start;
  }
};

int main()
{
  vector<double> pd{1,3,5}; // 期望陣列各位置的機率分佈權值
  vector<size_t> Score(pd.size(),0); // 累記實際亂數產生所處位置

  Multi_probability_distribution MPD(pd);

  for (int i = 0; i < 100; ++i)
    ++Score[MPD()];

  for (int i = 0; i < Score.size(); ++i)
    cout << "[" << i << "] = " << Score[i] << endl;

}







沒有留言:

張貼留言