Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Negative Binomial Sales Quota Example.

Boost , Math Toolkit 2.5.0 , Negative Binomial Distribution Examples

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Пример программыnegative_binomial_example1.cpp (полный исходный код)демонстрирует простое использование для определения вероятности выполнения квоты продаж.

На основаниипроблемы доктор Диана Эванс, профессор математики в Технологическом институте Роуз-Хулмана.

Пэт обязан продавать конфеты, чтобы собрать деньги на поездку в 6-й класс. В районе тридцать домов, и Пэт не должен возвращаться домой, пока не будут проданы пять конфетных баров. Поэтому ребенок ходит от двери к двери, продавая конфеты. В каждом доме есть 0,4 вероятность (40%) продажи одного конфетного батончика и 0,6 вероятность (60%) продажи ничего.

Какова функция вероятностной массы (плотности) для продажи последнего (пятого) шоколадного батончика в н-м доме?

Отрицательное биномиальное (r, p) распределение описывает вероятность k неудач и r успехов в k+r испытаниях Бернулли (p) с успехом в последнем испытании. (Испытание АБернулли— это испытание, в котором возможны только два исхода, успех неудачи и р — вероятность успеха). Смотрите такжеРаспределение БернуллииПриложения Бернулли.

В этом примере мы намеренно произведем множество вычислений и выводов, чтобы продемонстрировать, как отрицательное биномиальное распределение может быть реализовано с этой библиотекой: оно также преднамеренно перекомментировано.

Во-первых, нам нужно определить макросы для контроля ошибок и дискретных политик обработки. Для этого простого примера мы хотим избежать выбрасывания исключения (политики по умолчанию) и просто вернуть бесконечность. Мы хотим рассматривать распределение как непрерывное, поэтому мы выбираем дискретную политику квантиля реального, а не политику по умолчанию integer_round_outwards.

#define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real

После этого нам нужны некоторые включения, чтобы обеспечить легкий доступ к отрицательному биномиальному распределению.

[Caution] Caution

Важно, чтобы #включить распределения и т. д.послевышеописанных #определений

И, конечно, нам нужна библиотека iostream.

#include <boost/math/distributions/negative_binomial.hpp>
  // for negative_binomial_distribution
  using boost::math::negative_binomial; // typedef provides default type is double.
  using  ::boost::math::pdf; // Probability mass function.
  using  ::boost::math::cdf; // Cumulative density function.
  using  ::boost::math::quantile;
#include <iostream>
  using std::cout; using std::endl;
  using std::noshowpoint; using std::fixed; using std::right; using std::left;
#include <iomanip>
  using std::setprecision; using std::setw;
#include <limits>
  using std::numeric_limits;

Всегда разумно использовать блоки, потому что политика по умолчанию заключается в том, чтобы сделать исключение, если что-то пойдет не так.

Простой блок улова (см. ниже) гарантирует, что вы получите полезное сообщение об ошибке вместо резкого прерывания программы.

