Base-Stock Controller
For single-sourcing problems over an infinite time horizon, the base-stock controller maintains a fixed target inventory level. When inventory falls below this level due to demand fluctuations, a replenishment order is immediately placed to restore the stock to the target level.
Key Concepts
Target Inventory Level: The target inventory level that triggers replenishment orders whenever stock dips below it.
Mathematical Structure
To mathematically describe the optimal order policy of single-sourcing problems (Arrow, Harris, & Marschak, 1951; Scarf & Karlin, 1958), we use \(l\) and \(z^*\) to respectively denote the replenishment lead time and the target inventory-position level (i.e., the target net inventory level plus all items ordered but not received yet). The inventory position of single-sourcing dynamics at time \(t\), \(\tilde{I}_t\), is given by
where \(I_t\) and \(q_t\) denote the net inventory at time \(t\) and the replenishment order placed at time \(t\), respectively.
The optimal order quantity is \(q_t=\max\{0, z^*-\tilde{I}_t\}\), where the target level \(z^*\) is the parameter to be determined.
Example Usage
We now present two examples to demonstrate how the BaseStockController can be called and evaluated in idinn.
>>> import torch
>>> from idinn.sourcing_model import SingleSourcingModel
>>> from idinn.single_controller import BaseStockController
>>> from idinn.demand import UniformDemand
>>> # First example
>>> single_sourcing_model = SingleSourcingModel(
... lead_time=0,
... holding_cost=5,
... shortage_cost=495,
... init_inventory=10,
... demand_generator=UniformDemand(low=0, high=4),
... )
>>> controller_base = BaseStockController()
>>> # z_star should be 4
>>> controller_base.fit(single_sourcing_model)
>>> print(f"z_star: {controller_base.z_star}")
z_star: 4
>>> # Avg. cost near 10
>>> avg_cost = controller_base.get_average_cost(single_sourcing_model, sourcing_periods=1000, seed=42)
>>> print(f"Average Cost: {avg_cost:.2f}")
Average Cost: 10.39
>>> # Second example
>>> single_sourcing_model = SingleSourcingModel(
... lead_time=2,
... holding_cost=5,
... shortage_cost=495,
... init_inventory=10,
... demand_generator=UniformDemand(low=0, high=4),
... )
>>> controller_base = BaseStockController()
>>> controller_base.fit(single_sourcing_model)
>>> # z_star should be 11
>>> print(f"z_star: {controller_base.z_star}")
z_star: 11
>>> # Avg. cost near 29
>>> avg_cost = controller_base.get_average_cost(single_sourcing_model, sourcing_periods=1000, seed=42)
>>> print(f"Average Cost: {avg_cost:.2f}")
Average Cost: 29.53
References
Scarf, H., & Karlin, S. (1958). Inventory models of the Arrow-Harris-Marschak type with time lag. In K. J. Arrow, S. Karlin, & H. E. Scarf (Eds.), Studies in the Mathematical Theory of Inventory and Production (Stanford University Press, Stanford, CA).
Arrow, K. J., Harris, T., & Marschak, J. (1951). Optimal inventory policy. Econometrica, 19(3), 250–272.