----------------------------------------------------------------------------- Gibbs-Poole-Stockmeyer algorithm, finding a reordering for the given graph, operating only on nodes which are yet unlabelled (indicated with -1 in the vector rlabel).
| 127 | // graph, operating only on nodes which are yet unlabelled (indicated |
| 128 | // with -1 in the vector rlabel). |
| 129 | std::vector<std::int32_t> |
| 130 | gps_reorder_unlabelled(const graph::AdjacencyList<std::int32_t>& graph, |
| 131 | std::span<const std::int32_t> rlabel) |
| 132 | { |
| 133 | common::Timer timer("Gibbs-Poole-Stockmeyer ordering"); |
| 134 | |
| 135 | const std::int32_t n = graph.num_nodes(); |
| 136 | |
| 137 | // Degree comparison function |
| 138 | auto cmp_degree = [&graph](auto a, auto b) |
| 139 | { return graph.num_links(a) < graph.num_links(b); }; |
| 140 | |
| 141 | // ALGORITHM I. Finding endpoints of a pseudo-diameter. |
| 142 | |
| 143 | // A. Pick an arbitrary vertex of minimal degree and call it v |
| 144 | std::int32_t v = 0; |
| 145 | std::int32_t dmin = std::numeric_limits<std::int32_t>::max(); |
| 146 | for (std::int32_t i = 0; i < n; ++i) |
| 147 | { |
| 148 | if (int d = graph.num_links(i); rlabel[i] == -1 and d < dmin) |
| 149 | { |
| 150 | v = i; |
| 151 | dmin = d; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | // B. Generate a level structure Lv rooted at vertex v. |
| 156 | graph::AdjacencyList<int> lv = create_level_structure(graph, v); |
| 157 | graph::AdjacencyList<int> lu(0); |
| 158 | bool done = false; |
| 159 | int u = 0; |
| 160 | std::vector<int> S; |
| 161 | while (!done) |
| 162 | { |
| 163 | // Sort final level S of Lv into increasing degree order |
| 164 | auto lv_final = lv.links(lv.num_nodes() - 1); |
| 165 | S.resize(lv_final.size()); |
| 166 | std::partial_sort_copy(lv_final.begin(), lv_final.end(), S.begin(), S.end(), |
| 167 | cmp_degree); |
| 168 | int w_min = std::numeric_limits<int>::max(); |
| 169 | done = true; |
| 170 | |
| 171 | // C. Generate level structures rooted at vertices s in S selected |
| 172 | // in order of increasing degree. |
| 173 | for (int s : S) |
| 174 | { |
| 175 | graph::AdjacencyList<int> lstmp = create_level_structure(graph, s); |
| 176 | if (lstmp.num_nodes() > lv.num_nodes()) |
| 177 | { |
| 178 | // Found a deeper level structure, so restart |
| 179 | v = s; |
| 180 | lv = lstmp; |
| 181 | done = false; |
| 182 | break; |
| 183 | } |
| 184 | |
| 185 | // D. Let u be the vertex of S whose associated level structure |
| 186 | // has smallest width |
no test coverage detected