Discrete Event Simulatiuon in Python
Discrete Event Simulation in Python
Introduction to Dynamic Systems and Discrete-Event Simulation Models
Dynamic and Steady Systems
Dynamic Systems: Dynamic systems are systems that change over time. These changes can be due to internal factors, external influences, or a combination of both. The state of a dynamic system evolves according to a set of defined rules or equations, which can be deterministic or stochastic. Examples of dynamic systems include weather patterns, stock market fluctuations, and population growth models.
Steady Systems: Steady systems, also known as steady-state systems, are systems that do not change over time. In these systems, the variables remain constant, and there is no evolution or fluctuation in their state. Steady systems are often used as a simplification for analyzing systems where changes are negligible or occur over very long periods. Examples of steady systems include a car moving at a constant speed on a straight road or a chemical reaction that has reached equilibrium.
!pip install simpyimport simpy
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt# Define the lift discrete event model
def lift_discrete_event_model(sim_time, number_hotel_floors, lift_people_capacity, travel_time_between_floors, stop_time_open_doors):
# Initialize the simulation environment
env = simpy.Environment()
# Define the lift process
def lift(env, number_hotel_floors, lift_people_capacity, travel_time_between_floors, stop_time_open_doors):
while True:
for floor in range(number_hotel_floors):
yield env.timeout(travel_time_between_floors)
yield env.timeout(stop_time_open_doors)
for floor in range(number_hotel_floors - 1, -1, -1):
yield env.timeout(travel_time_between_floors)
yield env.timeout(stop_time_open_doors)
# Start the lift process
env.process(lift(env, number_hotel_floors, lift_people_capacity, travel_time_between_floors, stop_time_open_doors))
# Run the simulation
env.run(until=sim_time)
# Collect results (this is a placeholder, actual implementation may vary)
results = {
"Time": np.arange(0, sim_time, 1),
"Floor": np.random.randint(0, number_hotel_floors, sim_time)
}
# Convert results to a DataFrame
df_results = pd.DataFrame(results)
return df_results
# Create a dictionary containing the processes and durations
processes = {
"Sourcing": 5,
"Manufacturing": 3,
"Assembling": 2,
"Selling": 3,
"Delivering": 4
}
# Floor and lift parameters
number_hotel_floors = 5
lift_people_capacity = 15
travel_time_between_floors = 0.05
stop_time_open_doors = 0.1
sim_time = 5
# Run the model
df_results = lift_discrete_event_model(sim_time, number_hotel_floors, lift_people_capacity, travel_time_between_floors, stop_time_open_doors)
# Display the results
df_resultsMathematical models of dynamic systems
Defining a Mathematical Model
A mathematical model is a description of a system using mathematical concepts and language. The process of developing a mathematical model is termed 'mathematical modeling'. Mathematical models are used in the natural sciences (such as physics, biology, earth science, meteorology) and engineering disciplines (such as computer science, artificial intelligence), as well as in the social sciences (such as economics, psychology, sociology, political science).
A mathematical model can take many forms, including but not limited to:
- Differential Equations: Used to describe the behavior of dynamic systems.
- Algebraic Equations: Used for systems in equilibrium.
- Statistical Models: Used to represent data and infer relationships.
- Stochastic Models: Incorporate randomness and are used for systems that are inherently unpredictable.
The choice of model depends on the nature of the system being studied and the goals of the analysis. For example, in the context of dynamic systems, differential equations are often used to model the change in system states over time.
Here is a simple example of a differential equation used to model the growth of a population:
[ \frac{dP}{dt} = rP ]
where:
- ( P ) is the population size,
- ( t ) is time,
- ( r ) is the growth rate.
This equation states that the rate of change of the population over time is proportional to the current population size, which is a characteristic of exponential growth.
import matplotlib.pyplot as plt
# Model engine
def discrete_model(processes, simulation_time):
# Initialize time
time = 0
time_series = [time]
# Run end condition
while (time < simulation_time):
process_names = list(processes.keys())
# Loop over all processes
for p in range(len(process_names)):
process_name_p = process_names[p]
# account for effect of each process
time += processes[process_name_p]
time_series.append(time)
return time_series
# Run configuration
# Simulation period
simulation_time = 365
# Define processes (example)
processes = {
'process_1': 5,
'process_2': 2,
'process_3': 3
}
# Run model
time_series = discrete_model(processes, simulation_time)
# Generate x and y data for plotting
x = range(len(time_series))
y = time_series
plt.plot(x, y, color='green', marker='o',
markersize=2, linestyle='dashed',
linewidth=2)
plt.xlabel('Step')
plt.ylabel('Time')
plt.title('Discrete Model Simulation')
plt.show()# Exercises
processes = {
"Sourcing raw material": 5,
"Transport of raw material": 1,
"Manufacturing parts": 3,
"Assembling parts": 2,
"Selling products": 3,
}
# Add the new key-value pair to the processes dictionary
processes["Delivering products"] = 1.5
# Assign the simulation time
simulation_time = 365*5
# Define the discrete_model_build_phone function
def discrete_model_build_phone(processes, simulation_time):
cumulative_time = []
individual_process_time = []
total_time = 0
for process, duration in processes.items():
total_time += duration
cumulative_time.append(total_time)
individual_process_time.append(duration)
return cumulative_time, individual_process_time
# Run the model
time_all = discrete_model_build_phone(processes, simulation_time)
cumulative_time = time_all[0]
individual_process_time = time_all[1]
# Create 2D plot
import matplotlib.pyplot as plt
plt.plot(cumulative_time, individual_process_time,
color='black', markerfacecolor='mediumvioletred',
marker='o', markersize=6, linewidth=1.5)
plt.xlabel("Cumulative duration (days)")
plt.ylabel("Duration of each process (days)")
plt.grid()
plt.show()Introduction to discrete event simulations
Discrete Event Models
Discrete event models are a type of simulation where the operation of a system is represented as a chronological sequence of events. Each event occurs at a specific instant in time and marks a change of state in the system. These models are particularly useful for systems where changes occur at discrete points in time, rather than continuously.
Key Concepts
- Events: The fundamental units of change in the system. Each event occurs at a specific time and triggers a change in the state of the system.
- State: The collection of variables that describe the system at any given time.
- Clock: A variable that keeps track of the current simulation time.
- Event List: A list that keeps track of all scheduled events and their associated times.
Applications
- Manufacturing processes
- Queueing systems
- Computer networks
- Traffic flow
Example
In the provided code, a discrete event model is used to simulate the process of building a phone. The model tracks the cumulative time and individual process times for various stages such as sourcing raw material, manufacturing parts, and delivering products.
# Define the discrete_model_build_phone function def discrete_model_build_phone(processes, simulation_time): cumulative_time = [] individual_process_time = [] total_time = 0 for process, duration in processes.items(): total_time += duration cumulative_time.append(total_time) individual_process_time.append(duration) return cumulative_time, individual_process_time # Run the model time_all = discrete_model_build_phone(processes, simulation_time) cumulative_time = time_all[0] individual_process_time = time_all[1] # Create 2D plot import matplotlib.pyplot as plt plt.plot(cumulative_time, individual_process_time, color='black', markerfacecolor='mediumvioletred', marker='o', markersize=6, linewidth=1.5) plt.xlabel("Cumulative duration (days)") plt.ylabel("Duration of each process (days)") plt.grid() plt.show()
# Mock functions to simulate the behavior of manage_requests and dispatch_taxi
import random
def manage_requests():
return random.randint(1, 3)
def dispatch_taxi():
return random.randint(1, 3)
# Initialize time
time = 0
# Model components
while time < 10:
# Process 1
time_duration_1 = manage_requests()
time += time_duration_1
# Process 2
time_duration_2 = dispatch_taxi()
time += time_duration_2
# Output the current time for debugging purposes
print(f"Current time: {time}")# Exercises
def discrete_model_farm(process_dict, simulation_time):
# Initiate variables
time = 0
supply_chain = 0
# Define ending condition
while time < simulation_time:
supply_chain += 1
process_names = list(process_dict.keys())
for p in range(len(process_names)):
event_duration = process_dict[process_names[p]]
# Add the process duration
time += event_duration
print(f"{process_names[p]} (completed): time = {time}")
print(f"COMPLETED: Production cycle #{supply_chain} | Time = {time} days")
# Create dictionary
process_dict = {
"Compost": 5,
"Amendment": 3,
"Weeding": 4,
"Planting": 2,
"Watering and growing": 60,
"Harvesting": 7,
"Delivery": 2
}
# Simulatiom time (days)
simulation_time = 365
# Run the model
discrete_model_farm(process_dict, simulation_time)