LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
solver_ba_spnlp.h
Go to the documentation of this file.
1
#pragma once
2
/**
3
* @file solver_ba_spnlp.h
4
* @ingroup line_solvers
5
* @brief Linear-programming bounds on the mean marking and the throughputs of a
6
* stochastic timed Petri net.
7
*
8
* Port of `matlab/src/solvers/BA/solver_ba_spnlp_analyzer.m`. The polytope and
9
* the LP are `spn::spn_lpbnd`; this analyzer maps the LINE model onto them
10
* and reads one side of the bracket back per place.
11
*
12
* METHOD NAMES. Four, in two families: `spnlp.upper` and `spnlp.lower` are the
13
* Markovian LP and need exponential firing times; `spnlp.op.upper` and
14
* `spnlp.op.lower` drop the second-moment, covariance and Little's-law families
15
* and the whole E[X_p e_t] block with them, which is what removes the
16
* exponential requirement and admits any phase-type law. The operational pair
17
* is much looser, and is the reference's own "without Markovian assumption"
18
* column.
19
*
20
* BOUND CONVENTION. Q(i,0) is the reported side of the bracket on the mean
21
* number of tokens in place i. Tp(i,0) is the same side of the bracket on the
22
* token throughput of that place, and R follows by Little's law from the two.
23
* U(i,0) = Q(i,0) DELIBERATELY: a Place is an INF station and LINE reports
24
* U = Q at an infinite server, which is what SolverCTMC and
25
* `solver_nc_spn_analyzer` both do on the same net. The reference's place
26
* utilization 1 - P(m = 0) is a different quantity and is not this column.
27
*
28
* SINGLE CLASS ONLY, and column 0 is the only one written, matching
29
* `solver_nc_spn.h`: `spn_lpbnd` puts one level per place because
30
* `NetworkStruct::transparam` carries no class dimension, and refuses a
31
* coloured net rather than collapse it. The MATLAB, JAR and python twins carry
32
* the class axis and do not have this restriction.
33
*
34
* A TRANSITION GETS NO ROW. It is a stateful node and not a station, so it has
35
* no station index; the mode throughputs and enabling probabilities the LP also
36
* brackets stay inside `spn_lpbnd`'s return value, the same way `spn_metrics`
37
* keeps mode_tput and mode_util off the table.
38
*
39
* HOW TIGHT. The reference's own Table 2 measures it on a four-server
40
* production line: the upper side lands 2% to 11% above simulation and the
41
* lower side 30% to 40% below it, both comfortably inside the operational
42
* bounds it also reports. Expect a usable upper bound and a weak lower one.
43
*
44
* Reference: Z. Liu (1998). Performance analysis of stochastic timed Petri nets
45
* using linear programming approach. IEEE Transactions on Software Engineering
46
* 24(11), 1014-1030.
47
*/
48
49
#include <cstddef>
50
#include <string>
51
52
#include "
line/api/spn/spn_lpbnd.h
"
53
#include "
line/lang/qn/network_struct.h
"
54
#include "
line/solvers/ba/solver_ba_analyzer.h
"
55
#include "
line/util/error.h
"
56
57
namespace
line
{
58
namespace
ba
{
59
60
/** Whether a resolved method name belongs to the Petri-net LP family. */
61
inline
bool
is_spnlp_method
(
const
std::string& method) {
62
return
method.rfind(
"spnlp"
, 0) == 0;
63
}
64
65
/**
66
* Moment-relaxation LP bounds for a stochastic Petri net.
67
*
68
* @param L the refreshed struct of a net holding Places and Transitions
69
* @param opt the method; every other gate belongs to `spn_lpbnd`
70
*/
71
template
<
class
T>
72
BaSolution<T>
solver_ba_spnlp_analyzer
(
const
qn::NetworkStruct<T>
& L,
const
BaOptions
&
opt
) {
73
const
T zero =
num_traits<T>::from_int
(0);
74
const
std::size_t M = L.
nstations
, K = L.
nclasses
;
75
76
BaSolution<T>
s;
77
s.
Q
=
Matrix<T>
(M, K, zero);
78
s.
U
=
Matrix<T>
(M, K, zero);
79
s.
R
=
Matrix<T>
(M, K, zero);
80
s.
Tp
=
Matrix<T>
(M, K, zero);
81
s.
C
.assign(K, zero);
82
s.
X
.assign(K, zero);
83
s.
iter
= 1;
84
85
bool
markovian;
86
bool
upper;
87
if
(
opt
.method ==
"spnlp.upper"
) {
88
markovian =
true
;
89
upper =
true
;
90
}
else
if
(
opt
.method ==
"spnlp.lower"
) {
91
markovian =
true
;
92
upper =
false
;
93
}
else
if
(
opt
.method ==
"spnlp.op.upper"
) {
94
markovian =
false
;
95
upper =
true
;
96
}
else
if
(
opt
.method ==
"spnlp.op.lower"
) {
97
markovian =
false
;
98
upper =
false
;
99
}
else
{
100
throw
UnsupportedError
(
"solver_ba_spnlp_analyzer: unknown SPN bound method '"
+
101
opt
.method +
102
"'. Valid: spnlp.upper, spnlp.lower, spnlp.op.upper, "
103
"spnlp.op.lower"
);
104
}
105
106
// ---- model gates ----
107
// Every other check belongs to `spn_lpbnd`, which refuses by name on the
108
// mode it cannot represent. What must be decided here is only whether this
109
// is a Petri net at all, and whether the places carry an embedded queue the
110
// relaxation has no variable for.
111
bool
hasTransition =
false
;
112
for
(std::size_t i = 0; i < L.
nodes
.size() && !hasTransition; ++i)
113
hasTransition = L.
nodes
[i].nodetype ==
lang::NodeType::Transition
;
114
if
(!hasTransition)
115
throw
UnsupportedError
(
"solver_ba_spnlp_analyzer: method '"
+
opt
.method +
116
"' bounds a stochastic Petri net; this model has no Transition "
117
"node. Use the queueing-network bound families"
);
118
for
(std::size_t i = 0; i < L.
nodes
.size(); ++i) {
119
if
(L.
nodes
[i].nodetype !=
lang::NodeType::Place
)
continue
;
120
const
std::size_t ist = L.
nodes
[i].station;
121
if
(ist >= 1 && ist <= M && L.
stations
[ist - 1].sched != SchedStrategy::INF)
122
throw
UnsupportedError
(
"solver_ba_spnlp_analyzer: method '"
+
opt
.method +
123
"' does not support queueing places: place "
+ L.
nodes
[i].name +
124
" serves under a non-INF discipline, and the relaxation "
125
"carries one variable per place marking with no notion of an "
126
"embedded queue"
);
127
}
128
129
spn::SpnLpOptions
lpopt;
130
lpopt.
markovian
= markovian;
131
const
spn::SpnLpBounds
bnd =
spn::spn_lpbnd
(L, lpopt);
132
133
for
(std::size_t pp = 0; pp < bnd.
places
.size(); ++pp) {
134
const
std::size_t ist = L.
nodes
[bnd.
places
[pp] - 1].station;
135
if
(ist < 1 || ist > M)
continue
;
136
const
double
q = upper ? bnd.
tokens_hi
[pp] : bnd.
tokens_lo
[pp];
137
const
double
t = upper ? bnd.
place_tput_hi
[pp] : bnd.
place_tput_lo
[pp];
138
s.
Q
(ist - 1, 0) =
num_traits<T>::from_double
(q);
139
s.
U
(ist - 1, 0) =
num_traits<T>::from_double
(q);
140
s.
Tp
(ist - 1, 0) =
num_traits<T>::from_double
(t);
141
if
(t > 0) s.
R
(ist - 1, 0) =
num_traits<T>::from_double
(q / t);
142
}
143
144
if
(!L.
classes
.empty()) {
145
const
std::size_t ref = L.
classes
[0].refstat;
146
if
(ref >= 1 && ref <= M) s.
X
[0] = s.
Tp
(ref - 1, 0);
147
T nk = zero;
148
for
(std::size_t i = 0; i < M; ++i) nk += s.
Q
(i, 0);
149
if
(
num_traits<T>::to_double
(s.
X
[0]) > 0 &&
num_traits<T>::to_double
(nk) > 0)
150
s.
C
[0] = nk / s.
X
[0];
151
}
152
return
s;
153
}
154
155
}
// namespace ba
156
}
// namespace line
line::Matrix::Matrix
Matrix()
Definition
matrix.h:58
line::UnsupportedError::UnsupportedError
UnsupportedError(const std::string &what)
Definition
error.h:51
line::qn::NetworkStruct
A network plus its refreshed NetworkStruct.
Definition
network_struct.h:838
line::qn::NetworkStruct::nclasses
std::size_t nclasses
Definition
network_struct.h:1074
line::qn::NetworkStruct::classes
std::vector< JobClass > classes
Definition
network_struct.h:854
line::qn::NetworkStruct::stations
std::vector< Station< T > > stations
stations[k-1] is the k-th station
Definition
network_struct.h:851
line::qn::NetworkStruct::nodes
std::vector< NodeDef > nodes
every node, in creation order
Definition
network_struct.h:850
line::qn::NetworkStruct::nstations
std::size_t nstations
Definition
network_struct.h:1074
error.h
The exception types the port throws.
line::ba
Definition
solver_ba_analyzer.h:65
line::ba::solver_ba_spnlp_analyzer
BaSolution< T > solver_ba_spnlp_analyzer(const qn::NetworkStruct< T > &L, const BaOptions &opt)
Moment-relaxation LP bounds for a stochastic Petri net.
Definition
solver_ba_spnlp.h:72
line::ba::is_spnlp_method
bool is_spnlp_method(const std::string &method)
Whether a resolved method name belongs to the Petri-net LP family.
Definition
solver_ba_spnlp.h:61
line::lang::NodeType::Place
@ Place
Definition
lang_types.h:333
line::lang::NodeType::Transition
@ Transition
Definition
lang_types.h:334
line::opt
Definition
bisection_solver.h:31
line::spn::spn_lpbnd
SpnLpBounds spn_lpbnd(const qn::NetworkStruct< T > &sn, const SpnLpOptions &options=SpnLpOptions())
Bracket the mean tokens and the throughputs of a stochastic Petri net.
Definition
spn_lpbnd.h:157
line
Definition
aoi_dist2ph.h:52
network_struct.h
A queueing network and its refreshed NetworkStruct.
solver_ba_analyzer.h
Port of matlab/src/solvers/BA/solver_ba_analyzer.m, the bound-analysis handler behind SolverBA.
spn_lpbnd.h
Linear-programming bounds on the mean marking and the throughputs of a stochastic timed Petri net.
line::ba::BaOptions
The options SolverBA reads.
Definition
solver_ba_analyzer.h:70
line::ba::BaSolution
Class-level results, the [Q,U,R,T,C,X] of solver_ba_analyzer.
Definition
solver_ba_analyzer.h:104
line::ba::BaSolution::U
Matrix< T > U
Definition
solver_ba_analyzer.h:105
line::ba::BaSolution::R
Matrix< T > R
Definition
solver_ba_analyzer.h:105
line::ba::BaSolution::iter
int iter
Definition
solver_ba_analyzer.h:109
line::ba::BaSolution::C
std::vector< T > C
Definition
solver_ba_analyzer.h:106
line::ba::BaSolution::Tp
Matrix< T > Tp
Definition
solver_ba_analyzer.h:105
line::ba::BaSolution::X
std::vector< T > X
Definition
solver_ba_analyzer.h:106
line::ba::BaSolution::Q
Matrix< T > Q
Definition
solver_ba_analyzer.h:105
line::num_traits
Definition
number.h:111
line::spn::SpnLpBounds
The brackets; each vector pair holds the minimum then the maximum.
Definition
spn_lpbnd.h:121
line::spn::SpnLpBounds::place_tput_hi
std::vector< double > place_tput_hi
Definition
spn_lpbnd.h:126
line::spn::SpnLpBounds::tokens_lo
std::vector< double > tokens_lo
Definition
spn_lpbnd.h:125
line::spn::SpnLpBounds::places
std::vector< std::size_t > places
1-based node indices, in level order
Definition
spn_lpbnd.h:122
line::spn::SpnLpBounds::tokens_hi
std::vector< double > tokens_hi
Definition
spn_lpbnd.h:125
line::spn::SpnLpBounds::place_tput_lo
std::vector< double > place_tput_lo
Definition
spn_lpbnd.h:126
line::spn::SpnLpOptions
Options of the relaxation.
Definition
spn_lpbnd.h:94
line::spn::SpnLpOptions::markovian
bool markovian
true (the default) uses the second-moment, covariance and Little's law families, which need exponenti...
Definition
spn_lpbnd.h:101
include
line
solvers
ba
solver_ba_spnlp.h
Generated by
1.18.0