Returns exactly (n-1) edges forming tree of minimum total length that connects all points. Undirected acyclic graph.
361{
362 const auto n =
static_cast<size_t>(
points.cols());
363 if (n < 2) {
364 return {};
365 }
366
367 const auto dim =
static_cast<size_t>(
points.rows());
368 const double* base =
points.data();
369
370 EdgeList mst_edges;
371 mst_edges.reserve(n - 1);
372
373 std::vector<bool> in_mst(n, false);
374 std::priority_queue<Edge, std::vector<Edge>, std::greater<>> pq;
375
376 in_mst[0] = true;
377
378 for (size_t j = 1; j < n; ++j) {
379 pq.push({ .a = 0, .b = j, .weight = std::sqrt(dist_sq(base, base + j * dim, dim)) });
380 }
381
382 while (!pq.empty() && mst_edges.size() < n - 1) {
383 const Edge e = pq.top();
384 pq.pop();
385
386 if (in_mst[e.b]) {
387 continue;
388 }
389
390 mst_edges.emplace_back(e.a, e.b);
391 in_mst[e.b] = true;
392
393 const double* pb = base + e.b * dim;
394 for (size_t j = 0; j < n; ++j) {
395 if (!in_mst[j]) {
396 pq.push({ .a = e.b, .b = j, .weight = std::sqrt(dist_sq(pb, base + j * dim, dim)) });
397 }
398 }
399 }
400
401 MF_DEBUG(Journal::Component::Kinesis, Journal::Context::Runtime,
402 "minimum_spanning_tree: {} points, generated {} edges",
403 n, mst_edges.size());
404
405 return mst_edges;
406}
#define MF_DEBUG(comp, ctx,...)
std::vector< glm::vec2 > * points