226 std::vector<vertex_idx_t>& heads,
230 std::vector< std::vector<size_t> > head2child;
231 size_t len = adj_matrix.rows();
232 assert(adj_matrix.rows() == adj_matrix.cols());
233 head2child.resize(len);
234 for (
size_t i = 1; i < len; i++)
236 head2child[heads[offset+i]].push_back(i);
239 std::vector<size_t> connected(len, 0);
242 while (std::find(std::next(connected.begin()), connected.end(), 0) != connected.end())
244 std::vector< std::vector<size_t> > loops;
245 find_loops(heads, loops, connected, len, offset);
247 std::pair<size_t, size_t> best_new_arc = std::make_pair(0, 0);
248 float best_score = 0;
249 for (
size_t l = 0; l < loops.size(); l++)
251 for (
size_t i = 0; i < loops[l].size(); i++)
253 size_t from = loops[l][i];
254 for (
size_t j = 1; j < len; j++)
256 if (connected[j] == 0)
258 if (j == heads[offset+from])
260 if (adj_matrix(from, j) > best_score || best_new_arc.first == 0)
262 best_score = adj_matrix(from, j);
263 best_new_arc = std::make_pair(from, j);
269 if (best_new_arc.first == 0 || best_new_arc.second == 0)
270 throw std::runtime_error(
"make_connected best_new_arc first or second should be 0");
272 heads[offset+best_new_arc.first] = best_new_arc.second;
275 head2child.resize(len);
276 for (
size_t i = 1; i < len; i++)
278 head2child[heads[offset+i]].push_back(i);
281 std::fill(connected.begin(), connected.end(), 0);
359 std::vector<vertex_idx_t>& heads,
363 assert(adj_matrix.rows() == adj_matrix.cols());
364 size_t len = adj_matrix.rows();
366 std::vector<edge_t> all_edges;
367 all_edges.reserve(len * len);
368 std::vector<std::vector<edge_t*>> in_edges;
369 in_edges.resize(len);
371 for (vertex_idx_t i = 1; i < len; i++)
372 for (vertex_idx_t j = 1; j < len; j++)
376 all_edges.push_back(edge_t(j, i, adj_matrix(i, j)));
377 in_edges[i].push_back(&all_edges.back());
380 for (edge_t& e : all_edges)
381 in_edges[e.target].push_back(&e);
383 std::vector<std::vector<edge_t*>> cycle(len);
384 std::vector<edge_t*> lambda(len);
385 std::vector<vertex_idx_t> roots;
386 std::vector<vertex_idx_t> final_roots;
387 boost::disjoint_sets_with_storage<> S(2 * len);
388 boost::disjoint_sets_with_storage<> W(2 * len);
389 std::vector<vertex_idx_t> min(len);
390 std::vector<edge_t*> enter(len);
391 std::vector<edge_t*> F;
392 std::vector<weight_t> edge_weight_change(len);
394 for (vertex_idx_t v = 0; v < len; ++v)
403 while (!roots.empty())
405 vertex_idx_t curr = roots.back();
408 if (in_edges[curr].empty())
410 final_roots.push_back(min[curr]);
414 edge_t *optimal_in_edge = in_edges[curr].front();
415 for (edge_t* e : in_edges[curr])
416 if (e->weight > optimal_in_edge->weight)
419 F.push_back(optimal_in_edge);
420 for (edge_t* e : cycle[curr])
422 e->parent = optimal_in_edge;
423 optimal_in_edge->children.push_back(e);
426 if (cycle[curr].empty())
427 lambda[curr] = optimal_in_edge;
430 if (W.find_set(optimal_in_edge->source) != W.find_set(optimal_in_edge->target))
432 enter[curr] = optimal_in_edge;
433 W.union_set(optimal_in_edge->source, optimal_in_edge->target);
437 std::vector<edge_t*> cycle_edges = { optimal_in_edge };
438 std::vector<vertex_idx_t> cycle_repr = { S.find_set(optimal_in_edge->target) };
439 edge_t* least_costly_edge = optimal_in_edge;
440 enter[curr] =
nullptr;
442 for (vertex_idx_t v = S.find_set(optimal_in_edge->source);
444 v = S.find_set(enter[v]->source))
446 cycle_edges.push_back(enter[v]);
447 cycle_repr.push_back(v);
449 if (enter[v]->weight < least_costly_edge->weight)
450 least_costly_edge = enter[v];
453 for (edge_t* e : cycle_edges)
454 edge_weight_change[S.find_set(e->target)] = least_costly_edge->weight - e->weight;
456 vertex_idx_t cycle_root = min[S.find_set(least_costly_edge->target)];
459 vertex_idx_t new_repr = cycle_repr.front();
460 for (vertex_idx_t v : cycle_repr)
463 new_repr = S.find_set(new_repr);
465 min[new_repr] = cycle_root;
466 roots.push_back(new_repr);
467 cycle[new_repr].swap(cycle_edges);
469 for (vertex_idx_t v : cycle_repr)
471 for (edge_t* e : in_edges[v])
473 e->weight += edge_weight_change[v];
477 std::vector<edge_t*> new_in_edges;
478 for (
size_t i = 1; i < cycle_repr.size(); ++i)
480 typename std::vector<edge_t*>::iterator i1 = in_edges[cycle_repr[i]].begin();
481 typename std::vector<edge_t*>::iterator e1 = in_edges[cycle_repr[i]].end();
482 typename std::vector<edge_t*>::iterator i2 = in_edges[cycle_repr[i-1]].begin();
483 typename std::vector<edge_t*>::iterator e2 = in_edges[cycle_repr[i-1]].end();
485 while (i1 != e1 || i2 != e2)
487 while (i1 != e1 && S.find_set((*i1)->source) == new_repr)
490 while (i2 != e2 && S.find_set((*i2)->source) == new_repr)
493 if (i1 == e1 && i2 == e2)
498 new_in_edges.push_back(*i2);
503 new_in_edges.push_back(*i1);
506 else if ( (*i1)->source < (*i2)->source )
508 new_in_edges.push_back(*i1);
511 else if ( (*i1)->source > (*i2)->source )
513 new_in_edges.push_back(*i2);
518 if ( (*i1)->weight > (*i2)->weight )
519 new_in_edges.push_back(*i1);
521 new_in_edges.push_back(*i2);
528 in_edges[cycle_repr[i]].swap(new_in_edges);
529 new_in_edges.clear();
532 in_edges[new_repr].swap(in_edges[cycle_repr.back()]);
533 edge_weight_change[new_repr] = weight_t(0);
537 std::vector<edge_t*> F_roots;
540 if (e->parent ==
nullptr)
541 F_roots.push_back(e);
544 for (vertex_idx_t v : final_roots)
546 if (lambda[v] !=
nullptr)
547 remove_from_f(lambda[v], F_roots);
550 while (!F_roots.empty())
552 edge_t* e = F_roots.back();
558 heads[offset + e->target] = e->source;
559 remove_from_f(lambda[e->target], F_roots);