5#ifndef LINE_API_MAPQN_MAPQN_BND_LR_H
6#define LINE_API_MAPQN_MAPQN_BND_LR_H
98 for (
int j = 0; j < p.
M; ++j) {
99 for (
int k = 0; k < p.
K[j]; ++k) {
100 for (
int i = 0; i < p.
M; ++i) m.
row_add_int(x.
C(j, k, i), 1);
116 for (
int j = 0; j < p.
M; ++j) {
117 for (
int k = 0; k < p.
K[j]; ++k) {
118 for (
int i = 0; i < p.
M; ++i) {
119 for (
int h = 0; h < p.
K[i]; ++h) {
120 if (!((j < i) || (j == i && k < h)))
continue;
121 for (
int ni = 1; ni <= p.
N; ++ni) m.
row_add_int(x.
p1(j, k, i, ni, h), 1);
122 for (
int nj = 1; nj <= p.
N; ++nj) m.
row_add_int(x.
p1(i, h, j, nj, k), -1);
137 for (
int i = 0; i < p.
M; ++i) {
138 for (
int u = 0; u < p.
K[i]; ++u) {
139 for (
int j = 0; j < p.
M; ++j) {
140 if (j == i)
continue;
141 for (
int k = 0; k < p.
K[j]; ++k)
142 for (
int h = 0; h < p.
K[j]; ++h)
143 m.
row_add(x.
p1(j, k, i, 0, u), qr_rate(p, j, i, k, h));
144 for (
int k = 0; k < p.
K[i]; ++k)
145 m.
row_add(x.
p1(i, k, i, 1, k), T(-qr_rate(p, i, j, k, u)));
162 for (
int i = 0; i < p.
M; ++i) {
163 for (
int ni = 0; ni <= p.
N - 1; ++ni) {
164 for (
int j = 0; j < p.
M; ++j) {
165 if (j == i)
continue;
166 for (
int k = 0; k < p.
K[j]; ++k)
167 for (
int h = 0; h < p.
K[j]; ++h)
168 for (
int u = 0; u < p.
K[i]; ++u)
169 m.
row_add(x.
p1(j, k, i, ni, u), qr_rate(p, j, i, k, h));
170 for (
int k = 0; k < p.
K[i]; ++k)
171 for (
int h = 0; h < p.
K[i]; ++h)
172 m.
row_add(x.
p1(i, k, i, ni + 1, k), T(-qr_rate(p, i, j, k, h)));
188 for (
int i = 0; i < p.
M; ++i) {
189 for (
int j = 0; j < p.
M; ++j) {
190 if (j == i)
continue;
191 for (
int k = 0; k < p.
K[i]; ++k)
192 for (
int h = 0; h < p.
K[i]; ++h)
193 m.
row_add(x.
U(i, k), qr_rate(p, i, j, k, h));
194 for (
int k = 0; k < p.
K[j]; ++k) {
195 for (
int h = 0; h < p.
K[j]; ++h) {
196 const T w = qr_rate(p, j, i, k, h);
197 for (
int u = 0; u < p.
K[i]; ++u)
198 for (
int nj = 1; nj <= p.
N; ++nj)
200 for (
int u = 0; u < p.
K[i]; ++u) m.
row_add(x.
p1(j, k, i, 0, u), T(-w));
223 detail::p1_check_objective(p, objective_queue, objective_phase);
227 detail::p1_bounds(p, x, m);
232 detail::p1_zer1(p, x, m);
233 detail::p1_zer2(p, x, m);
234 detail::p1_zer3(p, x, m);
235 detail::p1_zer4(p, x, m);
236 detail::p1_cequ(p, x, m);
237 detail::p1_one1(p, x, m);
238 detail::p1_utlb(p, x, m);
239 detail::p1_utlc(p, x, m);
240 detail::p1_qlen(p, x, m);
241 detail::p1_clen(p, x, m);
242 detail::p1_one(p, x, m);
243 detail::p1_popc(p, x, m);
244 detail::lr_mpcb(p, x, m);
245 detail::p1_srvb(p, x, m);
246 detail::lr_ujnt(p, x, m);
247 detail::lr_gffl0(p, x, m);
248 detail::lr_gffl(p, x, m);
249 detail::lr_qbal(p, x, m);
250 detail::p1_uub1(p, x, m);
251 detail::p1_qub1(p, x, m);
266 if (!out.
ok)
return out;
268 std::size_t maxK = 0;
269 for (
int i = 0; i < p.
M; ++i)
270 if (
static_cast<std::size_t
>(p.
K[i]) > maxK) maxK =
static_cast<std::size_t
>(p.
K[i]);
271 out.
U =
Matrix<T>(
static_cast<std::size_t
>(p.
M), maxK);
272 out.
IT =
Matrix<T>(
static_cast<std::size_t
>(p.
M), maxK);
273 out.
Q =
Matrix<T>(
static_cast<std::size_t
>(p.
M), maxK);
274 for (
int i = 0; i < p.
M; ++i) {
275 for (
int k = 0; k < p.
K[i]; ++k) {
276 const std::size_t ii =
static_cast<std::size_t
>(i), kk =
static_cast<std::size_t
>(k);
277 out.
U(ii, kk) = sol.
x[x.
U(i, k)];
278 out.
IT(ii, kk) = sol.
x[x.
IT(i, k)];
279 out.
Q(ii, kk) = sol.
x[x.
Q(i, k)];
Sparse LP in the natural form, with per-variable bounds.
void set_maximize(bool m)
true to maximize c'x (the default), false to minimize.
std::size_t num_rows() const
void emit_eq_int(long rhs)
void row_add_int(std::size_t j, long v)
void set_cost(std::size_t j, const T &v)
std::size_t num_vars() const
void row_add(std::size_t j, const T &v)
row(j) += v, the accumulation the MATLAB reference performs.
The exception types the port throws.
The variable layout and the constraint families shared by the two reductions that carry singly-indexe...
Model parameters and variable indexing shared by the mapqn QR bounds.
Dense matrix and non-owning view.
const char * lp_status_name(LpStatus s)
LpSolution< T > simplex_solve(const LpModel< T > &model, std::size_t max_iterations=0)
Solve the model.
MapqnBndLrResult< T > mapqn_bnd_lr(const MapqnParams< T > &p, int objective_queue, int objective_phase, MapqnSense sense=MapqnSense::Max)
Bound U(objective_queue, objective_phase) over the linear-reduction polytope.
MapqnSense
Which direction the bound is taken in.
MapqnP1Index LrIndex
Variable layout of the LR model: the shared p1-level blocks and nothing else.
Number-type abstraction for the templated API port.
Templated primal simplex with Bland's rule.
T objective
c'x, in the sense requested (max or min)
std::vector< T > x
primal solution in the ORIGINAL variable space
Result of a general LR bound solve.
Matrix< T > IT
M x max(K) idle times, 0 beyond K(i).
Matrix< T > U
M x max(K) utilizations, 0 beyond K(i).
std::string status
textual LP status
T objective
the bound on U(objective_queue, objective_phase)
Matrix< T > Q
M x max(K) mean queue lengths, 0 beyond K(i).
std::vector< T > x
full solution vector, indexed by LrIndex
bool ok
the LP reached an optimal vertex
Variable layout of the p1-level models.
std::size_t Q(int i, int k) const
std::size_t IT(int i, int k) const
std::size_t C(int j, int k, int i) const
std::size_t p1(int j, int k, int i, int ni, int h) const
std::size_t U(int i, int k) const
std::size_t num_vars() const
Parameters of a MAP queueing network for the QR bounds.
std::vector< int > K
K[i] = number of phases at queue i.