5#ifndef LINE_SOLVERS_CTMC_SOLVER_CTMC_FCR_H
6#define LINE_SOLVERS_CTMC_SOLVER_CTMC_FCR_H
58 for (std::size_t f = 0; f <
sn.regions.size(); ++f)
59 for (std::size_t r = 0; r <
sn.regions[f].rule.size(); ++r) {
61 if (d == DropStrategy::DROP)
continue;
62 const char* nm = d == DropStrategy::WAITQ ?
"WAITQ"
63 : d == DropStrategy::BAS ?
"BAS"
64 : d == DropStrategy::BBS ?
"BBS"
65 : d == DropStrategy::RSRD ?
"RSRD"
68 std::string(
"SolverCTMC: finite capacity region ") + std::to_string(f + 1) +
69 " applies " + nm +
" to class " + std::to_string(r + 1) +
70 ", which augments the state with a per-region waiting queue (WAITQ) or a held-job "
71 "marker (BAS/BBS/RSRD); only DROP is ported, and it is a filter on the state "
72 "space rather than extra state");
87 const std::size_t M =
sn.stations.size(), K =
sn.nclasses;
88 for (std::size_t f = 0; f <
sn.regions.size(); ++f) {
90 double total = 0, memory = 0;
91 std::vector<double> per_class(K, 0.0);
92 double gcap = -1.0, memcap = -1.0;
93 std::vector<double> ccap(K, -1.0);
94 bool any_member =
false;
95 for (std::size_t i = 0; i < M; ++i) {
98 for (std::size_t k = 0; k < K; ++k) {
100 if (!std::isfinite(n))
continue;
107 for (std::size_t k = 0; k < K; ++k)
108 if (rg.
cap[i][k] != -1.0)
109 ccap[k] = ccap[k] == -1.0 ? rg.
cap[i][k] : std::min(ccap[k], rg.
cap[i][k]);
110 if (rg.
cap[i][K] != -1.0)
111 gcap = gcap == -1.0 ? rg.
cap[i][K] : std::min(gcap, rg.
cap[i][K]);
113 memcap = memcap == -1.0 ? rg.
maxmem[i] : std::min(memcap, rg.
maxmem[i]);
115 if (!any_member)
continue;
116 if (gcap != -1.0 && total > gcap + 1e-9)
return false;
117 if (memcap != -1.0 && memory > memcap + 1e-9)
return false;
118 for (std::size_t k = 0; k < K; ++k)
119 if (ccap[k] != -1.0 && per_class[k] > ccap[k] + 1e-9)
return false;
121 for (std::size_t row = 0; row < rg.
lincon_A.rows() && row < rg.
lincon_b.size(); ++row) {
123 for (std::size_t k = 0; k < K && k < rg.
lincon_A.cols(); ++k)
140 if (
sn.regions.empty())
return space;
143 std::vector<NetState<T>> out;
144 for (std::size_t s = 0; s < space.size(); ++s) {
145 std::vector<T> nir(A.
cols());
146 for (std::size_t c = 0; c < A.
cols(); ++c) nir[c] = A(s, c);
151 "SolverCTMC: no state satisfies the finite capacity regions; check that the region "
152 "caps admit the model's population");
166 std::vector<bool> in(
sn.stations.size(),
false);
167 for (std::size_t f = 0; f <
sn.regions.size(); ++f) {
168 bool has_drop =
false;
169 for (std::size_t r = 0; r <
sn.regions[f].rule.size(); ++r)
170 if (
sn.regions[f].rule[r] == DropStrategy::DROP) has_drop =
true;
171 if (!has_drop)
continue;
172 for (std::size_t i = 0; i < in.size() && i <
sn.regions[f].members.size(); ++i)
173 if (
sn.regions[f].members[i]) in[i] =
true;
UnsupportedError(const std::string &what)
A network plus its refreshed NetworkStruct.
The exception types the port throws.
std::vector< bool > ctmc_in_drop_region(const NetworkStruct< T > &sn)
True where a class sits at a station inside a DROP region, per station.
bool ctmc_region_admissible(const NetworkStruct< T > &sn, const std::vector< T > &nir)
True when nir – the per-(station, class) counts of one state, in (ist-1)*K + k order – satisfies ever...
std::vector< NetState< T > > ctmc_filter_regions(const NetworkStruct< T > &sn, const std::vector< NetState< T > > &space)
The states of space a DROP region admits, in their original order.
void ctmc_check_region_rules(const NetworkStruct< T > &sn)
Refuse the region rules this port does not implement.
Matrix< T > ctmc_state_space_aggr(const NetworkStruct< T > &sn, const std::vector< NetState< T > > &space)
Port of StateSpaceAggr: the per-(station, class) job counts of every state, as an (nstates x nstation...
DropStrategy
Blocking and loss rules, with the values of MATLAB DropStrategy.
A queueing network and its refreshed NetworkStruct.
Port of solver_ctmc.m: the infinitesimal generator of a queueing network, assembled from the enumerat...
Port of the MATLAB +State package: the encoding that turns a station's state row into marginal job co...
FINITE CAPACITY REGIONS, MATLAB's refreshRegions output.
std::vector< T > lincon_b
Matrix< T > lincon_A
optional linear constraint A n <= b
std::vector< std::vector< double > > cap
(nstations x nclasses+1), -1 = unbounded
std::vector< double > maxmem
per member station, -1 = unbounded
std::vector< T > size
per class; size is the memory footprint
std::vector< bool > members
membership, independent of the caps
One network state: the per-stateful-node local rows it is composed of.