7  Single-Period Stochastic Inventory

NoteLearning objectives

After reading this chapter you should be able to:

  • recognize a single-period problem and say why it is not a one-period version of a multi-period one
  • work the ordering decision by hand as a marginal analysis
  • characterize a demand history and fit a distribution to it
  • formulate the newsvendor problem in both its cost and its profit forms
  • derive and interpret the critical ratio
  • solve the model for continuous and for discrete demand
  • extend the model to a penalty cost and to stock already on hand
  • estimate the answer by simulation, and say when that is worth doing
  • build the model in a worksheet and in code, and check each against the other

7.1 One Order, One Chance

Every model so far has known its demand. Chapter 3 and Chapter 4 took a constant rate, Chapter 5 let the rate vary by period and still knew it, and Chapter 6 computed it from a production plan. Assumption 5 of Section 6.8 is the one this chapter removes. From here on demand is a random variable, and the decision is made before it is observed.

We begin with the simplest such problem, in which the decision is made once.

Example 7.1 (The last order for the mower deck belt) The distributor of Chapter 5 has stocked the mower deck belt for years. The deck it fits is now out of production, so the seasonal pattern of Table 5.1 is over and what remains is steady replacement demand from owners of machines already in the field. The supplier is discontinuing the belt and has offered one last order.

What is stocked? One item, the belt.

What is the demand process? Weekly demand is random and no longer seasonal. It will run for about fourteen more weeks, until a redesigned deck reaches the dealers and the belt becomes unsellable.

When is inventory reviewed? Once. There is one decision and no second chance.

What triggers replenishment, and how much? Nothing triggers it. The distributor names a quantity now.

What happens to unmet demand? It is lost. A dealer who cannot get the belt from this distributor gets it elsewhere.

What costs are incurred, and when? The belt costs $50 and sells for $95. Belts left when the deck is withdrawn go to a scrap dealer at $12.

Three things about Example 7.1 distinguish it from everything before it.

There is no ordering cost in the model. Recall from Table 1.10 that \(k\) is the price of placing an order, and that the models of Chapter 3 through Chapter 6 trade it against holding. Here exactly one order is placed whatever its size, so \(k\) is the same under every decision. A constant added to every alternative cannot change which alternative is least, which is the argument of Section 1.4.1. Thus, \(k\) drops out, and with it the entire question those chapters were about.

Leftover stock has no future value. Recall from Section 1.2.7 that a single-period problem is not a multi-period problem with the number of periods set to one. In a multi-period problem a unit left at the end of a period is available at the start of the next, so the cost of having too many is a holding charge for one period. Here it is the whole loss on the unit, $50 paid against $12 recovered. That is why the trade-off is overage against underage rather than holding against ordering.

The two errors are priced differently, and neither is free. Order too many and the distributor loses $38 a belt. Order too few and it loses the $45 margin on each belt it could have sold. Notice that both are opportunity costs measured against the decision that could have been made, and that neither appears in any ledger. Section 1.4.2 is why.

7.1.1 Demand Is Not Sales

One distinction has to be made before any data are used, because it is the commonest error in this material and it is invisible in the answer.

  • Let demand represent what customers would have bought.
  • Let sales represent what they did buy.

The two differ whenever the shelf was empty. A week that sold 40 belts because 40 were on the shelf and a week that sold 40 because 40 were wanted look identical in a sales record. That is, sales are demand censored at whatever was available, and a history of sales understates both the average and the spread. It understates them most in the weeks when the item mattered, because those are the weeks it ran out.

Recall from Section 2.3 that a stock record is only as good as the transactions behind it. This is the same point about a different record. An organization that wants to model demand has to record the demand it could not fill, and most do not. Where that record does not exist, the fitted distribution of Section 7.3 is biased low and every quantity computed from it is too small. You should say so when you report the answer, rather than let the arithmetic imply a precision the data do not carry.

The next section makes the decision without any distribution theory at all.

7.2 Working the Decision by Hand

Before any calculus, we can make the decision with arithmetic a planner would do on a whiteboard. The method is worth more than the answer, because it produces the rule that the rest of the chapter derives formally.

Let’s start with a sketch of demand rather than a fitted distribution. Suppose the distributor, asked for a judgment, offers five outcomes for total remaining demand and a probability for each.

Table 7.1: A five-point sketch of remaining demand for the belt. The mean is 485 belts. The sketch is coarse: the argument below needs the shape of demand and not its detail.
Demand \(x\), belts 300 400 500 600 700
\(P\{X = x\}\) 0.15 0.25 0.30 0.20 0.10
\(P\{X \le x\}\) 0.15 0.40 0.70 0.90 1.00

The decision is how many belts to buy, in hundreds. Rather than evaluate every candidate, we ask a smaller question. Given that we have decided on some quantity, is one more hundred belts worth buying?

Buying one more hundred pays off when demand turns out to exceed the quantity we already have, which happens with probability \(P\{X \ge Q+100\}\), and each of those belts earns the $45 margin. It costs when demand falls at or below the quantity we already have, which happens with probability \(P\{X \le Q\}\), and each unsold belt loses $38. The extra hundred is worth buying when

\[ 45 \times 100 \times P\{X \ge Q+100\} \;>\; 38 \times 100 \times P\{X \le Q\} \tag{7.1}\]

Table 7.2 works Equation 7.1 one step at a time.

Step 1, from 300 to 400. Demand reaches 400 or more with probability 0.85, so the gain is \(45(100)(0.85) = \$3{,}825\). Demand stops at 300 with probability 0.15, so the loss is \(38(100)(0.15) = \$570\). The step is worth $3,255. Take it.

Step 2, from 400 to 500. Demand reaches 500 or more with probability 0.60, giving \(45(100)(0.60) = \$2{,}700\). Demand stops at 400 or below with probability 0.40, giving \(38(100)(0.40) = \$1{,}520\). The step is worth $1,180. Take it.

Step 3, from 500 to 600. Demand reaches 600 or more with probability 0.30, giving $1,350. Demand stops at 500 or below with probability 0.70, giving $2,660. The step loses $1,310. Stop.

Table 7.2: The marginal analysis, one hundred belts at a time. Notice that the net column changes sign once and never changes back, which is what makes stopping at the first negative step correct rather than merely convenient.
From To \(P\{X \ge \text{to}\}\) Gain \(P\{X \le \text{from}\}\) Loss Net
300 400 0.85 $3,825 0.15 $570 +$3,255
400 500 0.60 $2,700 0.40 $1,520 +$1,180
500 600 0.30 $1,350 0.70 $2,660 -$1,310
600 700 0.10 $450 0.90 $3,420 -$2,970

Order 500 belts. Notice that 500 is more than the mean of 485. The distributor should plan to be left with belts more often than it plans to run out, because running out costs more per belt than scrapping does.

That the net column changes sign exactly once is not luck. Rearranging Equation 7.1, the step is worth taking while

\[ P\{X \le Q\} < \frac{45}{45+38} = \frac{c_{u}}{c_{u}+c_{o}} = 0.5422 \tag{7.2}\]

and the left side is a cumulative distribution function, which never decreases. Thus, once the test fails it fails for every larger quantity, and the rule is to order the smallest quantity whose cumulative probability reaches 0.5422. From Table 7.1 that is 500 belts, since \(F(400) = 0.40\) is short of it and \(F(500) = 0.70\) clears it.

That ratio is the answer to the whole chapter, and Section 7.6 derives it properly.

A check, and a reason to trust the shortcut. Costing all five candidates directly should agree, and it does.

Table 7.3: Expected profit at each candidate quantity, computed from Table 7.1 without any shortcut.
\(Q\) 300 400 500 600 700
Expected profit $13,500 $16,755 $17,935 $16,625 $13,655

Table 7.3 peaks at 500, which is where Table 7.2 stopped and where Equation 7.2 pointed. Three routes, one answer. That check is worth performing the first time you use marginal analysis on a new problem, because the marginal argument is only valid when the expected profit has a single peak, and the direct calculation is what confirms it.

Notice what the hand method cost. Five outcomes, four steps, no distribution and no calculus. What it cannot do is tell the distributor anything between 400 and 500 belts, and the real decision is a number of belts rather than a number of hundreds. For that we need a distribution, and that is the next two sections.

7.3 Getting a Demand Distribution

Every model from here to the end of the book takes a demand distribution as an input, and the distribution carries more of the answer than the policy formula built on top of it does. This section fits one.

The subject has a book of its own. Appendix B of Simulation Modeling using the KSL (Rossetti 2026) gives the procedure in full, and Chapter 2 of the same text shows how to carry it out with the library this book’s code uses. What follows is that procedure applied to an inventory problem, with the one difference that matters here made explicit: demand for a spare part is a count, so every tool below is a discrete one.

The data. The distributor has 104 weeks of demand for the belt, recorded after the deck went out of production. They are in data/ch7-weekly-demand.csv in the course code project, two columns and a header:

week,demand
1,94
2,67
3,31

Read them the way Section C.4 assumes they arrive, as a file whose contents you did not choose:

val df = DataFrame.readCsv(
    File("data/ch7-weekly-demand.csv"),
    colTypes = mapOf("week" to ColType.Int, "demand" to ColType.Int)
)
val history: IntArray = df.getColumn("demand").toList().map { it as Int }.toIntArray()

Notice that the column types are named rather than left to be inferred. That is the practice Section 2.4.4 of (Rossetti 2026) follows, and the reason is that a column of counts silently read as text, or as real numbers, fails later and somewhere else.

7.3.1 Look Before You Model

Appendix B of (Rossetti 2026) opens its fitting procedure by plotting the data. A summary statistic answers a question you already thought to ask. A picture shows you the thing you did not.

Three plots answer three different questions, and the KSL draws all three.

val h = Histogram(Histogram.createBreakPoints(0.0, 12, 10.0), "Weekly demand")
h.collect(history.toDoubles())
h.histogramPlot().showInBrowser()

ObservationsPlot(history.toDoubles()).showInBrowser()
ACFPlot(history.toDoubles()).showInBrowser()

What shape is it? Figure 7.1 is the histogram, on bins of ten belts. The break points are given rather than recommended, because ten belts to a bin is what the Data sheet of Chapter7Models.xlsx uses and a figure that disagrees with the spreadsheet beside it is worse than no figure.

Figure 7.1: Weekly demand for the belt over 104 weeks, in bins of ten. Each bin is closed below and open above, so the tallest bar counts the 26 weeks that sold 10 through 19 belts. Notice the shape: a peak well to the left, a long thin tail reaching past 110, and no suggestion of symmetry anywhere in it. That single picture has already ruled out the normal distribution.

Is it the same process throughout? Figure 7.2 plots the weeks in the order they occurred. What you are looking for is a trend, a level shift, or a season, and what is there is none of those: the series wanders about a constant level for two years. That matters because the season really is over, which is what Example 7.1 claimed and what this plot lets a reader check rather than accept.

Are the weeks independent? Figure 7.3 is the autocorrelation plot. Every lag falls inside the band, including the first, whose correlation is 0.1423 against a band of about \(\pm 1.96/\sqrt{104} = \pm 0.19\). Recall from Section B.5.5 that autocorrelated demand breaks the variance of a sum. Section 7.7 is about to add fourteen of these weeks together and treat their variances as adding, so this is the plot that licenses the arithmetic two sections from now.

Figure 7.2: The weeks in the order they occurred.
Figure 7.3: Autocorrelation through twenty lags.

Taken together the three plots say the weeks are independent, identically distributed, and strongly right-skewed. That is the finding that lets the rest of the section treat the 104 numbers as 104 draws from one distribution.

7.3.2 Summarize It

Now the statistics, which the KSL accumulates as the data are collected.

