LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_mva_bound_analyzer.m
1function [Q,U,R,T,C,X,lG,runtime,iter] = solver_mva_bound_analyzer(sn, options)
2% [Q,U,R,T,C,X,LG,RUNTIME,ITER] = SOLVER_MVA_BOUND_ANALYZER(QN, OPTIONS)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7T0=tic;
8iter = 1;
9Q = []; U = [];
10R = []; T = [];
11C = []; X = [];
12lG = NaN;
13
14line_debug('MVA bound analyzer starting: method=%s, nclasses=%d, njobs=%s', options.method, sn.nclasses, mat2str(sn.njobs));
15
16switch options.method
17 case 'aba.upper'
18 line_debug('Using ABA upper bound');
19 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
20 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
21 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
22 end
23 V = sn.visits{1}(:);
24 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
25 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
26 Dmax = max(D);
27 N = sn.nclosedjobs;
28 C(1,1) = Z + N * sum(D);
29 X(1,1) = min( 1/Dmax, N / (Z + sum(D)));
30 T(:,1) = V .* X(1,1);
31 R(:,1) = 1 ./ sn.rates * N;
32 R(sn.sched == SchedStrategy.INF,1) = 1 ./ sn.rates(sn.sched == SchedStrategy.INF,1);
33 Q(:,1) = T(:,1) .* R(:,1);
34 U(:,1) = T(:,1) ./ sn.rates;
35 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
36 lG = - N*log(X(1,1)); % approx
37 end
38 runtime=toc(T0);
39 case 'aba.lower'
40 line_debug('Using ABA lower bound');
41 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
42 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
43 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
44 end
45 V = sn.visits{1}(:);
46 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
47 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
48 N = sn.nclosedjobs;
49 X(1,1) = N / (Z + N*sum(D));
50 C(1,1) = Z + sum(D);
51 T(:,1) = V .* X(1,1);
52 R(:,1) = 1 ./ sn.rates;
53 Q(:,1) = T(:,1) .* R(:,1);
54 U(:,1) = T(:,1) ./ sn.rates;
55 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
56 lG = - N*log(X(1,1)); % approx
57 end
58 runtime=toc(T0);
59 case 'bjb.upper'
60 line_debug('Using BJB upper bound');
61 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
62 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
63 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
64 end
65 V = sn.visits{1}(:);
66 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
67 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
68 Dmax = max(D);
69 N = sn.nclosedjobs;
70 Xaba_upper_1 = min( 1/Dmax, (N-1) / (Z + sum(D)));
71 Xaba_lower_1 = (N-1) / (Z + (N-1)*sum(D));
72 C(1,1) = (Z+sum(D)+max(D)*(N-1-Z*Xaba_lower_1));
73 X(1,1) = min(1/Dmax, N / (Z+sum(D)+mean(D)*(N-1-Z*Xaba_upper_1)));
74 T(:,1) = V .* X(1,1);
75 % RN undefined in the literature so we use ABA upper
76 R(:,1) = 1 ./ sn.rates * N;
77 %RN = 0*TN;
78 %RN(sn.sched ~= SchedStrategy.INF,1) = NaN * D+ max(D) ./ V(sn.sched ~= SchedStrategy.INF) .* (N-1-Z*Xaba_lower_1) / (sn.nstations - sum(sn.sched == SchedStrategy.INF));
79 R(sn.sched == SchedStrategy.INF,1) = 1 ./ sn.rates(sn.sched == SchedStrategy.INF,1);
80 Q(:,1) = T(:,1) .* R(:,1);
81 U(:,1) = T(:,1) ./ sn.rates;
82 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
83 lG = - N*log(X(1,1)); % approx
84 end
85 runtime=toc(T0);
86 case 'bjb.lower'
87 line_debug('Using BJB lower bound');
88 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
89 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
90 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
91 end
92 V = sn.visits{1}(:);
93 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
94 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
95 Dmax = max(D);
96 N = sn.nclosedjobs;
97 Xaba_upper_1 = min( 1/Dmax, (N-1) / (Z + sum(D)));
98 Xaba_lower_1 = (N-1) / (Z + (N-1)*sum(D));
99 C(1,1) = (Z+sum(D)+mean(D)*(N-1-Z*Xaba_upper_1));
100 X(1,1) = N / (Z+sum(D)+max(D)*(N-1-Z*Xaba_lower_1));
101 T(:,1) = V .* X(1,1);
102 % RN undefined in the literature so we use ABA lower
103 R(:,1) = 1 ./ sn.rates;
104 %RN = 0*TN;
105 %RN(sn.sched ~= SchedStrategy.INF,1) = NaN * 1 ./ sn.rates(sn.sched ~= SchedStrategy.INF,1) + mean(D) ./ V(sn.sched ~= SchedStrategy.INF) .* (N-1-Z*Xaba_upper_1) / (sn.nstations - sum(sn.sched == SchedStrategy.INF));
106 R(sn.sched == SchedStrategy.INF,1) = 1 ./ sn.rates(sn.sched == SchedStrategy.INF,1);
107 Q(:,1) = T(:,1) .* R(:,1);
108 U(:,1) = T(:,1) ./ sn.rates;
109 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
110 lG = - N*log(X(1,1)); % approx
111 end
112 runtime=toc(T0);
113 case 'pb.upper'
114 line_debug('Using PB upper bound');
115 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
116 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
117 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
118 end
119 V = sn.visits{1}(:);
120 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
121 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
122 Dmax = max(D);
123 N = sn.nclosedjobs;
124 Xaba_upper_1 = min( 1/Dmax, (N-1) / (Z + sum(D)));
125 Xaba_lower_1 = (N-1) / (Z + (N-1)*sum(D));
126 Dpb2 = sum(D.^2)/sum(D);
127 DpbN = sum(D.^N)/sum(D.^(N-1));
128 C(1,1) = (Z+sum(D)+DpbN*(N-1-Z*Xaba_lower_1));
129 X(1,1) = min(1/Dmax, N / (Z+sum(D)+Dpb2*(N-1-Z*Xaba_upper_1)));
130 T(:,1) = V .* X(1,1);
131 % RN undefined in the literature so we use ABA upper
132 R(:,1) = 1 ./ sn.rates * N;
133 %RN = 0*TN;
134 %RN(sn.sched ~= SchedStrategy.INF,1) = NaN * 1 ./ sn.rates(sn.sched ~= SchedStrategy.INF,1) + (D.^N/sum(D.^(N-1))) ./ V(sn.sched ~= SchedStrategy.INF) * (N-1-Z*Xaba_upper_1);
135 R(sn.sched == SchedStrategy.INF,1) = 1 ./ sn.rates(sn.sched == SchedStrategy.INF,1);
136 Q(:,1) = T(:,1) .* R(:,1);
137 U(:,1) = T(:,1) ./ sn.rates;
138 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
139 lG = - N*log(X(1,1)); % approx
140 end
141 runtime=toc(T0);
142 case 'pb.lower'
143 line_debug('Using PB lower bound');
144 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
145 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
146 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
147 end
148 V = sn.visits{1}(:);
149 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
150 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
151 Dmax = max(D);
152 N = sn.nclosedjobs;
153 Xaba_upper_1 = min( 1/Dmax, (N-1) / (Z + sum(D)));
154 Xaba_lower_1 = (N-1) / (Z + (N-1)*sum(D));
155 Dpb2 = sum(D.^2)/sum(D);
156 DpbN = sum(D.^N)/sum(D.^(N-1));
157 C(1,1) = (Z+sum(D)+Dpb2*(N-1-Z*Xaba_upper_1));
158 X(1,1) = N / (Z+sum(D)+DpbN*(N-1-Z*Xaba_lower_1));
159 T(:,1) = V .* X(1,1);
160 % RN undefined in the literature so we use ABA lower
161 R(:,1) = 1 ./ sn.rates;
162 %RN = 0*TN;
163 %RN(sn.sched ~= SchedStrategy.INF,1) = NaN * 1 ./ sn.rates(sn.sched ~= SchedStrategy.INF,1) + (D.^2/sum(D)) ./ V(sn.sched ~= SchedStrategy.INF) * (N-1-Z*Xaba_upper_1);
164 R(sn.sched == SchedStrategy.INF,1) = 1 ./ sn.rates(sn.sched == SchedStrategy.INF,1);
165 Q(:,1) = T(:,1) .* R(:,1);
166 U(:,1) = T(:,1) ./ sn.rates;
167 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
168 lG = - N*log(X(1,1)); % approx
169 end
170 runtime=toc(T0);
171 case 'sb.upper'
172 line_debug('Using SB upper bound');
173 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
174 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
175 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
176 end
177 if any(sn.sched == SchedStrategy.INF)
178 line_error(mfilename,'Unsupported method for a model with infinite-server stations.');
179 end
180 V = sn.visits{1}(:);
181 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
182 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
183 N = sn.nclosedjobs;
184 A3 = sum(D.^3);
185 A2 = sum(D.^2);
186 A1 = sum(D);
187 Dmax = max(D);
188 C(1,1) = Z+A1+(N-1)*(A1*A2+A3)/(A1^2+A2);
189 X(1,1) = min([1/Dmax,N / (Z+A1+(N-1)*(A1*A2+A3)/(A1^2+A2))]);
190 T(:,1) = V .* X(1,1);
191 % RN undefined in the literature so we use ABA lower
192 R(:,1) = 1 ./ sn.rates;
193 %RN = 0*TN;
194 %RN(sn.sched ~= SchedStrategy.INF,1) = NaN * 1 ./ sn.rates(sn.sched ~= SchedStrategy.INF,1) + (D.^2/sum(D)) ./ V(sn.sched ~= SchedStrategy.INF) * (N-1-Z*Xaba_upper_1);
195 R(sn.sched == SchedStrategy.INF,1) = 1 ./ sn.rates(sn.sched == SchedStrategy.INF,1);
196 Q(:,1) = T(:,1) .* R(:,1);
197 U(:,1) = T(:,1) ./ sn.rates;
198 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
199 lG = - N*log(X(1,1)); % approx
200 end
201 runtime=toc(T0);
202 case 'sb.lower'
203 line_debug('Using SB lower bound');
204 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
205 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
206 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
207 end
208 if any(sn.sched == SchedStrategy.INF)
209 line_error(mfilename,'Unsupported method for a model with infinite-server stations.');
210 end
211 V = sn.visits{1}(:);
212 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
213 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
214 N = sn.nclosedjobs;
215 AN = sum(D.^N);
216 A1 = sum(D);
217 C(1,1) = Z+A1+(N-1)*(AN/A1)^(1/(N-1));
218 X(1,1) = N / (Z+A1+(N-1)*(AN/A1)^(1/(N-1)));
219 T(:,1) = V .* X(1,1);
220 % RN undefined in the literature so we use ABA lower
221 R(:,1) = 1 ./ sn.rates;
222 %RN = 0*TN;
223 %RN(sn.sched ~= SchedStrategy.INF,1) = NaN * 1 ./ sn.rates(sn.sched ~= SchedStrategy.INF,1) + (D.^2/sum(D)) ./ V(sn.sched ~= SchedStrategy.INF) * (N-1-Z*Xaba_upper_1);
224 R(sn.sched == SchedStrategy.INF,1) = 1 ./ sn.rates(sn.sched == SchedStrategy.INF,1);
225 Q(:,1) = T(:,1) .* R(:,1);
226 U(:,1) = T(:,1) ./ sn.rates;
227 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
228 lG = - N*log(X(1,1)); % approx
229 end
230 runtime=toc(T0);
231 case 'gb.upper'
232 line_debug('Using GB upper bound');
233 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
234 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
235 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
236 end
237 V = sn.visits{1}(:);
238 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
239 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
240 N = sn.nclosedjobs;
241 Dmax = max(D);
242 X(1,1) = min(1/Dmax, pfqn_xzgsbup(D,N,Z));
243 C(1,1) = N / pfqn_xzgsblow(D,N,Z);
244 T(:,1) = V .* X(1,1);
245 XNlow = pfqn_xzgsblow(D,N,Z);
246 k = 0;
247 for i=1:sn.nstations
248 if sn.sched(i) == SchedStrategy.INF
249 R(i,1) = 1 / sn.rates(i);
250 Q(i,1) = X(1,1) * R(i,1);
251 else
252 k = k + 1;
253 Q(i,1) = pfqn_qzgbup(D,N,Z,k);
254 R(i,1) = Q(i,1) / XNlow / V(i) ;
255 end
256 end
257 R(sn.sched == SchedStrategy.INF,1) = 1 ./ sn.rates(sn.sched == SchedStrategy.INF,1);
258 U(:,1) = T(:,1) ./ sn.rates;
259 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
260 lG = - N*log(X(1,1)); % approx
261 end
262 runtime=toc(T0);
263 case 'gb.lower'
264 line_debug('Using GB lower bound');
265 if sn.nclasses==1 && sn.nclosedjobs >0 % closed single-class queueing network
266 if any(sn.nservers(sn.sched ~= SchedStrategy.INF)>1)
267 line_error(mfilename,'Unsupported method for a model with multi-server stations.');
268 end
269 V = sn.visits{1}(:);
270 Z = sum(V(sn.sched == SchedStrategy.INF) ./ sn.rates(sn.sched == SchedStrategy.INF));
271 D = V(sn.sched ~= SchedStrategy.INF) ./ sn.rates(sn.sched ~= SchedStrategy.INF);
272 N = sn.nclosedjobs;
273 X(1,1) = pfqn_xzgsblow(D,N,Z);
274 C(1,1) = N / pfqn_xzgsbup(D,N,Z);
275 T(:,1) = V .* X(1,1);
276 XNup = pfqn_xzgsbup(D,N,Z);
277 k = 0;
278 for i=1:sn.nstations
279 if sn.sched(i) == SchedStrategy.INF
280 R(i,1) = 1 / sn.rates(i);
281 Q(i,1) = X(1,1) * R(i,1);
282 else
283 k = k + 1;
284 Q(i,1) = pfqn_qzgblow(D,N,Z,k);
285 R(i,1) = Q(i,1) / XNup / V(i) ;
286 end
287 end
288 U(:,1) = T(:,1) ./ sn.rates;
289 U((sn.sched == SchedStrategy.INF),1) = Q((sn.sched == SchedStrategy.INF),1);
290 lG = - N*log(X(1,1)); % approx
291 end
292 runtime=toc(T0);
293end
294end