LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
warmStartPlacement.m
1function placement = warmStartPlacement(initSolver, sn)
2% PLACEMENT = WARMSTARTPLACEMENT(INITSOLVER, SN)
3%
4% Integer job placement (nstations x nclasses) decided by the steady-state
5% solution of an auxiliary solver.
6%
7% If the auxiliary solver is a SolverCTMC, the exact stationary distribution
8% over the aggregate state space is computed and the placement is the mode of
9% that distribution (the most probable aggregate state). For any other network
10% solver, the steady-state mean queue lengths are used instead and rounded to
11% an integer placement that conserves each closed-class population.
12%
13% Only service stations (Queue/Delay) receive an initial population.
14
15M = sn.nstations;
16K = sn.nclasses;
17if isa(initSolver, 'SolverCTMC')
18 placement = placementFromCtmcSteadyState(initSolver, M, K);
19else
20 placement = placementFromMeanQLen(initSolver, sn, M, K);
21end
22end
23
24function placement = placementFromCtmcSteadyState(ctmcSolver, M, K)
25% Placement from the exact CTMC stationary distribution: solve the CTMC,
26% aggregate the stationary probabilities over the aggregate (per-station,
27% per-class job count) state space, and return the aggregate state of maximum
28% stationary probability.
29snc = ctmcSolver.getStruct();
30[Q,~,SSq,~,~,~,snc] = solver_ctmc(snc, ctmcSolver.getOptions());
31pi = ctmc_solve_reducible(Q);
32pi = pi(:);
33pi(pi < GlobalConstants.Zero) = 0;
34
35% Aggregate the stationary probability over identical aggregate states and
36% locate the mode of the aggregate distribution.
37[uRows, ~, ic] = unique(SSq, 'rows');
38aggrProb = accumarray(ic, pi);
39[~, bidx] = max(aggrProb);
40modeState = uRows(bidx, :);
41
42% Map the aggregate-state columns (nclasses per stateful station, in station
43% order) onto the placement matrix.
44placement = zeros(M, K);
45col = 1;
46for i = 1:snc.nstations
47 ind = snc.stationToNode(i);
48 if ~snc.isstateful(ind)
49 continue;
50 end
51 isService = snc.nodetype(ind) == NodeType.Queue || snc.nodetype(ind) == NodeType.Delay;
52 for r = 1:K
53 v = modeState(col);
54 col = col + 1;
55 if isService
56 placement(i, r) = v;
57 end
58 end
59end
60end
61
62function placement = placementFromMeanQLen(initSolver, sn, M, K)
63% Placement from the steady-state mean queue lengths of a generic network
64% solver: floor the per-station means and distribute the residual closed-class
65% jobs by largest remainder so each closed population is conserved.
66QN = initSolver.getAvgQLen();
67placement = zeros(M, K);
68for r = 1:K
69 njobs = sn.njobs(r);
70 isClosed = isfinite(njobs);
71 floors = zeros(1, M);
72 fracs = -ones(1, M);
73 eligible = false(1, M);
74 for i = 1:M
75 ind = sn.stationToNode(i);
76 eligible(i) = sn.nodetype(ind) == NodeType.Queue || sn.nodetype(ind) == NodeType.Delay;
77 if ~eligible(i)
78 continue;
79 end
80 m = max(0, QN(i, r));
81 if isClosed
82 floors(i) = floor(m);
83 fracs(i) = m - floors(i);
84 else
85 floors(i) = round(m);
86 end
87 placement(i, r) = floors(i);
88 end
89 if isClosed
90 % Largest-remainder apportionment of the residual jobs.
91 residual = round(njobs) - sum(floors);
92 while residual > 0
93 [bf, bi] = max(fracs);
94 if bf < 0
95 % All remainders consumed: place the leftover jobs at the
96 % reference station so the population is conserved.
97 refStation = sn.refstat(r);
98 if ~eligible(refStation)
99 refStation = find(eligible, 1);
100 end
101 placement(refStation, r) = placement(refStation, r) + residual;
102 residual = 0;
103 break;
104 end
105 placement(bi, r) = placement(bi, r) + 1;
106 fracs(bi) = -1;
107 residual = residual - 1;
108 end
109 end
110end
111end
Definition Station.m:245