MayaFlux 0.5.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 362 of file ProximityGraphs.cpp.

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