import simpy
import pandas as pd
import random
from vidigi.animation import animate_activity_log
from vidigi.utils import EventPosition, create_event_position_df
Step 2. Set up simulation parameters
A very simple example with one server - avoiding the vidigi logger class
If you would prefer to implement your own approach to logging, you can avoid the use of the EventLogger class, and instead manually build your event logs, as shown in this example.
Step 1. Import required libraries
vidigi
simpy
- for simulation model (or see the Ciw functions and examples elsewhere in this documentation)random
- for generating random arrivalspandas
- for managing dataframes
# Simple simulation parameters
= 50
SIM_DURATION = 1
NUM_SERVERS = 1.0
ARRIVAL_RATE = 3.0 SERVICE_TIME
Step 3. Write model code with event logs
Create a simple simulation model using simpy
.
On the left is a basic simpy
model. If not familiar check out simpy
documentation for intro to simpy.
On the right is how we incorporate vidigi
. Information for vidigi
collected in a list of dictionaries which we will convert into a dataframe. You need a arrival_departure
event.
Simple SimPy Model
def patient_generator(env, server, event_log):
"""Generate patients arriving at the shop"""
= 0
patient_id
while True:
+= 1
patient_id
# Start the patient process
env.process(patient_process(env, patient_id, server, event_log))
# Wait for next arrival
yield env.timeout(random.expovariate(ARRIVAL_RATE))
def patient_process(env, patient_id, server, event_log):
"""Process a single patient through the system"""
# Request server
with server.request() as request:
yield request
# Service time
= random.expovariate(1.0/SERVICE_TIME)
service_duration yield env.timeout(service_duration)
# Run the simulation
def run_simulation():
= simpy.Environment()
env = simpy.Resource(env, capacity=NUM_SERVERS)
server = []
event_log
# Start patient generator
env.process(patient_generator(env, server, event_log))
# Run simulation
=SIM_DURATION) env.run(until
With Vidigi Modifications
def patient_generator(env, server, event_log):
"""Generate patients arriving at the shop"""
= 0
patient_id
while True:
+= 1
patient_id
# Log arrival
event_log.append({ 'patient': patient_id,
'event': 'arrival',
'event_type': 'arrival_departure',
'time': env.now
})
# Start the patient process
env.process(patient_process(env, patient_id, server, event_log))
# Wait for next arrival
yield env.timeout(random.expovariate(ARRIVAL_RATE))
def patient_process(env, patient_id, server, event_log):
"""Process a single patient through the system"""
# Log start of queue wait
event_log.append({ 'patient': patient_id,
'event': 'queue_wait_begins',
'event_type': 'queue',
'time': env.now
})
# Request server
with server.request() as request:
yield request
# Log service start
event_log.append({ 'patient': patient_id,
'event': 'service_begins',
'event_type': 'resource_use',
'time': env.now,
'resource_id': 1
})
# Service time
= random.expovariate(1.0/SERVICE_TIME)
service_duration yield env.timeout(service_duration)
# Log service end
event_log.append({ 'patient': patient_id,
'event': 'service_complete',
'event_type': 'resource_use_end',
'time': env.now,
'resource_id': 1
})
# Log departure
event_log.append({ 'patient': patient_id,
'event': 'depart',
'event_type': 'arrival_departure',
'time': env.now
})
# Run the simulation
def run_simulation():
= simpy.Environment()
env = simpy.Resource(env, capacity=NUM_SERVERS)
server = []
event_log
# Start patient generator
env.process(patient_generator(env, server, event_log))
# Run simulation
=SIM_DURATION)
env.run(until
return pd.DataFrame(event_log)
Step 4. Run simulation
# Run simulation and get event log
= run_simulation()
event_log_df print(f"Generated {len(event_log_df)} events")
Generated 125 events
Step 5. Create event positions dataframe
# Define positions for animation
= create_event_position_df([
event_positions ='arrival', x=0, y=350, label="Entrance"),
EventPosition(event='queue_wait_begins', x=250, y=250, label="Queue"),
EventPosition(event='service_begins', x=250, y=150, resource='server', label="Being Served"),
EventPosition(event='depart', x=250, y=50, label="Exit")
EventPosition(event ])
Step 6. Create animation
Explaining:
plotly_height
andplotly_width
override_x_max
andoverride_y_max
setup_mode
every_x_time_units
# Create animation
animate_activity_log(=event_log_df,
event_log=event_positions,
event_position_df="patient",
entity_col_name=1,
every_x_time_units=600,
plotly_height=360,
override_x_max=SIM_DURATION
limit_duration )