supply_chain_node
Module¶
Overview¶
This module contains the SupplyChainNode
class, which is a stage or node
in a supply chain network.
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 SupplyChainNode
is used primarily for multi-echelon inventory optimization (MEIO)
or simulation. SupplyChainNode
objects are rarely, if ever, used as standalone objects;
rather, they are included in SupplyChainNetwork
objects, which describe the complete instance
to be optimized or simulated.
The node object contains many attributes, and different functions use different sets of attributes.
For example, the stockpyl.ssm_serial.optimize_base_stock_levels()
function takes a
SupplyChainNetwork
whose nodes contain values for echelon_holding_cost
, lead_time
, stockout_cost
,
and demand_source
attributes, while stockpyl.gsm_serial.optimize_committed_service_times()
uses local_holding_cost
, processing_time
, etc.
Therefore, to determine which attributes are needed, refer to the documentation for the function
you are using.
API Reference¶
- class SupplyChainNode(index, name=None, network=None, **kwargs)[source]¶
The
SupplyChainNode
class contains the data, state variables, and performance measures for a supply chain node.- network¶
The network that contains the node.
- Type
- local_holding_cost¶
Local holding cost, per unit per period. [\(h'\)]
- Type
float
- echelon_holding_cost¶
Echelon holding cost, per unit per period. (Note: not currently supported.) [\(h\)]
- Type
float
- local_holding_cost_function¶
Function that calculates local holding cost per period, as a function of ending inventory level. Function must take exactly one argument, the ending IL. Function should check that IL > 0.
- Type
function
- in_transit_holding_cost¶
Holding cost coefficient used to calculate in-transit holding cost for shipments en route from the node to its downstream successors, if any. If
in_transit_holding_cost
isNone
, then the stage’s local_holding_cost is used. To ignore in-transit holding costs, setin_transit_holding_cost
= 0.- Type
float
- stockout_cost¶
Stockout cost, per unit (per period, if backorders). [\(p\)]
- Type
float
- stockout_cost_function¶
Function that calculates stockout cost per period, as a function of ending inventory level. Function must take exactly one argument, the ending IL. Function should check that IL < 0.
- Type
function
- purchase_cost¶
Cost incurred per unit. (Note: not currently supported.)
- Type
float
- revenue¶
Revenue earned per unit of demand met. (Note: not currently supported.) [\(r\)]
- Type
float
- shipment_lead_time¶
Shipment lead time. [\(L\)]
- Type
int
- lead_time¶
An alias for
shipment_lead_time
.- Type
int
- order_lead_time¶
Order lead time. (Note: not currently supported.)
- Type
int
- demand_source¶
Demand source object.
- Type
- initial_inventory_level¶
Initial inventory level.
- Type
float
- initial_orders¶
Initial outbound order quantity.
- Type
float
- initial shipments
Initial inbound shipment quantity.
- Type
float
- supply_type¶
Supply type , as a string. Currently supported strings are:
None
‘U’: unlimited
- Type
str
- order_capacity¶
Maximum size of an order.
- Type
float
- disruption_process¶
Disruption process object (if any).
- Type
- state_vars¶
List of
NodeStateVars
, one for each period in a simulation.- Type
list of
NodeStateVars
- problem_specific_data¶
Placeholder for object that is used to provide data for specific problem types.
- Type
object
- predecessors(include_external=False)[source]¶
Return a list of all predecessors of the node, as
SupplyChainNode
objects.- Parameters
include_external (bool, optional) – Include the external supplier (if any)? Default =
False
.- Returns
List of all predecessors, as
SupplyChainNode
objects.- Return type
list
- successors(include_external=False)[source]¶
Return a list of all successors of the node, as
SupplyChainNode
objects.- Parameters
include_external (bool, optional) – Include the external customer (if any)? Default =
False
.- Returns
List of all successors, as
SupplyChainNode
objects.- Return type
list
- predecessor_indices(include_external=False)[source]¶
Return a list of indices of all predecessors of the node.
- Parameters
include_external (bool, optional) – Include the external supplier (if any)? Default =
False
.- Returns
List of all predecessor indices.
- Return type
list
- successor_indices(include_external=False)[source]¶
Return a list of indices of all successors of the node.
- Parameters
include_external (bool, optional) – Include the external customer (if any)? Default =
False
.- Returns
List of all successor indices.
- Return type
list
- property descendants¶
A list of all descendants of the node, as
SupplyChainNode
objects. A descendant is a node that is downstream from the node but not necessarily directly adjacent; that is, a node that can be reached from the node via a directed path. Read only.
- property ancestors¶
A list of all ancestors of the node, as
SupplyChainNode
objects. An ancestor is a node that is upstream from the node but not necessarily directly adjacent; that is, a node from which we can reach the node via a directed path. Read only.
- property neighbors¶
A list of all neighbors (successors and predecessors) of the node, as
SupplyChainNode
objects. Read only.
- property neighbor_indices¶
A list of indices of all neighbors (successors and predecessors) of the node. Read only.
- property holding_cost¶
An alias for
local_holding_cost
. Read only.
- property forward_echelon_lead_time¶
Total shipment lead time for node and all of its descendants. Rosling (1989) calls this \(M_i\); Zipkin (2000) calls it \(\underline{L}_j\). Some assembly-system algorithms assume that the nodes are indexed in order of forward echelon lead time. Read only.
- property equivalent_lead_time¶
Difference between forward echelon lead time for the node (node \(i\)) and for node \(i-1\), where the nodes are indexed in non-decreasing order of forward_echelon_lead_time, consecutively. (If nodes are not indexed in this way, results will be unreliable.)
If node is the smallest-indexed node in the network, equivalent lead time equals forward echelon lead time, which also equals shipment lead time.
Rosling (1989) calls this \(L_i\); Zipkin (2000) calls it \(L''_j\).
Read only.
- property derived_demand_mean¶
Mean of derived demand, i.e., external demand at node and all of its descendants. Read only.
- property derived_demand_standard_deviation¶
Standard deviation of derived demand, i.e., external demand at node and all of its descendants. Read only.
- property state_vars_current¶
An alias for the most recent set of state variables, i.e., for the current period. (Period is determined from
self.network.period
). Read only.
- property disrupted¶
Is the node currently disrupted?
(Works even if the node has no
DisruptionProcess
object in itsdisruption_process
attribute.)
- initialize()[source]¶
Initialize the parameters in the object to their default values. Also initializes attributes that are objects (
demand_source
,disruption_process
,_inventory_policy
):
- deep_equal_to(other, rel_tol=1e-08)[source]¶
Check whether node “deeply equals”
other
, i.e., if all attributes are equal, including attributes that are themselves objects.Note the following caveats:
Does not check equality of
network
.Checks predecessor and successor equality by index only.
Does not check equality of
local_holding_cost_function
orstockout_cost_function
.Does not check equality of
state_vars
.
- Parameters
other (
SupplyChainNode
) – The node to compare this one to.rel_tol (float, optional) – Relative tolerance to use when comparing equality of float attributes.
- Returns
True
if the two nodes are equal,False
otherwise.- Return type
bool
- to_dict()[source]¶
Convert the
SupplyChainNode
object to a dict. Converts the object recursively, callingto_dict()
on each object that is an attribute of the node (DemandSource
, etc.).Successors and predecessors are stored as their indices only, not
SupplyChainNode
objects. They should be replaced with the node objects if this function is called recursively from aSupplyChainNetwork
’sfrom_dict()
method.Similarly,
network
object is not filled, but should be filled with the network object if this function is called recursively from aSupplyChainNetwork
’sfrom_dict()
method.- Returns
The dict representation of the node.
- Return type
dict
- classmethod from_dict(the_dict)[source]¶
Return a new
SupplyChainNode
object with attributes copied from the values inthe_dict
. List attributes are deep-copied so changes to the original dict do not get propagated to the object._predecessors
and_successors
attributes are set to the indices of the nodes, like they are in the dict, but should be converted to node objects if this function is called recursively from aSupplyChainNetwork
’sfrom_dict()
method.Similarly,
network
object is not filled, but should be filled with the network object if this function is called recursively from aSupplyChainNetwork
’sfrom_dict()
method.- Parameters
the_dict (dict) – Dict representation of a
SupplyChainNode
, typically created usingto_dict()
.- Returns
The object converted from the dict.
- Return type
- add_successor(successor)[source]¶
Add
successor
to the node’s list of successors.Important
This method simply updates the node’s list of successors. It does not add
successor
to the network or addself
as a predecessor ofsuccessor
. Typically, this method is called by the network rather than directly. Use theadd_successor()
method inSupplyChainNetwork
instead.- Parameters
successor (
SupplyChainNode
) – The node to add as a successor.
- add_predecessor(predecessor)[source]¶
Add
predecessor
to the node’s list of predecessors.Important
This method simply updates the node’s list of predecessors. It does not add
predecessor
to the network or addself
as a successor ofpredecessor
. Typically, this method is called by the network rather than directly. Use theadd_predecessor()
method inSupplyChainNetwork
instead.- Parameters
predecessor (
SupplyChainNode
) – The node to add as a predecessor.
- remove_successor(successor)[source]¶
Remove
successor
from the node’s list of successors.Important
This method simply updates the node’s list of successors. It does not remove
successor
from the network or removeself
as a predecessor ofsuccessor
. Typically, this method is called by theremove_node()
method of theSupplyChainNetwork
rather than directly.- Parameters
successor (
SupplyChainNode
) – The node to remove as a successor.
- remove_predecessor(predecessor)[source]¶
Remove
predecessor
from the node’s list of predecessors.Important
This method simply updates the node’s list of predecessors. It does not remove
predecessor
from the network or removeself
as a successor ofpredecessor
. Typically, this method is called by theremove_node()
method of theSupplyChainNetwork
rather than directly.- Parameters
predecessor (
SupplyChainNode
) – The node to remove as a predecessor.
- get_one_successor()[source]¶
Get one successor of the node. If the node has more than one successor, return the first in the list. If the node has no successors, return
None
.- Returns
successor – A successor of the node.
- Return type
- class NodeStateVars(node=None, period=None)[source]¶
The
NodeStateVars
class contains values of the state variables for a supply chain node during a simulation. All state variables refer to their values at the end of a period (except during the period itself, in which case the values might be intermediate until the period is complete).- node¶
The node the state variables refer to.
- Type
- period¶
The period of the simulation that the state variables refer to.
- Type
int
- inbound_shipment_pipeline¶
inbound_shipment_pipeline[p][r]
= shipment quantity arriving from predecessor nodep
inr
periods from the current period. Ifp
isNone
, refers to external supply.- Type
dict
- inbound_shipment¶
inbound_shipment[p]
= shipment quantity arriving at node from predecessor nodep
in the current period. Ifp
isNone
, refers to external supply.- Type
dict
- inbound_order_pipeline¶
inbound_order_pipeline[s][r]
= order quantity arriving from successor nodes
inr
periods from the current period. Ifs
isNone
, refers to external demand.- Type
dict
- inbound_order¶
inbound_order[s]
= order quantity arriving at node from successor nodes
in the current period. Ifs
isNone
, refers to external demand.- Type
dict
- demand_cumul¶
Cumulative demand (from all sources, internal and external) from period 0 through the current period. (Used for
fill_rate
calculation.)- Type
float
- outbound_shipment¶
outbound_shipment[s]
= outbound shipment to successor nodes
. Ifs
isNone
, refers to external demand.- Type
dict
- on_order_by_predecessor¶
on_order_by_predecessor[p]
= on-order quantity (items that have been ordered from successor nodep
but not yet received) at node. Ifp
isNone
, refers to external supply.- Type
dict
- inventory_level¶
Inventory level (positive, negative, or zero) at node
- Type
float
- backorders_by_successor¶
backorders_by_successor[s]
= number of backorders for successors
. Ifs
isNone
, refers to external demand.- Type
dict
- outbound_disrupted_items¶
outbound_disrupted_items[s]
= number of items held for successors
due to a type-SP disruption ats
. (Since external demand cannot be disrupted,outbound_disrupted_items[None]
always = 0.) Items held for successor are not included inbackorders_by_successor
. Sum over all successors ofbackorders_by_successor + outbound_disrupted_items
should always equal max{0, -inventory_level
}.- Type
dict
- inbound_disrupted_items¶
inbound_disrupted_items[p]
= number of items from predecessorp
that are being held before receipt due to a type-RP disruption at the node.- Type
dict
- raw_material_inventory¶
raw_material_inventory[p]
= number of units of predecessorp
’s product in raw-material inventory at node. Ifp
isNone
, refers to external supply.- Type
dict
- disrupted¶
True
if the node was disrupted in the period,False
otherwise.- Type
bool
- holding_cost_incurred¶
Holding cost incurred at the node in the period.
- Type
float
- stockout_cost_incurred¶
Stockout cost incurred at the node in the period.
- Type
float
- in_transit_holding_cost_incurred¶
In-transit holding cost incurred at the node in the period.
- Type
float
- revenue_earned¶
Revenue earned at the node in the period.
- Type
float
- total_cost_incurred¶
Total cost (less revenue) incurred at the node in the period.
- Type
float
- demand_met_from_stock¶
Demands met from stock at the node in the period.
- Type
float
- demand_met_from_stock_cumul¶
Cumulative demands met from stock from period 0 through the current period. (Used for
fill_rate
calculation.)- Type
float
- fill_rate¶
Cumulative fill rate in periods 0, …, period.
- Type
float
- order_quantity¶
order_quantity[p]
= order quantity placed by the node to predecessorp
in period. Ifp
isNone
, refers to external supply.- Type
dict
- property on_hand¶
Current on-hand inventory. Read only.
- property backorders¶
Current number of backorders. Should always equal sum over all successors
s
ofbackorders_by_successor[s]
+outbound_disrupted_items[s]
. Read only.
- in_transit_to(successor)[source]¶
Return current total inventory in transit to a given successor. (Declared as a function, not a property, because needs to take an argument.) Includes items that will be/have been delivered during the current period.
- Parameters
successor (
SupplyChainNode
) – The successor node.- Return type
The current inventory in transit to the successor.
- in_transit_from(predecessor)[source]¶
Return current total inventory in transit from a given predecessor. (Declared as a function, not a property, because needs to take an argument.) Includes items that will be/have been delivered during the current period (
self.network.period
).- Parameters
predecessor (
SupplyChainNode
) – The predecessor node (orNone
for external supplier).- Return type
The current inventory in transit from the predecessor.
- property in_transit¶
Current total inventory in transit to the node. If node has more than 1 predecessor (it is an assembly node), including external supplier, in-transit items are counted using the “units” of the node itself. That is, they are divided by the total number of predecessors. Read only.
- property on_order¶
Current total on-order quantity. If node has more than 1 predecessor (it is an assembly node), including external supplier, on-order items are counted using the “units” of the node itself. That is, they are divided by the total number of predecessors. Read only.
- property raw_material_aggregate¶
Total raw materials at the node. Raw materials are counted using the “units” of the node itself. That is, they are divided by the total number of predecessors. Read only.
- property inbound_disrupted_items_aggregate¶
Total inbound disrupted items at the node. Inbound disrupted items are counted using the “units” of the node itself. That is, they are divided by the total number of predecessors. Read only.
- inventory_position(predecessor_index=None)[source]¶
Current local inventory position at node. Equals inventory level plus on-order inventory. On-order includes raw material inventory that has not yet been processed, as well as inbound disrupted items due to type-RP disruptions. If the node has more than one predecessor (including external supplier), set
predecessor_index
for predecessor-specific inventory position, or set toNone
to use aggregate on-order and raw material inventory (counting such items using the “units” of the node itself).- Parameters
predecessor_index (int, optional) – Predecessor to consider in inventory position calculation (excluding all others), or
None
to include all predecessors.- Returns
The inventory position.
- Return type
float
- property echelon_on_hand_inventory¶
Current echelon on-hand inventory at node. Equals on-hand inventory at node and at or in transit to all of its downstream nodes. Read only.
- property echelon_inventory_level¶
Current echelon inventory level at node. Equals echelon on-hand inventory minus backorders at terminal node(s) downstream from node. Read only.
- echelon_inventory_position(predecessor_index=None)[source]¶
Current echelon inventory position at node. Equals echelon inventory level plus on order items. On-order includes raw material inventory that has not yet been processed. If the node has more than one predecessor (including external supplier), set
predecessor_index
for predecessor-specific inventory position, or set toNone
to use aggregate on-order and raw material inventory (counting such items using the “units” of the node itself).- Parameters
predecessor_index (int, optional) – Predecessor to consider in inventory position calculation (excluding all others), or
None
to include all predecessors.- Returns
The echelon inventory position.
- Return type
float
- to_dict()[source]¶
Convert the
NodeStateVars
object to a dict. List and dict attributes are deep-copied so changes to the original object do not get propagated to the dict.The
node
attribute is set to the index of the node (if any), rather than to the object.- Returns
The dict representation of the object.
- Return type
dict
- classmethod from_dict(the_dict)[source]¶
Return a new
NodeStateVars
object with attributes copied from the values inthe_dict
. List and dict attributes are deep-copied so changes to the original dict do not get propagated to the object.The
node
attribute is set to the index of the node, like it is in the dict, but should be converted to a node object if this function is called recursively from aSupplyChainNode
’sfrom_dict()
method.- Parameters
the_dict (dict) – Dict representation of a
NodeStateVars
, typically created usingto_dict()
.- Returns
The object converted from the dict.
- Return type
- reindex_state_variables(old_to_new_dict)[source]¶
Change indices of state variable dict keys using
old_to_new_dict
.- Parameters
old_to_new_dict (dict) – Dict in which keys are old indices and values are new indices.
- deep_equal_to(other, rel_tol=1e-08)[source]¶
Check whether object “deeply equals”
other
, i.e., if all attributes are equal, including attributes that are lists or dicts.Note the following caveats:
Checks the equality of
node.index
but not the entirenode
object.
- Parameters
other (
NodeStateVars
) – The state variables to compare this one to.rel_tol (float, optional) – Relative tolerance to use when comparing equality of float attributes.
- Returns
True
if the two state variables objects are equal,False
otherwise.- Return type
bool