 Home Libraries People FAQ More

##### 負二項銷售限額(Negative Binomial Sales Quota)實例.

Pat 被要求去賣糖果棒(candy bars)來為六年級的field trip賺錢。一共有30家鄰居，並且在沒有賣出5個糖果棒之前，假定Pat不會回家。所以Pat一家接一家地去賣糖果棒。在每一家，賣出一個糖果棒的概率為0.4(40%)，而沒有賣出糖果棒的概率為0.6(60%)。

```#define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real```

注意 在上面的#define 後面 #include distributions 是非常重要的

```#include <boost/math/distributions/negative_binomial.hpp>
//  為了使用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
{```

`double sales_quota = 5; // Pat's 銷售限額(sales quota) - successes (r).`

`double success_fraction = 0.4; // success_fraction (p) - 因此 failure_fraction is 0.6.`

`negative_binomial nb(sales_quota, success_fraction); // 缺省為double類型.`

```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; // 在這個住宅區中的家庭數量.

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.
```

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

```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
```

```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
```

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

```Probability that Pat finishes on the 30 house is 0.00069145
```

```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
```

/*因此在訪問了所有的家庭之後仍然沒有賣出所有的糖果棒的概率為：`1 - cdf(nb, all_houses - sales_quota)`，當使用這種方法時可能產生嚴重的不精確性，所能最好使用函數cdf的補集：因此在第31個家庭(不存在)或在第31個家庭之後還沒有賣出所有的糖果棒的概率為`cdf(complement(nb, all_houses - sales_quota))`為什麼有補集(Why complements)?

```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
```

```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個糖果棒都被賣出的嚴格絕對可能性(Demanding absolute certainty)，暗示著試驗的總次數為無窮次。(當然，在這個住宅區僅有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) fraction = 1-alpha, as percent =  100 * (1-alpha[i]) %
cout.precision(3);
for (int i = 0; i < sizeof(ps)/sizeof(ps); 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]))`

`#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real`

```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
```

```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)
{ // 因為我們已經將溢出策略(overflow policy)設置為 ignore_error,
// 永遠都不可能拋出溢出異常(overflow exception).
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 !
```