I am following up on my recent simplified job shop simulation example in SimPy. Today I want to show you how you can collect simulation data in a SimPy simulation model. I will use the data for data visualization. As you will see visualizing SimPy simulation data is easy and flexible.
A simple job shop model in SimPy
I implement another simple job shop model in Python using SimPy. For this I need two modules: random and SimPy. Below code sets up the model framework, comprised of a Jobshop model and a Job model. Both are implemented with Python classes.
import simpy
import random
class Jobshop:
def __init__(self, env):
self.env = env
self.machine1 = simpy.Resource(env, capacity=1)
self.machine2 = simpy.Resource(env, capacity=1)
self.jobs_completed = 0
self.proc_times = []
def fulfill_job(self, job):
# request a machine
with self.machine1.request() as req1, self.machine2.request() as req2:
requests = [req1, req2]
yield self.env.all_of(requests)
# simulate processing time
proc_time = random.expovariate(1.0/5.0)
yield self.env.timeout(proc_time)
# record processing time
self.proc_times.append(self.env.now - job.arrival_time)
self.jobs_completed += 1
def run_production(self):
while True:
# generate new job release time
arrival_time = random.expovariate(1.0/10.0)
# wait for job to be released accoring to simulated schedule
yield self.env.timeout(arrival_time)
# create new production order, i.e. machine job
job = Job(self.env.now)
self.env.process(self.fulfill_job(job))
class Job:
def __init__(self, arrival_time):
self.arrival_time = arrival_time
The job shop has 2 machines, and a job can be processed on any machine. Every machine can only process one job at the time. Processing time is randomly distributed. The simulation data that I want to collect it the actual processing time of a job on a machine. This data is collected in a list as an attribute of the Jobshop class (proc_times).
Implementing simulation and visualizing SimPy results
Below I implement the simulation model, consuming the model frame developed in above code. I visualize the collected processing times in the form of a histogram with matplotlib in Python.
# implement the simulation
env = simpy.Environment()
jobshop = Jobshop(env)
env.process(jobshop.run_production())
env.run(until=100000)
# visualize collected processing time data
plt.hist(jobshop.proc_times, bins=50)
plt.xlabel('Processing time on machine')
plt.ylabel('Frequency')
plt.title('Job processing times on machine')
plt.show()
print(f"Jobs completed: {jobshop.jobs_completed}")
print(f"Average processing time: {sum(jobshop.proc_times)/len(jobshop.proc_times)}")
This generates the following plot:
This output was expected, as processing times were modelled with the expovariate() random method in the first place.
Related SimPy content
If you are interested in discrete-event simulation modelling in Python and R then check out the following SCDA blog posts:
- Link: Parking lot simulator with simmer in R
- Link: Poultry supply chain simulator
- Link: End-to-end poultry supply chain simulation
SimPy is my favorite simulation tool and it is especially good for modelling business processes and operations. A job shop is just one example of this. Using SimPy you can also simulate an entire supply chain, with inventory rules, control logics, production schedules, forecasts and more. You will have to develop the frame yourself, but SimPy equips you with all the necessary basics.
Data scientist focusing on simulation, optimization and modeling in R, SQL, VBA and Python
Leave a Reply