val s = Statistic("Weekly demand", history.toDoubles())
val b = BoxPlotSummary(history.toDoubles(), "Weekly demand")
println(s)
println(b)
Table 7.4: Summary of the 104 weeks. Statistic carries the first four moments and the lag one correlation; BoxPlotSummary carries the quartiles.
Statistic Value
Weeks observed 104
Mean 33.2404
Variance 613.0387
Standard deviation 24.7596
Coefficient of variation 0.7449
Variance to mean ratio 18.4426
Skewness 1.2630
Smallest week 0
First quartile 16.0
Median 26.5
Third quartile 40.0
Largest week 113
Weeks with no demand 2

Read three things off Table 7.4 before going further.

The median sits well below the mean. A median of 26.5 against a mean of 33.24 says the distribution is right-skewed: most weeks are quiet and a few are very large. The skewness of 1.2630 is the same statement with a number attached, and Figure 7.1 is the same statement with a picture attached. Three routes, one finding.

Demand is a count. The weeks are whole belts, two of them are zero, and the quantity has no meaning between whole numbers. Thus, the families to consider are the discrete ones of Section C.1 and not the continuous ones of Section C.2.

For a count the diagnostic is the variance to mean ratio. Equation C.1 rather than the coefficient of variation, because the ratio is what each discrete family fixes or bounds. Here

\[ \mathit{VMR} = \frac{613.0387}{33.2404} = 18.44 \]

7.3.3 Hypothesize, Estimate, Test

Step 1, hypothesize. Equation C.1 does most of this step by itself. Recall from Section C.1.1 that the Poisson fixes \(\mathit{VMR} = 1\), and from Section C.1.3 that the binomial forces \(\mathit{VMR} < 1\). A ratio of 18.44 is near neither, and no choice of parameter repairs that, because in both families the variance is decided the moment the mean is estimated. What remains is Section C.1.2, the negative binomial, which admits any \(\mathit{VMR} > 1\) and which is the Poisson with its constant-rate assumption relaxed. That is a plausible story for a spare part: the rate at which mower decks need belts is not the same in every week.

Step 2, estimate. The KSL estimates the parameters of every discrete family it knows in one call. PMFModeler is the discrete counterpart of the PDFModeler of Section 2.4.2 of (Rossetti 2026), and it is deliberately narrower: there are fewer discrete families, so it estimates parameters and leaves the choosing to you.

val modeler = PMFModeler(history)
for (result in modeler.estimateParameters(modeler.defaultEstimators)) {
    println(if (result.success) "${result.parameters}" else "FAILED: ${result.message}")
}
RV Type = NegativeBinomial
Double Parameters {probOfSuccess=0.05422232292974839, numSuccesses=1.9057024844439698}
RV Type = Poisson
Double Parameters {mean=33.24038461538462}
FAILED: Cannot match moments when sample average <= estimated variance
RV Type = Binomial
Double Parameters {probOfSuccess=0.29133420825260514, numTrials=114.09708737864078}

Read that output carefully, because the most useful line in it is the failure. The binomial estimator that matches moments refuses to return an answer, and the reason it gives is Equation C.1 in words: a binomial cannot have a variance above its mean. That is the software performing Step 1 rather than the analyst. The binomial that did return an answer did so by matching the largest observation instead of the moments, and it reports 114.1 trials, a fractional number of trials for a quantity that has no trials in it. Notice that an estimate being returned is not the same thing as a family being appropriate.

The negative binomial estimate is the method of moments of Section C.4, and it is worth confirming by hand. Matching Equation C.3 to the sample mean \(\bar{x}\) and the sample variance \(s^{2}\), we get

\[ \hat{p} = \frac{\bar{x}}{s^{2}} = \frac{33.2404}{613.0387} = 0.054222, \qquad \hat{r} = \frac{\bar{x}^{2}}{s^{2}-\bar{x}} = \frac{33.2404^{2}}{613.0387-33.2404} = 1.9057 \tag{7.3}\]

which is what the KSL reported. Notice that \(1/\hat{p} = 18.44\) is the variance to mean ratio we started with, so the fitted \(\hat{p}\) carries no information the summary did not already have. That is true of the method of moments generally: the fit is a restatement of two summary numbers in the parameters of a family.

The KSL uses the success convention of Equation C.3, so probOfSuccess is \(p\) and the mean is \(r(1-p)/p\). That agrees with the check above. The warning in Section C.1.2 is not hypothetical; you should confirm the convention every time before passing a parameter to a routine.

Step 3, test. For a discrete model the KSL performs a chi-squared goodness of fit test, forming bins of approximately equal probability.

val fitted = NegativeBinomial(0.054222, 1.9057)
val gof = DiscretePMFGoodnessOfFit(
    history.toDoubles(), fitted, numEstimatedParameters = 2,
    breakPoints = PMFModeler.makeZeroToInfinityBreakPoints(history.size, fitted)
)
println(gof.chiSquaredTestResults())
Table 7.5: The chi-squared goodness of fit test on the 104 weeks, for the two families Equation C.1 left in contention. Notice that the Poisson is not rejected narrowly. Its test statistic is more than twenty times the negative binomial’s.
Model \(\chi^{2}\) Degrees of freedom \(p\)-value At the 0.05 level
Negative binomial, \(\hat{p}=0.0542\), \(\hat{r}=1.9057\) 23.35 17 0.1382 do not reject
Poisson, \(\hat{\lambda}=33.2404\) 571.98 16 0.0000 reject

Table 7.5 is the confirmation, not the decision. The decision was made by the variance to mean ratio, and a test that had contradicted it would have been telling us that something is wrong with the data rather than with Equation C.1.

Figure 7.4 is the same conclusion drawn rather than tabulated. The KSL calls this a PMF comparison plot and Section 2.4.4 of (Rossetti 2026) uses one at the same point in the procedure.

Figure 7.4: The fitted negative binomial against the 104 weeks. The empirical mass function is spiky because it has to be: 104 observations spread over 54 distinct values put a mass of 1/104 or 2/104 on most of them. That is exactly why Table 7.5 bins before it tests. What to read here is whether the black curve runs through the middle of the red forest, which it does.

7.3.4 What the Test Does Not Settle

A goodness of fit test asks whether the data are inconsistent with a family. Failing to reject is not proof. With 104 observations spread over twenty bins, several of the bins carry an expected count below five, which is the condition under which the chi-squared approximation is least trustworthy, and the KSL flags each of them. The test and the ratio narrow the field, and the choice among what survives is yours to defend. Where two survivors disagree enough to change the decision, Section 7.7 shows what to do: compute the answer under both and report the spread.

What this section did not do. It did not deseasonalize, because Figure 7.2 shows nothing to remove and the season is over. It did not forecast, which is a different job from fitting a distribution and is outside this book. And it did not correct for censoring, because the distributor does not record lost sales, which is the limitation Section 7.1.1 warned about and which no amount of care here repairs.

It also did not have to deal with an item whose history is mostly zeros. The belt sold in 102 of its 104 weeks. Section 7.4 takes up the items that do not.

7.4 Intermittent and Slow-Moving Demand

The belt is demanded in almost every week: 2 of its 104 weeks were empty. Many items are not like that, and a history in which most periods are empty needs a different treatment.

Recall from Example 2.4 that a demand history is classified by two statistics: the average interval between demands, \(\mathit{ADI}\), and the squared coefficient of variation of the non-zero sizes, \(\mathit{CV}^{2}\). An item with \(\mathit{ADI} > 1.32\) is intermittent, and one that is also variable in size, \(\mathit{CV}^{2} > 0.49\), is lumpy. Those two cut-offs are not conventions; Syntetos et al. (2005) derive them as the points at which one forecasting method overtakes another, which is why they are the oddly specific numbers they are. For the belt, \(\mathit{ADI} = 104/102 = 1.02\), comfortably under the threshold, which is the check that licenses everything Section 7.3 did.

Two things go wrong when an intermittent series is handed to Section 7.3 unchanged.

A single family has to explain two different things. The distribution of period demand for an intermittent item is a mixture of a point mass at zero and a distribution of sizes. Fitting one continuous family to it forces that family to account for both how often demand happens and how large it is, and no family in Section C.2 can do that well. Section C.4.3 gives the two repairs, a zero-modified family or a compound representation.

The coefficient of variation goes past where the normal is usable. Table C.1 gives a normal model at a coefficient of variation of 1.0 a sixth of its probability below zero. Intermittent items routinely run past 1.0, so the family that is most often reached for is the one most surely wrong. That is not a small error in a tail; it is a model asserting that demand is frequently negative.

Neither repair is needed for this chapter, because Section 7.8 handles the slow-moving case directly with a discrete distribution and no mixture. Both matter from Section 8.11 onward, where the quantity being modeled is demand over a lead time and the zeros no longer aggregate away.

One topic this book does not cover is forecasting an intermittent series, as opposed to fitting a distribution to it.

That literature begins with Croston (1972). Croston’s insight was that exponentially smoothing an intermittent series directly is wrong, because the estimate jumps at every demand and decays through every empty period. Thus, it is highest immediately after a demand, which is exactly when the stock has been drawn down and a replenishment is most likely to be triggered. An estimator that looks unbiased across the whole series is biased upward at the only moments anyone reads it. His method smooths two series separately instead, the size of a demand when one happens and the interval between demands, and combines them into a demand rate.

Syntetos and Boylan (2001) then showed that the obvious way of combining them is biased. The ratio of two independent smoothed estimates does not estimate the ratio of their means, so Croston’s estimator runs high, and Syntetos and Boylan (2005) gave the correction that now carries their names. The same authors’ categorization scheme (Syntetos et al. 2005) is the source of the \(\mathit{ADI}\) and \(\mathit{CV}^{2}\) cut-offs above, and it exists to say which of these estimators to use.

Fitting asks what the distribution of demand is. Forecasting asks what next period’s demand will be. They are different questions, both are needed in practice, and this chapter asks only the first.

7.5 The Newsvendor Model

We can now state the problem formally. It carries the name of a vendor buying newspapers for the day, and it applies to any resource committed before the need for it is known.

  • Let \(X\) represent demand over the period, a random variable with cumulative distribution function \(F(x) = P\{X \le x\}\).
  • Let \(Q\) represent the quantity ordered, the decision.
  • Let \(c_{o}\) represent the overage cost, the loss on each unit left at the end of the period, in dollars per unit.
  • Let \(c_{u}\) represent the underage cost, the loss on each unit of demand that could not be met, in dollars per unit.

Both are opportunity costs measured against the decision that could have been made, and both are strictly positive. Section 7.9 says what it means when one of them is not.

At the end of the period exactly one of two things has happened. Either \(Q > X\) and \(Q - X\) units are left over, or \(Q < X\) and \(X - Q\) units of demand went unmet. Using the notation \((y)^{+} = \max(y, 0)\) of Section C.3, both cases are covered by one expression:

\[ C(Q, X) = c_{o}(Q-X)^{+} + c_{u}(X-Q)^{+} \tag{7.4}\]

Notice that exactly one of the two terms is non-zero for any realized demand. Equation 7.4 is a random variable because \(X\) is, and we choose \(Q\) to minimize its expectation, \(E[C(Q,X)]\).

7.5.1 The Same Model as a Profit

Much of the literature and all of the practice writes this as a profit rather than a cost, in terms of quantities that appear on an invoice.

  • Let \(c\) represent the purchase cost, \(s\) the selling price, and \(u\) the salvage value per unit, with \(s > c > u\).

The vendor sells \(\min(X, Q)\) units, salvages \((Q-X)^{+}\), and pays for \(Q\):

\[ G(Q, X) = s\min(X, Q) + u(Q-X)^{+} - cQ \tag{7.5}\]

The two formulations are the same model. Matching terms,

\[ c_{o} = c - u, \qquad c_{u} = s - c \tag{7.6}\]

so the overage cost is what a unit loses between the counter and the scrap yard, and the underage cost is the margin forgone. For the belt, \(c_{o} = 50 - 12 = \$38\) and \(c_{u} = 95 - 50 = \$45\), which are the numbers Section 7.2 used.

