MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ minimum_spanning_tree()

MAYAFLUX_API EdgeList MayaFlux::Kinesis::minimum_spanning_tree ( const Eigen::MatrixXd &  points)

Compute minimum spanning tree (Prim's algorithm)

Parameters
pointsDxN matrix where each column is a point
Returns
Edge list forming MST

Returns exactly (n-1) edges forming tree of minimum total length that connects all points. Undirected acyclic graph.

Complexity: O(n² log n) with priority queue

Definition at line 360 of file ProximityGraphs.cpp.

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

References MayaFlux::Journal::Kinesis, MF_DEBUG, points, and MayaFlux::Journal::Runtime.

Referenced by generate_proximity_graph().

+ Here is the caller graph for this function: