######################################################################## ######################################################################## # # Queue.py # Simulate a queue where people arrive randomly with an average time of # X seconds between people and are dealt with in Y seconds on average # Use a loop with a 1 second step in the simulation # # Print the maximum wait that any one of 1000 simulated people had # Note this solution uses numpy to generate distrubibutions, you can # also "math" functions and "random" functions (import math,random) # ######################################################################## ######################################################################## X = 10 # starting value, can be adjusted Y = 7 # starting value, can be adjusted nPerson = 1000 # number of people to simulate, stop when all dealt with import numpy as np def timeToNext(beta): """Return time to next person, input is beta = 1/(average arrival rate)""" # functional form of time to next person if ac is the average arrival time # is p(t) = 1/beta * exp(- t / beta ) # where beta = beta # np.random.exponential uses scale = beta # https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.random.exponential.html ranExp = np.random.exponential(scale = beta, size=1) return int(ranExp) # note forcing integer times here to simplify def addAPerson(t,q): """ Function to add a person to the queue with average time between people = X""" # t = time added # q = your queue q.append(t) # write your function here def removeAPerson(t,q): """Function to remove a person how has been dealt with, record time they waited""" # t = time removed # q = your queue return t-q.pop(0) #time waited def arriveTimesArray(n,dt): """Return a numpy array of integers, which are the times each person will arrive""" # Make an array of the delta time between each person arriving # call the function timeToNext(dt) n times using the fromiter function in numpy # see # https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.fromiter.html deltaT = np.fromiter( (timeToNext(dt) for i in range(n)), dtype=int ) # # Then accumulate the results to get the arrival time of each person # Sometimes more than one person can arrive in each second interval # and # https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ufunc.accumulate.html return np.add.accumulate( deltaT ) def timerLoop(X,Y): """Run a loop to add and remove people as required""" arriveTimes = arriveTimesArray(nPerson,X) # queue q = [] # waied times wait = [] # nAdd = number of person already added to queue nAdd =0 t = 0 # so first time is zero leaveTime = None # nobody yet in the queue so noone can leave... while(len(q) > 0 or nAdd < nPerson) : # are there still people to add or people queuing while ( nAdd < nPerson and t == arriveTimes[nAdd] ): # t = time to add a person addAPerson(t,q) nAdd += 1 # move pointer to persons up one if( leaveTime is None ): leaveTime = t+timeToNext(Y) # can now start removing people # if we can should a person and there are people to remove while( leaveTime is not None and t == leaveTime and len(q) > 0 ): wait.append(removeAPerson(t,q)) if( len(q) > 0 ): leaveTime = t+timeToNext(Y) else: leaveTime = None # queue is empty again t += 1 # move to next second print("Max time waited was {}s average {}s".format(np.max(wait),np.mean(wait))) timerLoop(X,Y) print("\nRerun with different arrival times and processing times\ntimerLoop(10,7) # default values")