Maximizing Equation 7.5 and minimizing Equation 7.4 give the same \(Q\). Recall from Section 1.4.1 that a term which does not depend on the decision shifts an objective without moving its optimum. The two expressions differ by \((s-c)E[X]\), which is the profit the vendor would make if every unit demanded were sold, and that quantity does not depend on \(Q\). It shifts the objective without moving its optimum, and

\[ E[G(Q,X)] = (s-c)E[X] - E[C(Q,X)] \tag{7.7}\]

Use whichever formulation your audience speaks. This chapter derives in costs, because Equation 7.4 is shorter, and reports in profits, because that is what the distributor will ask for. Section 7.7 now works the model with a continuous demand distribution, where the critical ratio is a quantile.

7.6 The Critical Ratio

The expected cost has a closed form, and it is written in the first order loss function of Section C.3. Recall that \(G^{1}(b) = E[(X-b)^{+}]\) is the expected amount by which demand exceeds \(b\).

We take the expectation of Equation 7.4 term by term. The second term is \(G^{1}(Q)\) by definition, so the expected shortage is

\[ E\left[(X-Q)^{+}\right] = G^{1}(Q) \tag{7.8}\]

The first term needs one step. Notice the identity \((Q-X)^{+} = (X-Q)^{+} + Q - X\), which holds in both cases: when \(X < Q\) the right side is \(0 + Q - X\), and when \(X \ge Q\) it is \(X - Q + Q - X = 0\). Taking expectations, we have

\[ E\left[(Q-X)^{+}\right] = G^{1}(Q) + Q - E[X] \tag{7.9}\]

which says the expected leftover is the expected shortage plus however far the order sits above the mean. Putting the two together, we have

\[ E[C(Q)] = c_{o}\left(G^{1}(Q) + Q - E[X]\right) + c_{u}G^{1}(Q) = (c_{u}+c_{o})G^{1}(Q) + c_{o}\left(Q - E[X]\right) \tag{7.10}\]

Equation 7.10 is the whole model in one line. The first term is the cost of being short, weighted by both prices because a unit short is both a sale lost and a unit not held. The second is the cost of the position itself.

Differentiating. Recall from Section C.3 that \(dG^{1}(Q)/dQ = -G^{0}(Q)\), where \(G^{0}(Q) = 1 - F(Q)\). Differentiating Equation 7.10 term by term, we get

\[ \frac{d}{dQ}E[C(Q)] = -(c_{u}+c_{o})G^{0}(Q) + c_{o} \tag{7.11}\]

Setting Equation 7.11 to zero, we get \(G^{0}(Q) = c_{o}/(c_{u}+c_{o})\), and since \(G^{0} = 1 - F\),

\[ F(Q^{*}) = \frac{c_{u}}{c_{u}+c_{o}}, \qquad Q^{*} = F^{-1}\!\left(\frac{c_{u}}{c_{u}+c_{o}}\right) \tag{7.12}\]

The quantity \(c_{u}/(c_{u}+c_{o})\) is the critical ratio. It is the rule Equation 7.2 produced by hand, and Equation 7.12 is why that rule was right. Notice that the optimum is a minimum: the second derivative is \((c_{u}+c_{o})f(Q)\), which is non-negative everywhere, so the expected cost is convex and the stationary point is the bottom.

7.6.1 Reading the Critical Ratio

Equation 7.12 says something sharper than “solve for \(Q\)”. The left side is \(P\{X \le Q^{*}\}\), the probability that demand falls short of the order. That is the probability of having too much. Thus, the critical ratio is not an input to the answer; it is the answer, expressed as a service level the costs imply.

The ratio depends only on the relative size of the two costs, so it can be read as odds. For example, if being short costs three times as much as being long, then \(c_{u}/(c_{u}+c_{o}) = 3/4\) and it is optimal to run a 75% chance of leftovers. At four times it is 80%, and at nine times it is 90%.

Two consequences follow, and both contradict what an organization usually rewards.

Never having leftovers is bad. A buyer who ends every period with nothing left is not being careful. They are ordering at a critical ratio near zero, which is only correct when a lost sale costs nothing. For the belt the ratio is 0.5422, so the distributor should expect leftovers in about 54% of futures. A manager who treats scrapped belts as evidence of a mistake will push the buyer below the optimum, and the loss will never appear in any account because it is a sale that did not happen.

Never having unsatisfied customers is also bad. The mirror error costs just as much. At the belt’s ratio the distributor should expect to run out about 46% of the time. A service target of 99% is a claim that \(c_{u}\) is ninety-nine times \(c_{o}\), and if that is not true the stock is too large.

Thus, the useful question to ask of a stated service level is not whether it is high enough. It is what ratio of costs would make it optimal, and whether anyone believes those costs. Section 4.4.3 made the same move for the economic order quantity, reading a firm’s behavior back into the parameters it implies.

7.7 Continuous Demand

With a continuous demand distribution, Equation 7.12 is a quantile and the work is arithmetic.

Example 7.2 (The final buy, solved) Take Example 7.1 with the demand distribution of Section 7.3.

Notation. Let \(X\) represent total demand over the fourteen remaining weeks. Let \(X_{i}\) represent demand in week \(i\), negative binomial with mean 33.2404 and variance 613.0387 from the fit of Equation 7.3.

The distribution of the total. Weekly demands are independent. Recall from Section B.2 that the mean and the variance of a sum then add:

\[ E[X] = 14(33.2404) = 465.37 \text{ belts}, \qquad \mathit{Var}[X] = 14(613.0387) = 8582.54 \]

so \(\sigma = \sqrt{8582.54} = 92.64\) belts and the coefficient of variation is \(92.64/465.37 = 0.1991\).

Which family. Section 7.3 fitted a discrete model to weekly demand, and demand over fourteen weeks is discrete too. Treating the total as continuous is an approximation, and it is a safe one here for the reason Section 7.8 gives at the end: one belt is \(1/92.64\), or 1.1%, of the standard deviation of the total, so rounding cannot decide the answer. The weekly data, where one belt is 4% of the standard deviation, would not have earned the same treatment.

The family to approximate with is the normal. Section 7.3 rejected the normal for weekly demand, whose coefficient of variation is 0.7449. The total over fourteen weeks has a coefficient of variation of 0.1991, and Table C.1 says a normal at that coefficient puts essentially nothing below zero. The normal is safe here and was not safe there. Recall from Section B.2 that a sum of many independent terms tends toward the normal whatever the terms look like.

The critical ratio. From Equation 7.6, \(c_{o} = \$38\) and \(c_{u} = \$45\), so

\[ \frac{c_{u}}{c_{u}+c_{o}} = \frac{45}{83} = 0.542169 \]

The quantity. Standardizing, we have \(Q^{*} = \mu + z\sigma\) where \(z = \Phi^{-1}(0.542169) = 0.1059\). That is,

\[ Q^{*} = 465.37 + 0.1059(92.64) = 475.18 \text{ belts} \]

so the distributor orders 475 belts.

The consequences. From Table C.2 the standard normal loss function at \(z = 0.1059\) is \(\Phi^{1}(0.1059) = 0.3482\), so by Equation C.20 we get an expected shortage of \(92.64(0.3482) = 32.26\) belts. Reading Equation 7.9, the expected leftover is \(32.26 + 475.18 - 465.37 = 42.07\) belts. The distributor expects to scrap about 42 belts and to turn away about 32 dealers.

The cost. From Equation 7.10,

\[ E[C(Q^{*})] = 38(42.07) + 45(32.26) = 1598.71 + 1451.72 = \$3{,}050.43 \]

The check. The other form of Equation 7.10 must agree: \((45+38)(32.26) + 38(475.18 - 465.37) = 2677.62 + 372.81 = \$3{,}050.43\). The two agree, which confirms both the loss function and the quantity computed from it. That check is worth performing every time, because it catches a missing \(\sigma\) in the loss function immediately.

In business terms. By Equation 7.7 the expected profit is \((95-50)(465.37) - 3050.43 = \$17{,}891.01\). The distributor commits $23,750 to buy 475 belts and expects to clear about $17,900 on them.

Three things about Example 7.2 are worth more than the answer.

The optimum is flat. Ordering the mean rounded to whole belts, 465, costs $3,068.88 against the optimum’s $3,050.43, which is 0.6% worse. The economic order quantity of Section 3.7 is flat in the same way and for the same reason: the objective is smooth and its derivative vanishes at the optimum. Thus, the value of this calculation is not the last belt. It is knowing that 475 is right and 700 is not, and 700 costs $8,930, nearly three times the optimum.

The family matters less than the fit, and here that can be measured. Recall from Equation C.3 that a sum of independent negative binomials sharing \(p\) is negative binomial with the same \(p\) and the numbers of successes added. Thus, the fitted weekly model of Equation 7.3 gives the fourteen-week distribution exactly, as \(\mathit{NB}(\hat{p} = 0.054222, 14\hat{r} = 26.6798)\), with the same mean and variance used above. Apply Equation 7.13 to it and the answer is 469 belts, because \(F(468) = 0.5392\) is short of the ratio and \(F(469) = 0.5434\) clears it. Now price the four candidate orders against that exact model.

Table 7.6: What the choice of family costs, measured against the distribution the data were fitted to rather than against the other candidates. The gamma happens to land on the exact answer.
Model used to choose \(Q\) Normal Lognormal Gamma Exact negative binomial
\(Q\), rounded to whole belts 475 466 469 469
Expected cost under the exact model $3,061.28 $3,057.19 $3,055.38 $3,055.38
Penalty against the exact answer 0.19% 0.06% 0.00% 0.00%

Read Table 7.6 as a bound rather than as a ranking. The worst of the three continuous families costs 0.19% more than choosing correctly, on a decision worth about $3,050. That spread is small because the coefficient of variation of the total is 0.1991. It would not be small at the weekly coefficient of 0.7449, which is another reason Section 7.3 is worth doing carefully.

The normal’s defect is real and did not bite. A normal with this mean and standard deviation puts \(\Phi(-465.37/92.64) = \Phi(-5.02)\) below zero, which is about one in four million. Notice that this is a statement about this aggregation and not about the normal in general. The same family applied to the weekly data would have put about 9% of its mass below zero.

7.8 Discrete Demand

When demand is counted in small whole numbers, a continuous distribution is the wrong tool and the inverse in Equation 7.12 does not exist. A discrete cumulative distribution function is a staircase. Thus, a critical ratio almost never lands exactly on a step.

The rule that replaces it follows from the same marginal argument as Equation 7.2. We keep adding a unit while the expected gain exceeds the expected loss, which means while \(F(Q) < c_{u}/(c_{u}+c_{o})\). That is,

\[ Q^{*} = \min\left\{Q : F(Q) \ge \frac{c_{u}}{c_{u}+c_{o}}\right\} \tag{7.13}\]

Equation 7.13 is not an inverse. It is the smallest quantity whose cumulative probability reaches the ratio, and at that quantity \(F(Q^{*})\) is usually strictly greater than the ratio. That gap is not an error. It is the staircase, and it means a discrete newsvendor generally achieves a service level a little better than the one its costs call for, because it cannot buy a fraction of a unit.

WarningEvaluate a discrete second order loss function only at whole units

The first order loss function of a discrete distribution is defined for every real argument, and from version R1.7 of the KSL firstOrderLossFunction evaluates it correctly at any argument. Earlier versions were correct only at whole numbers, returned a value that was usually negative in between, and raised no error. The second order loss function is another matter. secondOrderLossFunction is correct at whole units and returns an approximation between them, in R1.7 as before, because the discrete definition in Equation C.10 is a statement about whole units.

That restriction costs nothing here, because Equation 7.13 only ever asks about whole units. It matters when a quantity that came from a continuous model is priced against a discrete one, which is what Table 7.6 does: round first, then evaluate.

Example 7.3 (A one-time buy of spare transformers) Recall the municipal utility storeroom of Example 4.5, which carries a pad-mount transformer at $3,800. The utility is about to begin a capital project after which the specification changes, so transformers not used will be obsolete.

