Skip to content

Instantly share code, notes, and snippets.

@djordon
Last active June 11, 2016 16:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save djordon/251fb66a385bb949a214 to your computer and use it in GitHub Desktop.
Save djordon/251fb66a385bb949a214 to your computer and use it in GitHub Desktop.
An analysis of different grocery store checkout processes.
import matplotlib.pyplot as plt
import queueing_tool as qt
import numpy as np
# Queueing parameters
a, b = 158, 50
h = 13.0
nc = 8
mu = 30.0
# Data collection variables and parameters
N = 500
w0 = np.array([])
s0 = np.zeros(N)
# Queueing process functions
rate = lambda t: a + b - b * np.cos(2 * np.pi * t / h)
arr = lambda t: qt.poisson_random_measure(t, rate, a + 2 * b)
ser = lambda t: t + np.random.exponential(1 / mu)
# The Queue
q = qt.QueueServer(nServers=nc, deactive_t=h,
arrival_f=arr, service_f=ser)
for k in range(N) :
q.collect_data = True
q.set_active()
q.simulate(t=h+5)
data = q.fetch_data()
s0[k] = np.std(data[:,1] - data[:, 0])
w0 = np.hstack((w0, data[:,1] - data[:, 0]))
q.clear()
# The queueing network definition
adjacency = {
0: {1: {'edge_type': 1}},
1: {k: {'edge_type': 2} for k in range(2, 2 + nc)}
}
g = qt.adjacency2graph(adjacency, edge_type)
qclass = {1: qt.QueueServer, 2: qt.QueueServer }
qargs = {1: {'nServers': 1, 'deactive_t': h,
'arrival_f': arr,
'service_f': lambda t: t,
'AgentClass': qt.GreedyAgent},
2: {'nServers': 1,
'service_f': ser}}
qn = qt.QueueNetwork(adjacency, q_classes=qclass, q_args=qargs)
w1 = np.array([])
s1 = np.zeros(N)
for k in range(N) :
qn.start_collecting_data(eType=2)
qn.initialize(eType=1)
qn.simulate(t=h+5)
data = qn.data_queues(eType=2)
good = data[:,1] > 0
s1[k] = np.std(data[good, 1] - data[good, 0])
w1 = np.hstack( (w1, data[good,1] - data[good, 0]) )
qn.clear()
# Transform from hours to minutes
w0 = w0 * 60
s0 = s0 * 60
w1 = w1 * 60
s1 = s1 * 60
plt.style.use('ggplot')
## Waiting time plots
fig, ax = plt.subplots(2, 1, dpi=80, figsize=(10,14))
n, bins, patches = ax[1].hist(w1, bins=50, range=(0, 40), normed=True)
n, bins, patches = ax[0].hist(w0, bins=bins, normed=True)
ylim = max(ax[0].get_ylim()[1], ax[1].get_ylim()[1])
out = ax[1].axvline(np.mean(w1), linestyle='--')
out = ax[1].set_title('Traditional checkout')
out = ax[1].set_xlabel('Waiting times (in minutes)')
out = ax[1].set_ylabel('Percentage of customers')
out = ax[1].set_ylim((0, ylim))
out = ax[1].text(np.mean(w1) + max(w1) / 100.0, 0.5 * ylim,
'Mean of {0}'.format(round(np.mean(w1), 1)) )
out = ax[0].axvline(np.mean(w0), linestyle='--')
out = ax[0].set_title("Trader Joe's checkout")
out = ax[0].set_xlabel('Waiting times (in minutes)')
out = ax[0].set_ylabel('Percentage of customers')
out = ax[0].set_ylim((0, ylim))
out = ax[0].text(np.mean(w0) + max(w0) / 100.0, 0.5 * ylim,
'Mean of {0}'.format(round(np.mean(w0), 1)) )
plt.savefig('waiting_times_both_systems.png', dpi=80,
bbox_inches='tight', transparent=True)
#plt.show()
## Waiting time standard deviation plots
fig, ax = plt.subplots(2, 1, dpi=80, figsize=(10,14))
n, bins, patches = ax[1].hist(s1, bins=35, normed=True)
n, bins, patches = ax[0].hist(s0, bins=bins, normed=True)
ylim = max(ax[0].get_ylim()[1], ax[1].get_ylim()[1])
out = ax[1].axvline(np.mean(s1), linestyle='--')
out = ax[1].set_title('Traditional checkout')
out = ax[1].set_xlabel('Standard deviations of waiting times')
out = ax[1].set_ylabel('Percentage of observations')
out = ax[1].set_ylim((0, ylim))
out = ax[1].text(np.mean(s1) + max(s1) / 100.0, 0.95 * ylim,
'Mean of {0}'.format(round(np.mean(s1), 1)) )
out = ax[0].axvline(np.mean(s0), linestyle='--')
out = ax[0].set_title("Trader Joe's checkout")
out = ax[0].set_xlabel('Standard deviation of waiting times')
out = ax[0].set_ylabel('Percentage of observations')
out = ax[0].set_ylim((0, ylim))
out = ax[0].text(np.mean(s0) + max(s0) / 100.0, 0.95 * ylim,
'Mean of {0}'.format(round(np.mean(s0), 1)) )
plt.savefig('waiting_time_std_both_systems.png', dpi=80,
bbox_inches='tight', transparent=True)
#plt.show()
# For better display purposes
qn.g.new_vertex_property('pos')
pos = {}
for v in qn.g.nodes() :
if v == 0 :
pos[v] = [0, 1]
elif v == 1 :
pos[v] = [0, 0.5]
else :
pos[v] = [-3.5 + (v - 2.0), 0]
qn.draw(fname="store.png", figsize=(16, 3.5), pos=pos)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment