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] = ISThe 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] = 10The 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/5For 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)