Model Production and finding out the Optimal Plan

111 views
Skip to first unread message

Sebastian Granath

unread,
Sep 26, 2024, 5:08:35 AM9/26/24
to python-simpy

Hello all,

Like many others have mentioned, I am fairly new to the SimPy framework and am uncertain about its limitations.

In my project, I would like to build a simulation model for a production site and use a weekly production plan as input. The question I want to answer is: "What is the most efficient way to produce the products in the weekly plan?" given the constraints of the model.

My implementation plan is to start by building the model in smaller components (buffers, machines, transport, etc.), then apply an optimization model on top to vary the weekly plan. The goal is to determine what order of execution would yield the fastest production while minimizing the waiting times that naturally occur in the production process (e.g., cooling time, heating time).

Would this be a good use case for SimPy? Additionally, what methods would you recommend for logging events so that a visualization of the plan could be created?

Michael Gibbs

unread,
Sep 29, 2024, 12:45:48 AM9/29/24
to python-simpy
Yes, simpy can model production line processes.  You can log by adding logging/print statements at the start and end of the processes, or by having a logging process that logs the state of your model at a time Interval 

bobo

unread,
Sep 30, 2024, 10:14:17 AM9/30/24
to python-simpy
Hi Sebastian,

As Michael says, SimPy is a great choice for modeling production processes, especially when you want to simulate discrete-events like processing times, machine operations, and transport delays. It allows you to build complex systems by modeling them as processes that interact with each other.

For logging events, a simple approach would be to use dictionaries to record timestamps and states during the simulation. After collecting the data, you can use libraries like Pandas and Seaborn to visualise and analyse the results.

Below is some sample code that demonstrates how to:
Build a simple production simulation.
Log events using dictionaries.
Visualise the production timeline using Seaborn.

import simpy
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# Initialise the data logging dictionary
log_data = {
    'Product': [],
    'Process': [],
    'Start_Time': [],
    'End_Time': []
}

# Define the production processes
def production_process(env, name, machines, log_data):
    """Simulates the production process of a single product."""
    # Process 1: Heating
    with machines['Heater'].request() as request:
        yield request
        start_time = env.now
        yield env.timeout(2)  # Heating time
        end_time = env.now
        # Log the event
        log_data['Product'].append(name)
        log_data['Process'].append('Heating')
        log_data['Start_Time'].append(start_time)
        log_data['End_Time'].append(end_time)
   
    # Process 2: Processing
    with machines['Processor'].request() as request:
        yield request
        start_time = env.now
        yield env.timeout(3)  # Processing time
        end_time = env.now
        # Log the event
        log_data['Product'].append(name)
        log_data['Process'].append('Processing')
        log_data['Start_Time'].append(start_time)
        log_data['End_Time'].append(end_time)
   
    # Process 3: Cooling
    with machines['Cooler'].request() as request:
        yield request
        start_time = env.now
        yield env.timeout(1)  # Cooling time
        end_time = env.now
        # Log the event
        log_data['Product'].append(name)
        log_data['Process'].append('Cooling')
        log_data['Start_Time'].append(start_time)
        log_data['End_Time'].append(end_time)

def product_generator(env, machines, log_data, weekly_plan):
    """Generates products based on the weekly production plan."""
    for i, product in enumerate(weekly_plan):
        yield env.timeout(product['arrival_time'])
        env.process(production_process(env, f'Product_{i+1}', machines, log_data))

# Set up the simulation environment
env = simpy.Environment()

# Define the machines as resources
machines = {
    'Heater': simpy.Resource(env, capacity=1),
    'Processor': simpy.Resource(env, capacity=1),
    'Cooler': simpy.Resource(env, capacity=1)
}

# Example weekly production plan
weekly_plan = [
    {'arrival_time': 0},
    {'arrival_time': 1},
    {'arrival_time': 2},
    {'arrival_time': 3},
    {'arrival_time': 4},
]

# Start the product generator
env.process(product_generator(env, machines, log_data, weekly_plan))

# Run the simulation
env.run()

# Convert log data into a DataFrame
df = pd.DataFrame(log_data)

# Print the DataFrame
print(df)

# Visualise the production timeline
plt.figure(figsize=(12, 6))
sns.set_style("whitegrid")

# Create a color palette for the processes
processes = df['Process'].unique()
palette = sns.color_palette("tab10", len(processes))
color_dict = dict(zip(processes, palette))

# Plot the Gantt chart
for product_name, product in df.groupby('Product'):
    for _, row in product.iterrows():
        plt.barh(
            y=row['Product'],
            width=row['End_Time'] - row['Start_Time'],
            left=row['Start_Time'],
            edgecolor='black',
            color=color_dict[row['Process']],
            label=row['Process'] if row['Product'] == 'Product_1' else ""
        )

# Remove duplicate labels in the legend
handles, labels = plt.gca().get_legend_handles_labels()
by_label = dict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys(), title='Process')

plt.xlabel('Time')
plt.ylabel('Product')
plt.title('Production Timeline')
plt.show()
Screenshot 2024-09-30 at 11.10.42 AM.png

Here's a little explanation of what's going on...

Simulation Setup:
- We define three resources: Heater, Processor, and Cooler, each representing a machine in the production line.
- The production_process function simulates the steps each product goes through, requesting access to the necessary machines and logging the start and end times.
- The product_generator function introduces products into the system based on the weekly_plan, which specifies the arrival times of each product.
Logging Events:
- Events are logged into the log_data dictionary whenever a process starts and ends.
- This dictionary is later converted into a Pandas DataFrame for easier manipulation and visualization.
Visualisation:
- We use Seaborn and Matplotlib to create a Gantt chart that visualises the timeline of each product through the different processes.
- Each bar in the chart represents the time a product spends in a particular process.

I hope this helps!

Best,
Harry Munro
Founder, TeachEm

Michael Gibbs

unread,
Sep 30, 2024, 11:26:05 PM9/30/24
to python-simpy
Harry:

Nice example 
Reply all
Reply to author
Forward
0 new messages