What is the demand process? Failures arrive independently at a low rate. Over the project window the utility expects 6 failures, and models the count as Poisson with \(\lambda = 6\).

What costs are incurred? A transformer bought and not used scraps at $900, so \(c_{o} = 3800 - 900 = \$2{,}900\). A failure with no spare on the shelf is covered by an emergency purchase at $9,500, so \(c_{u} = 9500 - 3800 = \$5{,}700\).

The critical ratio. \(5700/(5700+2900) = 5700/8600 = 0.662791\).

The quantity. We walk the Poisson distribution function until it reaches the ratio.

Table 7.7: The Poisson newsvendor, walked one transformer at a time. Notice that the cost column confirms the rule rather than being used by it: the rule reads the \(F(Q)\) row and stops at 7 because 0.6063 is short of 0.6628 and 0.7440 clears it.
\(Q\) 4 5 6 7 8
\(F(Q)\) 0.2851 0.4457 0.6063 0.7440 0.8472
Expected shortage \(G^{1}(Q)\) 2.2330 1.5181 0.9637 0.5700 0.3140
Expected cost $13,404 $10,155 $8,288 $7,802 $8,501

The answer. Buy 7 spare transformers, at a cost of $26,600, with an expected total of $7,802 in obsolescence and emergency purchases.

The check. Table 7.7 costs each candidate directly from Equation 7.10, using the Poisson loss function of Table C.3. The minimum is at 7, where the rule put it.

Does rounding the continuous answer work? Usually, and not always. Treating demand as normal with mean 6 and variance 6 gives \(6 + \Phi^{-1}(0.6628)\sqrt{6} = 6 + 0.4201(2.4495) = 7.029\), which rounds to 7 and agrees.

Now change one number. Suppose the emergency purchase costs $8,150 rather than $9,500, so that \(c_{u} = \$4{,}350\) and the critical ratio is exactly 0.6000. The exact rule reads \(F(5) = 0.4457\) and \(F(6) = 0.6063\), and stops at 6 transformers. The normal approximation gives \(6 + 0.2533(2.4495) = 6.621\), which rounds to 7. The approximation buys one transformer too many, at $3,800, which is a real error on a real decision.

The lesson is about when the approximation is safe rather than whether it is. A normal approximation to a discrete distribution is good when the mean is large enough that one unit is a small fraction of the standard deviation. At \(\lambda = 6\) the standard deviation is 2.45 units, so a single transformer is 40% of it, and rounding decides the answer. At \(\lambda = 600\) a single unit is 4% of the standard deviation and rounding decides nothing. Thus, you should use Equation 7.13 whenever the numbers are small, which is exactly when slow-moving items are involved and exactly when each unit is expensive.

7.9 Extensions

Four variations cover most of what a real single-period problem adds, and none of them changes Equation 7.12. They change what goes into it.

7.9.1 A Penalty Beyond the Lost Margin

Equation 7.6 sets \(c_{u} = s - c\), the margin forgone. That is the whole cost only when a customer turned away this time returns next time as though nothing had happened. Where a stockout costs more than the sale, add it.

  • Let \(\pi\) represent the stockout penalty of Section 1.4.6, in dollars per unit of unmet demand, so that \(c_{u} = s - c + \pi\).

For the belt, suppose the distributor judges that a dealer refused a belt costs $40 in future business beyond the margin lost today. Then \(c_{u} = 45 + 40 = 85\) and the critical ratio rises from 0.5422 to \(85/123 = 0.6911\). The quantity rises with it, from 475 belts to \(465.37 + 0.4988(92.64) = 511.58\), so 512 belts.

Notice the direction and the size. A penalty of $40, which is under half the selling price, moved the order by 37 belts, which is 7.8%. Recall from Section 1.5.5 that \(\pi\) is the parameter no ledger contains and the one hardest to defend. The right way to report this decision is not a single number. It is that 475 belts is right if a stockout costs only the margin and 512 if it costs $40 more, and that the organization should say which it believes.

7.9.2 Stock Already on Hand

Suppose the distributor already holds \(I\) belts when the final order is placed. The decision is now how many to add, but the model is unchanged in a way worth seeing.

What the model determines is the quantity that should be available for the period, which is the stock on hand plus the order. Call that the order-up-to level \(S^{*}\), and notice that Equation 7.12 computes it exactly as before, because the cost of ending the period with \(S - X\) units left does not care how they got there. That is,

\[ S^{*} = F^{-1}\!\left(\frac{c_{u}}{c_{u}+c_{o}}\right), \qquad Q^{*} = \left(S^{*} - I\right)^{+} \tag{7.14}\]

For the belt, \(S^{*} = 475.18\), so with 120 belts already on hand the order is \(475.18 - 120 = 355.18\), or 355 belts. With 600 already on hand the order is zero, and the distributor is over-stocked before it begins.

Equation 7.14 is the first appearance of a structure the rest of the book uses constantly. The \((R, S)\) policy of Section 8.13 builds its whole rule on an order-up-to level, and the \((s, S)\) policy of Chapter 8 is the same idea with a trigger attached. Notice that the truncation at zero matters: a newsvendor cannot sell stock back, so an excess position is simply carried.

7.9.3 When the Model Refuses

Equation 7.12 requires \(c_{o} > 0\) and \(c_{u} > 0\), and the two ways that fails are both informative.

If \(c_{u} \le 0\) there is no penalty for being short, so the critical ratio is zero or negative and the answer is to order nothing. That is correct, and it usually means the problem was stated wrongly: an item nobody loses anything by running out of is an item nobody should stock.

If \(c_{o} \le 0\), which happens when the salvage value equals or exceeds the purchase cost, the critical ratio is one or more and the answer is to order without limit. That is also correct and also a sign of a mis-stated problem. A unit that can always be disposed of for at least what it cost carries no risk, so nothing stops you buying it. An unbounded answer is the model reporting that you have described a situation with no downside, and the right response is to find the cost you left out.

7.9.4 Is It Really a Single Period?

The strongest assumption in this chapter is the one in the title. Leftover stock must have no value after the period. That is exactly true for a perishable item, a newspaper or a flu vaccine, and exactly true for the final buy of Example 7.1 because the deck is withdrawn.

It is false for most inventory. A belt left over in an ordinary week is a belt available next week, worth its purchase cost less one week of holding, and that is a multi-period problem. Applying the newsvendor model there charges the whole value of the unit against a decision that costs only a week of carrying, so the order comes out far too small.

Thus, the test to apply before using this chapter is a single question. What is a leftover unit worth at the end of the period? If the answer is its scrap value, this is a newsvendor problem. If the answer is nearly what you paid, it is not, and Chapter 8 is where to go.

7.10 Estimating the Answer by Simulation

Everything so far has been a formula. This section computes the same answer by sampling, and it is the first simulation in this book.

The order matters. Equation 7.12 already gives the exact answer for Example 7.2, so simulating it proves nothing about the belt. What it proves is that the simulation is right, and that is worth having before the simulation is pointed at a problem where no formula exists.

The model is Equation 7.5 evaluated on sampled demand. Notice that the sampling is done from the fitted model of Equation 7.3 and not from the normal approximation to it. The simulation can sample counts as easily as it can sample real numbers, so there is no reason to hand it the approximation, and sampling counts removes the truncation at zero a normal would have needed.

val demand = NegativeBinomialRV(probOfSuccess = 0.054222, numSuccess = 26.6798, streamNum = 1)
val stat = Statistic("profit at Q")

demand.resetStartStream()
repeat(100_000) {
    val d = demand.value
    stat.collect(s * minOf(d, q) + u * maxOf(0.0, q - d) - c * q)
}
println("%.2f +/- %.2f".format(stat.average, stat.halfWidth))

Notice resetStartStream. Running it before each candidate makes every quantity face the same hundred thousand demands, which is what lets the rows of Table 7.8 be compared with one another rather than only with the exact answer. It also makes each row reproducible on its own, which a shared advancing stream would not. Section 7.12.3 packages this loop as estimate, priced by the same cost function the exact route uses.

Table 7.8: Expected profit estimated by simulation, 100,000 replications at each quantity, every quantity facing the same demands. The closed form is Equation 7.10 evaluated on the exact negative binomial of Table 7.6.
\(Q\) 440 460 469 490 510
Estimated profit $17,737.18 $17,877.57 $17,893.03 $17,818.04 $17,610.98
Half-width $21.02 $24.68 $26.31 $29.95 $33.15
Closed form $17,732.96 $17,871.00 $17,886.06 $17,811.30 $17,606.01

Read Table 7.8 one column at a time. The estimate at \(Q^{*} = 469\) is $17,893.03 with a half-width of $26.31, so the interval is \([\$17{,}866.72, \$17{,}919.34]\), and the exact $17,886.06 lies inside it. So does the exact figure in every other column. Five agreements are a great deal more convincing than one, and they cost nothing extra to report. That agreement is the validation, and it is the reason to do the easy case first. Notice also that the simulation puts its peak at the same candidate the formula does, which the common demands make a fair comparison rather than a lucky one.

Notice what the simulation has that the formula does not. Every figure in Table 7.8 carries a half-width. A simulated answer is an estimate with a standard error, and reporting one without its interval is reporting a number that is not there. Recall from Section B.2 that the half-width shrinks with the square root of the replication count. Thus, ten times the precision costs a hundred times the run.

And notice what it costs. The exact answer took one walk up a distribution function. The estimate took half a million samples and is still uncertain in the third significant figure. Simulation is not how you solve the newsvendor problem.

7.10.1 When It Is Worth It

Simulation earns its place the moment any assumption behind Equation 7.12 fails, and four failures are common.

A demand distribution with no convenient inverse. A mixture, from Section C.3.8, has no closed-form quantile. The formula needs a search; the simulation does not care.

A salvage rule that is not linear. For example, suppose the scrap dealer takes the first 100 belts at $12 and the rest at $4. Equation 7.4 no longer has constant \(c_{o}\), the derivation of Equation 7.12 breaks, and three lines change in the simulation. Example 7.5 runs it.

A constraint. A supplier minimum, a case quantity, a budget shared with another item. A budget is the easy case. The multiplier of Section 4.2.2 still works, because each item’s expected cost is its own and the budget is a sum, and the exercises of Section 7.14.4 carry it through. A supplier minimum or a case quantity is harder. It makes the order jump, the derivative the multiplier relies on no longer exists, and a search over simulated costs is often the shortest route.

More than one item that interact. Two products competing for one display, or a substitution rule sending refused demand for one to the other. There is no newsvendor formula for that, and there is an obvious simulation.

In all four the pattern is the same. That is, the policy stays simple, a single quantity chosen once, and what changes is the cost function. A cost function is easier to sample than to integrate. Building and running models of systems that no formula reaches is the subject of Rossetti (2026), and Appendix E points the way in.

7.11 Building These Models in a Worksheet

The worksheets of Section 5.8 and Section 6.9 each laid out a procedure across rows. This one is different, because the decision is a single number and the work is in producing the distribution it is a quantile of.

7.11.1 The Five Sheets

Chapter7Models.xlsx has five working sheets, and the division between them is the argument of this chapter made visible. A sixth, Notes, says what the other five are for. Table 7.9 lists them in the order the chapter uses them.

Table 7.9: The working sheets of Chapter7Models.xlsx, in the order the chapter uses them. The sheets are linked: Fit takes its demand from Data, Newsvendor takes its moments from Fit, and Fit and Horizon read the critical ratio back from Newsvendor. Only Discrete stands alone.
Sheet What it does Which part of the chapter
Data holds the 104-week history, its summary statistics and its histogram Section 7.3.1 and Section 7.3.2
Fit rules families out by the variance to mean ratio, fits the survivor, aggregates it over fourteen weeks, and prices four candidate orders Section 7.3.3 and Table 7.6
Horizon walks the exact fourteen-week negative binomial one belt at a time Section 7.7
Newsvendor the decision for the belt, from the invoice prices to the expected profit Example 7.2 and Section 7.9
Discrete the decision for the spare transformer, walked one unit at a time Example 7.3

