LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_rqna.m
1function [Q,U,R,T,C,X,lG,totiter] = solver_rqna(sn, options)
2% [Q,U,R,T,C,X,lG,totiter] = SOLVER_RQNA(SN, OPTIONS)
3%
4% Robust Queueing Network Analyzer (RQNA) based on indices of dispersion.
5% Approximates the steady-state performance of a single-class open queueing
6% network of single-server FCFS queues with Markovian routing and general
7% (non-renewal) external arrival and (non-exponential) service processes.
8%
9% Reference: W. Whitt and W. You (2018), "A Robust Queueing Network Analyzer
10% Based on Indices of Dispersion", INFORMS J. on Computing. This routine
11% implements Algorithm 1 (general framework): traffic-rate equations, limiting
12% variability equations, time-dependent IDC equations with default correction
13% terms alpha (eq. 34) and beta (eqs. 38-39), and the robust-queueing (RQ)
14% workload approximation (eq. 13) with the derived performance measures.
15%
16% Copyright (c) 2012-2026, Imperial College London
17% All rights reserved.
18
19if sn.nclasses > 1
20 line_error(mfilename, 'RQNA supports single-class open networks only. Use the ''qna'' method for multiclass models.');
21end
22if any(isfinite(sn.njobs))
23 line_error(mfilename, 'RQNA supports open networks only (no closed classes).');
24end
25
26M = sn.nstations;
27K = sn.nclasses; % == 1
28
29Q = zeros(M,K); U = zeros(M,K); R = zeros(M,K); T = zeros(M,K);
30X = zeros(1,K); lG = NaN; totiter = 1;
31
32% ----- identify source and queueing stations -----
33isSource = false(M,1);
34schedInf = false(M,1);
35for i = 1:M
36 nd = sn.stationToNode(i);
37 isSource(i) = (sn.nodetype(nd) == NodeType.Source);
38 schedInf(i) = (sn.sched(i) == SchedStrategy.INF);
39end
40srcList = find(isSource);
41qstat = find(~isSource); % queueing (and delay) stations
42nq = numel(qstat);
43
44% single-class station-to-station routing matrix
45rtS = full(sn.rt); % (nstateful x nstateful) for single class
46
47% ----- external arrival process (from the source) -----
48if isempty(srcList)
49 line_error(mfilename, 'RQNA requires an open network with a Source station.');
50end
51src = srcList(1);
52arvMAP = sn.proc{src,1}{1};
53lambda_src = map_lambda(arvMAP);
54c2_src = map_idc(arvMAP);
55arvIdc = @(t) map_count_idc(arvMAP, t);
56
57% ----- per-queue data -----
58mu = zeros(nq,1); cs2 = zeros(nq,1);
59lambda0 = zeros(nq,1); c2a0 = zeros(nq,1);
60svcMAP = cell(nq,1);
61qsplit = zeros(nq,1); % source split prob into each queue
62P = zeros(nq,nq);
63for a = 1:nq
64 ia = qstat(a);
65 mu(a) = sn.rates(ia,1);
66 cs2(a) = sn.scv(ia,1);
67 svcMAP{a} = sn.proc{ia,1}{1};
68 qsplit(a) = rtS(src, ia);
69 lambda0(a) = lambda_src * qsplit(a);
70 for b = 1:nq
71 ib = qstat(b);
72 P(a,b) = rtS(ia, ib);
73 end
74end
75
76% external arrival IDC seen by each queue = split of the source process (eq. 31)
77% I_{a,0,b}(t) = q_b I_src(t) + (1-q_b); c2_{a,0,b} = q_b c2_src + (1-q_b)
78c2a0 = qsplit .* c2_src + (1 - qsplit);
79a0IdcFun = @(t) qsplit .* arvIdc(t) + (1 - qsplit);
80
81% service IDC vector-valued function I_{s,a}(t)
82sIdcFun = @(t) local_svc_idc(svcMAP, t);
83
84% ----- traffic variability equations (limiting + time-dependent) -----
85corrections = struct();
86if isfield(options,'config') && isstruct(options.config)
87 if isfield(options.config,'rqna_alpha'), corrections.alpha = options.config.rqna_alpha; end
88 if isfield(options.config,'rqna_beta'), corrections.beta = options.config.rqna_beta; end
89end
90ctx = npfqn_traffic_idc(lambda0, P, c2a0, a0IdcFun, mu, cs2, sIdcFun, corrections);
91lambda = ctx.lambda;
92rho = ctx.rho;
93
94% near-immediate feedback elimination is applied by default (Whitt-You
95% Algorithm 2 / Section 4.2); set options.config.rqna_feedback_elim=false for
96% the plain RQNA (Algorithm 1) without elimination.
97doElim = true;
98if isfield(options,'config') && isstruct(options.config) && isfield(options.config,'rqna_feedback_elim')
99 doElim = logical(options.config.rqna_feedback_elim);
100end
101
102% ----- per-queue robust-queueing workload and performance -----
103for a = 1:nq
104 ia = qstat(a);
105 T(ia,1) = lambda(a);
106 if lambda(a) <= 0
107 continue;
108 end
109 if schedInf(ia)
110 % infinite-server (delay) station: no waiting
111 U(ia,1) = lambda(a)/mu(a);
112 Q(ia,1) = lambda(a)/mu(a);
113 R(ia,1) = 1/mu(a);
114 continue;
115 end
116 phat = 0;
117 if doElim
118 phat = local_phat(P, rho, a);
119 end
120 if phat > options.tol
121 % ----- near-immediate feedback elimination at station a -----
122 Ra = local_elim_response(a, P, rho, lambda, mu, cs2, svcMAP, ...
123 lambda0, arvMAP, qsplit, corrections);
124 R(ia,1) = Ra;
125 else
126 IaFun_a = @(x) local_component(ctx, x, a);
127 [~, Wa] = qsys_gig1_rq(rho(a), mu(a), cs2(a), IaFun_a);
128 R(ia,1) = Wa + 1/mu(a); % per-visit response time = waiting + service
129 end
130 U(ia,1) = rho(a);
131 Q(ia,1) = lambda(a) * R(ia,1);% mean number in system (Little, incl. service)
132end
133
134% source station bookkeeping
135T(src,1) = lambda_src;
136
137C = sum(R,1);
138X(1) = lambda_src;
139Q(isnan(Q)) = 0; U(isnan(U)) = 0; R(isnan(R)) = 0; C(isnan(C)) = 0;
140end
141
142function phat = local_phat(P, rho, a)
143% Near-immediate feedback probability at station a: the probability that a
144% customer departing a returns to a before visiting any station with strictly
145% higher traffic intensity (Whitt-You [52] eq. 3.8/3.9, H={a}).
146Hc = setdiff(find(rho <= rho(a) + 1e-9), a); % equal/lower-rho cloud
147if isempty(Hc)
148 phat = P(a,a);
149 return;
150end
151F = inv(eye(numel(Hc)) - P(Hc,Hc));
152phat = P(a,a) + P(a,Hc) * F * P(Hc,a);
153end
154
155function Ra = local_elim_response(a, P, rho, lambda, mu, cs2, svcMAP, ...
156 lambda0, arvMAP, qsplit, corrections)
157% Near-immediate feedback elimination at station a (Whitt-You Algorithm 2 /
158% Corollary 4.2). Reduced network: collapse only the equal/lower-rho cloud Hc
159% to instantaneous switches (censoring, eq. 3.8), retaining the strictly
160% higher-rho stations as real queues so that the global traffic rates and the
161% arrival variability from the upstream bottleneck(s) are preserved. The
162% near-immediate self-return at a (self-loop phat in the censored network) is
163% removed by immediate-feedback elimination (Section 4.1): remove the self-loop,
164% renormalize a's remaining routing by 1/(1-phat) and replace a's service by the
165% geometric-sum service. The IDC equations are re-solved on the reduced network,
166% then RQ is applied at a with the per-visit adjustment W = (1-phat) Wtilde.
167Hc = setdiff(find(rho <= rho(a) + 1e-9), a); % equal/lower-rho cloud (switches)
168Hi = setdiff(find(rho > rho(a) + 1e-9), a); % strictly higher-rho stations
169R = [a, reshape(Hi,1,[])]; % retained stations, a first
170m = numel(R);
171if isempty(Hc)
172 Fhc = []; G = zeros(0,m); Pred = P(R,R);
173else
174 Fhc = inv(eye(numel(Hc)) - P(Hc,Hc)); % fundamental matrix of the cloud
175 G = Fhc * P(Hc,R); % first-passage Hc-station -> R
176 Pred = P(R,R) + P(R,Hc) * Fhc * P(Hc,R); % censored routing among R
177end
178phat = Pred(1,1); % near-immediate return prob at a
179phat = min(max(phat,0), 1 - 1e-9);
180
181% immediate-feedback elimination at a (position 1 in R)
182if phat > 0
183 Pred(1,:) = Pred(1,:) / (1 - phat);
184end
185Pred(1,1) = 0;
186
187% first-passage external arrival rate and IDC into each retained station
188arvIdc = @(t) map_count_idc(arvMAP, t);
189c2fun_i = @(i,t) qsplit(i)*arvIdc(t) + (1 - qsplit(i));
190lam0R = zeros(m,1);
191for rr = 1:m
192 lam0R(rr) = lambda0(R(rr));
193 for ii = 1:numel(Hc)
194 lam0R(rr) = lam0R(rr) + lambda0(Hc(ii)) * G(ii,rr);
195 end
196end
197c2a0R = zeros(m,1);
198for rr = 1:m
199 if lam0R(rr) <= 0, continue; end
200 s = lambda0(R(rr)) * (qsplit(R(rr))*map_idc(arvMAP) + (1 - qsplit(R(rr))));
201 for ii = 1:numel(Hc)
202 g = G(ii,rr);
203 ci = qsplit(Hc(ii))*map_idc(arvMAP) + (1 - qsplit(Hc(ii)));
204 s = s + lambda0(Hc(ii)) * g * (g*ci + (1-g));
205 end
206 c2a0R(rr) = s / lam0R(rr);
207end
208a0IdcR = @(t) local_fp_ext_idc_R(t, R, Hc, G, lambda0, c2fun_i, lam0R);
209
210% service data on R; station a gets the geometric-sum (folded) service
211muR = mu(R); cs2R = cs2(R);
212svcR = cell(m,1);
213for rr = 1:m, svcR{rr} = svcMAP{R(rr)}; end
214svcR{1} = local_geom_map(svcMAP{a}, phat);
215muR(1) = (1-phat) * mu(a);
216cs2R(1) = phat + (1-phat) * cs2(a);
217sIdcR = @(t) local_svc_idc(svcR, t);
218
219% re-solve the IDC equations on the reduced network and apply RQ at a
220ctxR = npfqn_traffic_idc(lam0R, Pred, c2a0R, a0IdcR, muR, cs2R, sIdcR, corrections);
221IaFunA = @(x) local_component(ctxR, x, 1);
222[~, Wt] = qsys_gig1_rq(rho(a), muR(1), cs2R(1), IaFunA);
223Ra = (1-phat) * Wt + 1/mu(a); % per-visit adjustment (mean visits 1/(1-phat))
224end
225
226function Ir = local_fp_ext_idc_R(t, R, Hc, G, lambda0, c2fun_i, lam0R)
227% First-passage external arrival IDC into each retained station of the reduced
228% network (superposition of the direct external and the cloud-entering splits).
229m = numel(R);
230Ir = ones(m,1);
231for rr = 1:m
232 if lam0R(rr) <= 0, continue; end
233 num = lambda0(R(rr)) * c2fun_i(R(rr), t);
234 for ii = 1:numel(Hc)
235 g = G(ii,rr);
236 num = num + lambda0(Hc(ii)) * g * (g*c2fun_i(Hc(ii),t) + (1-g));
237 end
238 Ir(rr) = num / lam0R(rr);
239end
240end
241
242function out = local_geom_map(map, p)
243% Geometric random sum of i.i.d. PH service times with success prob (1-p):
244% PH(alpha, T) -> PH(alpha, T + p*t0*alpha), t0 = -T*e. Yields the head-of-line
245% immediate-feedback-eliminated service (Whitt-You Section 4.1).
246D0 = map{1};
247e = ones(size(D0,1),1);
248t0 = -D0 * e;
249al = map_pie(map);
250D0m = D0 + p * (t0 * al);
251D1m = (1-p) * (t0 * al);
252out = {D0m, D1m};
253end
254
255function Is = local_svc_idc(svcMAP, t)
256% t is either a scalar time (same for all queues) or a length-nq vector giving
257% the per-queue evaluation time (service IDC evaluated at rho_a * t).
258nq = numel(svcMAP);
259Is = zeros(nq,1);
260if isscalar(t)
261 tt = repmat(t, nq, 1);
262else
263 tt = t(:);
264end
265for a = 1:nq
266 Is(a) = map_count_idc(svcMAP{a}, tt(a));
267end
268end
269
270function ia = local_component(ctx, x, a)
271v = ctx.IaFun(x);
272ia = v(a);
273end
Definition Station.m:287
Definition Station.m:245