Chapter7Models.xlsx, and the cells that carry the mathematicsThe decision is a single number; the work is in producing the distribution it is a quantile of. The division between the sheets is the chapter’s argument made visible.
| Sheet | What it does | Which part of the chapter |
|---|---|---|
Data |
the 104-week history, its statistics and histogram | look and summarize |
Fit |
rules families out by the variance to mean ratio, fits the survivor, aggregates over 14 weeks, prices four candidates | hypothesize, estimate, test; the family table |
Horizon |
walks the exact fourteen-week negative binomial one belt at a time | the exact answer, 469 |
Newsvendor |
the belt’s decision, from invoice prices to expected profit | the final buy and the extensions |
Discrete |
the transformer’s decision, one unit at a time | the staircase rule |
The sheets are linked: Fit reads Data, Newsvendor reads its moments from Fit, and Fit and Horizon read the critical ratio back from Newsvendor. Only Discrete stands alone.
Fit: the Procedure on a SheetRow 8 computes the ratio, 18.4426. Row 12 answers each family: the Poisson needs one and the binomial below one, so both read no, the step the KSL’s estimator performed by refusing.
Rows 17 and 18 fit the survivor: \(\hat{p} = 0.054222\), \(\hat{r} = 1.9057\).
Notice the two checks. Row 19 computes \(1/\hat{p}\) less the ratio and reads zero; rows 20 and 21 rebuild the mean and variance from the parameters. Both catch the other convention for \(p\), the commonest error with this family.
Horizon: Walking the Exact ModelThe fourteen-week total is negative binomial with \(p = 0.054222\) and \(r = 14 \times 1.9057 = 26.6798\). Excel’s NEGBINOM.DIST will not take a number of successes that is not whole, so the sheet builds the mass function by recursion:
\[ \begin{aligned} g(0) &= p^{r} &&\text{start}\\ g(x) &= g(x-1)\,\frac{(x + r - 1)(1 - p)}{x} &&\text{each row from the row above} \end{aligned} \]
and everything after it is a running sum.
| Belts | 468 | 469 |
|---|---|---|
| \(F\) | 0.539170 | 0.543428 |
| Reached 0.5422? | no | yes |
The staircase rule stops at 469, where the first order loss function reads 35.1478 belts of expected shortage: the figure every other model on the workbook is priced against.
Newsvendor: the Cells That Carry the Mathematics| Cell | Formula | Result |
|---|---|---|
| B11, B12 | =B6-B7, =B5-B6+B8 |
\(c_o\), \(c_u\) with \(\pi\) |
| B10 | =B12/(B12+B11) |
critical ratio |
| B14 | =IF(OR(B11<=0,B12<=0),...) |
when the model refuses |
| B21, B22 | =NORM.S.INV(B10), =B17+B21*B18 |
\(z\), \(Q^{*}\) |
| B26 | =B24-B21*B25 |
\(\Phi^{1}(z) = \phi(z) - z(1 - \Phi(z))\) |
| B27, B28 | =B18*B26, =B22-B17+B27 |
shortage, leftover |
| B32, B33 | the two forms of the cost | must agree: B34 reads 0 |
| B35 | =(B5-B6)*B17-B32 |
expected profit |
| B50 | =MAX(0,B49-B48) |
order, given stock on hand |
Notice that the loss function is a formula, not a macro: Excel has none, and needs none, since \(\Phi^{1}\) is two built-in functions and a subtraction. And the arithmetic check of the final buy is wired into the sheet.
The sheet ships holding the belt. B17 and B18 return \(\mu = 465.3654\) and \(\sigma = 92.6420\), every digit carried; B22 returns \(Q^{*} = 475.1761\); B27 returns an expected shortage of 32.2605.
The check, by hand. The normal loss table steps \(z\) by tenths: \(\Phi^{1}(0.1) = 0.3509\) and \(\Phi^{1}(0.2) = 0.3069\). Interpolating to \(z = 0.1059\):
\[ \begin{aligned} \Phi^{1}(0.1059) &\approx 0.3509 - 0.059(0.3509 - 0.3069) = 0.3483 &&\text{linear interpolation}\\ G^{1}(Q^{*}) &= 92.6420(0.3483) = 32.27 \text{ belts} &&\text{scale by } \sigma \end{aligned} \]
against B27’s 32.2605 from the exact 0.3482: a hundredth of a belt, the interpolation. A loss function that has lost its \(\sigma\) is off by a factor of 92, and no interpolation error looks like that.
B32 and B33 both return $3,050.43, B34 reads zero, and B35 returns $17,891.01: the final buy’s figures to the cent.
The scrap dealer offers $20 a belt rather than $12 for whatever is left. What is the offer worth, and should the order change? One cell answers both: set B7 to 20.
\[ c_o = \$30, \qquad \frac{45}{75} = 0.6000, \qquad Q^{*} = 488.84, \qquad E[G] = \$18{,}257.08 \]
The expected profit rises $366.06. How much of that comes from re-optimizing the order?
Type the old order, 475.1761, into B40: under the new salvage it costs $2,713.86, so its profit is \(45(465.3654) - 2{,}713.86 = \$18{,}227.58\).
| Source of the $366.06 | Amount |
|---|---|
| The higher price on belts that would have been left over anyway | $336.57 |
| Re-optimizing the order, 14 more belts | $29.49 |
Take the offer. The extra belts are worth having but are not where the money is: the flatness of the optimum, measured on a decision someone has to make.
Pointing the sheets at a new item. Paste a history into column B of Data and every sheet but Discrete follows it, family verdicts included; the period length is Fit!B26. Or type a known mean and standard deviation over Newsvendor!B17 and B18, which breaks the link to Fit deliberately. Discrete walks 0 to 15 units; if no row reaches the ratio, B12 returns #N/A rather than a wrong answer.
No simulation. A sampled spreadsheet recalculates whenever anything is touched and gives a different answer each time: the wrong tool for a number someone must defend.
No second item. Nothing on a sheet knows another item exists. With a shared budget or bin space, each order depends on the others through a multiplier.
The code has neither limit.
Five requirements: solve exactly for continuous and discrete models; evaluate any quantity, not only the best; estimate a quantity’s profit by sampling with the same cost function; refuse a problem with no finite positive answer; take stock on hand.
LossFunctionDistributionIfc already is one, and the first decision is not to reimplement it.The instructive rejection
Newsvendor reads like the central class. It fails because the cost structure and the demand model already do everything: given both, the optimal quantity is one line, and a class whose only method is one line is a function wearing a costume.
data class SinglePeriodCosts(val price: Double, val cost: Double,
val salvage: Double, val penalty: Double = 0.0) {
val overageCost: Double get() = cost - salvage
val underageCost: Double get() = price - cost + penalty
val criticalRatio: Double get() = underageCost / (underageCost + overageCost)
fun profit(q: Double, d: Double): Double =
price * min(d, q) + salvage * max(q - d, 0.0) - cost * q - penalty * max(d - q, 0.0)
}fun optimalLevel(costs: SinglePeriodCosts, demand: DistributionFunctionIfc): Double {
val ratio = costs.criticalRatio
if (demand !is DiscreteDistributionIfc) return demand.invCDF(ratio)
var x = max(floor(demand.invCDF(ratio)), 0.0)
while (x > 0.0 && demand.cdf(x - 1.0) >= ratio) x -= 1.0
while (demand.cdf(x) < ratio) x += 1.0
return x
}overageCost and underageCost are \(c_o = c - u\) and \(c_u = s - c + \pi\); profit is the profit for one realized demand d. For a discrete demand, the two loops make optimalLevel the staircase rule exactly, whatever convention the library’s quantile uses. copy(penalty = 40.0) is the $40 penalty in one line.
fun estimate(demand: RVariableIfc, q: Double, replications: Int,
profit: (q: Double, d: Double) -> Double): Statistic {
val stat = Statistic("profit at %.2f".format(q))
demand.resetStartStream()
repeat(replications) { stat.collect(profit(q, demand.value)) }
return stat
}
fun estimate(costs: SinglePeriodCosts, demand: RVariableIfc, q: Double, replications: Int) =
estimate(demand, q, replications, costs::profit)The simulation loop with its free variables named. The second form passes costs::profit, the very function the cost structure defines; the first takes any profit function.
A solver and an estimator that share a cost function can be checked against each other; one that does not share it cannot. When the exact route stops applying, only the profit function changes, and the machinery that samples it is the machinery validated against the formula while the formula held.
order 475.18 units, to a level of 475.18 with 0.00 on hand
critical ratio 0.542169 F(level) 0.542169
expected shortage 32.2605 units
expected leftover 42.0712 units
expected cost 3050.43
expected profit 17891.01
order 469.00 units, to a level of 469.00 with 0.00 on hand
critical ratio 0.542169 F(level) 0.543428
expected shortage 35.1478 units
expected leftover 38.7824 units
expected cost 3055.38
expected profit 17886.06
The check against the worksheet. The first block is B22, B27, B28, B32 and B35 of Newsvendor to every digit; the second is Horizon’s 469. Notice F(level): equal to the ratio against the normal, a little above it against the negative binomial. That is the staircase.
The scrap dealer takes the first 100 belts at $12 and the rest at $4. Only the profit function changes:
Q estimate half-width summed
420 17443.54 17.64 17440.64
430 17598.94 19.50 17595.40
440 17717.80 21.41 17713.30
450 17799.34 23.33 17793.51
460 17842.54 25.26 17835.67
470 17847.14 27.18 17839.83
480 17813.90 29.07 17806.45
490 17743.39 30.91 17736.37
500 17637.05 32.70 17630.75
best on the grid: Q = 470
best by the summed profit, one belt at a time: Q = 466, profit 17842.70; at 469 it is 17841.11
Validation. Every summed value lies inside its interval. Every estimate sits above its summed value, which is not a bias: the rows face the same demands and share one sampling error, so comparisons across rows are far sharper than one half-width suggests.
What it means. The best order is 466 against 469; keeping 469 costs $1.59. The rule barely moves the order. With the tier at 25 belts it bites: the best order falls to 460, and staying at 469 costs $14.69.
The workbook is the chapter’s argument made visible: look, fit, aggregate, decide, with the checks wired into cells that read zero.
One cell priced a scrap offer: $366.06, of which $29.49 came from changing the order. The optimum is flat.
The software shares one cost function between an exact route and a sampled one, so each checks the other, and the sampled route keeps working where the formula stops.
The chapter in one line. A single period is defined by leftovers with no future value; the critical ratio is the probability of having too much that the costs make optimal; and the distribution carries more of the answer than the formula does.
Read before next session: the opening of Continuous and Periodic Review Systems, One Item, Watched Continuously and What to Measure.
Today’s material was Building These Models in a Worksheet and Designing the Software.
Next session:
The newsvendor returns next chapter: the base-stock model turns out to be one.