| 220 | */ |
| 221 | template<typename SetType> |
| 222 | std::vector<DepGraphIndex> ExhaustiveLinearize(const DepGraph<SetType>& depgraph) |
| 223 | { |
| 224 | // The best linearization so far, and its chunking. |
| 225 | std::vector<DepGraphIndex> linearization; |
| 226 | std::vector<FeeFrac> chunking; |
| 227 | |
| 228 | std::vector<DepGraphIndex> perm_linearization; |
| 229 | // Initialize with the lexicographically-first linearization. |
| 230 | for (DepGraphIndex i : depgraph.Positions()) perm_linearization.push_back(i); |
| 231 | // Iterate over all valid permutations. |
| 232 | do { |
| 233 | /** What prefix of perm_linearization is topological. */ |
| 234 | DepGraphIndex topo_length{0}; |
| 235 | TestBitSet perm_done; |
| 236 | while (topo_length < perm_linearization.size()) { |
| 237 | auto i = perm_linearization[topo_length]; |
| 238 | perm_done.Set(i); |
| 239 | if (!depgraph.Ancestors(i).IsSubsetOf(perm_done)) break; |
| 240 | ++topo_length; |
| 241 | } |
| 242 | if (topo_length == perm_linearization.size()) { |
| 243 | // If all of perm_linearization is topological, check if it is perhaps our best |
| 244 | // linearization so far. |
| 245 | auto perm_chunking = ChunkLinearization(depgraph, perm_linearization); |
| 246 | auto cmp = CompareChunks(perm_chunking, chunking); |
| 247 | // If the diagram is better, or if it is equal but with more chunks (because we |
| 248 | // prefer minimal chunks), consider this better. |
| 249 | if (linearization.empty() || cmp > 0 || (cmp == 0 && perm_chunking.size() > chunking.size())) { |
| 250 | linearization = perm_linearization; |
| 251 | chunking = perm_chunking; |
| 252 | } |
| 253 | } else { |
| 254 | // Otherwise, fast forward to the last permutation with the same non-topological |
| 255 | // prefix. |
| 256 | auto first_non_topo = perm_linearization.begin() + topo_length; |
| 257 | assert(std::is_sorted(first_non_topo + 1, perm_linearization.end())); |
| 258 | std::reverse(first_non_topo + 1, perm_linearization.end()); |
| 259 | } |
| 260 | } while(std::next_permutation(perm_linearization.begin(), perm_linearization.end())); |
| 261 | |
| 262 | return linearization; |
| 263 | } |
| 264 | |
| 265 | |
| 266 | /** Stitch connected components together in a DepGraph, guaranteeing its corresponding cluster is connected. */ |
no test coverage detected