gsm_helpers
Module¶
Overview¶
The gsm_helpers
module contains helper code for the dynamic programming (DP) algorithm
to solve the guaranteed-service model (GSM) for multi-echelon inventory systems with tree structures
by Graves and Willems (2000, 2003), which is implemented in the gsm_tree
module.
Note
The terms “node” and “stage” are used interchangeably in the documentation.
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 multi-echelon inventory optimization in Stockpyl, see the tutorial page for multi-echelon inventory optimization.
References
S. C. Graves and S. P. Willems. Optimizing strategic safety stock placement in supply chains. Manufacturing and Service Operations Management, 2(1):68-83, 2000.
S. C. Graves and S. P. Willems. Erratum: Optimizing strategic safety stock placement in supply chains. Manufacturing and Service Operations Management, 5(2):176-177, 2003.
API Reference¶
- solution_cost_from_cst(tree, cst)[source]¶
Calculate expected cost per period of given solution as specified by committed service times (CSTs).
- Parameters
tree (
SupplyChainNetwork
) – The multi-echelon tree network. Network need not have been relabeled.cst (dict) – Dict of CSTs for each node, using the same node labeling as tree. [\(S\)]
- Returns
cost – Expected cost of the solution. [\(g(S)\)]
- Return type
float
Example (Example 6.5):
>>> from stockpyl.instances import load_instance >>> tree = preprocess_tree(load_instance("example_6_5")) >>> solution_cost_from_cst(tree, {1: 0, 2: 0, 3: 0, 4: 1}) 8.277916867529369
- solution_cost_from_base_stock_levels(tree, local_bsl)[source]¶
Calculate expected cost per period of given solution as specified by base-stock levels. Cost is based on safety stock, which is calculated as base-stock level minus demand mean.
- Parameters
tree (
SupplyChainNetwork
) – The multi-echelon tree network. Graph need not have been relabeled.local_bsl (dict) – Dict of local base-stock levels for each node, using the same node labeling as tree. [\(y\)]
- Returns
cost – Expected cost of the solution. [\(g(S)\)]
- Return type
float
Example (Example 6.5):
>>> from stockpyl.instances import load_instance >>> tree = preprocess_tree(load_instance("example_6_5")) >>> solution_cost_from_base_stock_levels(tree, {1: 2.45, 2: 1.00, 3: 1.41, 4: 0.00}) 8.27
- inbound_cst(tree, node_index, cst)[source]¶
Determine the inbound CST (\(SI\)) for one or more stages, given all of the outbound CSTs. The inbound CST is calculated as the maximum of the outbound CST for all predecessors, and the external inbound CST (if any).
- Parameters
tree (
SupplyChainNetwork
) – The multi-echelon tree network. Network need not have been relabeled.node_index (node or iterable container) – A single node index or a container of node indices (dict, list, set, etc.).
cst (dict) – Dict of CSTs for each node, using the same node labeling as
tree
. [\(S\)]
- Returns
SI – Inbound CST of node
node_index
(ifnode_index
is a single node); or a dictionary of inbound CST values keyed by node (ifnode_index
is an iterable container) [\(SI\)].- Return type
int or dict
Example (Problem 6.9):
>>> from stockpyl.instances import load_instance >>> tree = preprocess_tree(load_instance("problem_6_9")) >>> inbound_cst(tree, 3, {1: 3, 2: 3, 3: 31, 4: 3, 5: 10, 6: 2}) 10
- net_lead_time(tree, node_index, cst)[source]¶
Determine the net lead time (NLT) for one or more stages, given the outbound CSTs.
- Parameters
tree (
SupplyChainNetwork
) – The multi-echelon tree network. Network need not have been relabeled.node_index (node or iterable container) – A single node index or a container of node indices (dict, list, set, etc.).
cst (dict) – Dict of CSTs for each node, using the same node labeling as tree. [\(S\)]
- Returns
nlt – NLT of node
node_index
(ifnode_index
is a single node); or a dictionary of NLT values keyed by node (ifnode_index
is an iterable container).- Return type
int or dict
Example (Problem 6.9):
>>> from stockpyl.instances import load_instance >>> tree = preprocess_tree(load_instance("problem_6_9")) >>> net_lead_time(tree, tree.node_indices, {1: 3, 2: 3, 3: 31, 4: 3, 5: 10, 6: 2}) {1: 35, 2: 35, 3: 0, 4: 0, 5: 0, 6: 0}
- cst_to_base_stock_levels(tree, node_index, cst)[source]¶
Determine base-stock levels for one or more stages, for given committed service times (CST).
- Parameters
tree (
SupplyChainNetwork
) – The multi-echelon tree network. Graph need not have been relabeled.node_index (node or iterable container) – A single node index or a container of node indices (dict, list, set, etc.).
cst (dict) – Dict of CSTs for each node, using the same node labeling as tree. [\(S\)]
- Returns
base_stock_level – Base-stock level of node
node_index
(ifnode_index
is a single node); or a dictionary of base-stock levels keyed by node (ifnode_index
is an iterable container). [\(y\)]- Return type
float or dict
Example (Problem 6.9):
>>> from stockpyl.instances import load_instance >>> tree = preprocess_tree(load_instance("example_6_5")) >>> cst_to_base_stock_levels(tree, tree.node_indices, {1: 0, 2: 0, 3: 0, 4: 1}) {1: 2.4494897427831783, 3: 1.4142135623730951, 2: 1.0, 4: 0.0}
- safety_stock_levels(tree, node_index, cst)[source]¶
Determine safety stock levels for one or more nodes, for given committed service times (CST).
- Parameters
tree (
SupplyChainNetwork
) – The multi-echelon tree network. Graph need not have been relabeled.node_index (node or iterable container) – A single node index or a container of node indices (dict, list, set, etc.).
cst (dict) – Dict of CSTs for each node, using the same node labeling as tree. [\(S\)]
- Returns
safety_stock_level – Safety stock of node
node_index
(ifnode_index
is a single node); or a dictionary of safety stock values keyed by node (ifnode_index
is an iterable container).- Return type
float or dict
Example (Problem 6.9):
>>> from stockpyl.instances import load_instance >>> tree = preprocess_tree(load_instance("example_6_5")) >>> safety_stock_levels(tree, tree.node_indices, {1: 0, 2: 0, 3: 0, 4: 1}) {1: 2.4494897427831783, 3: 1.4142135623730951, 2: 1.0, 4: 0.0}