Data holds the history and assumes nothing about it. The statistics block computes the mean, the variance, the standard deviation, the coefficient of variation, and the median, and puts the median next to the mean because Section 7.3 reads them together.

Figure 7.5: The Fit sheet, rows 1 to 32. The diagnostic block computes the variance to mean ratio and answers yes or no for each discrete family. The fit block applies Equation 7.3 and checks it twice, and the horizon block multiplies the weekly moments by fourteen. Notice that row 19 reads zero and that rows 20 and 21 return the moments the fit was made from.

Fit does Steps 1 to 3 of Section 7.3, and Figure 7.5 shows it. Row 8 computes Equation C.1 as 18.4426, and row 12 answers each family’s requirement in turn. The Poisson needs a ratio of one and the binomial a ratio below one, so both read no, which is the step the KSL’s binomial estimator performs by refusing the data. Rows 17 and 18 then fit the one family left standing, \(\hat{p} = 0.054222\) and \(\hat{r} = 1.9057\). Notice the two checks that follow. Row 19 computes \(1/\hat{p}\) less the ratio and reads zero, and rows 20 and 21 rebuild the mean and the variance from the fitted parameters. Both catch the other convention for \(p\), which is the commonest error in fitting this family. Rows 26 to 32 aggregate over the fourteen weeks and carry the critical ratio across from Newsvendor.

Horizon is the fitted model aggregated over the fourteen weeks and walked one belt at a time. Let \(g(x)\) represent the mass function of the fourteen-week total, a negative binomial with \(p = \hat{p} = 0.054222\) and \(r = 14\hat{r} = 26.6798\). Excel’s NEGBINOM.DIST will not take a number of successes that is not a whole number, so the sheet builds \(g\) from the recursion \(g(x) = g(x-1)(x+r-1)(1-p)/x\), started from \(g(0) = p^{r}\), and everything after it is a running sum. The walk stops at 700 belts, so the sheet reports the tail it did not reach, and you need not wonder why the last cumulative probability is not one.

Figure 7.6: The Horizon sheet at belts 465 to 473. The columns are the mass function, the distribution function, the first order loss function and whether the distribution function has reached the critical ratio. Notice where the last column turns: at 469, which is the exact answer of Section 7.7.

Figure 7.6 shows the rows where the decision is made. Read the distribution function column down to the critical ratio of 0.5422. \(F(468) = 0.539170\) falls short of it and \(F(469) = 0.543428\) clears it, so Equation 7.13 stops at 469 belts. The loss function column is \(G^{1}\) by the recursion of Equation C.13, and at 469 it reads 35.1478 belts of expected shortage. That is the figure every other model on the workbook is priced against.

Figure 7.7: The comparison block at the bottom of Fit. Each column is one family’s answer, rounded to a whole belt and then priced against the exact model on Horizon. Notice that the penalty in row 41 is never more than a fifth of a percent.

Figure 7.7 is Table 7.6 as the worksheet computes it. Row 38 holds each family’s quantile at the critical ratio, and row 39 rounds it to whole belts. Row 40 prices the rounded order on the exact model, which is why the gamma and the exact columns agree exactly. Row 41 states each cost as a penalty over the exact answer. Notice that it never exceeds 0.19%. The rounding comes before the pricing for the reason Section 7.8 gives.

Newsvendor is the decision for the belt, and Discrete is the decision for the transformer. They carry the mathematics of Section 7.6, so we take them cell by cell.

7.11.2 The Cells That Carry the Mathematics

Figure 7.8: The Newsvendor sheet, rows 1 to 36. The invoice prices come first and the costs the model uses second. Demand is read from Fit, then come the answer and its consequences, and last the expected cost computed twice. Notice that row 34, the difference between the two forms of Equation 7.10, reads zero.

Figure 7.8 shows the sheet from the top down. The four blue cells, B5 to B8, are the item’s inputs, and they are in the units of an invoice rather than of the model. The two blocks at the bottom of the sheet have one blue cell each, B40 and B48. Table 7.10 translates the rest of it, one row at a time. Read the last column first: every row is one result of this chapter rewritten in a language Excel evaluates.

Table 7.10: The cells of the Newsvendor sheet that carry the mathematics, in the order the derivation of Section 7.6 produces them rather than the order the sheet lays them out.
Cell Holds Formula Which result it is
B11 \(c_{o}\) =B6-B7 Equation 7.6
B12 \(c_{u}\) =B5-B6+B8 Equation 7.6, with the penalty of Section 7.9.1
B10 critical ratio =B12/(B12+B11) Equation 7.12
B14 well posed? =IF(OR(B11<=0,B12<=0),"REFUSED…","admissible") Section 7.9.3
B17, B18 \(\mu\), \(\sigma\) =Fit!B27, =Fit!B29 the moments of a sum, Example 7.2
B21 \(z\) =NORM.S.INV(B10) the standard normal quantile
B22 \(Q^{*}\) =B17+B21*B18 Equation 7.12 for the normal
B24, B25 \(\phi(z)\), \(1 - \Phi(z)\) =NORM.S.DIST(B21,FALSE), =1-NORM.S.DIST(B21,TRUE) the standard normal density and tail
B26 \(\Phi^{1}(z)\) =B24-B21*B25 \(\phi(z) - z\left(1-\Phi(z)\right)\)
B27 \(G^{1}(Q^{*})\) =B18*B26 Equation C.20 and Equation 7.8
B28 expected leftover =B22-B17+B27 Equation 7.9
B32, B33 \(E[C(Q^{*})]\) =B11*B28+B12*B27 and =(B12+B11)*B27+B11*(B22-B17) the two forms of Equation 7.10
B35 expected profit =(B5-B6)*B17-B32 Equation 7.7
B49 \(S^{*}\) =B22 the order-up-to level of Equation 7.14
B50 the order =MAX(0,B49-B48) Equation 7.14, with \(I\) in B48

Notice two things in Table 7.10. First, the loss function in B26 is a formula and not a macro. Excel has no normal loss function, and it does not need one, because \(\Phi^{1}\) is two built-in functions and a subtraction. Second, B32 and B33 compute the same quantity two ways. Thus, the arithmetic check of Example 7.2 is wired into the sheet, and B34 reads zero or something above it is wrong.

Figure 7.9: The bottom of Newsvendor, rows 38 to 50. The upper block prices any quantity typed into B40, and the lower one turns the order-up-to level into an order given the stock on hand in B48.

Figure 7.9 holds the two blocks that do not solve anything. B40 to B44 price whatever quantity is typed into B40. The sheet ships holding 465, the mean in whole belts, so B44 shows the 0.6% penalty that Section 7.7 quotes for ordering the mean. B48 to B50 are Equation 7.14, and typing 120 into B48 returns the order of 355.18 belts that Section 7.9.2 computes.

Figure 7.10: The Discrete sheet, rows 1 to 29. The item block holds the transformer’s prices and the Poisson mean, and the walk below lays out one row per candidate quantity. Notice that the highlighted row is chosen by the Reached? column and not by the cost column beside it, and that the two agree.

Discrete, in Figure 7.10, walks Equation 7.13. B5 to B8 are the inputs and B9 to B11 derive the two costs and the ratio exactly as Newsvendor does. Each row of the walk holds a candidate \(Q\), the Poisson mass and distribution functions from POISSON.DIST, the loss function by Equation C.13, and the expected cost. Column F asks whether \(F(Q)\) has reached B11, and column G marks the first row where it has. B12 reads its answer from that column with INDEX and MATCH rather than repeating the logic. Thus, the rule and the direct calculation of Table 7.7 sit side by side, and when you change a price you watch both move.

Two conventions hold on the workbook. It carries no macros, so every number on it can be traced by clicking on the cell that produced it. And it computes the expected cost of every candidate on Discrete, although Equation 7.13 does not need the costs, so that the rule can be checked.

7.11.3 Reading the Sheets

The workbook ships holding the belt and the transformer, so the first use of it is to confirm that it says what the chapter says. The second is to ask it something the chapter did not.

Example 7.4 (Reading the Newsvendor and Discrete sheets) The distributor wants to confirm the workbook before trusting it with the final buy, and then to use it to price an offer from the scrap dealer.

The input block. On Newsvendor, B5 to B8 hold \(s = \$95\), \(c = \$50\), \(u = \$12\) and \(\pi = 0\). These are the cells you type the item into.

The derived block. B11 and B12 return \(c_{o} = \$38\) and \(c_{u} = \$45\), B10 returns the critical ratio 0.5422, and B14 reads “admissible”.

Demand. B17 and B18 return \(\mu = 465.3654\) and \(\sigma = 92.6420\) belts, read from rows 27 and 29 of Fit. Notice that the sheet carries every digit, where Example 7.2 rounded to 465.37 and 92.64.

The answer. B21 returns \(z = 0.1059\) and B22 returns \(Q^{*} = 475.1761\) belts. B27 and B28 return an expected shortage of 32.2605 belts and an expected leftover of 42.0712 belts.

The check, by hand. Let’s reproduce B27 from Table D.2, which steps \(z\) by tenths. The table gives \(\Phi^{1}(0.1) = 0.3509\) and \(\Phi^{1}(0.2) = 0.3069\). Interpolating to \(z = 0.1059\),

\[ \Phi^{1}(0.1059) \approx 0.3509 - 0.059(0.3509 - 0.3069) = 0.3509 - 0.0026 = 0.3483 \]

and by Equation C.20 the expected shortage is \(92.6420(0.3483) = 32.27\) belts. B27 holds 32.2605, from the exact \(\Phi^{1}(0.1059) = 0.3482\) that Example 7.2 used. The two differ by a hundredth of a belt, which is the interpolation, because \(\Phi^{1}\) curves between the rows of the table. That check is worth performing once on any sheet you did not build. A loss function that has lost its \(\sigma\) is off by a factor of 92, and no interpolation error looks like that.

The cost, twice. B32 and B33 both return $3,050.43, and B34 reads zero. B35 returns an expected profit of $17,891.01. These are the figures of Example 7.2, now carried to the cent. B36 prices the unrounded 475.18 belts at $23,758.80, where the example priced the 475 actually ordered, $23,750.

Now a real question. The scrap dealer calls with an offer of $20 a belt rather than $12 for whatever is left when the deck is withdrawn. What is the offer worth, and should the order change? One cell answers both. Set B7 to 20 and read the sheet:

\[ c_{o} = \$30, \qquad \frac{c_{u}}{c_{u} + c_{o}} = \frac{45}{75} = 0.6000, \qquad Q^{*} = 488.84 \text{ belts}, \qquad E[G(Q^{*}, X)] = \$18{,}257.08 \]

What it is worth. The expected profit rises by $366.06, from $17,891.01 to $18,257.08 before rounding. Now type the old order, 475.1761, into B40 and read B43. Under the new salvage value the old order costs $2,713.86, so its expected profit is \(45(465.3654) - 2{,}713.86 = \$18{,}227.58\). Thus, of the $366.06, $336.57 comes from the higher price on the belts that would have been left over anyway, and only $29.49 comes from re-optimizing the order. Each figure is rounded from the sheet’s full precision, which is why the printed values differ by a cent in the last place. In other words, the offer is worth taking, and the 14 extra belts it calls for are worth having but are not where the money is. That is the flatness of Section 7.7 again, now measured on a decision someone has to make.

The transformer. On Discrete, the highlighted row is \(Q = 7\) with an expected cost of $7,802, which is Table 7.7. Set the emergency price in B8 to $8,150 and the highlight moves up one row to 6, which is the change Section 7.8 made by hand. Exactly where it moves is a question for Exercise 7.21. Restore both sheets before going on.

7.11.4 Using the Sheets on Your Own Item

