1function placement = warmStartPlacement(initSolver, sn)
2% PLACEMENT = WARMSTARTPLACEMENT(INITSOLVER, SN)
4% Integer job placement (nstations x nclasses) decided by
the steady-state
5% solution of an auxiliary solver.
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.
13% Only service stations (Queue/Delay) receive an initial population.
17if isa(initSolver,
'SolverCTMC')
18 placement = placementFromCtmcSteadyState(initSolver, M, K);
20 placement = placementFromMeanQLen(initSolver, sn, M, K);
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);
33pi(pi < GlobalConstants.Zero) = 0;
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, :);
42% Map
the aggregate-state columns (nclasses per stateful station, in station
43% order) onto
the placement matrix.
44placement = zeros(M, K);
46for i = 1:snc.nstations
47 ind = snc.stationToNode(i);
48 if ~snc.isstateful(ind)
51 isService = snc.nodetype(ind) == NodeType.Queue || snc.nodetype(ind) == NodeType.Delay;
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);
70 isClosed = isfinite(njobs);
73 eligible = false(1, M);
75 ind = sn.stationToNode(i);
76 eligible(i) = sn.nodetype(ind) == NodeType.Queue || sn.nodetype(ind) == NodeType.Delay;
83 fracs(i) = m - floors(i);
87 placement(i, r) = floors(i);
90 % Largest-remainder apportionment of
the residual jobs.
91 residual = round(njobs) - sum(floors);
93 [bf, bi] = max(fracs);
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);
101 placement(refStation, r) = placement(refStation, r) + residual;
105 placement(bi, r) = placement(bi, r) + 1;
107 residual = residual - 1;