Visualizing stats with salabim (DES, Python)

Having introduced salabim for discrete-event simulation (DES) in Python I want to follow-up on its stats-related functionality. I do so in today’s blog post: Stats with salabim!

Discrete-event simulation, job shop, and Python

Discrete-event simulation is one of several simulation methods applicable by SCM analysts, production planners and operations research analysts. Below chart provides a rough categorization of these simulation methods.

stats with salabim for discrete event simulation in Python

Discrete-event simulation is applied mainly for operative and detailed objectives, such as e.g. production planning, factory design, or business process design and improvement. It is the appropriate method for complex systems described well by sequential events and queues. Here are some examplary simulation use cases that you can read for a start:

A job shop, for example, is a system that can benefit from discrete-event simulation for its design and/or continued improvement.

Job shop simulation and stats with salabim

Below Python code implements a job shop simulation model in Python using salabim. I have used this simple example in previous blog posts. In this case we are modelling a simplified job shop with 2 machines and 100 jobs. Jobs can be processed on any machine, but only by one machine at the time. Machines process jobs with a specified processing time (duration). Machines, in this case, have a capacity of 1. Once a machine has processed a job it is complete. The production schedule, in this case, is simplified to some extend and modelled by a random job generator. The job generator creates new jobs at randomly distributed intervals with a specified mean time between jobs. The code implements animated stats, in addition to model implementation and simulation execution.

The first part imports salabim and sets up constants as well as relevant dataypes (Product class). Product extends the salabim Component class. It implements a process method. This method is used for requesting and holding a ressource, for a specified duration.

import salabim as sim

SEED = 42
MACHINES = 2    # amount of machines
INTERVAL = 3    # mean time between two jobs
DURATION = 5.0  # mean processing time of a job
JOBS = 100      # number of jobs that have to be completed

class Product(sim.Component):
    def process(self):
        yield self.request(machines)
        print(f"{} started at time {}")
        yield self.hold(DURATION)
        print(f"{} completed at time {}")

The next part sets up the simulation environment and defines the ressources. The part source, i.e. the component generator, is also defined in this section:

env = sim.Environment(random_seed=SEED)
machines = sim.Resource("machines", capacity=MACHINES)

sim.ComponentGenerator(Product, iat=sim.Exponential(INTERVAL), force_at=True, number=JOBS)

Lastly, the simulation run and animation is implemented.

env.modelname("jobshop demonstration")

machines.claimers().animate(x=700, y=100, title="work in progress", direction="e")

machines.requesters().animate(x=200, y=100, title="work waiting", direction="e")

machines.claimers().length.animate(x=10, y=300, width=1000, height=100, vertical_scale=15, horizontal_scale=20, title="number of work in prgress")

machines.requesters().length.animate(x=10, y=500, width=1000, height=100, vertical_scale=15, horizontal_scale=20, title="number of work waiting")


This results in an animation. Below image shows a snapshot of the animation.

The animation shows work in progress and backlog / work waiting throughout time.

Related content

If you are interested in discrete-event simulation and its applications, or its specific implementations in e.g. R, AnyLogic, VisualComponents and Python, check out the following SCDA publications:

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.