rq Module

Overview

The rq module contains code for solving the \((r,Q)\) optimization problem, including a number of approximations.

Note

The notation and references (equations, sections, examples, etc.) used below refer to Snyder and Shen, Fundamentals of Supply Chain Theory (FoSCT), 2nd edition (2019).

See Also

For an overview of single-echelon inventory optimization in Stockpyl, see the tutorial page for single-echelon inventory optimization.

API Reference

r_q_cost(reorder_point, order_quantity, holding_cost, stockout_cost, fixed_cost, demand_mean, demand_sd, lead_time)[source]

Calculate the exact cost of the given solution for an \((r,Q)\) policy with given parameters. Assumes demand is normally distributed.

Parameters
  • reorder_point (float) – Reorder point. [\(r\)]

  • order_quantity (float) – Order quantity. [\(Q\)]

  • holding_cost (float) – Holding cost per item per unit time. [\(h\)]

  • stockout_cost (float) – Stockout cost per item per unit time. [\(p\)]

  • fixed_cost (float) – Fixed cost per order. [\(K\)]

  • demand_mean (float) – Mean demand per unit time. [\(\lambda\)]

  • demand_sd (float) – Standard deviation of demand per unit time. [\(\tau\)]

  • lead_time (float) – Lead time. [\(L\)]

Returns

cost – Expected cost per unit time. [\(g(r,Q)\)]

Return type

float

Raises
  • ValueError – If order_quantity, holding_cost, stockout_cost, or fixed_cost <= 0.

  • ValueError – If demand_mean, demand_sd, or lead_time < 0.

Equations Used (equation (5.7)):

\[g(r,Q) = \frac{K\lambda + \int_r^{r+Q} g(y)dy}{Q}\]

where \(g(y)\) is the newsvendor cost function.

Example (Example 5.1):

>>> r_q_cost(126.8, 328.5, 0.225, 7.5, 8, 1300, 150, 1/12)
78.07116250928294
r_q_optimal_r_for_q(order_quantity, holding_cost, stockout_cost, demand_mean, demand_sd, lead_time, tol=1e-06)[source]

Calculate optimal \(r\) for the given \(Q\). Assumes demand is normally distributed.

Finds \(r\) using bisection search.

Parameters
  • order_quantity (float) – Order quantity. [\(Q\)]

  • holding_cost (float) – Holding cost per item per unit time. [\(h\)]

  • stockout_cost (float) – Stockout cost per item per unit time. [\(p\)]

  • demand_mean (float) – Mean demand per unit time. [\(\lambda\)]

  • demand_sd (float) – Standard deviation of demand per unit time. [\(\tau\)]

  • lead_time (float) – Lead time. [\(L\)]

  • tol (float) – Absolute tolerance to use for convergence. The algorithm terminates when \(g(r)\) and \(g(r+Q)\) are within tol of each other.

Returns

reorder_point – Optimal reorder point for given order quantity. [\(r(Q)\)]

Return type

float

Raises
  • ValueError – If order_quantity, holding_cost, or stockout_cost <= 0.

  • ValueError – If demand_mean, demand_sd, or lead_time < 0.

Equation Used (equation (5.9)):

\[g(r) = g(r+Q)\]

where \(g(y)\) is the newsvendor cost function.

Example (Example 5.2):

>>> r_q_optimal_r_for_q(300, 0.225, 7.5, 1300, 150, 1/12)
129.4272799263067
r_q_eil_approximation(holding_cost, stockout_cost, fixed_cost, demand_mean, demand_sd, lead_time, tol=1e-06)[source]

Determine \(r\) and \(Q\) using the “expected-inventory-level” (EIL) approximation. Assumes demand is normally distributed.

The EIL approximation is one of the oldest and most widely known approximations for the \((r,Q)\) optimization problem, dating back to Whitin (1953) and Hadley and Whitin (1963).

Parameters
  • holding_cost (float) – Holding cost per item per unit time. [\(h\)]

  • stockout_cost (float) – Stockout cost per item per unit time. [\(p\)]

  • fixed_cost (float) – Fixed cost per order. [\(K\)]

  • demand_mean (float) – Mean demand per unit time. [\(\lambda\)]

  • demand_sd (float) – Standard deviation of demand per unit time. [\(\tau\)]

  • lead_time (float) – Lead time. [\(L\)]

  • tol (float) – Absolute tolerance to use for convergence. The algorithm terminates when both \(r\) and \(Q\) are within tol of their previous values. [\(\epsilon\)]

Returns

  • reorder_point (float) – Reorder point. [\(r\)]

  • order_quantity (float) – Order quantity. [\(Q\)]

  • cost (float) – Approximate expected cost per unit time. [\(g(r,Q)\)]

