-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTheaterSim.py
118 lines (84 loc) · 3.14 KB
/
TheaterSim.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#%%
# Simulation code adapted from https://github.com/realpython/materials/blob/master/simulation-with-simpy/simulate.py
import simpy
import random
import statistics
wait_times = 0
number_ppl = 0
class Theater(object):
"""Object that holds all simpy Resources for the theater
"""
def __init__(self, env, num_cashiers, num_servers, num_ushers):
"""initializes
Args:
env (simpy.environment): a Simpy environment for simulation
num_cashiers (int): number of cashiers
num_servers (int): number of servers
num_ushers (int): number of ushers
"""
self.env = env
self.cashier = simpy.Resource(env, num_cashiers)
self.server = simpy.Resource(env, num_servers)
self.usher = simpy.Resource(env, num_ushers)
def purchase_ticket(self, moviegoer):
# 1-3 minutes to buy ticket
yield self.env.timeout(random.randint(1, 3))
def check_ticket(self, moviegoer):
# 3 seconds to check ticket
yield self.env.timeout(3 / 60)
def sell_food(self, moviegoer):
# 1-5 minutes to buy food
yield self.env.timeout(random.randint(1, 5))
def go_to_movies(env, moviegoer, theater):
# Moviegoer arrives at the theater
arrival_time = env.now
with theater.cashier.request() as request:
yield request
yield env.process(theater.purchase_ticket(moviegoer))
with theater.usher.request() as request:
yield request
yield env.process(theater.check_ticket(moviegoer))
if random.choice([True, False]):
with theater.server.request() as request:
yield request
yield env.process(theater.sell_food(moviegoer))
# Moviegoer heads into the theater
global wait_times
global number_ppl
wait_times += (env.now - arrival_time)
number_ppl += 1
def run_theater(env, num_cashiers, num_servers, num_ushers):
theater = Theater(env, num_cashiers, num_servers, num_ushers)
# initial 3 movie goers
for moviegoer in range(1):
env.process(go_to_movies(env, moviegoer, theater))
while True:
yield env.timeout(.2) # Wait a bit before generating a new person
moviegoer += 1
env.process(go_to_movies(env, moviegoer, theater))
def oneSimRun(state):
"""Takes a state for number of chasiers, servers and ushers and runs a
hour and a half sim and returns the score
Args:
state (tuple(int)): holds state for number of cashiers, servers and
ushers respectfully.
Returns:
float: the sum of the ratios avg_waitime/max_weight_time and cost/budget
"""
global wait_times
global number_ppl
wait_times = 0
number_ppl = 0
num_cashiers, num_servers, num_ushers = state
env = simpy.Environment()
env.process(run_theater(env, num_cashiers, num_servers, num_ushers))
env.run(until=90)
total_cost = num_servers + num_cashiers + num_ushers
wait_score = (wait_times/number_ppl)/10
print
cost_score = total_cost/20
if wait_score > 1:
wait_score += 100
if cost_score > 1:
cost_score += 100
return wait_score + cost_score