Newsvendor takes its demand from Fit, and Fit takes it from the history on Data. Thus, there are two ways to point the sheet at a new item. If you have a history of the same kind, paste it into column B of Data and every sheet but Discrete follows it, including the family verdicts on Fit. The length of the period is the number of weeks in B26 of Fit. The statistics read the named range Demand, which spans the 104 weeks shipped, so a longer history means widening that name. If you already know the mean and the standard deviation over the period, type them over B17 and B18 of Newsvendor. That breaks the link to Fit deliberately, and the comparison of families on Fit no longer describes your item.

Discrete stands alone. Its demand is a Poisson mean in B5, and the walk covers zero to 15 units. That is enough for the transformer and for any item whose mean is under about seven. When no row of the walk reaches the ratio, B12 returns #N/A rather than a wrong answer, which is the sheet saying the walk is too short. A larger mean belongs on Newsvendor, for the reason Section 7.8 gives at its end: once one unit is a small fraction of the standard deviation, rounding decides nothing.

7.11.5 What the Worksheet Does Not Do

Two things the workbook does not do, for different reasons.

The first is Section 7.10. A spreadsheet can sample, but a sampled spreadsheet recalculates every time anything is touched. It gives a different answer each time, which is the wrong tool for a number someone will be asked to defend.

The second is more than one item. Every sheet here holds one item, and nothing on it knows that a second item exists. When several items draw on one budget or one storage area, the order of each depends on all of the others, through a multiplier of the kind Section 4.2.2 introduced. Section 4.7.1 built that machinery for lot sizing, and the exercises of Section 7.14.4 build it for the newsvendor.

Section 7.12 now turns the same model into code, where neither limit applies.

7.12 Designing the Software

Section 5.9 and Section 6.10 each had an algorithm to organize. This chapter has a formula, so the design question is different and smaller: what are the pieces, and what keeps the two ways of computing the answer in agreement?

7.12.1 What the Software Must Do

Five requirements follow from the chapter, and each one names where in the chapter it comes from.

  1. Solve exactly, by Equation 7.12 for a continuous model and by Equation 7.13 for a discrete one, for any family with a quantile and a first order loss function.
  2. Evaluate any quantity and not only the best one, because Table 7.7, Table 7.6 and Table 7.8 all price a grid.
  3. Estimate the profit of a quantity by sampling, priced by the same cost function the exact route uses, Section 7.10.
  4. Refuse a problem with no finite, positive answer, Section 7.9.3.
  5. Take stock already on hand, Section 7.9.2.

7.12.2 Finding the Nouns

A demand model is a distribution with a quantile and a first order loss function. Notice that this is not a new class. It is LossFunctionDistributionIfc from Section C.3.9, which the KSL already provides for every family this chapter uses, and the design’s first decision is not to reimplement it.

A single-period cost structure is \(c_{o}\) and \(c_{u}\), together with the mapping from \(s\), \(c\), \(u\) and \(\pi\) that produces them. It owns Equation 7.6, it owns the critical ratio, and it owns the refusal of Section 7.9.3: a cost structure with a non-positive \(c_{o}\) or \(c_{u}\) is rejected at construction rather than allowed to return an absurd quantity later.

A solution pairs a quantity with what it implies: the expected shortage, the expected leftover, the expected cost, the expected profit. It is computed for any quantity and not only the optimal one, because the tables of this chapter all need a grid.

Newsvendor is the instructive rejection. It reads like the central class and the chapter is named after it. It fails because the cost structure and the demand model already do everything between them. Given both, the optimal quantity is one line, and a class whose only method is one line is a function wearing a costume.

7.12.3 The Classes

The code is in code/, package inventory.newsvendor, file SinglePeriod.kt. The cost structure is a data class.

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 cost(q: Double, d: Double): Double =
        overageCost * max(q - d, 0.0) + underageCost * max(d - q, 0.0)
    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)
}

The four constructor parameters are \(s\), \(c\), \(u\) and \(\pi\). overageCost and underageCost are Equation 7.6, criticalRatio is Equation 7.12, and cost and profit are Equation 7.4 and Equation 7.5 for one realized demand d, a value of \(X\). An init block, not shown, refuses a non-positive \(c_{o}\) or \(c_{u}\) with a message naming Section 7.9.3. Notice that price is the value of a unit at the moment it is needed. For the belt that is the selling price, and for the transformer of Example 7.3 it is the emergency purchase price, because that is what a missing unit costs to replace. A data class also gives copy, so a variation is one line. For the belt’s costs, copy(penalty = 40.0) is Section 7.9.1.

The exact route is two functions.

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
}

optimalLevel is Equation 7.12 when demand is continuous. When it is discrete, the two loops make the answer Equation 7.13 exactly, the smallest whole unit whose distribution function reaches the ratio, whatever convention the library’s quantile uses for a staircase. It takes any DistributionFunctionIfc, which is what lets Table 7.6 ask a lognormal and a gamma for a quantity without asking either for a loss function.

fun evaluate(costs: SinglePeriodCosts, demand: LossFunctionDistributionIfc,
             level: Double, onHand: Double = 0.0): NewsvendorSolution {
    val shortage = demand.firstOrderLossFunction(level)
    val leftover = shortage + level - demand.mean()
    val expectedCost = costs.overageCost * leftover + costs.underageCost * shortage
    return NewsvendorSolution(costs, level, onHand, demand.cdf(level), shortage, leftover,
        expectedCost, (costs.price - costs.cost) * demand.mean() - expectedCost)
}

fun solve(costs: SinglePeriodCosts, demand: LossFunctionDistributionIfc, onHand: Double = 0.0) =
    evaluate(costs, demand, max(optimalLevel(costs, demand), onHand), onHand)

evaluate prices any level, the stock available for the period, which is \(S\) of Section 7.9.2, and onHand is its \(I\). Its lines are Equation 7.8, Equation 7.9, Equation 7.10 and Equation 7.7, in that order. solve evaluates at the optimal level, and onHand carries Equation 7.14: the level does not depend on what is already there, and the order is the difference. When more than the level is already on hand, the level is what is on hand and nothing is ordered. NewsvendorSolution holds the eight values and computes orderQuantity as \((S - I)^{+}\).

The sampled route is one function.

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)

This is the loop of Section 7.10 with its free variables given names. resetStartStream is there for the reason that section gives: every quantity estimated with the same demand faces the same demands. The second form passes costs::profit, the very function the cost structure defines. The first form takes any profit function, which is what Section 7.10.1 needs.

7.12.4 The Two Routes Must Agree

The design’s real content is the agreement Section 7.10 demonstrated. The same cost structure is evaluated two ways, exactly and by sampling, and the two must agree.

That agreement is not a convenience; it is what the design is for. A solver and an estimator that share a cost function can be checked against each other, and one that does not share it cannot. Both routes take their costs from SinglePeriodCosts. The exact route uses its overageCost and underageCost through the loss function in evaluate, and the sampled route calls its profit on each demand in estimate. The two are tied by Equation 7.7, which a test in the code checks.

Notice what that buys when the exact route stops applying. Under the nonlinear salvage rule of Section 7.10.1 the loss function integration is no longer valid, but the sampled evaluation still is. Only the profit function changes, and the machinery that samples and averages it is the machinery that was validated against the formula when the formula held. That is the whole argument for building it this way. Section 7.12.5 puts both routes to work on the belt.

7.12.5 Running the Chapter’s Examples

NewsvendorExamples.kt holds everything below. Run it with ./gradlew run -PmainClass=inventory.newsvendor.NewsvendorExamplesKt. The output shown is the program’s, with its section headings left out.

Example 7.5 (The final buy in code, and a salvage rule no formula takes) The distributor wants the final buy computed in code, checked against the workbook, and then priced under a salvage rule the workbook cannot take.

Building the item. DemandFitting.fittedHorizon returns the fourteen-week negative binomial of Section 7.7, fitted from the history file rather than typed in. We solve against the normal the Newsvendor sheet uses, and then against the exact model.

val belt = SinglePeriodCosts(price = 95.0, cost = 50.0, salvage = 12.0)
val horizon = DemandFitting.fittedHorizon()
val normal = Normal(horizon.mean(), horizon.variance())
println(solve(belt, normal))
println(solve(belt, horizon))
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 printed. The second is the exact answer of Figure 7.6: 469 belts, \(F(469) = 0.543428\), and an expected shortage of 35.1478 belts. Notice the line F(level). Against the normal it equals the critical ratio, because a continuous quantile lands on it exactly; against the negative binomial it is a little above, which is the staircase of Section 7.8.

The families. Table 7.6 is a short loop.

for ((name, model) in families) {
    val q = optimalLevel(belt, model).roundToInt().toDouble()
    println("%-10s Q = %4.0f   expected cost under the exact model %9.2f"
        .format(name, q, evaluate(belt, horizon, q).expectedCost))
}
normal     Q =  475   expected cost under the exact model   3061.28
lognormal  Q =  466   expected cost under the exact model   3057.19
gamma      Q =  469   expected cost under the exact model   3055.38
exact      Q =  469   expected cost under the exact model   3055.38

families pairs each name with a KSL distribution moment-matched to the horizon, or with horizon itself. optimalLevel asks each one for its quantile, and evaluate prices the rounded answer against horizon alone, which is row 40 of Figure 7.7.

Now the item the formula cannot take. Section 7.10.1 supposed that the scrap dealer takes the first 100 belts at $12 and the rest at $4. The profit function changes, so we write it and hand it to estimate:

val twoTier = { q: Double, d: Double ->
    val left = max(q - d, 0.0)
    belt.price * min(d, q) + 12.0 * min(left, tier) + 4.0 * max(left - tier, 0.0) - belt.cost * q
}
for (q in 420..500 step 10) {
    val stat = estimate(demand, q.toDouble(), 100_000, twoTier)
    ...
}

Here tier is 100 and demand is a NegativeBinomialRV with the parameters of horizon, on stream 1, as in Section 7.10. Notice that twoTier is Equation 7.5 with its salvage term replaced, and that nothing else in the call changes. The column headed summed is the check. It computes the same expected profit by summing twoTier against the negative binomial’s mass function, which is possible here because demand has a mass function we can walk.

    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, so the sampled route is right under the new rule as it was under the old one. Notice also that every estimate sits above its summed value, by between $2.90 and $7.45. That is not a bias. Every row faces the same hundred thousand demands, so the rows share one sampling error, and it happens to be positive. Thus, the comparison across rows is far sharper than any one half-width suggests.

What it means for the belt. Summing one belt at a time, the best order is 466, against 469 under the linear salvage value, and keeping 469 costs $1.59 over the close-out. In other words, the rule barely moves the order. It does lower the profit, by about $45 at 469, because the second tier is reached in about one close-out in seven: the expected leftover at 469 is 38.8 belts, and more than 100 are left over with probability 0.145. The program repeats the run with the tier at 25 belts, and there the rule bites. The best order falls to 460, and staying at 469 costs $14.69 over the close-out.

The limit. The summed column was available only because this is one item whose demand has a mass function. Make demand a mixture whose distribution cannot be walked one unit at a time, or let two items share a budget and substitute for one another, and the column cannot be computed. The estimate column still can, and it is the same function that has now agreed with exact answers twice.

7.13 Summary

The single-period problem is not a short multi-period problem. What distinguishes it is that leftover stock has no future value, so the cost of ordering one too many is the whole loss on the unit rather than a period of carrying. That is also the test for whether this chapter applies.

The ordering cost disappears. One order is placed whatever its size, so \(k\) is constant across every alternative and cannot affect which is best. The trade-off that remains is overage against underage, and both are opportunity costs that appear in no ledger.

The answer is a quantile, and the quantile is the answer. The critical ratio \(c_{u}/(c_{u}+c_{o})\) is the probability of having too much that the costs imply, and \(Q^{*} = F^{-1}\) of it. Read as odds it says that if being short costs three times as much as being long, it is optimal to run a 75% chance of leftovers. Thus, never having leftovers is not careful buying, and never disappointing a customer is not good service. Each is a claim about a ratio of costs, and the useful question about a service target is what ratio would make it optimal.