Raises
  • ValueError – If holding_cost, stockout_cost, or fixed_cost <= 0.

  • ValueError – If demand_mean, demand_sd, or lead_time < 0.

Equations Used (equation (5.17), (5.18), (5.16)):

\[ \begin{align}\begin{aligned}r = F^{-1}\left(1 - \frac{Qh}{p\lambda}\right)\\Q = \sqrt{\frac{2\lambda[K + pn(r)]}{h}}\\g(r,Q) = h\left(r - \lambda L + \frac{Q}{2}\right) + \frac{K\lambda}{Q} + \frac{p\lambda n(r)}{Q}\end{aligned}\end{align} \]

Algorithm Used: Iterative algorithm for EIL approximation for \((r,Q)\) policy (Algorithm 5.1)

References

    1. Whitin, The Theory of Inventory Management, Princeton University Press, Princeton, NJ, 1953.

  1. Hadley and T. M. Whitin, Analysis of Inventory Systems, Prentice-Hall, Englewood Cliffs, NJ, 1963.

Example (Example 5.2):

>>> r_q_eil_approximation(0.225, 7.5, 8, 1300, 150, 1/12)
(213.97044213580244, 318.5901810768729, 95.45114022285196)
r_q_eoqb_approximation(holding_cost, stockout_cost, fixed_cost, demand_mean, demand_sd, lead_time)[source]

Determine \(r\) and \(Q\) using the “EOQ with backorders” (EOQB) approximation. Assumes demand is normally distributed.

See Zheng (1992) for a thorough exploration of the EOQB approximation.

Parameters
  • holding_cost (float) – Holding cost per item per unit time. [\(h\)]

  • stockout_cost (float) – Stockout cost per item per unit time. [\(p\)]

  • fixed_cost (float) – Fixed cost per order. [\(K\)]

  • demand_mean (float) – Mean demand per unit time. [\(\lambda\)]

  • demand_sd (float) – Standard deviation of demand per unit time. [\(\tau\)]

  • lead_time (float) – Lead time. [\(L\)]

Returns

  • reorder_point (float) – Reorder point. [\(r\)]

  • order_quantity (float) – Order quantity. [\(Q\)]

Raises
  • ValueError – If holding_cost, stockout_cost, or fixed_cost <= 0.

  • ValueError – If demand_mean, demand_sd, or lead_time < 0.

Equations Used (equations (3.27) and (5.9)):

\[ \begin{align}\begin{aligned}Q^* = \sqrt{\frac{2K\lambda(h+p)}{hp}}\\g(r) = g(r+Q)\end{aligned}\end{align} \]

where \(g(y)\) is the newsvendor cost function.

References

Y.-S. Zheng, On Properties of Stochastic Inventory Systems, Management Science 38(1), 87-103 (1992).

Example (Example 5.2):

>>> r_q_eoqb_approximation(0.225, 7.5, 8, 1300, 150, 1/12)
(128.63781442427097, 308.5737801203754)
r_q_eoqss_approximation(holding_cost, stockout_cost, fixed_cost, demand_mean, demand_sd, lead_time)[source]

Determine \(r\) and \(Q\) using the “EOQ plus safety stock” (EOQ+SS) approximation. Assumes demand is normally distributed.

Parameters
  • holding_cost (float) – Holding cost per item per unit time. [\(h\)]

  • stockout_cost (float) – Stockout cost per item per unit time. [\(p\)]

  • fixed_cost (float) – Fixed cost per order. [\(K\)]

  • demand_mean (float) – Mean demand per unit time. [\(\lambda\)]

  • demand_sd (float) – Standard deviation of demand per unit time. [\(\tau\)]

  • lead_time (float) – Lead time. [\(L\)]

Returns

  • reorder_point (float) – Reorder point. [\(r\)]

  • order_quantity (float) – Order quantity. [\(Q\)]

Raises
  • ValueError – If holding_cost, stockout_cost, or fixed_cost <= 0.

  • ValueError – If demand_mean, demand_sd, or lead_time < 0.

Equations Used (equations (3.4) and (5.21)):

\[ \begin{align}\begin{aligned}Q^* = \sqrt{\frac{2K\lambda}{h}}\\r = \mu + z_{\alpha}\sigma\end{aligned}\end{align} \]

Example (Example 5.5):

>>> r_q_eoqss_approximation(0.225, 7.5, 8, 1300, 150, 1/12)
(190.3369965715624, 304.0467800264368)
r_q_loss_function_approximation(holding_cost, stockout_cost, fixed_cost, demand_mean, demand_sd, lead_time, tol=1e-06)[source]

Determine \(r\) and \(Q\) using the “loss function” approximation. Assumes demand is normally distributed.

This approximation is due to Hadley and Whitin (1963).

