LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
ldes_warmstart.m
1%% LDES warm start from an auxiliary solver
2% An auxiliary solver is passed to SolverLDES as an argument, its steady-state
3% distribution is computed, and that distribution decides the initial state of
4% the simulation. Since the simulation then starts (approximately) in steady
5% state, the initialization bias vanishes and no warmup samples are discarded,
6% so a target accuracy is reached with fewer simulated events (and less time)
7% than a cold-started run.
8%
9% Auxiliary-solver dispatch inside SolverLDES.initFromSolver:
10% - SolverCTMC: the exact stationary distribution over the aggregate state
11% space is computed and the initial state is its mode;
12% - any other solver (e.g. SolverMVA): the steady-state mean queue lengths
13% are rounded to a placement conserving the closed populations.
14%
15% The benchmark model is a closed NEAR-BALANCED tandem, whose job split mixes
16% slowly: the bias of the default cold start (all jobs at the reference
17% station) persists beyond what the MSER-5 transient filter can remove.
18%
19% Copyright (c) 2012-2026, Imperial College London
20% All rights reserved.
21
22N = 100;
23seeds = [23000 23001 23002];
24budgets = [10000 50000 200000];
25
26% Exact reference solution (exact MVA; the model is product-form)
27exact = SolverMVA(buildModel(N), 'method', 'exact').getAvgQLen();
28fprintf('Exact mean queue lengths: %s\n', mat2str(round(exact', 2)));
29
30% Warm-start placement, computed ONCE by passing the auxiliary solver to
31% SolverLDES; the derived options.init_sol is then reused across runs.
32T0 = tic;
33m = buildModel(N);
34proto = SolverLDES(m, SolverMVA(m, 'method', 'exact'));
35initSol = proto.options.init_sol;
36initTime = toc(T0);
37fprintf('Warm placement from SolverMVA (%.3fs): %s\n\n', initTime, mat2str(initSol));
38
39% On a small instance, SolverCTMC yields the mode of the exact stationary
40% distribution instead (feasible when the state space is small):
41mS = buildModel(20);
42protoCtmc = SolverLDES(mS, SolverCTMC(mS));
43fprintf('CTMC distribution-mode placement (N=20): %s\n\n', mat2str(protoCtmc.options.init_sol));
44
45% Compare accuracy and wall-clock time of cold vs warm starts
46fprintf('%10s %14s %14s\n', 'samples', 'COLD err/time', 'WARM err/time');
47coldTime = 0; warmTime = initTime;
48coldAt = NaN; warmAt = NaN;
49for b = budgets
50 [ce, ct] = runSet(@() buildModel(N), exact, b, seeds, []);
51 [we, wt] = runSet(@() buildModel(N), exact, b, seeds, initSol);
52 coldTime = coldTime + ct; warmTime = warmTime + wt;
53 if isnan(coldAt) && ce < 0.10, coldAt = b; end
54 if isnan(warmAt) && we < 0.10, warmAt = b; end
55 fprintf('%10d %6.2f%% %5.2fs %6.2f%% %5.2fs\n', b, 100*ce, ct, 100*we, wt);
56 if ~isnan(coldAt) && ~isnan(warmAt)
57 break
58 end
59end
60fprintf('\nSamples to reach 10%% error: COLD=%d, WARM=%d\n', coldAt, warmAt);
61
62function [err, rtime] = runSet(factory, exact, samples, seeds, initSol)
63% Average L1 relative error and total wall-clock over the seed set.
64err = 0; rtime = 0;
65for s = seeds
66 model = factory();
67 T0 = tic;
68 if isempty(initSol)
69 solver = SolverLDES(model, 'samples', samples, 'seed', s, 'verbose', false);
70 else
71 solver = SolverLDES(model, 'samples', samples, 'seed', s, 'verbose', false);
72 solver.options.init_sol = initSol;
73 solver.options.config.tranfilter = 'fixed';
74 solver.options.config.warmupfrac = 0;
75 end
76 QN = solver.getAvgQLen();
77 rtime = rtime + toc(T0);
78 err = err + sum(abs(QN - exact)) / sum(exact);
79end
80err = err / length(seeds);
81end
82
83function model = buildModel(n)
84% Closed near-balanced tandem: Think(Exp,1) -> Queue1(Exp,1.0) -> Queue2(Exp,0.98)
85model = Network('ldesWarmStart');
86think = Delay(model, 'Think');
87queue1 = Queue(model, 'Queue1', SchedStrategy.FCFS);
88queue2 = Queue(model, 'Queue2', SchedStrategy.FCFS);
89jobs = ClosedClass(model, 'Jobs', n, think);
90think.setService(jobs, Exp(1.0));
91queue1.setService(jobs, Exp(1.0));
92queue2.setService(jobs, Exp(0.98)); % near-balanced bottleneck
93P = model.initRoutingMatrix();
94P{1}(think, queue1) = 1.0;
95P{1}(queue1, queue2) = 1.0;
96P{1}(queue2, think) = 1.0;
97model.link(P);
98end
Definition Station.m:245