LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
solver_rqt.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_SOLVERS_MVA_SOLVER_RQT_H
6#define LINE_SOLVERS_MVA_SOLVER_RQT_H
7
8/**
9 * @file
10 * @ingroup line_solvers
11 * Robust Queueing Network Analyzer (RQNA) of Robust Queueing Theory, a port of
12 * matlab/src/solvers/MVA/solver_rqt.m, cross-checked against
13 * jar/src/main/java/jline/solvers/mva/handlers/Solver_rqt.java.
14 *
15 * Single-class open network of FCFS queues with Markovian routing. The
16 * stochastic primitives are replaced by polyhedral uncertainty sets and each
17 * node is analysed in isolation under a worst case. The algorithm is Section 7.2
18 * of the reference: the external streams get Gamma_a = sigma_a, the effective
19 * arrival process at each node follows from the network characterization of
20 * Theorem 10 (npfqn_traffic_rqt), the service variability parameter from the
21 * adaptation of Section 7.1 (qsys_gigk_rqt_gamma), and the system time at each
22 * node is the worst-case bound of Theorem 3 (qsys_gigk_rqt). The published step
23 * 3, path enumeration, is not needed here: LINE aggregates per-node system times
24 * into per-class response times through the visit ratios.
25 *
26 * The adaptation is regressed against simulation in heavy traffic, so accuracy
27 * degrades at low utilization: on M/M/1 the error is about 5% at rho=0.9 but over
28 * 50% at rho=0.5.
29 *
30 * REFERENCE INDEXING, REPRODUCED. Like solver_qna and solver_rqna, the reference
31 * indexes the stateful-indexed sn.rt with STATION indices, which is exact only
32 * when every stateful node is a station; that precondition is asserted.
33 *
34 * ARITHMETIC: transcendental (real exponents), so under Rational the body is
35 * discarded and RQT is refused by name, matching solver_qna and solver_rqna.
36 *
37 * Reference: C. Bandi, D. Bertsimas, N. Youssef (2015). Robust Queueing Theory.
38 * Operations Research 63(3), 676-700.
39 */
40
41#include <cmath>
42#include <cstddef>
43#include <vector>
44
52#include "line/util/error.h"
53#include "line/util/matrix.h"
54
55namespace line {
56namespace mva {
57
58template <class T>
60 if constexpr (!num_traits<T>::has_transcendental) {
61 throw UnsupportedError(
62 "solver_rqt: robust queueing theory needs transcendental arithmetic (real exponents); "
63 "rerun with --arith double or --arith real");
64 } else {
65 const T zero = num_traits<T>::from_int(0), one = num_traits<T>::from_int(1);
66 const T two = num_traits<T>::from_int(2);
67
68 // One predicate for the gate and the run: list_valid_methods asks the same
69 // question before it advertises 'rqt', so the sentence a caller reads here is
70 // the sentence that kept the row off the report.
71 {
72 const std::string rqt_reason = mva_single_class_open_reason(L, "rqt");
73 if (!rqt_reason.empty()) throw UnsupportedError(rqt_reason);
74 }
75 const std::size_t M = L.nstations;
76 for (std::size_t r = 0; r < L.nclasses; ++r)
77 if (std::isfinite(L.classes[r].population))
78 throw UnsupportedError("solver_rqt: RQT supports open networks only (no closed classes)");
79 if (L.nof_stateful() != M)
80 throw UnsupportedError(
81 "solver_rqt: the reference indexes the stateful-indexed sn.rt with station indices, "
82 "which is only correct when every stateful node is a station");
83
85 s.Q = Matrix<T>(M, 1, zero);
86 s.U = Matrix<T>(M, 1, zero);
87 s.R = Matrix<T>(M, 1, zero);
88 s.Tp = Matrix<T>(M, 1, zero);
89 s.X.assign(1, zero);
90 s.C.assign(1, zero);
91 s.method = "rqt";
92 s.iter = 1;
93
94 // Configuration: adaptation regime, exact worst case, tail coefficients.
95 std::string regime = opt.rqt_regime.empty() ? std::string("independent") : opt.rqt_regime;
96 const bool useExact = opt.rqt_exact;
97 const T alpha_a_src = num_traits<T>::from_double(opt.rqt_alpha_a > 0 ? opt.rqt_alpha_a : 2.0);
98 const T alpha_s_cfg = num_traits<T>::from_double(opt.rqt_alpha_s > 0 ? opt.rqt_alpha_s : 2.0);
99
100 // Source and queueing (incl. delay) stations.
101 std::size_t src = M;
102 std::vector<bool> isSource(M, false), schedInf(M, false);
103 for (std::size_t i = 0; i < M; ++i) {
104 isSource[i] = (L.stations[i].nodetype == qn::NodeType::Source);
105 schedInf[i] = (L.stations[i].sched == qn::SchedStrategy::INF);
106 if (isSource[i] && src == M) src = i;
107 }
108 if (src == M)
109 throw UnsupportedError("solver_rqt: RQT requires an open network with a Source station");
110 std::vector<std::size_t> qstat;
111 for (std::size_t i = 0; i < M; ++i)
112 if (!isSource[i]) qstat.push_back(i);
113 const std::size_t nq = qstat.size();
114
115 auto rtS = [&](std::size_t i, std::size_t j) -> T { return L.rt(i, j); };
116
117 // External arrival process from the Source.
118 const mam::Map<T> arvMAP = lang::dist_to_map(L.service[src][0]);
119 const T lambda_src = mam::map_lambda(arvMAP);
120 const T sigma_a_src = qsys::detail::num_sqrt(mam::map_scv(arvMAP)) / lambda_src;
121
122 // Per-node primitives.
123 std::vector<T> mu(nq, zero), sigma_s(nq, zero), lambda0(nq, zero), Gamma0(nq, zero);
124 std::vector<T> alpha0(nq, alpha_a_src), alpha_s(nq, alpha_s_cfg);
125 std::vector<std::size_t> nserv(nq, 1);
126 Matrix<T> F(nq, nq, zero);
127 for (std::size_t a = 0; a < nq; ++a) {
128 const std::size_t ia = qstat[a];
129 mu[a] = L.rates(ia, 0);
130 sigma_s[a] = qsys::detail::num_sqrt(L.scv(ia, 0)) / mu[a];
131 const double ns = num_traits<T>::to_double(L.stations[ia].nservers);
132 if (std::isfinite(ns) && ns > 0) nserv[a] = static_cast<std::size_t>(ns);
133 // the source stream reaches node a thinned by q, Theorem 6
134 const T q = rtS(src, ia);
135 lambda0[a] = T(lambda_src * q);
136 if (q > zero)
137 Gamma0[a] = sigma_a_src * qsys::detail::num_pow(T(one / q), T(one / alpha_a_src));
138 for (std::size_t b = 0; b < nq; ++b) F(a, b) = rtS(ia, qstat[b]);
139 }
140
141 // Effective arrival processes, Theorem 10.
142 const npfqn::TrafficRqt<T> eff = npfqn::npfqn_traffic_rqt(lambda0, Gamma0, alpha0, F);
143
144 // Per-node worst-case analysis.
145 for (std::size_t a = 0; a < nq; ++a) {
146 const std::size_t ia = qstat[a];
147 const T lam = eff.lambda[a];
148 s.Tp(ia, 0) = lam;
149 if (lam <= zero) continue;
150 if (schedInf[ia]) {
151 s.U(ia, 0) = T(lam / mu[a]);
152 s.Q(ia, 0) = T(lam / mu[a]);
153 s.R(ia, 0) = T(one / mu[a]);
154 continue;
155 }
156 const T kk = num_traits<T>::from_int(static_cast<int>(nserv[a]));
157 const T rho = lam / (kk * mu[a]);
158 const T Gamma_s = qsys::qsys_gigk_rqt_gamma(rho, mu[a], eff.Gamma[a], sigma_s[a], nserv[a],
159 eff.alpha[a], regime);
160 const qsys::GigkRqtResult<T> w =
161 qsys::qsys_gigk_rqt(lam, mu[a], eff.Gamma[a], Gamma_s, nserv[a], eff.alpha[a], alpha_s[a]);
162 const T Ra = useExact ? w.Sworst : w.W;
163 s.R(ia, 0) = Ra;
164 s.U(ia, 0) = rho;
165 s.Q(ia, 0) = T(lam * Ra); // Little's law, number in system
166 }
167
168 s.Tp(src, 0) = lambda_src;
169 T csum = zero;
170 for (std::size_t i = 0; i < M; ++i) csum = T(csum + s.R(i, 0));
171 s.C[0] = csum;
172 s.X[0] = lambda_src;
173 (void)two;
174 return s;
175 }
176}
177
178} // namespace mva
179} // namespace line
180
181#endif // LINE_SOLVERS_MVA_SOLVER_RQT_H
UnsupportedError(const std::string &what)
Definition error.h:51
A network plus its refreshed NetworkStruct.
std::size_t nof_stateful() const
std::vector< std::vector< Distrib< T > > > service
service[i][r], 0-based station and class; a disabled entry marks a pair never visited.
Matrix< T > rt
sn.rt and sn.rtnodes: the class-expanded routing.
std::vector< JobClass > classes
std::vector< Station< T > > stations
stations[k-1] is the k-th station
Matrix< T > rates
(nstations x nclasses) service rates and SCVs, with a PARALLEL disabled flag instead of MATLAB's NaN ...
What refreshProcessRepresentations and refreshLST compute FROM a distribution: the (D0,...
The exception types the port throws.
Markovian arrival process descriptors: stationary vectors, rate, moments, autocorrelation and the ind...
Dense matrix and non-owning view.
The option and result types every MVA analyzer shares.
mam::Map< T > dist_to_map(const Distrib< T > &d)
T map_scv(const Map< T > &m)
Squared coefficient of variation.
Definition map_moment.h:140
T map_lambda(const Map< T > &m)
Stationary arrival rate, lambda = pi D1 e.
Definition map_moment.h:79
std::string mva_single_class_open_reason(const qn::NetworkStruct< T > &L, const std::string &method)
RQNA and RQT decompose an open network into GI/G/1 queues and build one uncertainty set per flow out ...
Definition mva_types.h:178
MvaSolution< T > solver_rqt(const qn::NetworkStruct< T > &L, const MvaOptions &opt)
Definition solver_rqt.h:59
TrafficRqt< T > npfqn_traffic_rqt(const std::vector< T > &lambda0, const std::vector< T > &Gamma0, const std::vector< T > &alpha0, const Matrix< T > &F)
Effective arrival processes of a network under the Robust Queueing calculus.
GigkRqtResult< T > qsys_gigk_rqt(const T &lambda, const T &mu, const T &Gamma_a, const T &Gamma_s, std::size_t k, const T &alpha_a, const T &alpha_s)
Robust Queueing Theory (RQT) worst-case system time of a G/G/k FCFS queue.
T qsys_gigk_rqt_gamma(const T &rho, const T &mu, const T &Gamma_a, const T &sigma_s, std::size_t k, const T &alpha_a, const std::string &regime="independent")
Service variability parameter of the Robust Queueing Theory (RQT) framework.
A queueing network and its refreshed NetworkStruct.
Effective arrival processes of a network under the Robust Queueing calculus.
Robust Queueing Theory (RQT) worst-case system time of a G/G/k FCFS queue.
Service variability parameter of the Robust Queueing Theory (RQT) framework.
A MAP as the pair of matrices (D0, D1).
Definition map_moment.h:53
The options SolverMVA reads.
Definition mva_types.h:31
Class-level results, the [Q,U,R,T,C,X] of the MATLAB analyzers.
Definition mva_types.h:96
std::vector< T > X
Definition mva_types.h:98
std::vector< T > C
Definition mva_types.h:98
std::vector< T > Gamma
effective variability parameter at each node
std::vector< T > lambda
effective arrival rate at each node
std::vector< T > alpha
effective tail coefficient at each node
T W
closed-form bound on the system time (Theorem 3 / Theorem 8)
T Sworst
exact worst-case system time over the uncertainty sets