25 template <
class GRAPH_MATRIX, 
typename num_t>
    27     GRAPH_MATRIX& in_A, std::vector<uint32_t>& out_part1,
    28     std::vector<uint32_t>& out_part2, num_t& out_cut_value, 
bool forceSimetry)
    31     GRAPH_MATRIX Adj, eigenVectors;
    32     std::vector<typename GRAPH_MATRIX::Scalar> eigenValues;
    35     if (in_A.cols() != int(nodeCount = in_A.rows()))
    44         Adj.setSize(nodeCount, nodeCount);
    45         for (
size_t i = 0; i < nodeCount; i++)
    46             for (
size_t j = i; j < nodeCount; j++)
    47                 Adj(i, j) = Adj(j, i) = 0.5f * (in_A(i, j) + in_A(j, i));
    53     GRAPH_MATRIX LAPLACIAN;
    56     LAPLACIAN.eig(eigenVectors, eigenValues);
    63     size_t nRows = eigenVectors.rows();
    66     for (
size_t i = 0; i < nRows; i++) 
mean += eigenVectors(i, colNo);
    72     for (
size_t i = 0; i < nRows; i++)
    74         if (eigenVectors(i, colNo) >= 
mean)
    75             out_part1.push_back(i);
    77             out_part2.push_back(i);
    83     if (!out_part1.size() || !out_part2.size())
    88         for (
int i = 0; i < Adj.cols(); i++)
    89             if (i <= Adj.cols() / 2)
    90                 out_part1.push_back(i);
    92                 out_part2.push_back(i);
    96     out_cut_value = nCut(Adj, out_part1, out_part2);
   102 template <
class GRAPH_MATRIX, 
typename num_t>
   104     GRAPH_MATRIX& in_A, std::vector<std::vector<uint32_t>>& out_parts,
   105     num_t threshold_Ncut, 
bool forceSimetry, 
bool useSpectralBisection,
   106     bool recursive, 
unsigned minSizeClusters, 
const bool verbose)
   111     std::vector<uint32_t> p1, p2;
   119     if (in_A.cols() != int(nodeCount = in_A.rows()))
   126         out_parts.push_back(p1);
   133         Adj.setSize(nodeCount, nodeCount);
   134         for (i = 0; i < nodeCount; i++)
   135             for (j = i; j < nodeCount; j++)
   136                 Adj(i, j) = Adj(j, i) = 0.5f * (in_A(i, j) + in_A(j, i));
   142     if (useSpectralBisection)
   143         SpectralBisection(Adj, p1, p2, cut_value, 
false);
   145         exactBisection(Adj, p1, p2, cut_value, 
false);
   149             "Cut:%u=%u+%u,nCut=%.02f->", (
unsigned int)nodeCount,
   150             (
unsigned int)p1.size(), (
unsigned int)p2.size(), cut_value);
   153     if (cut_value > threshold_Ncut || p1.size() < minSizeClusters ||
   154         p2.size() < minSizeClusters)
   156         if (
verbose) std::cout << 
"->NO!" << std::endl;
   160         for (i = 0; i < nodeCount; i++) p1.push_back(i);
   161         out_parts.push_back(p1);
   165         if (
verbose) std::cout << 
"->YES!" << std::endl;
   168         std::vector<std::vector<uint32_t>> p1_parts, p2_parts;
   175             GRAPH_MATRIX A_1(p1.size(), p1.size());
   176             for (i = 0; i < p1.size(); i++)
   177                 for (j = 0; j < p1.size(); j++) A_1(i, j) = in_A(p1[i], p1[j]);
   179             RecursiveSpectralPartition(
   180                 A_1, p1_parts, threshold_Ncut, forceSimetry,
   181                 useSpectralBisection, recursive, minSizeClusters);
   186             GRAPH_MATRIX A_2(p2.size(), p2.size());
   187             for (i = 0; i < p2.size(); i++)
   188                 for (j = 0; j < p2.size(); j++) A_2(i, j) = in_A(p2[i], p2[j]);
   190             RecursiveSpectralPartition(
   191                 A_2, p2_parts, threshold_Ncut, forceSimetry,
   192                 useSpectralBisection, recursive, minSizeClusters);
   198             for (i = 0; i < p1_parts.size(); i++)
   200                 for (j = 0; j < p1_parts[i].size(); j++)
   201                     p1_parts[i][j] = p1[p1_parts[i][j]];
   202                 out_parts.push_back(p1_parts[i]);
   206             for (i = 0; i < p2_parts.size(); i++)
   208                 for (j = 0; j < p2_parts[i].size(); j++)
   209                     p2_parts[i][j] = p2[p2_parts[i][j]];
   211                 out_parts.push_back(p2_parts[i]);
   218             out_parts.push_back(p1);
   219             out_parts.push_back(p2);
   229 template <
