The purpose of the package queuecomputer is to compute, deterministically, the output of a queue network given the arrival and service times for all customers. The most important functions are queue_step
, lag_step
and wait_step
.
The first argument to the functions queue_step
, lag_step
and wait_step
is a dataframe with a column of unique customer IDs labelled ‘ID’ and a column of arrival times labelled ‘times’. For example:
library(queuecomputer)
arrivals <- data.frame(ID = c(1:100), times = cumsum(rexp(100)))
head(arrivals)
## ID times
## 1 1 0.3199780
## 2 2 0.4630498
## 3 3 0.7251302
## 4 4 0.8995766
## 5 5 0.9654777
## 6 6 1.8800708
service <- rexp(100)
departures <- queue_step(arrival_df = arrivals, service = service)
head(departures)
## ID times
## 1 1 0.580407
## 2 2 4.037948
## 3 3 4.622707
## 4 4 5.465278
## 5 5 6.134305
## 6 6 7.953326
The resourcing schedule is specified with either a non-zero natural number, a server.stepfun
or a server.list
object. Use a non-zero natural number when the number of servers does not change over time. The server.stepfun
specifies a step function to indicate how many servers are available throughout the day. The computation speed for queue_step()
is much faster when using a server.stepfun
rather than a server.list
input for the servers
argument.
We create a server.stepfun
object with the as.server.stepfun
function.
# Zero servers available before time 10
# One server available between time 10 and time 50
# Three servers available between time 50 and time 100
# One server available from time 100 onwards
resource_schedule <- as.server.stepfun(c(10,50,100), c(0, 1, 3, 1))
resource_schedule
## $x
## [1] 10 50 100
##
## $y
## [1] 0 1 3 1
##
## attr(,"class")
## [1] "list" "server.stepfun"
departures <- queue_step(arrival_df = arrivals, service = service, servers = resource_schedule)
head(departures)
## ID times
## 1 1 10.26043
## 2 2 13.71797
## 3 3 14.30273
## 4 4 15.14530
## 5 5 15.81433
## 6 6 17.63335
The server.list
object is a list of step functions which represent each server, the range is \(\{0,1\}\), where 0 represents unavailable and 1 represents available and the knots represent the times where availability changes.
The as.server.list
function is used to create a server.list
object.
# Server 1 is available before time 10.
# Server 2 is available between time 15 and time 30.
# Server 3 is available after time 10.
as.server.list(list(10, c(15,30), 10), c(1,0,0))
## [[1]]
## Step function
## Call: stats::stepfun(times[[i]], y)
## x[1:1] = 10
## 2 plateau levels = 1, 0
##
## [[2]]
## Step function
## Call: stats::stepfun(times[[i]], y)
## x[1:2] = 15, 30
## 3 plateau levels = 0, 1, 0
##
## [[3]]
## Step function
## Call: stats::stepfun(times[[i]], y)
## x[1:1] = 10
## 2 plateau levels = 0, 1
##
## attr(,"class")
## [1] "list" "server.list"
It is simple to set up a chain of queueing elements with queuecomputer
. Suppose passengers must walk to a queue, then wait for service and then wait for their bags.
library(ggplot2)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
set.seed(500)
arrivals <- data.frame(ID = c(1:100), times = cumsum(rexp(100)))
service_l <- rexp(100, 0.8)
service_q <- rexp(100, 0.5)
arrivals_b <- data.frame(ID = c(1:100), times = cumsum(rexp(100, 0.8)))
# The queue elements can be computed one by one.
departures_1 <- lag_step(arrivals, service_l)
departures_2 <- queue_step(departures_1, service = service_q, servers = 2)
departures_3 <- wait_step(departures_2, arrivals_b$times)
departure_df <- data.frame(arrival_times = arrivals$times, departures_1 = departures_1$times, departures_2 = departures_2$times, departures_3 = departures_3$times) %>% reshape2::melt()
## No id variables; using all as measure variables
qplot(value, data = departure_df, colour = variable, geom = "density") + xlab("time")
# The queue elements can be chained together with the %>% operator.
departures <- lag_step(arrivals, service_l) %>% queue_step(service = service_q, servers = 2) %>% wait_step(arrivals_b$times)
all(departures$times == departures_3$times)
## [1] TRUE