77std::pair<std::vector<int>,
int> pas_swap_local(
const std::vector<int>& c, std::size_t p,
119 const std::vector<int>& N0 = std::vector<int>()) {
120 const std::size_t M = 2;
121 if (swap.empty())
throw InputError(
"pas_swap2order: no swap graph");
122 if (listRate.size() != M)
throw InputError(
"pas_swap2order: two rate functions are required");
123 std::vector<Matrix<T>> G(M);
124 if (swap.size() == 1) {
127 }
else if (swap.size() == M) {
131 throw InputError(
"pas_swap2order: expected one swap graph or one per queue");
135 std::vector<int> pop(N0);
137 if (G[0].rows() == 0)
throw InputError(
"pas_swap2order: cannot infer the class count");
138 pop.assign(G[0].rows(), 1);
140 const std::size_t R = pop.size();
142 bool anySwap =
false;
143 for (std::size_t m = 0; m < M; ++m)
144 for (std::size_t i = 0; i < G[m].rows(); ++i)
145 for (std::size_t j = 0; j < G[m].cols(); ++j)
146 if (G[m](i, j) != zero) anySwap =
true;
147 if (!anySwap)
return Matrix<T>(R, R, zero);
150 typedef std::pair<std::vector<int>, std::vector<int>> State;
152 for (std::size_t r = 0; r < R; ++r)
153 for (
int k = 0; k < pop[r]; ++k) init.first.push_back(
static_cast<int>(r) + 1);
155 std::set<State> seen;
156 std::vector<State> frontier, classStates;
158 frontier.push_back(init);
160 while (!frontier.empty()) {
161 const State st = frontier.back();
163 classStates.push_back(st);
164 for (std::size_t m = 0; m < M; ++m) {
165 const std::vector<int>& c = m == 0 ? st.first : st.second;
166 for (std::size_t p = 1; p <= c.size(); ++p) {
167 std::vector<int> prefix(c.begin(), c.begin() +
static_cast<std::ptrdiff_t
>(p));
170 std::vector<int> shorter(c.begin(),
171 c.begin() +
static_cast<std::ptrdiff_t
>(p - 1));
172 prevRate = listRate[m](shorter);
174 const T rate = T(listRate[m](prefix) - prevRate);
175 if (!(rate > rateTol))
continue;
176 const std::pair<std::vector<int>,
int> mv = detail::pas_swap_local(c, p, G[m]);
178 (m == 0 ? stn.first : stn.second) = mv.first;
179 (m == 0 ? stn.second : stn.first).push_back(mv.second);
180 if (seen.insert(stn).second) frontier.push_back(stn);
186 std::set<std::vector<int>> D;
187 for (std::size_t s = 0; s < classStates.size(); ++s) {
188 std::vector<int> c(classStates[s].first);
189 for (std::size_t k = classStates[s].second.size(); k > 0; --k)
190 c.push_back(classStates[s].second[k - 1]);
195 for (std::size_t a = 1; a <= R; ++a)
196 for (std::size_t b = 1; b <= R; ++b) {
197 if (a == b)
continue;
198 bool both =
false, forced =
true;
199 for (std::set<std::vector<int>>::const_iterator it = D.begin(); it != D.end(); ++it) {
200 const std::vector<int>& c = *it;
201 std::size_t maxa = 0, minb = 0;
202 for (std::size_t k = 0; k < c.size(); ++k) {
203 if (c[k] ==
static_cast<int>(a)) maxa = k + 1;
204 if (c[k] ==
static_cast<int>(b) && minb == 0) minb = k + 1;
206 if (maxa == 0 || minb == 0)
continue;
208 if (!(maxa < minb)) {
213 if (both && forced) H(a - 1, b - 1) = one;