supply_chain_network
Module¶
Overview¶
This module contains the SupplyChainNetwork
class, which is a network consisting of
one or more nodes. The network and nodes together specify a problem instance.
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).
A SupplyChainNetwork
is used primarily for multi-echelon inventory optimization (MEIO)
or simulation. Most data for the problem instance is specified
in the SupplyChainNode
objects contained within the SupplyChainNetwork
, rather than in
the network itself.
API Reference¶
- class SupplyChainNetwork(**kwargs)[source]¶
The
SupplyChainNetwork
class contains one or more nodes, each represented by aSupplyChainNode
object.- period¶
The current period. Used for simulation.
- Type
int
- problem_specific_data¶
Placeholder for object that is used to provide data for specific problem types.
- Type
object
- max_max_replenishment_time¶
Largest value of
max_replenishment_time
among all nodes in the network. Used bygsm_tree
module.- Type
int
- property nodes¶
List of all nodes in the network, as
SupplyChainNode
objects. Read only.
- property node_indices¶
List of indices of all nodes in the network. Read only.
- property source_nodes¶
List of all source nodes, i.e., all nodes that have no predecessors, as
SupplyChainNode
objects.
- property sink_nodes¶
List of all sink nodes, i.e., all nodes that have no successors, as
SupplyChainNode
objects.
- property edges¶
List of all edges, as tuples whose elements are the indices of the nodes in the edge.
- has_directed_cycle()[source]¶
Check whether network contains a directed cycle.
- Returns
True
if network contains a directed cycle,False
otherwise.- Return type
bool
- deep_equal_to(other, rel_tol=1e-08)[source]¶
Check whether network “deeply equals”
other
, i.e., if all attributes are equal, including attributes that are themselves objects.- Parameters
other (
SupplyChainNetwork
) – The network to compare this one to.rel_tol (float, optional) – Relative tolerance to use when comparing equality of float attributes.
- Returns
True
if the two networks are equal,False
otherwise.- Return type
bool
- to_dict()[source]¶
Convert the
SupplyChainNetwork
object to a dict. Converts the object recursively, callingto_dict()
on eachSupplyChainNode
in the network.- Returns
The dict representation of the network.
- Return type
dict
- classmethod from_dict(the_dict)[source]¶
Return a new
SupplyChainNetwork
object with attributes copied from the values inthe_dict
.- Parameters
the_dict (dict) – Dict representation of a
SupplyChainNetwork
, typically created usingto_dict()
.- Returns
The object converted from the dict.
- Return type
- get_node_from_index(index)[source]¶
Return node object with the specified index, or
None
if no matching node is found.- Parameters
index (int) – Index of node to find.
- Returns
The node whose index is
index
, orNone
if none.- Return type
- reindex_nodes(old_to_new_dict, new_names=None)[source]¶
Change indices of the nodes in the network using
old_to_new_dict
. Ifnew_names
is provided, also updatesname
attribute of the nodes.- Parameters
old_to_new_dict (dict) – Dict in which keys are old indices and values are new indices.
new_names (dict, optional) – Dict in which keys are old indices and values are new names.
- add_node(node)[source]¶
Add
node
to the network.node
will not be connected to other nodes that might be in the network already.If
node
is already in the network (as determined by the index), do nothing.- Parameters
node (
SupplyChainNode
) – The node to add to the network.
- add_edge(from_index, to_index)[source]¶
Add an edge to the network to and from the nodes with the specified indices. If the edge is already in the network, does nothing.
- Parameters
from_index (int) – Index of “from” node.
to_index (int) – Index of “to” node.
- Raises
ValueError – If either index is not in the network.
- add_edges_from_list(edge_list)[source]¶
Add multiple edges to the network from a list of index tuples. Any edge that is already in the network is ignored.
- Parameters
edge_list (list) – List of tuples of indices of nodes in edges.
- Raises
ValueError – If any of the nodes are not in the network.
- add_successor(node, successor_node)[source]¶
Add
successor_node
as a successor tonode
.node
must already be contained in the network.The method adds the nodes to each other’s lists of _successors and _predecessors. If
successor_node
is not already contained in the network, the method also adds it. (The node is assumed to be contained in the network if its index or name match those of a node in the network.)- Parameters
node (
SupplyChainNode
) – The node to which the successor should be added.successor_node (
SupplyChainNode
) – The node to be added as a successor.
- add_predecessor(node, predecessor_node)[source]¶
Add
predecessor_node
as a predecessor tonode
.node
must already be contained in the network.The method adds the nodes to each other’s lists of _successors and _predecessors. If
predecessor_node
is not already contained in the network, the method also adds it. (The node is assumed to be contained in the network if its index or name match those of a node in the network.)- Parameters
node (
SupplyChainNode
) – The node to which the successor should be added.predecessor_node (
SupplyChainNode
) – The node to be added as a predecessor.
- remove_node(node)[source]¶
Remove a node from the network. Remove the node from the node list and from its predecessors’ and successors’ successors and predecessors lists.
If
node
is not in the network (as determined by the index), do nothing.- Parameters
node (
SupplyChainNode
) – The node to remove.
- networkx_digraph()[source]¶
Build a NetworkX
DiGraph
object with the same structure as theSupplyChainNetwork
.- Returns
digraph – The
networkx
digraph
object.- Return type
DiGraph
- network_from_edges(edges, node_order_in_lists=None, **kwargs)[source]¶
Construct a supply chain network with the specified edges.
The
kwargs
parameters specify the attributes (data) for the nodes in the network. If they are provided, they must be either a dict, a list, or a singleton, with the following requirements:If the parameter is a dict, then the keys must contain the node indices and the values must contain the corresponding attribute values. If a given node index is contained in the list of edges but is not a key in the dict, the attribute value is set to
None
for that node.If the parameter is a singleton, then the attribute is set to that value for all nodes.
If the parameter is a list and
node_order_in_lists
is provided,node_order_in_lists
must contain the same indices as the nodes in the edges inedges
(otherwise aValueError
is raised). The values in the list are assumed to correspond to the node indices in the order they are specified innode_order_in_lists
. That is, the value in slotk
in the parameter list is assigned to the node with indexnode_order_in_lists[k]
. If a given node index is contained in the list of edges but is not innode_order_in_lists
, the attribute value is set toNone
for that node.If the parameter is a list and
node_order_in_lists
is not provided, the values in the list are assumed to correspond to the sorted list of node indices in the edge list. That is, the value in slotk
in the parameter list is assigned to the node in slotk
when the nodes in the edge list are sorted.
If
edges
isNone
or[]
, a single-node network is returned. The index of the node is set to 0, unlessnode_order_in_lists
is provided, in which case the node’s index is set tonode_order_in_lists[0]
. The rules forkwargs
above also apply to the single-node case.- The
supply_type
attribute is set to ‘U’ at all nodes that have no predecessors and to None
at all other nodes, no matter how (or whether) the corresponding parameter is set.
For the
demand_source
attribute, you may pass aDemandSource
object or the individual attributes of the demand source (mean
,round_to_int
, etc.). In the latter case, aDemandSource
object will be constructed with the specified attributes and filled into thedemand_source
attribute of the node. Note: If providing individual demand source attributes, thetype
attribute must be calleddemand_type
to avoid ambiguity with other objects.Similarly, you may pass
Policy
andDisruptionProcess
objects for theinventory_policy
anddisruption_process
attributes, or you may pass the individual attributes for these objects. Note: If providing individual inventory policy attributes, thetype
attribute must be calledpolicy_type
to avoid ambiguity with other objects.If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
or one of its attribute objects (DemandSource
,Policy
, orDisruptionProcess
), anAttributeError
is raised. (Exception:demand_type
andpolicy_type
are allowed even though they are not attributes ofSupplyChainNode
; see above.)Note
This function does not check that valid attributes have been provided for
demand_source
,inventory_policy
, anddisruption_process
. For example, it does not check that abase_stock_level
has been provided if the policy type is set toBS
.- Parameters
edges (list) – List of edges, with each edge specified as a tuple
(a, b)
, wherea
is the index of the predecessor andb
is the index of the successor node. IfNone
or empty, a single-node network is created.node_order_in_lists (list, optional) – List of node indices in the order in which the nodes are listed in any attributes that are lists. (
node_order_in_lists[k]
is the index of thek
th node.)kwargs (optional) – Optional keyword arguments to specify node attributes.
- Raises
AttributeError – If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
.
- single_stage_system(index=0, **kwargs)[source]¶
Generate a single-stage network.
The
kwargs
parameters specify the attributes (data) for the node.For the
demand_source
attribute, you may pass aDemandSource
object or the individual attributes of the demand source (mean
,round_to_int
, etc.). In the latter case, aDemandSource
object will be constructed with the specified attributes and filled into thedemand_source
attribute of the node. Note: If providing individual demand source attributes, thetype
attribute must be calleddemand_type
to avoid ambiguity with other objects.Similarly, you may pass
Policy
andDisruptionProcess
objects for theinventory_policy
anddisruption_process
attributes, or you may pass the individual attributes for these objects. Note: If providing individual inventory policy attributes, thetype
attribute must be calledpolicy_type
to avoid ambiguity with other objects.If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
or one of its attribute objects (DemandSource
,Policy
, orDisruptionProcess
), anAttributeError
is raised. (Exception:demand_type
andpolicy_type
are allowed even though they are not attributes ofSupplyChainNode
; see above.)Note
This function does not check that valid attributes have been provided for
demand_source
,inventory_policy
, anddisruption_process
. For example, it does not check that abase_stock_level
has been provided if the policy type is set toBS
.- Parameters
index (int, optional) – Index to use for the node. Default = 0.
kwargs (optional) – Optional keyword arguments to specify node attributes.
- Returns
network – The single-stage network, with parameters filled.
- Return type
- Raises
AttributeError – If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
.
Example (a
SupplyChainNetwork
object containing the data from Example 4.1):>>> network = single_stage_system(holding_cost=0.18, stockout_cost=0.70, demand_type='N', mean=50, standard_deviation=8, policy_type='BS', base_stock_level=56.6) >>> network.nodes[0].stockout_cost 0.7
- serial_system(num_nodes, node_order_in_system=None, node_order_in_lists=None, **kwargs)[source]¶
Generate a serial system with the specified number of nodes. By default, node 0 is upstream and node
num_nodes
- 1 is downstream, but this can be changed by settingnode_order_in_system
.The
kwargs
parameters specify the attributes (data) for the nodes in the network. If they are provided, they must be either a dict, a list, or a singleton, with the following requirements:If the parameter is a dict, then the keys must contain the node indices and the values must contain the corresponding attribute values. If a given node index is contained in
node_order_in_system
(or inrange(num_nodes)
, ifnode_order_in_system
is not provided) but is not a key in the dict, the attribute value is set toNone
for that node.If the parameter is a singleton, then the attribute is set to that value for all nodes.
If the parameter is a list and
node_order_in_lists
is provided,node_order_in_lists
must contain the same indices asnode_order_in_system
(if it is provided) or 0, …,num_nodes
- 1 (if it is not), otherwise aValueError
is raised. The values in the list are assumed to correspond to the node indices in the order they are specified innode_order_in_lists
. That is, the value in slotk
in the parameter list is assigned to the node with indexnode_order_in_lists[k]
.If the parameter is a list and
node_order_in_lists
is not provided, the values in the list are assumed to correspond to nodes in the same order asnode_order_in_system
(or inrange(num_nodes)
, ifnode_order_in_system
is not provided).
demand_source
andstockout_cost
attributes are only set at the downstream-most node, no matter how (or whether) the corresponding parameter is set.supply_type
attribute is set to ‘U’ at the upstream-most node and toNone
at all other nodes, no matter how (or whether) the corresponding parameter is set.For the
demand_source
attribute, you may pass aDemandSource
object or the individual attributes of the demand source (mean
,round_to_int
, etc.). In the latter case, aDemandSource
object will be constructed with the specified attributes and filled into thedemand_source
attribute of the node. Note: If providing individual demand source attributes, thetype
attribute must be calleddemand_type
to avoid ambiguity with other objects.Similarly, you may pass
Policy
andDisruptionProcess
objects for theinventory_policy
anddisruption_process
attributes, or you may pass the individual attributes for these objects. Note: If providing individual inventory policy attributes, thetype
attribute must be calledpolicy_type
to avoid ambiguity with other objects.If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
or one of its attribute objects (DemandSource
,Policy
, orDisruptionProcess
), anAttributeError
is raised. (Exception:demand_type
andpolicy_type
are allowed even though they are not attributes ofSupplyChainNode
; see above.)Note
This function does not check that valid attributes have been provided for
demand_source
,inventory_policy
, anddisruption_process
. For example, it does not check that abase_stock_level
has been provided if the policy type is set toBS
.- Parameters
num_nodes (int) – Number of nodes in the serial system.
node_order_in_system (list, optional) – List of node indices in the order that they appear in the serial system, with upstream-most node listed first. If omitted, the system will be indexed 0, …,
num_nodes
- 1.node_order_in_lists (list, optional) – List of node indices in the order in which the nodes are listed in any attributes that are lists. (
node_order_in_lists[k]
is the index of thek
th node.)kwargs (optional) – Optional keyword arguments to specify node attributes.
- Raises
AttributeError – If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
.
Example (a
SupplyChainNetwork
object containing the data from Example 4.1):>>> network = single_stage_system(holding_cost=0.18, stockout_cost=0.70, demand_type='N', mean=50, standard_deviation=8, policy_type='BS', base_stock_level=56.6) >>> network.nodes[0].stockout_cost 0.7
- return network_from_edges(
edges=[], node_order_in_lists=[index], **kwargs
)
- owmr_system(num_retailers, node_order_in_system=None, node_order_in_lists=None, **kwargs)[source]¶
Generate a one-warehouse, multiple-retailer (OWMR) (i.e., 2-echelon distribution) system with the specified number of retailers. By default, node 0 is the warehouse and nodes 1, …,
num_retailers
are the retailers, but this can be changed by settingnode_order_in_system
.The
kwargs
parameters specify the attributes (data) for the nodes in the network. If they are provided, they must be either a dict, a list, or a singleton, with the following requirements:If the parameter is a dict, then the keys must contain the node indices and the values must contain the corresponding attribute values. If a given node index is contained in
node_order_in_system
(or inrange(num_nodes)
, ifnode_order_in_system
is not provided) but is not a key in the dict, the attribute value is set toNone
for that node.If the parameter is a singleton, then the attribute is set to that value for all nodes.
If the parameter is a list and
node_order_in_lists
is provided,node_order_in_lists
must contain the same indices as the nodes in the edges inedges
(otherwise aValueError
is raised). The values in the list are assumed to correspond to the node indices in the order they are specified innode_order_in_lists
. That is, the value in slotk
in the parameter list is assigned to the node with indexnode_order_in_lists[k]
. If a given node index is contained in the list of edges but is not innode_order_in_lists
, the attribute value is set toNone
for that node.If the parameter is a list and
node_order_in_lists
is not provided, the values in the list are assumed to correspond to nodes in the same order asnode_order_in_system
(or inrange(num_retailers+1)
, ifnode_order_in_system
is not provided).
demand_source
attribute is not set at the warehouse node, no matter how (or whether) the corresponding parameter is set.``supply_type`` attribute is set to ‘U’ at the warehouse node and toNone
at all other nodes, no matter how (or whether) the corresponding parameter is set.For the
demand_source
attribute, you may pass aDemandSource
object or the individual attributes of the demand source (mean
,round_to_int
, etc.). In the latter case, aDemandSource
object will be constructed with the specified attributes and filled into thedemand_source
attribute of the node. Note: If providing individual demand source attributes, thetype
attribute must be calleddemand_type
to avoid ambiguity with other objects.Similarly, you may pass
Policy
andDisruptionProcess
objects for theinventory_policy
anddisruption_process
attributes, or you may pass the individual attributes for these objects. Note: If providing individual inventory policy attributes, thetype
attribute must be calledpolicy_type
to avoid ambiguity with other objects.If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
or one of its attribute objects (DemandSource
,Policy
, orDisruptionProcess
), anAttributeError
is raised. (Exception:demand_type
andpolicy_type
are allowed even though they are not attributes ofSupplyChainNode
; see above.)Note
This function does not check that valid attributes have been provided for
demand_source
,inventory_policy
, anddisruption_process
. For example, it does not check that abase_stock_level
has been provided if the policy type is set toBS
.- Parameters
num_retailers (int) – Number of retailers in OWMR system.
node_order_in_system (list, optional) – List of node indices in the order that they appear in the OWMR system, with warehouse node first and retailer nodes last. If omitted, the warehouse will have index 0 and the retailers will have indices 1, …,
num_retailers
.node_order_in_lists (list, optional) – List of node indices in the order in which the nodes are listed in any attributes that are lists. (
node_order_in_lists[k]
is the index of thek
th node.)kwargs (optional) – Optional keyword arguments to specify node attributes.
- Raises
AttributeError – If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
.
- mwor_system(num_warehouses, node_order_in_system=None, node_order_in_lists=None, **kwargs)[source]¶
Generate a multiple-warehouse, one-retailer (MWOR) (i.e., 2-echelon assembly) system with the specified number of warehouses. By default, node 0 is the retailer and nodes 1, …,
num_warehouses
are the warehouses, but this can be changed by settingnode_order_in_system
.The
kwargs
parameters specify the attributes (data) for the nodes in the network. If they are provided, they must be either a dict, a list, or a singleton, with the following requirements:If the parameter is a dict, then the keys must contain the node indices and the values must contain the corresponding attribute values. If a given node index is contained in
node_order_in_system
(or inrange(num_nodes)
, ifnode_order_in_system
is not provided) but is not a key in the dict, the attribute value is set toNone
for that node.If the parameter is a singleton, then the attribute is set to that value for all nodes.
If the parameter is a list and
node_order_in_lists
is provided,node_order_in_lists
must contain the same indices as the nodes in the edges inedges
(otherwise aValueError
is raised). The values in the list are assumed to correspond to the node indices in the order they are specified innode_order_in_lists
. That is, the value in slotk
in the parameter list is assigned to the node with indexnode_order_in_lists[k]
. If a given node index is contained in the list of edges but is not innode_order_in_lists
, the attribute value is set toNone
for that node.If the parameter is a list and
node_order_in_lists
is not provided, the values in the list are assumed to correspond to nodes in the same order asnode_order_in_system
(or inrange(num_warehouses+1)
, ifnode_order_in_system
is not provided).
demand_source
attribute is only set at the retailer node, no matter how (or whether) the corresponding parameter is set.supply_type
attribute is set to ‘U’ at the warehouse nodes and toNone
at the retailer node, no matter how (or whether) the corresponding parameter is set.For the
demand_source
attribute, you may pass aDemandSource
object or the individual attributes of the demand source (mean
,round_to_int
, etc.). In the latter case, aDemandSource
object will be constructed with the specified attributes and filled into thedemand_source
attribute of the node. Note: If providing individual demand source attributes, thetype
attribute must be calleddemand_type
to avoid ambiguity with other objects.Similarly, you may pass
Policy
andDisruptionProcess
objects for theinventory_policy
anddisruption_process
attributes, or you may pass the individual attributes for these objects. Note: If providing individual inventory policy attributes, thetype
attribute must be calledpolicy_type
to avoid ambiguity with other objects.If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
or one of its attribute objects (DemandSource
,Policy
, orDisruptionProcess
), anAttributeError
is raised. (Exception:demand_type
andpolicy_type
are allowed even though they are not attributes ofSupplyChainNode
; see above.)Note
This function does not check that valid attributes have been provided for
demand_source
,inventory_policy
, anddisruption_process
. For example, it does not check that abase_stock_level
has been provided if the policy type is set toBS
.- Parameters
num_warehouses (int) – Number of warehouses in MWOR system.
node_order_in_system (list, optional) – List of node indices in the order that they appear in the MWOR system, with warehouse nodes first and retailer node last. If omitted, the retailer will have index 0 and the warehouses will have indices 1, …,
num_warehouses
.node_order_in_lists (list, optional) – List of node indices in the order in which the nodes are listed in any attributes that are lists. (
node_order_in_lists[k]
is the index of thek
th node.)kwargs (optional) – Optional keyword arguments to specify node attributes.
- Raises
AttributeError – If
kwargs
contains a parameter that is not an attribute ofSupplyChainNode
.
- local_to_echelon_base_stock_levels(network, S_local)[source]¶
Convert local base-stock levels to echelon base-stock levels for a serial system.
Assumes network is serial system but does not assume anything about the labeling of the nodes.
- Parameters
network (
SupplyChainNetwork
) – The serial inventory network.S_local (dict) – Dict of local base-stock levels.
- Returns
S_echelon – Dict of echelon base-stock levels.
- Return type
dict
- echelon_to_local_base_stock_levels(network, S_echelon)[source]¶
Convert echelon base-stock levels to local base-stock levels for a serial system.
Assumes network is serial system but does not assume anything about the labeling of the nodes.
- Parameters
network (
SupplyChainNetwork
) – The serial inventory network.S_echelon (dict) – Dict of echelon base-stock levels.
- Returns
S_local – Dict of local base-stock levels.
- Return type
dict