MathematicaMVA is a Mathematica package implementing mean-value analysis (MVA) for closed queueing networks in Mathematica. It has been used for researching alternative MVA formulas which also have been implemented in the package.
ℹ️ For a version of this README with interactive examples open the README.nb file in Mathematica.
Load the package by using:
Get["https://github.com/svenkonings/MathematicaMVA/raw/master/QueueingNetworks.wl"]
A queueing network can be created using the QueueingNetwork
function. The QueueingNetwork
function requires a list of stations and a list of routes as arguments.
Stations are represented as a tuple of scheduling and service time. The scheduling can be either FCFS
or IS
. The service time can be a number or a variable. An FCFS station with service time s1
would be represented as {FCFS,s1}
.
Routes are represented as a tuple of the route itself and the routing probability. The route itself is a Rule
, TwoWayRule
, DirectedEdge
or UndirectedEdge
between two station indices (starting from 1). The routing probability can be a number or a variable. A route from station 1 to station 2 with routing probability r12
would be represented as {1 -> 2, r12}
.
An example queueing network would be:
network = QueueingNetwork[
{{FCFS, 10}, {IS, 100}, {FCFS, 20}, {FCFS, 120}},
{{1 -> 3, 4/5}, {1 -> 4, 1/5}, {2 -> 1, 1}, {3 -> 1, 1/2}, {3 -> 2, 1/2}, {4 -> 1, 3/4}, {4 -> 2, 1/4}}
]
Which yields the following queueing network:
We will continue to use this queueing network and refer to it as network
in the examples.
The station scheduling can be retrieved by using the Scheduling
function. The Scheduling
function requires a queueing network as argument and gives a list of schedules. An index argument can be added to retrieve the scheduling of a single station.
In[1] = Scheduling[network]
Out[1] = {FCFS, IS, FCFS, FCFS}
In[2] = Scheduling[network, 2]
Out[2] = IS
The service times can be retrieved using the ServiceTime
function. The ServiceTime
function requires a queueing network as argument and gives a list of service times. An index argument can be added to retrieve the service time of a single station.
In[1] = ServiceTime[network]
Out[1] = {10, 100, 20, 120}
In[2] = ServiceTime[network, 1]
Out[2] = 10
The routing probabilities can be retrieved using the RoutingProbability
function. The RoutingProbability
function requires a queueing network as argument and gives a matrix of routing probabilities. An index argument can be added to retrieve a list of routing probabilities originating from a single station. Another index argument can be added to retrieve the routing probability of a single route.
In[1] = RoutingProbability[network]
Out[1] = {{0, 0, 4/5, 1/5}, {1, 0, 0, 0}, {1/2, 1/2, 0, 0}, {3/4, 1/4, 0, 0}}
In[2] = RoutingProbability[network, 1]
Out[2] = {0, 0, 4/5, 1/5}
In[3] = RoutingProbability[network, 1, 3]
Out[3] = 4/5
For the next set of examples we will introduce another queueing network:
variableNetwork = QueueingNetwork[
{{FCFS, s1}, {FCFS, s2}, {FCFS, s3}},
{{1 -> 3, r13}, {2 -> 1, r21}, {2 -> 2, r22}, {3 -> 1, r31}, {3 -> 2, r32}}
]
Which yields the following network:
We will refer to this network as variableNetwork
in the examples.
The visit counts can be calculated using the VisitCount
function. The VisitCount
function requires a queueing network as argument and yields a list of visit counts. An index argument can be added to calculate the visit count of a single station.
ℹ️ VisitCount
is a Functions That Remember Values They Have Found to improve speed.
VisitCount[network] = {v1, v2, v3, v4}
In[1] = VisitCount[network]
Out[1] = {1, 9/20, 4/5, 1/5}
In[2] = VisitCount[network, 4]
Out[2] = 1/5
In[3] = VisitCount[variableNetwork]
Out[3] = {1, -(r32/(-1 + r22)), 1}
The service demands can be calculated using the ServiceDemand
function. The ServiceDemand
function requires a queueing network as argument and yields a list of service demands. An index argument can be added to calculate the service demand of a single station.
In[1] = ServiceDemand[network]
Out[1] = {10, 45, 16, 24}
In[2] = ServiceDemand[network, 1]
Out[2] = 10
In[3] = ServiceDemand[variableNetwork]
Out[3] = {s1, -((r32 s2)/(-1 + r22)), s3}
The throughput is calculated using the following formula, in a queueing network with
The throughput of the whole queueing network can be calculated using the Throughput
function. The Throughput
function requires a queueing network and the total number of customers as arguments. The result can be a number or, if there are free variables in the queueing network, an expression.
In[1] = Throughput[network, 1]
Out[1] = 1/95
In[2] = Throughput[network, 2]
Out[2] = 190/9957
In[3] = Throughput[variableNetwork, 1]
Out[3] = 1/(s1 - (r32 s2)/(-1 + r22) + s3)
The expected number of customers is calculated using the following formula, in a queueing network with
The expected number of customers can be calculated using the ExpectedNumberOfCustomers
function. The ExpectedNumberOfCustomers
function requires a queueing network and the total number of customers as arguments and yields a list of expected customer counts. An index argument can be added to calculate the expected number of customers of a single station.
In[1] = ExpectedNumberOfCustomers[network, 1]
Out[1] = {2/19, 9/19, 16/95, 24/95}
In[2] = ExpectedNumberOfCustomers[network, 2]
Out[2] = {2850/3319, 700/3319, 1184/3319, 1904/3319}
In[3] = ExpectedNumberOfCustomers[network, 1, 1]
Out[3] = 2/19
In[4] = ExpectedNumberOfCustomers[variableNetwork, 1, 1]
Out[4] = s1/(s1 - (r32 s2)/(-1 + r22) + s3)
The expected response time is calculated using the following formula, in a queueing network with
The expected response time can be calculated using the ExpectedResponseTime
function. The ExpectedResponseTime
function requires a queueing network and the total number of customers as arguments and yields a list of expected response times. An index argument can be added to calculate the expected response time of a single station.
In[1] = ExpectedResponseTime[network, 1]
Out[1] = {10, 100, 20, 120}
In[2] = ExpectedResponseTime[network, 2]
Out[2] = {210/19, 100, 444/19, 2856/19}
In[3] = ExpectedResponseTime[network, 2, 2]
Out[3] = 100
In[4] = ExpectedResponseTime[variableNetwork, 2, 2]
Out[4] = s2 (1 - (r32 s2)/((-1 + r22) (s1 - (r32 s2)/(-1 + r22) + s3)))
The expected response time per passage is calculated using the following formula, in a queueing network with
The expected response time per passage can be calculated using the ExpectedResponseTimePerPassage
function. The ExpectedResponseTimePerPassage
function requires a queueing network and the total number of customers as arguments and yields a list of expected response times per passage. An index argument can be added to calculate the expected response time per passage of a single station.
In[1] = ExpectedResponseTimePerPassage[network, 1]
Out[1] = {10, 45, 16, 24}
In[2] = ExpectedResponseTimePerPassage[network, 2]
Out[2] = {210/19, 45, 1776/95, 2856/95}
In[3] = ExpectedResponseTimePerPassage[network, 1, 2]
Out[3] = 45
In[4] = ExpectedResponseTimePerPassage[variableNetwork, 2, 2]
Out[4] = (r32 s2 (1 - (r32 s2)/((-1 + r22) (s1 - (r32 s2)/(-1 + r22) + s3))))/(-1 + r22)
For the next set of examples we will introduce another queueing network:
twoFCFSnetwork = QueueingNetwork[
{{FCFS, s1}, {FCFS, s2}},
{{1 -> 2, 1}, {2 -> 1, 1}}
]
Which yields the following network:
We will refer to this network as twoFCFSnetwork
in the examples.
The state space uses the following formula, in a queueing network with
The state space can be calculated using the StateSpace
function. The StateSpace
function requires the number of station and the total number of customers as arguments and yields the state space.
In[1] = StateSpace[3, 2]
Out[1] = {{2, 0, 0}, {0, 2, 0}, {0, 0, 2}, {1, 1, 0}, {1, 0, 1}, {0, 1, 1}}
In[2] = StateSpace[2, 3]
Out[2] = {{3, 0}, {0, 3}, {2, 1}, {1, 2}}
The following formulas have been derived for queueing networks with 2 FCFS stations and
The formulas can be applied with the ExpectedResponseTimePerPassageTwoFCFSFormula
and the ExpectedNumberOfCustomersTwoFCFSFormula
functions. There are two ways to call these functions.
The first way is by using the queueing network and the total number of customers as arguments. This applies the formula to all stations and returns a list of results. An index argument can be added to apply the formula for a single station
The second way is using the service demand of the first station (a), the service demand of the second station (b) and the total number of customers as arguments. This applies the formula to the first station.
In[1] = ExpectedNumberOfCustomersTwoFCFSFormula[twoFCFSnetwork, 1]
Out[1] = {s1/(s1 + s2), s2/(s1 + s2)}
In[2] = ExpectedNumberOfCustomersTwoFCFSFormula[twoFCFSnetwork, 2, 1]
Out[2] = (2 s1^2 + s1 s2)/(s1^2 + s1 s2 + s2^2)
In[3] = ExpectedNumberOfCustomersTwoFCFSFormula[d1, d2, 2]
Out[3] = (2 d1^2 + d1 d2)/(d1^2 + d1 d2 + d2^2)
In[4] = ExpectedResponseTimePerPassageTwoFCFSFormula[twoFCFSnetwork, 1]
Out[4] = {s1, s2}
In[5] = ExpectedResponseTimePerPassageTwoFCFSFormula[twoFCFSnetwork, 2, 2]
Out[5] = (s1 s2 + 2 s2^2)/(s1 + s2)
In[6] = ExpectedResponseTimePerPassageTwoFCFSFormula[d1, d2, 2]
Out[6] = (2 d1^2 + d1 d2)/(d1 + d2)
The following formulas have been derived for queueing networks with
The formulas can be applied with the ExpectedResponseTimePerPassageFCFSFormula
and the ExpectedNumberOfCustomersFCFSFormula
functions. There are two ways to call these functions.
The first way is by using the queueing network and the total number of customers as arguments. This applies the formula to all stations and returns a list of results. An index argument can be added to apply the formula for a single station.
The second way is using a list of service demands and the total number of customers as arguments. This applies the formula to the first station. An index argument can be added to apply the formula for a single station.
In[1] = ExpectedNumberOfCustomersFCFSFormula[twoFCFSnetwork, 1]
Out[1] = {s1/(s1 + s2), s2/(s1 + s2)}
In[2] = ExpectedNumberOfCustomersFCFSFormula[variableNetwork, 1, 2]
Out[2] = -((r32 s2)/((-1 + r22) (s1 - (r32 s2)/(-1 + r22) + s3)))
In[3] = ExpectedNumberOfCustomersFCFSFormula[{d1, d2, d3}, 1]
Out[3] = {d1/(d1 + d2 + d3), d2/(d1 + d2 + d3), d3/(d1 + d2 + d3)}
In[4] = ExpectedNumberOfCustomersFCFSFormula[{d1, d2, d3}, 1, 2]
Out[4] = d2/(d1 + d2 + d3)
In[5] = ExpectedResponseTimePerPassageFCFSFormula[twoFCFSnetwork, 1]
Out[5] = {s1, s2}
In[6] = ExpectedResponseTimePerPassageFCFSFormula[variableNetwork, 1, 2]
Out[6] = -((r32 s2)/(-1 + r22))
In[7] = ExpectedResponseTimePerPassageFCFSFormula[{d1, d2, d3}, 1]
Out[7] = {d1, d2, d3}
In[8] = ExpectedResponseTimePerPassageFCFSFormula[{d1, d2, d3}, 2, 1]
Out[8] = (2 d1^2 + d1 d2 + d1 d3)/(d1 + d2 + d3)
The following formulas for FCFS stations have been derived for queueing networks with
The formulas can be applied with the ExpectedResponseTimePerPassageFCFSAndISFormula
and the ExpectedNumberOfCustomersFCFSAndISFormula
functions. There are two ways to call these functions.
The first way is by using the queueing network and the total number of customers as arguments. This applies the formula to all stations and returns a list of results. An index argument can be added to apply the formula for a single station.
The second way is using a list of service demands, a list of station scheduling and the total number of customers as arguments. This applies the formula to the first station. An index argument can be added to apply the formula for a single station.
In[1] = ExpectedNumberOfCustomersFCFSAndISFormula[network, 1]
Out[1] = {2/19, 9/19, 16/95, 24/95}
In[2] = ExpectedResponseTimePerPassageFCFSAndISFormula[twoFCFSnetwork, 2, 1]
Out[2] = (2 s1^2 + s1 s2)/(s1 + s2)
In[3] = ExpectedNumberOfCustomersFCFSAndISFormula[{d1, d2}, {IS, FCFS}, 1]
Out[3] = {d1/(d1 + d2), d2/(d1 + d2)}
In[4] = ExpectedNumberOfCustomersFCFSAndISFormula[{d1, d2, d3}, {IS, FCFS, FCFS}, 1, 2]
Out[4] = d2/(d1 + d2 + d3)
In[5] = ExpectedResponseTimePerPassageFCFSAndISFormula[network, 1]
Out[5] = {10, 45, 16, 24}
In[6] = ExpectedResponseTimePerPassageFCFSAndISFormula[variableNetwork, 1, 2]
Out[6] = -((r32 s2)/(-1 + r22))
In[7] = ExpectedResponseTimePerPassageFCFSAndISFormula[{10, 15}, {IS, FCFS}, 4]
Out[7] = {2590/157, 7890/157}
In[8] = ExpectedResponseTimePerPassageFCFSAndISFormula[{10, 15, d3}, {IS, FCFS, IS}, 2, 2]
Out[8] = (600 + 15 d3)/(25 + d3)