{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Modeling and Simulation in Python\n", "\n", "Milestone: Queueing theory\n", "\n", "Copyright 2017 Allen Downey\n", "\n", "License: [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0)\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# If you want the figures to appear in the notebook, \n", "# and you want to interact with them, use\n", "# %matplotlib notebook\n", "\n", "# If you want the figures to appear in the notebook, \n", "# and you don't want to interact with them, use\n", "# %matplotlib inline\n", "\n", "# If you want the figures to appear in separate windows, use\n", "# %matplotlib qt5\n", "\n", "# To switch from one to another, you have to select Kernel->Restart\n", "\n", "%matplotlib inline\n", "\n", "from modsim import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### One queue or two?\n", "\n", "This notebook presents a solution to an exercise from *Modeling and Simulation in Python*. It uses features from the first four chapters to answer a question related to queueing theory, which is the study of systems that involve waiting in lines, also known as \"queues\".\n", "\n", "Suppose you are designing the checkout area for a new store. There is room for two checkout counters and a waiting area for customers. You can make two lines, one for each counter, or one line that serves both counters.\n", "\n", "In theory, you might expect a single line to be better, but it has some practical drawbacks: in order to maintain a single line, you would have to install rope barriers, and customers might be put off by what seems to be a longer line, even if it moves faster.\n", "\n", "So you'd like to check whether the single line is really better and by how much. Simulation can help answer this question.\n", "\n", "As we did in the bikeshare model, we'll assume that a customer is equally likely to arrive during any timestep. I'll denote this probability using the Greek letter lambda, $\\lambda$, or the variable name `lam`. Since it's a new store, we don't know what the value of $\\lambda$ will be, so we'll have to consider a range of possibilities. \n", "\n", "Based on data from other stores, you know that it takes 5 minutes for a customer to check out, on average. But checkout times are highly variable: most customers take less than 5 minutes, but some take substantially more. A simple way to model this variability is to assume that when a customer is checking out, they have the same probability of finishing up during each time step. I'll denote this probability using the Greek letter mu, $\\mu$, or the variable name `mu`.\n", "\n", "If we choose $\\mu=1/5$, the average number of time steps for each checkout will be 5 minutes, which is consistent with the data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Solution**\n", "\n", "I'll start by defining a `System` object to contain the system parameters." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def make_system(lam, mu):\n", " return System(lam=lam, mu=mu,\n", " x=0, duration=8*60)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As an example, I'll set the arrival rate to one customer per 8 minutes." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
| \n", " | value | \n", "
|---|---|
| lam | \n", "0.125 | \n", "
| mu | \n", "0.200 | \n", "
| x | \n", "0.000 | \n", "
| duration | \n", "480.000 | \n", "