5#ifndef LINE_API_MAPQN_MAPQN_P1_COMMON_H
6#define LINE_API_MAPQN_MAPQN_P1_COMMON_H
66 MapqnP1Index(
int m,
int n,
const std::vector<int>& k,
bool with_p2)
68 cumK.assign(
static_cast<std::size_t
>(
M) + 1, 0);
69 for (
int i = 0; i <
M; ++i)
cumK[i + 1] =
cumK[i] +
K[i];
71 block =
static_cast<std::size_t
>(
N + 1) *
sumK;
83 std::size_t
pk(
int i,
int k)
const {
84 return static_cast<std::size_t
>(
cumK[i]) +
static_cast<std::size_t
>(k);
87 std::size_t
half(
int i,
int ni,
int h)
const {
88 return static_cast<std::size_t
>(
N + 1) *
static_cast<std::size_t
>(
cumK[i]) +
89 static_cast<std::size_t
>(ni) *
static_cast<std::size_t
>(
K[i]) +
90 static_cast<std::size_t
>(h);
93 std::size_t
U(
int i,
int k)
const {
return off_U +
pk(i, k); }
94 std::size_t
IT(
int i,
int k)
const {
return off_IT +
pk(i, k); }
95 std::size_t
Q(
int i,
int k)
const {
return off_Q +
pk(i, k); }
96 std::size_t
C(
int j,
int k,
int i)
const {
97 return off_C +
pk(j, k) *
static_cast<std::size_t
>(
M) +
static_cast<std::size_t
>(i);
99 std::size_t
p1(
int j,
int k,
int i,
int ni,
int h)
const {
102 std::size_t
p1c(
int j,
int k,
int i,
int ni,
int h)
const {
105 std::size_t
p2(
int j,
int nj,
int k,
int i,
int ni,
int h)
const {
126T qr_rate(
const MapqnParams<T>& p,
int i,
int j,
int k,
int h) {
127 const std::size_t ki =
static_cast<std::size_t
>(k), hi =
static_cast<std::size_t
>(h);
128 const std::size_t ii =
static_cast<std::size_t
>(i), ji =
static_cast<std::size_t
>(j);
129 if (j != i)
return T(p.r(ii, ji) * p.mu[i](ki, hi));
130 return T(p.v[i](ki, hi) + p.r(ii, ii) * p.mu[i](ki, hi));
135void p1_bounds(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
136 const T one = num_traits<T>::from_int(1);
137 const T nn = num_traits<T>::from_int(p.N);
138 for (
int i = 0; i < p.M; ++i) {
139 for (
int k = 0; k < p.K[i]; ++k) {
140 m.set_bounds(x.U(i, k), T(), one);
141 m.set_bounds(x.IT(i, k), T(), one);
142 m.set_bounds(x.Q(i, k), T(), nn);
143 for (
int t = 0; t < p.M; ++t) m.set_bounds(x.C(i, k, t), T(), nn);
144 for (
int t = 0; t < p.M; ++t) {
145 for (
int nt = 0; nt <= p.N; ++nt) {
146 for (
int h = 0; h < p.K[t]; ++h) {
147 m.set_bounds(x.p1(i, k, t, nt, h), T(), one);
148 m.set_bounds(x.p1c(i, k, t, nt, h), T(), one);
158void p1_zer1(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
159 for (
int j = 0; j < p.M; ++j)
160 for (
int k = 0; k < p.K[j]; ++k) m.fix(x.p1(j, k, j, 0, k), T());
165void p1_zer2(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
166 for (
int j = 0; j < p.M; ++j)
167 for (
int k = 0; k < p.K[j]; ++k)
168 for (
int nj = 0; nj <= p.N; ++nj)
169 for (
int h = 0; h < p.K[j]; ++h)
170 if (h != k) m.fix(x.p1(j, k, j, nj, h), T());
175void p1_zer3(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
176 for (
int j = 0; j < p.M; ++j)
177 for (
int k = 0; k < p.K[j]; ++k)
178 for (
int i = 0; i < p.M; ++i)
180 for (
int h = 0; h < p.K[i]; ++h) m.fix(x.p1(j, k, i, p.N, h), T());
185void p1_zer4(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
186 for (
int j = 0; j < p.M; ++j)
187 for (
int k = 0; k < p.K[j]; ++k)
188 for (
int nj = 1; nj <= p.N; ++nj)
189 for (
int h = 0; h < p.K[j]; ++h) m.fix(x.p1c(j, k, j, nj, h), T());
194void p1_cequ(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
195 for (
int j = 0; j < p.M; ++j) {
196 for (
int k = 0; k < p.K[j]; ++k) {
197 m.row_add_int(x.C(j, k, j), 1);
198 m.row_add_int(x.Q(j, k), -1);
206void p1_one1(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
207 for (
int j = 0; j < p.M; ++j) {
208 for (
int i = 0; i < p.M; ++i) {
209 for (
int k = 0; k < p.K[j]; ++k) {
210 for (
int h = 0; h < p.K[i]; ++h) {
211 for (
int ni = 0; ni <= p.N; ++ni) {
212 m.row_add_int(x.p1(j, k, i, ni, h), 1);
213 m.row_add_int(x.p1c(j, k, i, ni, h), 1);
224void p1_utlb(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
225 for (
int i = 0; i < p.M; ++i) {
226 for (
int k = 0; k < p.K[i]; ++k) {
227 for (
int t = 0; t < p.M; ++t) {
228 m.row_add_int(x.U(i, k), 1);
229 for (
int nt = 0; nt <= p.N; ++nt)
230 for (
int h = 0; h < p.K[t]; ++h) m.row_add_int(x.p1(i, k, t, nt, h), -1);
239void p1_utlc(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
240 for (
int i = 0; i < p.M; ++i) {
241 for (
int k = 0; k < p.K[i]; ++k) {
242 for (
int t = 0; t < p.M; ++t) {
243 m.row_add_int(x.IT(i, k), 1);
244 for (
int nt = 0; nt <= p.N; ++nt)
245 for (
int h = 0; h < p.K[t]; ++h) m.row_add_int(x.p1c(i, k, t, nt, h), -1);
254void p1_qlen(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
255 for (
int i = 0; i < p.M; ++i) {
256 for (
int k = 0; k < p.K[i]; ++k) {
257 m.row_add_int(x.Q(i, k), 1);
258 for (
int ni = 0; ni <= p.N; ++ni) m.row_add_int(x.p1(i, k, i, ni, k), -ni);
271void p1_clen(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
272 for (
int j = 0; j < p.M; ++j) {
273 for (
int k = 0; k < p.K[j]; ++k) {
274 for (
int i = 0; i < p.M; ++i) {
275 m.row_add_int(x.C(j, k, i), 1);
276 for (
int ni = 0; ni <= p.N; ++ni)
277 for (
int h = 0; h < p.K[i]; ++h) m.row_add_int(x.p1(j, k, i, ni, h), -ni);
286void p1_one(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
287 for (
int j = 0; j < p.M; ++j) {
288 for (
int k = 0; k < p.K[j]; ++k) {
289 m.row_add_int(x.U(j, k), 1);
290 m.row_add_int(x.IT(j, k), 1);
298void p1_popc(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
299 for (
int i = 0; i < p.M; ++i)
300 for (
int k = 0; k < p.K[i]; ++k) m.row_add_int(x.Q(i, k), 1);
314void p1_srvb(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
315 for (
int i = 0; i < p.M; ++i) {
316 if (p.K[i] < 2)
continue;
317 for (
int k = 0; k < p.K[i]; ++k) {
318 for (
int j = 0; j < p.M; ++j) {
319 for (
int h = 0; h < p.K[i]; ++h) {
320 m.row_add(x.U(i, k), qr_rate(p, i, j, k, h));
321 m.row_add(x.U(i, h), T(-qr_rate(p, i, j, h, k)));
331void p1_uub1(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
332 for (
int i = 0; i < p.M; ++i) {
333 for (
int k = 0; k < p.K[i]; ++k) m.row_add_int(x.U(i, k), 1);
340void p1_qub1(
const MapqnParams<T>& p,
const MapqnP1Index& x, lp::LpModel<T>& m) {
341 for (
int j = 0; j < p.M; ++j) {
342 for (
int k = 0; k < p.K[j]; ++k) {
343 m.row_add_int(x.Q(j, k), 1);
344 m.row_add_int(x.U(j, k), -p.N);
352void p1_check_objective(
const MapqnParams<T>& p,
int objective_queue,
int objective_phase) {
353 if (p.N < 1)
throw InputError(
"mapqn: N must be at least 1");
354 if (objective_queue < 0 || objective_queue >= p.M)
355 throw InputError(
"mapqn: objective_queue out of range");
356 if (objective_phase < 0 || objective_phase >= p.K[objective_queue])
357 throw InputError(
"mapqn: objective_phase out of range");
Model parameters and variable indexing shared by the mapqn QR bounds.
Number-type abstraction for the templated API port.
Templated primal simplex with Bland's rule.
std::size_t Q(int i, int k) const
std::size_t p1c(int j, int k, int i, int ni, int h) const
std::size_t half(int i, int ni, int h) const
Flat (queue, population, phase) half-index, range block.
std::size_t block
(N+1) * sumK, the pairwise half-index range
std::size_t IT(int i, int k) const
MapqnP1Index(int m, int n, const std::vector< int > &k, bool with_p2)
std::size_t C(int j, int k, int i) const
std::size_t sumK
sum_i K(i)
std::vector< int > cumK
cumK[i] = sum_{i' < i} K(i')
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
std::size_t pk(int i, int k) const
Flat (queue, phase) index, range sumK.
std::size_t p2(int j, int nj, int k, int i, int ni, int h) const