Discrete demand needs the rule and not the inverse. A staircase distribution function rarely lands on the critical ratio, so the answer is the smallest quantity whose cumulative probability reaches it. Rounding a continuous approximation usually gives the same answer and sometimes does not, and it fails exactly where the items are slow-moving and expensive.

The demand distribution carries more of the answer than the formula does. Characterizing a history is cheap and settles more than a goodness of fit test does. Demand arrives in whole units, and for a count the variance to mean ratio of Equation C.1 decides the family before any of them is fitted: it is one for a Poisson and below one for a binomial, so a ratio of 18 leaves only the negative binomial standing. The test then confirms what the ratio chose. And a sales history is not a demand history, so a fitted distribution built from sales is biased low in the periods that mattered.

Which family you pick costs less than you would guess, and it can be measured. Fitting a count model makes the aggregate exactly computable, because negative binomials sharing \(p\) add. Table 7.6 prices the normal, lognormal and gamma answers against that exact model and none of them costs more than a fifth of a percent. Thus, the argument for care in Section 7.3 is not that the family is delicate; it is that the moments are, and every family in the table was given the same two.

Simulation belongs after the closed form, not instead of it. The newsvendor is the one model in this book whose simulation can be checked against an exact answer, which makes it the right place to build the habit. What simulation buys is the cases the formula cannot reach: a distribution with no inverse, a salvage rule that is not linear, a constraint, or two items that interact.

Table 7.11 collects the notation, which Appendix A repeats alongside the rest of the book’s.

Table 7.11: Notation introduced in this chapter.
Symbol Meaning
\(X\) Demand over the single period, a random variable
\(F(x)\) Cumulative distribution function of demand, \(P\{X \le x\}\)
\(Q\) Order quantity, the decision
\(Q^{*}\) The optimal order quantity
\(S^{*}\) Order-up-to level, when stock is already on hand
\(c_{o}\) Overage cost, the loss per unit left over
\(c_{u}\) Underage cost, the loss per unit of unmet demand
\(c\), \(s\), \(u\) Purchase cost, selling price, salvage value per unit
\(\pi\) Stockout penalty beyond the lost margin, per unit
\(G^{1}(Q)\) First order loss function, the expected shortage at \(Q\)

Chapter 8 removes the last assumption this chapter kept. There the period does not end, stock left over is worth what it cost, and the decision is not how much to buy once but when to buy and how much each time.

7.14 Exercises

Unless an exercise says otherwise, use the conventions of Section 1.8. Report quantities to the nearest whole unit and state the unrounded value alongside. Where a demand history is called for, generate it with the code of Section 7.3 and the seed the exercise gives, so that your answer and the instructor’s agree.

7.14.1 Terminology and Concepts

Exercise 7.1 Define each of the following in one sentence, and say what unit it carries: overage cost, underage cost, critical ratio, order-up-to level, censored demand.

Exercise 7.2 True or false, with one sentence of justification for each.

  1. Increasing the salvage value raises the optimal order quantity.
  2. A buyer who never has leftover stock is managing the item well.
  3. The ordering cost \(k\) does not appear in the newsvendor model because it is small.
  4. If the critical ratio is 0.5 then the optimal quantity is the mean of demand.
  5. Rounding the normal-approximation answer always gives the discrete optimum.

Exercise 7.3 Table 1.10 says that \(k\) is irrelevant with one order. Explain why, and then describe a single-period situation in which it would not be irrelevant. State what would have to be true of the supplier for your situation to arise.

Exercise 7.4 A distribution manager states a target of 98% service for an item. Using Equation 7.12, determine what ratio of underage to overage cost would make that target optimal. The item costs $40, sells for $60, and salvages for $25. What stockout penalty \(\pi\) would be needed to justify the target, and is it credible?

7.14.2 Working the Model by Hand

Exercise 7.5 A caterer must decide how many trays of a dish to prepare for one event. Each tray costs $18 to make and sells for $45. Unsold trays are donated and carry no salvage value. Demand is

Trays \(x\) 10 20 30 40 50
\(P\{X = x\}\) 0.10 0.20 0.35 0.25 0.10
  1. Compute \(c_{o}\), \(c_{u}\) and the critical ratio.
  2. Build the marginal analysis table of Table 7.2, one step of ten trays at a time, and report where it stops.
  3. Compute the expected profit at all five candidates directly and confirm the answer of part (b).
  4. Report the expected number of trays donated and the expected number of customers turned away at the optimum.

Exercise 7.6 An airline holds one spare engine module at a maintenance base. Failures over the coming season are Poisson with a mean of 3. A module costs $220,000 and is worth $60,000 if the fleet is retired before it is used. A failure with no module on hand grounds an aircraft at a cost of $500,000.

  1. Compute \(c_{o}\), \(c_{u}\) and the critical ratio.
  2. Using Equation 7.13, determine how many modules to hold. Show the \(F(Q)\) column you walked.
  3. Compute the expected cost at \(Q^{*} - 1\), \(Q^{*}\) and \(Q^{*} + 1\) and confirm the minimum.
  4. Compute the normal-approximation answer and compare. Explain the comparison in terms of the ratio of one unit to the standard deviation.

Exercise 7.7 For the final buy of Example 7.2, compute the expected shortage and expected leftover at \(Q = 450\), \(Q = 475.18\) and \(Q = 510\), using Table C.2 and Equation C.20. Work with the normal approximation, \(E[X] = 465.37\) and \(\sigma = 92.64\).

  1. Verify Equation 7.9 at each quantity, i.e. that the expected leftover equals the expected shortage plus \(Q - E[X]\).
  2. Compute the expected cost at each and confirm that 475.18 is the smallest.
  3. Express the cost at 450 and at 510 as a percentage above the optimum, and compare the shape of that penalty with Equation 3.22.
  4. Report the cost excess per belt of departure at each of the two quantities in part (c), dividing the excess by the distance from the optimum. Then do the same for two symmetric departures, 25 belts either side. The costs \(c_{u}\) and \(c_{o}\) differ by 18%, so being short ought to be the more expensive direction. Report by how much it actually is at 25 belts, and explain why the asymmetry is so much smaller than the ratio of the two costs suggests.

7.14.3 Modeling Problems

Exercise 7.8 A second item’s history is in data/ch7-exercise-demand.csv, 104 weeks in the same two columns as the belt’s. Work Section 7.3 on it from beginning to end, and report the code alongside each answer.

  1. Draw the three plots of Section 7.3.1 and say what each one settles. Include them with your answer.
  2. Report the summary statistics of Table 7.4 for this item. Which families does Equation C.1 rule out before anything is fitted, and why can no choice of parameter rescue them?
  3. Run PMFModeler on the history. Report every estimate it returns, including any that fail, and say what the failures mean.
  4. Compute \(\hat{p}\) and \(\hat{r}\) by hand from Equation 7.3 and confirm the KSL’s estimates. Then compare \(1/\hat{p}\) with the ratio from part (b) and explain why they must agree.
  5. Test the fitted negative binomial with DiscretePMFGoodnessOfFit and report the statistic, the degrees of freedom and the \(p\)-value. Do the same for a Poisson with the same mean, and compare the two.
  6. Suppose the item is being bought for a 20-week close-out with \(c = \$30\), \(s = \$55\) and \(u = \$8\). Compute the mean and variance of 20-week demand, the critical ratio, and \(Q^{*}\) under a normal approximation. Then compute \(Q^{*}\) exactly from the aggregated negative binomial, as Table 7.6 does, and report what the approximation costs.

Exercise 7.9 Return to Example 7.2.

  1. Plot or tabulate \(Q^{*}\) against the stockout penalty \(\pi\) for \(\pi = 0, 20, 40, 60, 80, 100\) dollars per belt.
  2. At what \(\pi\) does the optimal order reach 550 belts?
  3. The distributor is unwilling to name \(\pi\) but is confident the order should not exceed 525 belts. What upper bound on \(\pi\) does that imply? This is the move of Section 4.4.3, applied here.
  4. Your answer to part (a) should show the quantity rising steeply at first and then flattening. Explain that shape from the critical ratio rather than from the plot.

Exercise 7.10 A hospital pharmacy must decide a final order for a drug being withdrawn from the formulary. Demand over the remaining 90 days is normal with a mean of 400 doses and a standard deviation of 70. A dose costs $22, is billed at $58, and expired doses are destroyed at a disposal cost of $3 each.

  1. Note that the salvage value is negative. Compute \(c_{o}\) and explain the sign.
  2. Compute \(S^{*}\) and the order quantity if 85 doses are already on hand.
  3. Compute the order quantity if 450 doses are already on hand, and say what the pharmacy should do about the excess.

Exercise 7.11 For each of the following, determine whether the newsvendor model applies, and if it does not, identify the cost that has been left out or mis-stated.

  1. A retailer can return all unsold units to the supplier for a full refund.
  2. A publisher prints a commemorative program that has no value after the event and no shortage cost, because attendees who cannot get one simply do not.
  3. A grocer stocks a staple with a two-year shelf life, ordering weekly.
  4. A contractor buys a specialist part for one job; leftovers can be sold to another contractor at slightly above what was paid.

7.14.4 Several Items and a Shared Limit

The deck the belt fits is out of production, so the belt is not the only part facing a final buy. The distributor also stocks the deck’s spindle assembly, its blade and its idler pulley, and all four last orders are placed together for the same fourteen-week close-out. Table 7.12 gives the parts. The exercises of this subsection all use it, and each one says which parts and which limits it takes.

Table 7.12: The deck’s end-of-life parts. Prices are per unit, and space is the shelf volume one unit takes in the distributor’s bins. In code, take the belt’s model from DemandFitting.fittedHorizon, whose parameters print as these.
Part Demand over the close-out \(s\) \(c\) \(u\) Space per unit
Belt negative binomial, \(\mathit{NB}(0.054222, 26.6798)\), as in Section 7.7 $95 $50 $12 0.05 ft\(^{3}\)
Spindle assembly normal, mean 120, standard deviation 30 $240 $140 $25 1.20 ft\(^{3}\)
Blade normal, mean 300, standard deviation 60 $34 $18 $2 0.15 ft\(^{3}\)
Idler pulley Poisson, mean 9 $120 $65 $10 0.40 ft\(^{3}\)

The notation is that of Section 4.2.2, with part \(j\) in place of item \(j\). Let \(c_{j}\) represent part \(j\)’s purchase cost and \(v_{j}\) the space one unit takes. Let \(\theta\) represent the multiplier on a budget, in dollars of expected profit per dollar of budget, and \(\eta\) the multiplier on the bins, in dollars of expected profit per cubic foot. Under a limit that binds, each part is ordered at an adjusted critical ratio, below its own critical ratio, and Exercise 7.13 finds it.

Three conventions hold throughout. A multiplier is found from the unrounded quantities. Once it is found, a quantity computed from a continuous model is rounded down to a whole unit, so that a plan inside a limit stays inside it. A quantity from a discrete model is already whole, by Equation 7.13. Profits are expected profits by Equation 7.7, part by part, and a plan’s profit is their sum.

Exercise 7.12 The distributor has a final-buy budget, and the four unconstrained orders of Table 7.12 cost more than it. Answer each part true or false, and give the reason in one sentence.

  1. The best plan cuts every part’s order by the same percentage, so that the total just fits the budget.

  2. Under a budget that binds, every part’s adjusted critical ratio is below its critical ratio by the same amount.

  3. If the four unconstrained orders together cost less than the budget, the budget changes nothing, however close the two figures are.

  4. The part whose unconstrained order costs the most to buy is cut first, and the others are cut only if that is not enough.

  5. Multiple choice. The budget’s multiplier is \(\theta = 0.11\). Which statement is correct?

    1. One more unit of each part adds about $0.11 of expected profit.
    2. One more dollar of budget adds about $0.11 of expected profit.
    3. The budget should be raised by 11%.
    4. Each part’s adjusted critical ratio is 0.11 below its critical ratio.