Parameters
  • holding_cost (float) – Holding cost per item per unit time. [\(h\)]

  • stockout_cost (float) – Stockout cost per item per unit time. [\(p\)]

  • fixed_cost (float) – Fixed cost per order. [\(K\)]

  • demand_mean (float) – Mean demand per unit time. [\(\lambda\)]

  • demand_sd (float) – Standard deviation of demand per unit time. [\(\tau\)]

  • lead_time (float) – Lead time. [\(L\)]

  • tol (float) – Absolute tolerance to use for convergence. The algorithm terminates when both \(r\) and \(Q\) are within tol of their previous values. [\(\epsilon\)]

Returns

  • reorder_point (float) – Reorder point. [\(r\)]

  • order_quantity (float) – Order quantity. [\(Q\)]

Raises
  • ValueError – If holding_cost, stockout_cost, or fixed_cost <= 0.

  • ValueError – If demand_mean, demand_sd, or lead_time < 0.

Equations Used (equation (5.28) and (5.29)):

\[ \begin{align}\begin{aligned}Q = \sqrt{\frac{2\left[K\lambda + (h+p)n^{(2)}(r)\right]}{h}}\\n(r) = \frac{hQ}{h+p}\end{aligned}\end{align} \]

where \(n(\cdot)\) and \(n^{(2)}(\cdot)\) are the first- and second-order loss functions for the lead-time demand distribution.

References

  1. Hadley and T. M. Whitin, Analysis of Inventory Systems, Prentice-Hall, Englewood Cliffs, NJ, 1963.

Example (Example 5.6):

>>> r_q_loss_function_approximation(0.225, 7.5, 8, 1300, 150, 1/12)
(126.8670634479628, 328.4491421980451)
r_q_cost_poisson(reorder_point, order_quantity, holding_cost, stockout_cost, fixed_cost, demand_mean, lead_time)[source]

Calculate the exact cost of the given solution for an \((r,Q)\) policy with given parameters under Poisson demand.

Parameters
  • reorder_point (float) – Reorder point. [\(r\)]

  • order_quantity (float) – Order quantity. [\(Q\)]

  • holding_cost (float) – Holding cost per item per unit time. [\(h\)]

  • stockout_cost (float) – Stockout cost per item per unit time. [\(p\)]

  • fixed_cost (float) – Fixed cost per order. [\(K\)]

  • demand_mean (float) – Mean demand per unit time. [\(\lambda\)]

  • lead_time (float) – Lead time. [\(L\)]

Returns

cost – Expected cost per unit time. [\(g(r,Q)\)]

Return type

float

Raises
  • ValueError – If order_quantity <= 0 or is not an integer, or if reorder_point is not an integer.

  • ValueError – If holding_cost, stockout_cost, or fixed_cost <= 0.

  • ValueError – If demand_mean or lead_time < 0.

Equations Used (equation (5.48)):

\[g(r,Q) = \frac{K\lambda + \sum_{y=r+1}^{r+Q} g(y)}{Q}\]

where \(g(y)\) is the newsvendor cost function.

Example (Example 5.8):

>>> r_q_cost_poisson(3, 5, 20, 150, 100, 1.5, 2)
107.92358063314975
r_q_poisson_exact(holding_cost, stockout_cost, fixed_cost, demand_mean, lead_time)[source]

Determine optimal \(r\) and \(Q\) for Poisson demands, using the algorithm by Federgruen and Zheng (1992).

Parameters
  • holding_cost (float) – Holding cost per item per unit time. [\(h\)]

  • stockout_cost (float) – Stockout cost per item per unit time. [\(p\)]

  • fixed_cost (float) – Fixed cost per order. [\(K\)]

  • demand_mean (float) – Mean demand per unit time. [\(\lambda\)]

  • lead_time (float) – Lead time. [\(L\)]

Returns

  • reorder_point (float) – Reorder point. [\(r\)]

  • order_quantity (float) – Order quantity. [\(Q\)]

  • cost (float) – Expected cost per unit time. [\(g(r,Q)\)]

Raises
  • ValueError – If holding_cost, stockout_cost, or fixed_cost <= 0.

  • ValueError – If demand_mean or lead_time < 0.

Equations Used (equation (5.48)):

\[g(r,Q) = \frac{K\lambda + \sum_{y=r+1}^{r+Q} g(y)}{Q}\]

where \(g(y)\) is the newsvendor cost function for Poisson demands.

References

A. Federgruen and Y.-S. Zheng, An Efficient Algorithm for Computing an Optimal \((r,Q)\) Policy in Continuous Review Stochastic Inventory Systems, Operations Research 40(4), 808-813 (1992).

Example (Example 5.8):

>>> r_q_poisson_exact(20, 150, 100, 1.5, 2)
(3, 5, 107.92358063314975)