LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
tut15_bound_analysis.m
1% Example 15: Bound analysis with SolverBA
2%
3% A bounding solver answers a different question from SolverMVA. Instead of a
4% single point estimate it returns one guaranteed side of an interval, and the
5% .lower/.upper pair of a family brackets the exact solution. Bounds need only
6% the service demands and the population, never the service distributions, so
7% they are cheap enough to sit inside an optimization loop where a full solve
8% would be too slow.
9%
10% The model is a closed network with a think Delay and two Queues of unequal
11% speed, so that the bottleneck is well defined.
12
13%% Block 1: model
14N = 5; % number of jobs in the closed chain
15model = Network('BoundsDemo');
16delay = Delay(model,'Think');
17q1 = Queue(model,'Q1', SchedStrategy.PS);
18q2 = Queue(model,'Q2', SchedStrategy.PS);
19jobs = ClosedClass(model,'C', N, delay);
20delay.setService(jobs, Exp(1/2)); % think time Z = 2
21q1.setService(jobs, Exp(1/1.0)); % demand D1 = 1.0
22q2.setService(jobs, Exp(1/1.5)); % demand D2 = 1.5 (bottleneck)
23model.link(Network.serialRouting(delay,q1,q2));
24
25%% Block 2: the exact reference
26% The throughput at the reference station is the system throughput of the
27% closed chain, and is what every bound below brackets.
28Xexact = MVA(model,'method','exact').getAvgTable().Tput(1);
29
30%% Block 3: the bounds table
31% getBoundsTable is the counterpart of getAvgTable: it reports the bracket per
32% station and class, with columns Qlower/Qupper and Tlower/Tupper. A single
33% call evaluates both sides of the family of the selected method.
34gbTable = SolverBA(model,'method','gb.upper').getBoundsTable()
35
36%% Block 4: comparing families
37% getBounds is the programmatic accessor, returning the raw bracket rather
38% than a formatted table. aba uses only the bottleneck demand and the total
39% demand and is the crudest; bjb and gb exploit more structure. Which family
40% is sharpest is model dependent, so it is worth comparing several.
41fprintf('\n%-6s %12s %12s %12s\n','family','Tlower','Texact','Tupper');
42for family = {'aba','bjb','gb'}
43 b = SolverBA(model,'method',[family{1} '.upper']).getBounds();
44 fprintf('%-6s %12.6f %12.6f %12.6f\n', family{1}, ...
45 b.Tlower(1), Xexact, b.Tupper(1));
46end
47
48%% Block 5: a bound hierarchy tightening with the level option
49% Hierarchical families are parameterized by options.level: raising it spends
50% more work and returns a tighter pair. The Eager-Sevcik hierarchy pbh becomes
51% exact once the level reaches the population, so the bracket width falls to
52% zero at level N.
53fprintf('\n%-6s %12s %12s %12s\n','level','Tlower','Tupper','width');
54for level = 1:N
55 b = SolverBA(model,'method','pbh.upper','level',level).getBounds();
56 fprintf('%-6d %12.6f %12.6f %12.6f\n', level, ...
57 b.Tlower(1), b.Tupper(1), b.Tupper(1)-b.Tlower(1));
58end
59
60%% Block 6: one-sided families
61% Not every family is two-sided. cub is upper-only and mbjb and ldbcmp are
62% lower-only, so the missing side is reported as NaN rather than as zero,
63% which keeps "no bound" distinguishable from "the bound is zero".
64cubTable = SolverBA(model,'method','cub.upper').getBoundsTable()
65
66% listValidMethods reports every method name the solver accepts. Some carry
67% structural restrictions beyond the feature set: sb and sib are delay-free,
68% and lr additionally requires a single-server single-class closed model, so
69% on the model above they raise an error rather than return a wrong answer.
70fprintf('SolverBA advertises %d methods.\n', ...
71 numel(SolverBA(model).listValidMethods()));
Definition Station.m:245