Exercise 7.13 Take two parts, \(j = 1, 2\), with continuous demand. Let \(F_{j}\) represent part \(j\)’s distribution function and \(c_{o,j}\) and \(c_{u,j}\) its overage and underage costs. Let \(A\) represent the budget, in dollars, so that the plan must satisfy \(c_{1}Q_{1} + c_{2}Q_{2} \le A\).

  1. Write the Lagrange function for minimizing \(E[C_{1}(Q_{1})] + E[C_{2}(Q_{2})]\) subject to the budget, with a multiplier \(\theta \ge 0\), following Section 4.2.2.

  2. Differentiate it with the help of Equation 7.11 and show that at the optimum \[ F_{j}(Q_{j}) = \frac{c_{u,j} - \theta c_{j}}{c_{u,j} + c_{o,j}}, \qquad j = 1, 2. \]

    The right side is part \(j\)’s adjusted critical ratio.

  3. Show that the same condition follows from Equation 7.6 if each purchase cost is raised from \(c_{j}\) to \((1 + \theta)c_{j}\) and nothing else changes. Say what the multiplier is a surcharge on, and compare it with the surcharge of Section 4.2.2.

  4. What does the condition say about part \(j\) when \(\theta c_{j} \ge c_{u,j}\)? Relate your answer to Section 7.9.3.

  5. Explain why the check of Section 4.2.1 comes before any of this.

Exercise 7.14 Take only the spindle assembly and the blade of Table 7.12, with a final-buy budget of $18,000 for the two. Work by hand, with Table D.1 and Table D.2, and the result of Exercise 7.13.

  1. Compute each part’s unconstrained order and what the pair costs to buy. Does the budget bind?
  2. Find \(\theta\) by bisection. Start from the interval \([0, 1]\), try its midpoint, and keep the half in which the spend crosses $18,000. Stop when the interval is narrower than 0.01. At each trial report \(\theta\), both adjusted critical ratios, both unrounded quantities and the spend.
  3. At the last trial value of \(\theta\) that keeps the spend within the budget, round both quantities down, and report the plan, its spend, and each part’s expected profit.
  4. Report the expected profit the budget costs, against the unconstrained pair. Which part gave up more units, and which gave up more profit?

Exercise 7.15 Two slow movers are left for a smaller close-out: idler pulleys with Poisson demand of mean 3, and spindle assemblies with Poisson demand of mean 2, both at the prices of Table 7.12. The budget for the two is $450. Work by hand, with Table D.3.

  1. For each part tabulate \(F(k)\) for \(k = 0\) to 5, and the expected gain from the \((k+1)\)st unit, \(c_{u} - (c_{u} + c_{o})F(k)\), which is the marginal argument of Section 7.2. What are the unconstrained orders, and do they fit the budget?
  2. The greedy rule. Start with nothing. At each step, add one unit of whichever part has the larger expected gain per dollar, among those whose gain is positive and whose price fits in what is left of the budget. Stop when no unit qualifies. Keep a ledger with columns for the step, the pulleys, the spindles, each part’s next gain per dollar, the unit added, the spend, and the budget left, and re-render it after every step.
  3. Enumeration. Tabulate the expected profit of every pair that fits the budget, and find the best.
  4. Compare (b) and (c). Explain why the greedy rule missed, and say under what condition on the prices it could not have.

Exercise 7.16 Add a sheet named Budget to Chapter7Models.xlsx for the belt, the spindle assembly and the blade, with the belt’s demand taken as the normal of Example 7.2, mean 465.37 and standard deviation 92.64. Lay it out as Section 4.7.1 lays out the constrained lot sizing sheet: an input block holding the budget, a block that says whether the budget binds, a multiplier cell, a results block showing each part unconstrained beside constrained, and one row per part below.

  1. Implement the condition of Exercise 7.13 in the part rows, with NORM.INV for the quantity and the loss function of Table 7.10 for the expected profit.
  2. With a budget of $40,000, find the multiplier with Goal Seek, setting the spend of the unrounded quantities to the budget by changing the multiplier cell. Report \(\theta\), the three quantities rounded down, the spend, and the expected profit given up.
  3. Add a check row that computes \(F(Q)\) at each part’s unrounded quantity and confirms it equals the adjusted critical ratio, \((c_{u} - \theta c)/(c_{u} + c_{o})\).
  4. Repeat (b) at budgets of $44,000 and $46,000, and explain what the sheet does at the second.

Exercise 7.17 Take all four parts of Table 7.12, a final-buy budget of $43,000, and 195 ft\(^{3}\) of bins. Use SinglePeriodCosts, optimalLevel and evaluate from Section 7.12, and report the code you wrote alongside each answer.

  1. Compute the unconstrained plan, its spend and its space. Which limits does it break?
  2. Impose the budget alone. Re-price each part with copy, raising its purchase cost by \(\theta c_{j}\), and find \(\theta\) by bisection on the unrounded quantities. Report \(\theta\), the plan, its spend and its space. Does it fit the bins?
  3. Impose the bins alone. Raise each part’s purchase cost by \(\eta v_{j}\), and find \(\eta\) the same way. Report \(\eta\) and the plan. Does it fit the budget?
  4. Impose both. Alternate the two searches, each holding the other multiplier fixed, until neither changes in its sixth decimal place. Report \(\theta\), \(\eta\), the plan, its spend, its space and its expected profit, and say which limits bind.
  5. Confirm the expected profit of each part in (d) by simulation: use estimate with 100,000 replications on stream 1 for each part, and show that the value evaluate gives lies inside each interval.
  6. The multiplier on the budget is positive, but the plan’s spend does not reach $43,000. Explain why, naming the parts responsible.

Exercise 7.18 Use your answer to Exercise 7.17 (d).

  1. A neighboring warehouse offers extra bin space for the close-out at $10 per cubic foot. Another offers it at $15. Using the multipliers alone, say which offer, if either, the distributor should take, and why.
  2. Check your answer to (a) by solving again with 197 ft\(^{3}\) and with 205 ft\(^{3}\) of bins. Compare each gain in expected profit with what the extra space would cost at each price, and explain why the multiplier predicts the first comparison better than the second.
  3. The treasurer offers to raise the budget by $1,000 for a financing charge of $150. Should the distributor accept? Answer from the multipliers, then check by solving again.

Exercise 7.19 Read Erlebacher (2000) and Lau and Lau (1996). Both study the problem of this subsection with a single limit, and Lau and Lau (1996) goes on to several.

  1. Erlebacher (2000) writes the optimality condition as \(F_{i}(Q_{i}) = \alpha_{i} - \lambda\beta_{i}\). State how he defines \(\alpha_{i}\) and \(\beta_{i}\). Then show that when the limit is a budget, so that the resource a unit uses is its purchase cost, his condition is the one you derived in Exercise 7.13, with \(\lambda = \theta\).
  2. Erlebacher (2000) proposes three heuristics, H1, H2 and H3, that need no search for the multiplier. Apply all three to the spindle assembly and the blade of Exercise 7.14 under the $18,000 budget. Do not round, and price each plan by the pair’s expected profit. Find the exact optimum the same way, by bisection on \(\theta\) until the spend is within a cent of the budget, and report each heuristic’s shortfall from it as a percentage. Rank the three, and say whether the ranking agrees with his results for normal demand.
  3. H2 is optimal when every part’s demand is uniform. Say what H2 therefore assumes about the spindle and the blade, and explain why it does well here anyway. His Section 3 says when it does best.
  4. Lau and Lau (1996) show an order falling to zero as the capacity tightens. In the notation of Exercise 7.13, state when that happens. Then explain, from their Section 3, why a numerical search for the multiplier can fail near that point when a demand distribution has a positive lower bound or a long left tail.
  5. Lau and Lau (1996) handle several constraints by an active-set method that solves for the multipliers of the binding constraints together. Exercise 7.17 (d) alternated two one-dimensional searches instead. Say what their method does that alternation does not, and why alternation was enough there.

7.14.5 Using the Software

Exercise 7.20 The code of Section 7.12 is in code/, package inventory.newsvendor. Report the code you wrote alongside each answer.

  1. Reproduce Table 7.7 with evaluate on a KSL Poisson. Then use optimalLevel and copy to find, to the nearest dollar, the emergency purchase price below which the order falls from 7 transformers to 6.
  2. Reproduce Table 7.8 with estimate, and confirm that the value evaluate gives lies inside the confidence interval in every column, not only at \(Q^{*}\). Then increase the replications tenfold and report how the half-width changes; state whether it changed by the factor Section 7.10 predicts.
  3. Combine Section 7.9.1 and Section 7.9.2 against the exact model: a penalty of $40 per belt and 120 belts already on hand. Use solve with the fitted horizon of DemandFitting, and report the order-up-to level and the order. Compare them with what the normal answers of those two sections imply together, and explain the difference from the shape of the negative binomial.
  4. The scrap dealer of Example 7.5 now takes at most 60 belts, at $12 each, and the rest must be hauled away at a cost of $2 each. Write the profit function, and estimate it with estimate at \(Q = 400, 405, \ldots, 520\), using 100,000 replications and the stream of Example 7.5. Confirm the best quantity by summing the same function against the negative binomial’s mass function, one belt at a time. Then name the step in the derivation of Equation 7.12 that fails under this rule.

7.14.6 Using the Workbook

Exercise 7.21 Open Chapter7Models.xlsx and work entirely within it.

  1. On the Newsvendor sheet, reproduce Example 7.2 and confirm that the difference between the two forms of Equation 7.10 reads zero.
  2. Raise the salvage value from $12 to $30 and report what happens to \(c_{o}\), the critical ratio, \(Q^{*}\) and the expected cost. Explain the direction.
  3. Raise the salvage value to $50 and describe what the sheet does. Relate the result to Section 7.9.3.
  4. The Discrete sheet ships with Example 7.3 already entered. Confirm that the highlighted row is the one Table 7.7 gives. Then lower the emergency purchase price until the highlight moves, and report the price at which it does, to the nearest dollar.
  5. Restore the sheets, and set the stockout penalty on Newsvendor to $40. Read \(z\) from B21, and reproduce the expected shortage in B27 by hand from Table D.2, interpolating as Example 7.4 does. How far apart are your figure and the sheet’s, and what accounts for the gap?

7.14.7 From the Literature

Exercise 7.22 Section 7.4 states three results and derives none of them. This exercise works the first two by hand and reads the third.

  1. Croston’s method. The section claims that smoothing an intermittent series directly gives an estimate that is highest immediately after a demand, which is when a replenishment is most likely to be triggered. Demonstrate it. Take twelve periods in which demand is 10 units in periods 1, 6 and 11 and zero otherwise, and smooth it with \(\alpha = 0.2\) from a starting estimate of 2.0 units. Report the estimate after every period, and say where in the cycle it is highest and where it is lowest.
  2. Now apply Croston (1972) to the same twelve periods. Smooth the size of a demand and the interval between demands as two separate series, each with \(\alpha = 0.2\), each updated only in a period that has a demand, starting from a size of 6 units and an interval of 5 periods. Report the demand rate the two give after period 11, and compare it with your answer to part (a) in the same period.
  3. The bias. Syntetos and Boylan (2005) showed that the ratio of two independent smoothed estimates does not estimate the ratio of the means. Show it on the smallest example there is. Let \(A = 10\) with certainty and let \(B\) take the values 4 and 6 with equal probability, independently of \(A\). Compute \(E[A]/E[B]\) and \(E[A/B]\) and say which is larger. Then say in one sentence why Croston’s estimator therefore runs high, and in which direction a reorder point built on it errs.
  4. Which family, and when it matters. Table 7.6 measured what the choice of distribution family costs on the belt and found less than a fifth of a percent. Rossetti and Ünlü (2011) ask the same question for demand over a lead time and reach a sharper conclusion. Read it and report what they vary that Table 7.6 holds fixed, what they measure the error in, and which families they recommend. Then reconcile the two findings: name the regime in which the choice of family is cheap and the regime in which it is not, and say which one the belt is in and why.