1function [L, W, Ca, Cd, lambda, rho, X, iter] = me_mqn(M, R, openClasses, lambda0, Ca0, N, mu, Cs,
P, c, refstat, insens, options)
2%ME_MQN Maximum Entropy algorithm
for Mixed Queueing Networks
4% Extension of
the Kouvatsos (1994) Maximum Entropy Method to mixed
5% open/closed multiclass networks. The 1994 survey notes that
the closed
6% two-stage treatment carries over to mixed networks (Section 2.3) but
7% gives no algorithm; this implementation composes
the open (Section 3.2)
8% and closed (Section 3.3) ME algorithms by product-form-style
10% 1.
the open classes are solved by
the open GE-type fixed point on
11%
the station set, ignoring
the closed classes;
12% 2.
the closed classes are solved by
the two-stage pseudo-open plus
13% convolution algorithm on servers whose capacity
is reduced by
the
14% open-class utilization, mu_c(i,r) = mu(i,r)*(1-rho_o(i));
15% 3.
the open mean queue lengths are inflated by
the closed occupancy,
16% L_o(i,r) <- L_o(i,r)*(1 + Lc(i)) at single-server stations.
17% Steps 2-3 are exact in
the BCMP product-form limit (exponential
18% services, where they reduce to
the classical mixed MVA treatment) and
19% GE-type approximations otherwise. Only single-server and infinite-
20% server stations are supported.
23% M - Number of queues (stations)
24% R - Number of job classes
25% openClasses - Logical vector [1 x R], true for open classes
26% lambda0 - External arrival rates [M x R], zero columns for closed
27% Ca0 - External arrival scv [M x R]
28% N - Class populations [1 x R], Inf for open classes
29% mu - Service rates [M x R matrix]
30% Cs - Service scv [M x R matrix]
31%
P - Routing probability matrix [M x M x R],
P(j,i,r) = p_ji,r
32% c - (optional) Servers per queue [M x 1]; Inf marks an IS
33% queue; finite values must be 1 (default: ones(M,1))
34% refstat - (optional) Reference station per closed class [1 x R]
35% options - (optional) struct with tol / maxiter / verbose fields
38% L - Mean queue lengths [M x R matrix]
39% W - Mean response times [M x R matrix], W = L ./ lambda
40% Ca - Arrival scv at each queue [M x R matrix]
41% Cd - Departure scv at each queue [M x R matrix]
42% lambda - Throughputs at each queue [M x R matrix]
43% rho - Utilizations [M x R matrix]
44% X - Class throughputs [1 x R] (arrival rates for open classes,
45% reference-station throughputs for closed classes)
46% iter - Total number of fixed-point iterations
49% D.D. Kouvatsos, "Entropy Maximisation and Queueing Network Models",
50% Annals of Operations Research, 48:63-126, 1994. Sections 3.2-3.3.
52if nargin < 10 || isempty(c)
55if nargin < 11 || isempty(refstat)
56 refstat = zeros(1, R);
58if nargin < 12 || isempty(insens)
64insens = logical(insens(:));
65if ~isfield(options, 'tol')
68if ~isfield(options, 'maxiter')
69 options.maxiter = 1000;
71if ~isfield(options, 'verbose')
72 options.verbose = false;
75openClasses = logical(openClasses(:)');
77oc = find(openClasses);
78cc = find(~openClasses);
91% Step 1: open classes by
the Section 3.2 GE-type fixed point
92rho_o = zeros(M, 1); % per-station aggregate open utilization
94 [Lo, ~, Cao, Cdo, lamo, rhoo, itero] = me_oqn(M, Ro, lambda0(:, oc), Ca0(:, oc), ...
95 mu(:, oc), Cs(:, oc),
P(:, :, oc), c, insens, options);
100 lambda(:, oc) = lamo;
104 rho_o(i) = sum(rhoo(i, :));
108 X(oc(k)) = sum(lambda0(:, oc(k)));
112% Step 2: closed classes by
the Section 3.3 algorithm on servers with
113% capacity reduced by
the open-class utilization
118 mu_c(i, :) = mu_c(i, :) * max(1 - rho_o(i), 0);
121 [Lc, Wc, Cac, Cdc, lamc, rhoc, Xc, iterc] = me_cqn(M, Rc, N(cc), mu_c, Cs(:, cc), ...
122 P(:, :, cc), c, refstat(cc), insens, options);
128 lambda(:, cc) = lamc;
130 % Closed utilizations are relative to
the reduced capacity; rescale to
131 %
the busy fraction of
the physical server
135 rho(i, cc(k)) = rhoc(i, k);
137 rho(i, cc(k)) = rhoc(i, k) * max(1 - rho_o(i), 0);
143% Step 3: inflate
the open queue lengths by
the closed occupancy at
144% single-server stations (exact in
the product-form limit) and derive
145% response times by Little's law
149 Lc_i = sum(L(i, cc));
150 L(i, oc) = L(i, oc) * (1 + Lc_i);
156 if lambda(i, oc(k)) > 0
157 W(i, oc(k)) = L(i, oc(k)) / lambda(i, oc(k));