88 "pfqn_hst reads its marginals from pfqn_rgf and needs transcendental arithmetic");
93 const std::size_t M = L.size();
94 if (M == 0)
throw InputError(
"pfqn_hst requires at least one queueing station");
96 throw InputError(
"pfqn_hst: the station index is out of range for the supplied demands");
97 if (N < 1)
throw InputError(
"pfqn_hst requires an integer population of at least one job");
100 "pfqn_hst: the requested station has zero demand, so its queue-length marginals are "
104 const std::size_t Np =
static_cast<std::size_t
>(N);
108 res.
X = exp(T(rgf.
lg[Np - 1] - rgf.
lg[Np]));
110 const T logy = log(y);
113 res.
Pgeq.assign(Np + 1, zero);
114 for (std::size_t k = 0; k <= Np; ++k)
117 res.
p.assign(Np + 1, zero);
118 for (std::size_t k = 0; k <= Np; ++k)
119 res.
p[k] = T(res.
Pgeq[k] - (k + 1 <= Np ? res.
Pgeq[k + 1] : zero));
121 res.
U = T(y * res.
X);
123 for (std::size_t k = 1; k <= Np; ++k) res.
Q += res.
Pgeq[k];
126 res.
c.assign(Np, zero);
127 for (std::size_t n = 1; n <= Np; ++n) {
128 const T Pn1 = (n + 1 <= Np) ? res.
Pgeq[n + 1] : zero;
129 res.
c[n - 1] = T(T(Pn1 / res.
U) - res.
Pgeq[n]);
132 for (std::size_t k = 0; k < Np; ++k) res.
total += (res.
c[k] < zero ? T(-res.
c[k]) : res.
c[k]);
138 std::vector<T> pp(Np);
139 for (std::size_t n = 0; n < Np; ++n) pp[n] = res.
p[n + 1];
140 std::vector<std::size_t> ord(Np);
141 std::iota(ord.begin(), ord.end(),
static_cast<std::size_t
>(0));
143 std::vector<T> ratio(Np);
144 for (std::size_t n = 0; n < Np; ++n) ratio[n] = T(res.
c[n] / (pp[n] > tiny ? pp[n] : tiny));
145 std::stable_sort(ord.begin(), ord.end(),
146 [&ratio](std::size_t a, std::size_t b) { return ratio[b] < ratio[a]; });
149 std::vector<T> astar(Np, zero);
150 for (std::size_t k = 0; k <= Np; ++k) {
151 std::vector<T> a(Np, T(-one));
152 for (std::size_t t = 0; t < k; ++t) a[ord[t]] = one;
153 for (std::size_t piv = 0; piv < Np; ++piv) {
154 if (pp[piv] <= zero)
continue;
155 std::vector<T> aa = a;
157 for (std::size_t n = 0; n < Np; ++n) rest += pp[n] * aa[n];
158 rest -= pp[piv] * aa[piv];
159 const T v = T(-rest / pp[piv]);
160 if (v < T(-one) || v > one)
continue;
163 for (std::size_t n = 0; n < Np; ++n) obj += res.
c[n] * aa[n];
164 const T mobj = obj < zero ? T(-obj) : obj;
165 const T mbest = best < zero ? T(-best) : best;
174 for (std::size_t n = 0; n < Np; ++n) astar[n] = T(-astar[n]);
HstResult< T > pfqn_hst(const std::vector< T > &L, int N, const T &Z, std::size_t ist)
Operational sensitivity of throughput to homogeneous-service-time (HST) violations,...
RgfResult< T > pfqn_rgf(const std::vector< T > &L, int N, const T &Z)
Recursion by Generating Functions (RGF) for the normalizing constant of a SINGLE-CLASS closed product...