try
{

Продажа пяти конфет означает получение пяти успехов, поэтому успехи r = 5. Таким образом, общее количество испытаний (n, в данном случае посещаемых домов) составляет = успехи + неудачи или k + r = k + 5.

double sales_quota = 5; // Pat's sales quota - successes (r).

В каждом доме есть 0,4 вероятность (40%) продажи одного конфетного батончика и 0,6 вероятность (60%) продажи ничего.

double success_fraction = 0.4; // success_fraction (p) - so failure_fraction is 0.6.

Отрицательное биномиальное (r, p) распределение описывает вероятность k неудач и r успехов в k+r испытаниях Бернулли (p) с успехом в последнем испытании.Испытание Бернулли— это испытание, в котором возможны только два исхода, успех неудачи и р — вероятность успеха.

Поэтому мы начинаем с построения отрицательного биномиального распределения с параметрами sales_quota (необходимые успехи) и вероятностью успеха.

negative_binomial nb(sales_quota, success_fraction); // type double by default.

Для подтверждения отображаются параметры success_fraction & successes дистрибутива.

cout << "Pat has a sales per house success rate of " << success_fraction
  << ".\nTherefore he would, on average, sell " << nb.success_fraction() * 100
  << " bars after trying 100 houses." << endl;
int all_houses = 30; // The number of houses on the estate.
cout << "With a success rate of " << nb.success_fraction()
  << ", he might expect, on average,\n"
    "to need to visit about " << success_fraction * all_houses
    << " houses in order to sell all " << nb.successes() << " bars. " << endl;
Pat has a sales per house success rate of 0.4.
Therefore he would, on average, sell 40 bars after trying 100 houses.
With a success rate of 0.4, he might expect, on average,
to need to visit about 12 houses in order to sell all 5 bars.

Случайная переменная процента — это количество домов, которые необходимо посетить, чтобы продать пять конфетных батончиков, поэтому мы заменяем k = n — 5 на отрицательный биномиальный (5, 0,4) и получаемфункцию плотности вероятностираспределения посещенных домов. Очевидно, что лучший возможный случай - это то, что Пэт делает продажи на всех первых пяти домах.

Вычисляем это с помощью функции pdf:

cout << "Probability that Pat finishes on the " << sales_quota << "th house is "
  << pdf(nb, 5 - sales_quota) << endl; // == pdf(nb, 0)

Конечно, он не мог закончить на менее чем 5 домах, потому что он должен продать 5 шоколадных батончиков. Так что 5-й дом - это первый, на котором он может закончить.

Чтобы закончить на или до 8-го дома, Пат должен закончить в 5-м, 6-м, 7-м или 8-м доме. Вероятность того, что он закончит наровно( == ) на любом доме, является функцией плотности вероятности (pdf).

cout << "Probability that Pat finishes on the 6th house is "
  << pdf(nb, 6 - sales_quota) << endl;
cout << "Probability that Pat finishes on the 7th house is "
  << pdf(nb, 7 - sales_quota) << endl;
cout << "Probability that Pat finishes on the 8th house is "
  << pdf(nb, 8 - sales_quota) << endl;
Probability that Pat finishes on the 6th house is 0.03072
Probability that Pat finishes on the 7th house is 0.055296
Probability that Pat finishes on the 8th house is 0.077414

Сумма вероятностей для этих домов — кумулятивная функция распределения (cdf). Вычислить ее можно, добавив индивидуальные вероятности.

cout << "Probability that Pat finishes on or before the 8th house is sum "
  "\n" << "pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = "
  // Sum each of the mass/density probabilities for houses sales_quota = 5, 6, 7, & 8.
  << pdf(nb, 5 - sales_quota) // 0 failures.
    + pdf(nb, 6 - sales_quota) // 1 failure.
    + pdf(nb, 7 - sales_quota) // 2 failures.
    + pdf(nb, 8 - sales_quota) // 3 failures.
  << endl;
pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = 0.17367

Или, как правило, лучше, используя отрицательную биномиальнуюкумулятивнуюфункцию распределения.

cout << "\nProbability of selling his quota of " << sales_quota
  << " bars\non or before the " << 8 << "th house is "
  << cdf(nb, 8 - sales_quota) << endl;
Probability of selling his quota of 5 bars on or before the 8th house is 0.17367
cout << "\nProbability that Pat finishes exactly on the 10th house is "
  << pdf(nb, 10 - sales_quota) << endl;
cout << "\nProbability of selling his quota of " << sales_quota
  << " bars\non or before the " << 10 << "th house is "
  << cdf(nb, 10 - sales_quota) << endl;
Probability that Pat finishes exactly on the 10th house is 0.10033
Probability of selling his quota of 5 bars on or before the 10th house is 0.3669
cout << "Probability that Pat finishes exactly on the 11th house is "
  << pdf(nb, 11 - sales_quota) << endl;
cout << "\nProbability of selling his quota of " << sales_quota
  << " bars\non or before the " << 11 << "th house is "
  << cdf(nb, 11 - sales_quota) << endl;
Probability that Pat finishes on the 11th house is 0.10033
Probability of selling his quota of 5 candy bars
on or before the 11th house is 0.46723
cout << "Probability that Pat finishes exactly on the 12th house is "
  << pdf(nb, 12 - sales_quota) << endl;
cout << "\nProbability of selling his quota of " << sales_quota
  << " bars\non or before the " << 12 << "th house is "
  << cdf(nb, 12 - sales_quota) << endl;
Probability that Pat finishes on the 12th house is 0.094596
Probability of selling his quota of 5 candy bars
on or before the 12th house is 0.56182

Наконец, рассмотрим риск того, что Пэт не продаст свою квоту в 5 баров даже после посещения всех домов. Вычислите вероятность того, что онбудетпродавать на или до последнего дома: Вычислите вероятность того, что он продаст всю свою квоту на самый последний дом.

cout << "Probability that Pat finishes on the " << all_houses
  << " house is " << pdf(nb, all_houses - sales_quota) << endl;

Вероятность продажи его квоты в 5 баров на 30-й дом есть

Probability that Pat finishes on the 30 house is 0.00069145

Когда ему действительно не повезло!

Какова вероятность того, что Пэт исчерпает все 30 домов по соседству, авсе ещене продает необходимые 5 конфет?

cout << "\nProbability of selling his quota of " << sales_quota
  << " bars\non or before the " << all_houses << "th house is "
  << cdf(nb, all_houses - sales_quota) << endl;
Probability of selling his quota of 5 bars
on or before the 30th house is 0.99849

<Sothe riskof failingeven aftervisiting allthe housesis 1-thisprobability,><1 -cdf(nb,all_houses -sales_quota>< Butusing thisexpression maycause seriousinaccuracy,soitwould bemuch betterto usethe complementof thecdf:Sotherisk offailing evenat,orafter,the31th(non-existent) housesis 1-thisprobability,><1 -cdf(nb,all_houses -sales_quota)>Но использование этого выражения может вызвать серьезную неточность. Так что было бы гораздо лучше использовать __комплемент cdf (см.Почему комплементы?.

cout << "\nProbability of failing to sell his quota of " << sales_quota
  << " bars\neven after visiting all " << all_houses << " houses is "
  << cdf(complement(nb, all_houses - sales_quota)) << endl;
Probability of failing to sell his quota of 5 bars
even after visiting all 30 houses is 0.0015101

Мы также можем использовать квантиль (процентиль), обратный cdf, чтобы предсказать, на каком доме будет заканчиваться Пэт. Для 8-го дома:

double p = cdf(nb, (8 - sales_quota));
cout << "Probability of meeting sales quota on or before 8th house is "<< p << endl;
Probability of meeting sales quota on or before 8th house is 0.174
cout << "If the confidence of meeting sales quota is " << p
    << ", then the finishing house is " << quantile(nb, p) + sales_quota << endl;
cout<< " quantile(nb, p) = " << quantile(nb, p) << endl;
If the confidence of meeting sales quota is 0.17367, then the finishing house is 8

Требование абсолютной уверенности в том, что все 5 будут проданы, подразумевает бесконечное количество испытаний. (Конечно, в поместье всего 30 домов, поэтому он никогда не может быть уверенв продаже своей квоты).

cout << "If the confidence of meeting sales quota is " << 1.
    << ", then the finishing house is " << quantile(nb, 1) + sales_quota << endl;
//  1.#INF == infinity.
If the confidence of meeting sales quota is 1, then the finishing house is 1.#INF

И так же для некоторых других вероятностей:

cout << "If the confidence of meeting sales quota is " << 0.
    << ", then the finishing house is " << quantile(nb, 0.) + sales_quota << endl;
cout << "If the confidence of meeting sales quota is " << 0.5
    << ", then the finishing house is " << quantile(nb, 0.5) + sales_quota << endl;
cout << "If the confidence of meeting sales quota is " << 1 - 0.00151 // 30 th
    << ", then the finishing house is " << quantile(nb, 1 - 0.00151) + sales_quota << endl;
If the confidence of meeting sales quota is 0, then the finishing house is 5
If the confidence of meeting sales quota is 0.5, then the finishing house is 11.337
If the confidence of meeting sales quota is 0.99849, then the finishing house is 30

Обратите внимание, что, поскольку мы выбрали дискретную квантильную политику реального, результатом может быть «нереальный» дробный дом.

Если верно обратное, мы не хотим принимать какую-либо уверенность, то это равносильно предположению, что все первые испытания продаж будут успешными.

cout << "If confidence of meeting quota is zero\n(we assume all houses are successful sales)"
  ", then finishing house is " << sales_quota << endl;
If confidence of meeting quota is zero (we assume all houses are successful sales), then finishing house is 5
If confidence of meeting quota is 0, then finishing house is 5

Мы можем перечислить квантили для нескольких вероятностей:

 double ps[] = {0., 0.001, 0.01, 0.05, 0.1, 0.5, 0.9, 0.95, 0.99, 0.999, 1.};
 // Confidence as fraction = 1-alpha, as percent =  100 * (1-alpha[i]) %
 cout.precision(3);
 for (int i = 0; i < sizeof(ps)/sizeof(ps[0]); i++)
 {
   cout << "If confidence of meeting quota is " << ps[i]
     << ", then finishing house is " << quantile(nb, ps[i]) + sales_quota
     << endl;
}
If confidence of meeting quota is 0, then finishing house is 5
If confidence of meeting quota is 0.001, then finishing house is 5
If confidence of meeting quota is 0.01, then finishing house is 5
If confidence of meeting quota is 0.05, then finishing house is 6.2
If confidence of meeting quota is 0.1, then finishing house is 7.06
If confidence of meeting quota is 0.5, then finishing house is 11.3
If confidence of meeting quota is 0.9, then finishing house is 17.8
If confidence of meeting quota is 0.95, then finishing house is 20.1
If confidence of meeting quota is 0.99, then finishing house is 24.8
If confidence of meeting quota is 0.999, then finishing house is 31.1
If confidence of meeting quota is 1, then finishing house is 1.#INF

Мы могли бы применить функцию потолка, чтобы получить целочисленное значение «худшего случая» для дома.

ceil(quantile(nb, ps[i]))

Или, если бы мы использовали дискретную политику квантиля по умолчанию, integer_outside, опустив

#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real

Мы бы добились такого же эффекта.

Реальный результат дает некоторое представление о том, какой дом наиболее вероятен. Например, сравните реальное и целое_вне для 95% уверенности.

If confidence of meeting quota is 0.95, then finishing house is 20.1
If confidence of meeting quota is 0.95, then finishing house is 21

Реальное значение 20.1 намного ближе к 20, чем 21, поэтому integer_outside пессимистично. Мы могли бы также использовать политику integer_round_nearest, чтобы предположить, что 20 более вероятны.

Наконец, мы можем подсчитать вероятность того, что последняя продажа будет именно на каждом доме.

cout << "\nHouse for " << sales_quota << "th (last) sale.  Probability (%)" << endl;
cout.precision(5);
for (int i = (int)sales_quota; i < all_houses+1; i++)
{
  cout << left << setw(3) << i << "                             " << setw(8) << cdf(nb, i - sales_quota)  << endl;
}
cout << endl;
House for 5 th (last) sale.  Probability (%)
5                               0.01024
6                               0.04096
7                               0.096256
8                               0.17367
9                               0.26657
10                              0.3669
11                              0.46723
12                              0.56182
13                              0.64696
14                              0.72074
15                              0.78272
16                              0.83343
17                              0.874
18                              0.90583
19                              0.93039
20                              0.94905
21                              0.96304
22                              0.97342
23                              0.98103
24                              0.98655
25                              0.99053
26                              0.99337
27                              0.99539
28                              0.99681
29                              0.9978
30                              0.99849

Как отмечалось выше, использование блок-уловки всегда хорошая идея, даже если вы не ожидаете ее использования.

}
catch(const std::exception& e)
{ // Since we have set an overflow policy of ignore_error,
  // an overflow exception should never be thrown.
   std::cout << "\nMessage from thrown exception was:\n " << e.what() << std::endl;

Например, без игнорирования политики ошибки домена, если мы просим

pdf(nb, -1)

Например, мы получим:

Message from thrown exception was:
 Error in function boost::math::pdf(const negative_binomial_distribution<double>&, double):
 Number of failures argument is -1, but must be >= 0 !

PrevUpHomeNext

Статья Negative Binomial Sales Quota Example. раздела Math Toolkit 2.5.0 Negative Binomial Distribution Examples может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Negative Binomial Distribution Examples ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 01:51:40/0.006782054901123/0