Retail supply chain ABM in Python

In this article I post a simple distribution supply chain agent-based model in Python. Agent-based modelling (abbreviated to ABM) was already introduced by me in various other blog posts. Here are some introductionary references that will get you started.

I have also developed a Python package for grid-based agent-based simulations. This package can be used for implementing ABMs that are grid-based. Meaning, in which the environment, in which agents are located, can be modelled with a grid. Even models that do not require a grid based model can be implemented with such a framework. The package is now available e.g. here:

A grid-based model can be useful as it provides a concept for defining distances (including abstract distance measures such as e.g. social distance). Moreover, it provides a standardized concept for modeling interaction between agents. In this post I will not implement a grid-based simulation model. This is because it is not necessary in the case of the SCM distribution model discussed here.

Conceptual supply chain model

In this simple model there are two types of logic flows. Information flow and material flow:

  • Retailers can place orders with distributors. A distributor can place orders with manufacturers. This is the information flow.
  • Manufacturers can produce and ship products to distributors. The distributor can ship products to retailers. This is the material flow.

This is the retail distribution supply chain in its most simple form. Additions to the model would then e.g. be lead times, minimum ordering quantities, produt lot sizes, inventory policies etc. All of these additions can be added to an agent-based model such as the one discussed in this article.

Supply chain ABM in Python

Above figure illustrates the conceptual model. Next section implements above supply chain ABM in Python.

Implementing supply chain ABM in Python

Below I implement the supply chain ABM in Python. First, I implement the framework of classes that I will use. I will need a Retailer class, a Distributor class, and a Manufacturer class. I implement these classes in the code snipped below.

# RETAILER class
class Retailer:
    def __init__(self, inventory_level):
        self.inventory_level = inventory_level

    def order_from_distributor(self, quantity):
        if quantity > self.inventory_level:
            order_quantity = quantity - self.inventory_level
            return order_quantity
        else:
            return 0

    def receive_shipment(self, quantity):
        self.inventory_level += quantity

# DISTRIBUTOR class
class Distributor:
    def __init__(self, inventory_level):
        self.inventory_level = inventory_level

    def order_from_manufacturer(self, quantity):
        if quantity > self.inventory_level:
            order_quantity = quantity - self.inventory_level
            return order_quantity
        else:
            return 0

    def receive_shipment(self, quantity):
        self.inventory_level += quantity

# MANUFACTURER class
class Manufacturer:
    def __init__(self, production_capacity):
        self.production_capacity = production_capacity

    def produce_goods(self, quantity):
        if quantity <= self.production_capacity:
            return quantity
        else:
            return self.production_capacity

Next, I implement the simulation model itself. For this I write a function that takes 4 arguments. The retailer, the distributor, the manufacturer, and the number of iterations. I use the random module to generate random order quantities.

import random

# SIMULATION implementation
def simulate_supply_chain(retailer :Retailer, 
                          distributor :Distributor, 
                          manufacturer :Manufacturer, 
                          num_iterations :int
                         ) -> None:
    """ supply chain simulation

    simulates a supply chain with a retailer, a distributor, and a manufacturer;
    simulates over a specified amount of iteration;
    uses random to generate random order quantities

    Args:
    # retailer (Retailer): retailer agent that place orders at distributor
    # distributor (Distributor): distributor that palces order at manufacturer
    # manufacturer (Manufacturer): manufacturer that ships to distrubtor
    # num_iterations (int): 

    Returns:
    # None
    
    """
    for i in range(num_iterations):
        # retailer places order with distributor
        order_quantity = retailer.order_from_distributor(random.randint(5, 15))
        
        # distributor places order with manufacturer
        order_quantity = distributor.order_from_manufacturer(order_quantity)
        
        # manufacturer produces goods and ships to distributor
        shipped_quantity = manufacturer.produce_goods(order_quantity)
        distributor.receive_shipment(shipped_quantity)
        
        # distributor ships goods to retailer
        shipped_quantity = distributor.inventory_level
        retailer.receive_shipment(shipped_quantity)

This completes my exemplary supply chain ABM in Python.

Concluding remarks and related content

A realistic, commercial model would have to incorporate many additions. As initially pointed out e.g. lead times, order points, MOQs, lot sizes, etc. Also orders themselves would most likely not be generated by a simpe random number generator as in this case. Nevertheless, this simple example illustrates the concept of agent-based modelling for supply chain modelling. Even a very complex supply chain can be modelled in this way.

If you are interested in agent-based simulation you can consider checking out my grid-based agent simulation model examples:

You May Also Like

Leave a Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.