LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
mapqn_solution.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_API_MAPQN_MAPQN_SOLUTION_H
6#define LINE_API_MAPQN_MAPQN_SOLUTION_H
7
8/**
9 * @file
10 * @ingroup api_mapqn
11 * The result of a MAPQN linear or nonlinear bound program.
12 *
13 * Templated port of jar/src/main/java/jline/api/mapqn/Mapqn_solution.java and
14 * the native Python `MapqnSolution`. The QRF bound models write their answers
15 * into a NAME-KEYED variable table rather than into a fixed struct, because the
16 * variable set depends on the model that was built -- a linear-reduction bound
17 * carries per-phase utilizations `U_i_k`, a queue-recursive one carries the
18 * aggregate `U_i`, and the MVA-shaped variant writes `UN_i_k` / `QN_i_k`. This
19 * class is the accessor layer over that table, so a caller does not have to know
20 * which spelling the model it ran happens to use.
21 *
22 * THE `e_i_k` FALLBACK IS NOT A GUESS. Some solvers name the per-phase
23 * utilization variable `e_i_k` rather than `U_i_k`; the JAR's phase-indexed
24 * getter falls back to it and Python's does not, which means the same solution
25 * table reads as zero in one codebase and as the utilization in the other. The
26 * JAR's behaviour is kept here, since a zero utilization is indistinguishable
27 * from "the model did not write one" and silently understates every bound
28 * derived from it.
29 *
30 * A MISSING VARIABLE READS AS ZERO, in both references. That is a deliberate
31 * convention of the bound models -- a variable the model did not create is a
32 * quantity it does not constrain -- and not an error path.
33 *
34 * ARITHMETIC: field. Pure table lookup.
35 */
36
37#include <map>
38#include <string>
39
40#include "line/num/number.h"
41
42namespace line {
43namespace mapqn {
44
45/** Objective value and the name-keyed variable table of one bound program. */
46template <class T>
49 std::map<std::string, T> variables;
50
51 /** The named variable, or zero when the model did not create it. */
52 T get_variable(const std::string& name) const {
53 typename std::map<std::string, T>::const_iterator it = variables.find(name);
54 return it == variables.end() ? num_traits<T>::from_int(0) : it->second;
55 }
56
57 /** Aggregate utilization of queue i (1-based), as the QR models write it. */
58 T get_utilization(int i) const { return get_variable("U_" + std::to_string(i)); }
59
60 /** Per-phase utilization, with the `e_i_k` spelling as the fallback. */
61 T get_utilization(int i, int k) const {
62 const T u = get_variable("U_" + std::to_string(i) + "_" + std::to_string(k));
63 if (!(u == num_traits<T>::from_int(0))) return u;
64 return get_variable("e_" + std::to_string(i) + "_" + std::to_string(k));
65 }
66
67 /** Aggregate mean queue length of queue i (1-based). */
68 T get_queue_length(int i) const { return get_variable("Q_" + std::to_string(i)); }
69
70 /** Per-phase mean queue length, as the LR model writes it. */
71 T get_queue_length(int i, int k) const {
72 return get_variable("Q_" + std::to_string(i) + "_" + std::to_string(k));
73 }
74
75 /** The MVA-shaped variant's spellings (Mapqn_bnd_lr_mva). */
76 T get_utilization_mva(int i, int k) const {
77 return get_variable("UN_" + std::to_string(i) + "_" + std::to_string(k));
78 }
79 T get_queue_length_mva(int i, int k) const {
80 return get_variable("QN_" + std::to_string(i) + "_" + std::to_string(k));
81 }
82};
83
84} // namespace mapqn
85} // namespace line
86
87#endif // LINE_API_MAPQN_MAPQN_SOLUTION_H
Number-type abstraction for the templated API port.
Objective value and the name-keyed variable table of one bound program.
T get_queue_length(int i) const
Aggregate mean queue length of queue i (1-based).
T get_queue_length_mva(int i, int k) const
T get_utilization_mva(int i, int k) const
The MVA-shaped variant's spellings (Mapqn_bnd_lr_mva).
T get_queue_length(int i, int k) const
Per-phase mean queue length, as the LR model writes it.
T get_variable(const std::string &name) const
The named variable, or zero when the model did not create it.
T get_utilization(int i) const
Aggregate utilization of queue i (1-based), as the QR models write it.
T get_utilization(int i, int k) const
Per-phase utilization, with the e_i_k spelling as the fallback.
std::map< std::string, T > variables