Q1
Assume there are 10 operators. Simulate this system for 2 hours, and give both the percentage of customers who are “lost”, and the expected system time for customers who are serviced by operators.
In [35]:
import simpy
import numpy as np
In [36]:
def arrivals(env, res):
i = 0
while True:
yield env.timeout(-1/6*np.log(np.random.rand()))
res[‘arrivals’].append(env.now)
res[‘departures’].append(-1)
if len(res[‘op’].queue) + res[‘op’].count >= res[‘op’].capacity:
if len(res[‘op’].queue) >= 5:
res[‘lost’] += 1
i += 1
continue
if np.random.rand() < .1:
i += 1
continue
env.process(operators(env, res, i))
i += 1
def operators(env, res, i):
rqt = res['op'].request()
yield rqt
yield env.timeout(np.random.rand() + 1)
res['op'].release(rqt)
if np.random.rand() < .5:
env.process(survey(env, res, i))
else:
res['departures'][i] = env.now
def survey(env, res, i):
rqt = res['survey'].request()
yield rqt
yield env.timeout(-1/2 * np.log(np.random.rand()))
res['survey'].release(rqt)
res['departures'][i] = env.now
env = simpy.Environment()
res = {'op': simpy.Resource(env, capacity=5),
'survey': simpy.Resource(env),
'arrivals': [],
'departures': [],
'lost': 0}
env.process(arrivals(env, res))
env.run(until=120)
lost = res['lost'] / len(res['arrivals'])
arrivals = np.array(res['arrivals'])
departures = np.array(res['departures'])
arrivals = arrivals[departures > 0]
departures = departures[departures > 0]
system_time = np.mean(departures – arrivals)
print(system_time)
print(lost)
3.494364744596235
0.3865771812080537
Q2
Now, assume the survey is staffed by two people. One is very efficient, and always takes exactly 1 minute to conduct the survey. One is quite inefficient, and takes a uniform random amount of time on $[2,3]$ minutes to conduct the survey. Customers who are waiting to take the survey will be dealt with by whoever is available first; if both are available, the efficient surveyer deals with them.
Perform the same simulation as Q1, with this additional wrinkle.
In [37]:
def arrivals(env, res):
i = 0
while True:
yield env.timeout(-1/6*np.log(np.random.rand()))
res[‘arrivals’].append(env.now)
res[‘departures’].append(-1)
if len(res[‘op’].queue) + res[‘op’].count >= res[‘op’].capacity:
if len(res[‘op’].queue) >= 5:
res[‘lost’] += 1
i += 1
continue
if np.random.rand() < .1:
i += 1
continue
env.process(operators(env, res, i))
i += 1
def operators(env, res, i):
rqt = res['op'].request()
yield rqt
yield env.timeout(np.random.rand() + 1)
res['op'].release(rqt)
if np.random.rand() < .5:
env.process(survey(env, res, i))
else:
res['departures'][i] = env.now
def survey(env, res, i):
rqt1 = res['survey'][0].request()
rqt2 = res['survey'][1].request()
response = yield rqt1 | rqt2
if rqt1 in response:
rqt2.cancel()
yield env.timeout(1)
res['survey'][0].release(rqt1)
else:
yield env.timeout(np.random.rand() + 2)
res['survey'][1].release(rqt2)
res['departures'][i] = env.now
env = simpy.Environment()
res = {'op': simpy.Resource(env, capacity=5),
'survey': [simpy.Resource(env), simpy.Resource(env)],
'arrivals': [],
'departures': [],
'lost': 0}
env.process(arrivals(env, res))
env.run(until=120)
lost = res['lost'] / len(res['arrivals'])
arrival = np.array(res['arrivals'])
departure = np.array(res['departures'])
arrival = arrival[departure > 0]
departure = departure[departure > 0]
system_time = np.mean(departure – arrival)
print(system_time)
print(lost)
11.500757037998676
0.3708791208791209
Q3
Spectrum wants to minimize the number of operators staffed on the customer service line, while maintaining a bare minimum quality of service. Using the simulation from Q2, find the minimum number of operators that can be used, that keep the “lost” rate below 1 percent.
In [48]:
def simulate(N):
env = simpy.Environment()
res = {‘op’: simpy.Resource(env, capacity=N),
‘survey’: [simpy.Resource(env), simpy.Resource(env)],
‘arrivals’: [],
‘departures’: [],
‘lost’: 0}
env.process(arrivals(env, res))
env.run(until=120)
lost = res[‘lost’] / len(res[‘arrivals’])
arrival = np.array(res[‘arrivals’])
departure = np.array(res[‘departures’])
arrival = arrival[departure > 0]
departure = departure[departure > 0]
system_time = np.mean(departure – arrival)
return lost
for i in range(1, 20):
lost = simulate(i)
if lost < .01:
print(i, lost)
break
1 0.8730366492146597
2 0.7486842105263158
3 0.6202185792349727
4 0.5121951219512195
5 0.40575916230366493
6 0.299738219895288
7 0.11420204978038068
8 0.07142857142857142
9 0.03017241379310345
10 0.01585014409221902
11 0.007989347536617843
11 0.007989347536617843