2% Example: Multiclass closed queueing network with LCFS and LCFS-PR scheduling
4% This example demonstrates a 2-station closed queueing network where:
5% - Station 1: LCFS (Last-Come-First-Served, non-preemptive)
6% - Station 2: LCFS-PR (LCFS with Preemption-Resume)
9% G. Casale,
"A family of multiclass LCFS queueing networks with
10% order-dependent product-form solutions", QUESTA 2026.
12% Copyright (c) 2012-2026, Imperial College London
15%% Define service rates
16% mu(i,r) = service rate at station i
for class r
17mu = 1./[1, 3, 5; 2, 4, 6]; % 2 stations x 3
classes
18R = size(mu, 2); % number of
classes
20%% Create the network model
21model = Network(
'LCFS Multiclass Model');
24node{1} = Queue(model,
'Queue1', SchedStrategy.LCFS);
25node{2} = Queue(model,
'Queue2', SchedStrategy.LCFSPR);
27% Create job
classes (one job per
class)
29 jobclass{r} = ClosedClass(model, sprintf(
'Class%d', r), 1, node{1}, 0);
32% Set service times (exponential distributions)
34 node{1}.setService(
jobclass{r}, Exp(mu(1, r)));
35 node{2}.setService(
jobclass{r}, Exp(mu(2, r)));
38% Set up routing: jobs alternate between the two queues
39P = model.initRoutingMatrix;
41 P{r, r} = [0, 1; 1, 0]; % Queue1 -> Queue2 -> Queue1
46fprintf(
'Solving LCFS+LCFS-PR network with MVA...\n');
47solver_mva = MVA(model,
'method',
'exact');
48AvgTable_MVA = solver_mva.getAvgTable();
52%% Solve with CTMC
for validation
53fprintf(
'\nSolving with CTMC for validation...\n');
54solver_ctmc = CTMC(model);
55AvgTable_CTMC = solver_ctmc.getAvgTable();
60fprintf(
'\n=== Comparison ===\n');
61fprintf(
'Metric\t\t\tMVA\t\tCTMC\t\tDiff\n');
62fprintf(
'------\t\t\t---\t\t----\t\t----\n');
64% Compare queue lengths
68 q_mva = AvgTable_MVA.QLen(idx);
69 q_ctmc = AvgTable_CTMC.QLen(idx);
70 diff = abs(q_mva - q_ctmc);
71 fprintf(
'Q(%d,%d)\t\t\t%.6f\t%.6f\t%.2e\n', k, r, q_mva, q_ctmc, diff);
81 u_mva = AvgTable_MVA.Util(idx);
82 u_ctmc = AvgTable_CTMC.Util(idx);
83 diff = abs(u_mva - u_ctmc);
84 fprintf(
'U(%d,%d)\t\t\t%.6f\t%.6f\t%.2e\n', k, r, u_mva, u_ctmc, diff);
94 t_mva = AvgTable_MVA.Tput(idx);
95 t_ctmc = AvgTable_CTMC.Tput(idx);
96 diff = abs(t_mva - t_ctmc);
97 fprintf(
'T(%d,%d)\t\t\t%.6f\t%.6f\t%.2e\n', k, r, t_mva, t_ctmc, diff);
101%% Verify results match within tolerance
103qlen_match = all(abs(AvgTable_MVA.QLen - AvgTable_CTMC.QLen) < tol);
104util_match = all(abs(AvgTable_MVA.Util - AvgTable_CTMC.Util) < tol);
105tput_match = all(abs(AvgTable_MVA.Tput - AvgTable_CTMC.Tput) < tol);
107fprintf(
'\n=== Validation ===\n');
108if qlen_match && util_match && tput_match
109 fprintf(
'SUCCESS: MVA and CTMC results match within tolerance %.0e\n', tol);
111 fprintf(
'WARNING: Results differ beyond tolerance %.0e\n', tol);
113 fprintf(
' - Queue lengths do not match\n');
116 fprintf(
' - Utilizations do not match\n');
119 fprintf(
' - Throughputs do not match\n');