class GRAPH_MATRIX, 
typename num_t>
   231     const GRAPH_MATRIX& in_A, 
const std::vector<uint32_t>& in_part1,
   232     const std::vector<uint32_t>& in_part2)
   235     const size_t size1 = in_part1.size();
   236     const size_t size2 = in_part2.size();
   241     for (i = 0; i < size1; i++)
   242         for (j = 0; j < size2; j++) cut_AB += in_A(in_part1[i], in_part2[j]);
   245     for (i = 0; i < size1; i++)
   246         for (j = i; j < size1; j++)
   247             if (i != j) assoc_AA += in_A(in_part1[i], in_part1[j]);
   250     for (i = 0; i < size2; i++)
   251         for (j = i; j < size2; j++)
   252             if (i != j) assoc_BB += in_A(in_part2[i], in_part2[j]);
   254     num_t assoc_AV = assoc_AA + cut_AB;
   255     num_t assoc_BV = assoc_BB + cut_AB;
   260         return cut_AB / assoc_AV + cut_AB / assoc_BV;
   266 template <
class GRAPH_MATRIX, 
typename num_t>
   268     GRAPH_MATRIX& in_A, std::vector<uint32_t>& out_part1,
   269     std::vector<uint32_t>& out_part2, num_t& out_cut_value, 
bool forceSimetry)
   274     std::vector<bool> partition, bestPartition;
   275     std::vector<uint32_t> part1, part2;
   276     num_t partCutValue, bestCutValue = std::numeric_limits<num_t>::max();
   280     if (in_A.cols() != int(nodeCount = in_A.rows()))
   288         Adj.setSize(nodeCount, nodeCount);
   289         for (i = 0; i < nodeCount; i++)
   290             for (j = i; j < nodeCount; j++)
   291                 Adj(i, j) = Adj(j, i) = 0.5f * (in_A(i, j) + in_A(j, i));
   302     partition.resize(nodeCount, 
false);
   311         for (i = 0; i < nodeCount; i++)
   320         partCutValue = nCut(Adj, part1, part2);
   322         if (partCutValue < bestCutValue)
   324             bestCutValue = partCutValue;
   325             bestPartition = partition;
   333             carry = partition[i];
   334             partition[i] = !partition[i];
   336         } 
while (carry && i < nodeCount);
   340         for (i = 0; 
end && i < nodeCount; i++) 
end = 
end && partition[i];
   345     out_cut_value = bestCutValue;
   350     for (i = 0; i < nodeCount; i++)
   352         if (bestPartition[i])
   353             out_part2.push_back(i);
   355             out_part1.push_back(i);
 
static num_t nCut(const GRAPH_MATRIX &in_A, const std::vector< uint32_t > &in_part1, const std::vector< uint32_t > &in_part2)
Returns the normaliced cut of a graph, given its adjacency matrix A and a bisection: ...
 
#define THROW_EXCEPTION(msg)
 
std::string std::string format(std::string_view fmt, ARGS &&... args)
 
Abstract graph and tree data structures, plus generic graph algorithms. 
 
void laplacian(const MATIN &g, MATOUT &ret)
Computes the Laplacian of a square graph weight matrix. 
 
This file implements miscelaneous matrix and matrix/vector operations, and internal functions in mrpt...
 
static void exactBisection(GRAPH_MATRIX &in_A, std::vector< uint32_t > &out_part1, std::vector< uint32_t > &out_part2, num_t &out_cut_value, bool forceSimetry=true)
Performs an EXACT minimum n-Cut graph bisection, (Use CGraphPartitioner::SpectralBisection for a fast...
 
#define ASSERT_(f)
Defines an assertion mechanism. 
 
const_iterator end() const
 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
 
static void RecursiveSpectralPartition(GRAPH_MATRIX &in_A, std::vector< std::vector< uint32_t >> &out_parts, num_t threshold_Ncut=1, bool forceSimetry=true, bool useSpectralBisection=true, bool recursive=true, unsigned minSizeClusters=1, const bool verbose=false)
Performs the spectral recursive partition into K-parts for a given graph. 
 
double mean(const CONTAINER &v)
Computes the mean value of a vector. 
 
static void SpectralBisection(GRAPH_MATRIX &in_A, std::vector< uint32_t > &out_part1, std::vector< uint32_t > &out_part2, num_t &out_cut_value, bool forceSimetry=true)
Performs the spectral bisection of a graph. 
 
Finds the min-normalized-cut of a weighted undirected graph.