1function [Q,U,R,T,C,X,lG] = solver_nc_lcfsqn(sn, options, lcfsStat, lcfsprStat)
2% [Q,U,R,T,C,X,LG] = SOLVER_NC_LCFSQN(SN, OPTIONS, LCFSSTAT, LCFSPRSTAT)
3% Specialized NC solver
for LCFS + LCFS-PR 2-station networks
5% This function wraps
the pfqn_lcfsqn_ca algorithm and computes performance
6% metrics
using the convolution approach.
9% sn - network structure
10% options - solver options
11% lcfsStat - index of
the LCFS station
12% lcfsprStat - index of
the LCFS-PR station
15% Q - queue length matrix (stations x classes)
16% U - utilization matrix (stations x classes)
17% R - response time matrix (stations x classes)
18% T - throughput matrix (stations x classes)
19% C - cycle time vector (1 x classes)
20% X - throughput vector (1 x classes)
21% lG - log of normalizing constant
23% Copyright (c) 2012-2026, Imperial College London
30% Extract service times
for each class at each station
31% alpha(r) = mean service time at LCFS station
for class r
32% beta(r) = mean service time at LCFS-PR station
for class r
39 % Service rate at station
for class r
40 mu_lcfs = rates(lcfsStat, r);
41 mu_lcfspr = rates(lcfsprStat, r);
43 if mu_lcfs <= 0 || ~isfinite(mu_lcfs)
44 line_error(mfilename, sprintf(
'Invalid service rate at LCFS station for class %d.', r));
46 if mu_lcfspr <= 0 || ~isfinite(mu_lcfspr)
47 line_error(mfilename, sprintf(
'Invalid service rate at LCFS-PR station for class %d.', r));
50 alpha(r) = 1 / mu_lcfs;
51 beta(r) = 1 / mu_lcfspr;
55% Get population vector
59% Call
the LCFS convolution algorithm to get normalizing constant
60[G, ~] = pfqn_lcfsqn_ca(alpha, beta, N);
62% Compute log normalizing constant
69% Initialize output matrices
74% Compute throughputs and queue lengths
for each class
75% Based on
the approach in lcfsqn_perf.m
76% The permanent formulas assume one job per
class (K single-job classes);
77% classes with multiplicity N(r) > 1 are expanded into N(r) exchangeable
78% single-job copies, with G_exp = G * prod_r N(r)!
the distinguishable-jobs
79% normalizing constant, and per-copy metrics are scaled back by N(r).
81alphaE = repelem(alpha, N);
82betaE = repelem(beta, N);
83Gexp = G * prod(factorial(N));
84ecls = 1 + cumsum([0, N(1:end-1)]); % first expanded copy of each class
90 % throughput using permanent calculations
91 Tx = make_Tx(alphaE, betaE, xt, K, K, e);
92 Tcopy = Tcopy + alphaE(e)^(xt-1) * perm(Tx) / Gexp;
93 % queue length at station 1 (LCFS)
94 Yx = make_Yx(alphaE, betaE, xt, K, K, e);
95 Qcopy = Qcopy + perm(Yx) / Gexp;
97 T_lcfs(1:2,r) = N(r) * Tcopy;
98 Q_lcfs(1,r) = N(r) * Qcopy;
99 % Queue length at station 2 (LCFS-PR) by conservation
100 Q_lcfs(2,r) = njobs(r) - Q_lcfs(1,r);
104% Compute utilizations
108 U_lcfs(i,r) = T_lcfs(i,r) * alpha(r);
110 U_lcfs(i,r) = T_lcfs(i,r) * beta(r);
115% Map results back to LINE format
116% Initialize output matrices for all stations
125Q(lcfsStat, :) = Q_lcfs(1, :);
126Q(lcfsprStat, :) = Q_lcfs(2, :);
129U(lcfsStat, :) = U_lcfs(1, :);
130U(lcfsprStat, :) = U_lcfs(2, :);
132% Throughput is the same at all stations in a closed network
136 T(lcfsStat, r) = T_lcfs(1,r);
137 T(lcfsprStat, r) = T_lcfs(2,r);
141% Compute response times: R = Q / T (using Little's Law)
142for k = [lcfsStat, lcfsprStat]
145 R_resp(k, r) = Q(k, r) / T(k, r);
150% Compute cycle times: C = sum of response times at all stations
153 C(r) = R_resp(lcfsStat, r) + R_resp(lcfsprStat, r);
157% Return R_resp in variable R (overriding function parameter)
162function Tx = make_Tx(alpha, beta, xt, K, R, r)
163% Make Tx matrix
for throughput computation
164% alpha : vector of length R
165% beta : vector of length R
167% K : total population
168% R : number of classes
169% r :
class index to exclude
172 Tx = sym(zeros(K-1, K-1));
174 Tx = zeros(K-1, K-1);
182 Tx(idx, j) = alpha(i)^j;
185 Tx(idx, xt-1+j) = alpha(i)^(xt+j-1) * beta(i);
191function Y = make_Yx(alpha, beta, xt, K, R, r)
192% Make Yx matrix
for queue length computation
193% alpha : vector of length R
194% beta : vector of length R
196% K : total population
197% R : number of classes
201 Y = sym(zeros(K, K));
208 Y(i, j) = alpha(i)^j;
212 Y(i, xt+j) = alpha(i)^(xt+j-1) * beta(i);