10 #if !defined(CGRAPHPARTITIONER_H)
11 #error "This file can't be included from outside of CGraphPartitioner.h"
21 template <
class GRAPH_MATRIX,
typename num_t>
23 GRAPH_MATRIX& in_A, std::vector<uint32_t>& out_part1,
24 std::vector<uint32_t>& out_part2, num_t& out_cut_value,
bool forceSimetry)
30 if (in_A.cols() !=
int(nodeCount = in_A.rows()))
39 Adj.setSize(nodeCount, nodeCount);
40 for (
size_t i = 0; i < nodeCount; i++)
41 for (
size_t j = i; j < nodeCount; j++)
42 Adj(i, j) = Adj(j, i) = 0.5f * (in_A(i, j) + in_A(j, i));
48 GRAPH_MATRIX LAPLACIAN;
49 Adj.laplacian(LAPLACIAN);
67 for (
size_t i = 0; i < nRows; i++)
70 out_part1.push_back(i);
72 out_part2.push_back(i);
78 if (!out_part1.size() || !out_part2.size())
83 for (
int i = 0; i < Adj.cols(); i++)
84 if (i <= Adj.cols() / 2)
85 out_part1.push_back(i);
87 out_part2.push_back(i);
91 out_cut_value = nCut(Adj, out_part1, out_part2);
97 template <
class GRAPH_MATRIX,
typename num_t>
99 GRAPH_MATRIX& in_A, std::vector<std::vector<uint32_t>>& out_parts,
100 num_t threshold_Ncut,
bool forceSimetry,
bool useSpectralBisection,
101 bool recursive,
unsigned minSizeClusters,
const bool verbose)
106 std::vector<uint32_t> p1, p2;
114 if (in_A.cols() !=
int(nodeCount = in_A.rows()))
121 out_parts.push_back(p1);
128 Adj.setSize(nodeCount, nodeCount);
129 for (i = 0; i < nodeCount; i++)
130 for (j = i; j < nodeCount; j++)
131 Adj(i, j) = Adj(j, i) = 0.5f * (in_A(i, j) + in_A(j, i));
137 if (useSpectralBisection)
138 SpectralBisection(Adj, p1, p2, cut_value,
false);
140 exactBisection(Adj, p1, p2, cut_value,
false);
144 "Cut:%u=%u+%u,nCut=%.02f->", (
unsigned int)nodeCount,
145 (
unsigned int)p1.size(), (
unsigned int)p2.size(), cut_value);
148 if (cut_value > threshold_Ncut || p1.size() < minSizeClusters ||
149 p2.size() < minSizeClusters)
151 if (verbose) std::cout <<
"->NO!" << std::endl;
155 for (i = 0; i < nodeCount; i++) p1.push_back(i);
156 out_parts.push_back(p1);
160 if (verbose) std::cout <<
"->YES!" << std::endl;
163 std::vector<std::vector<uint32_t>> p1_parts, p2_parts;
170 GRAPH_MATRIX A_1(p1.size(), p1.size());
171 for (i = 0; i < p1.size(); i++)
172 for (j = 0; j < p1.size(); j++) A_1(i, j) = in_A(p1[i], p1[j]);
174 RecursiveSpectralPartition(
175 A_1, p1_parts, threshold_Ncut, forceSimetry,
176 useSpectralBisection, recursive, minSizeClusters);
181 GRAPH_MATRIX A_2(p2.size(), p2.size());
182 for (i = 0; i < p2.size(); i++)
183 for (j = 0; j < p2.size(); j++) A_2(i, j) = in_A(p2[i], p2[j]);
185 RecursiveSpectralPartition(
186 A_2, p2_parts, threshold_Ncut, forceSimetry,
187 useSpectralBisection, recursive, minSizeClusters);
193 for (i = 0; i < p1_parts.size(); i++)
195 for (j = 0; j < p1_parts[i].size(); j++)
196 p1_parts[i][j] = p1[p1_parts[i][j]];
197 out_parts.push_back(p1_parts[i]);
201 for (i = 0; i < p2_parts.size(); i++)
203 for (j = 0; j < p2_parts[i].size(); j++)
204 p2_parts[i][j] = p2[p2_parts[i][j]];
206 out_parts.push_back(p2_parts[i]);
213 out_parts.push_back(p1);
214 out_parts.push_back(p2);
224 template <
class GRAPH_MATRIX,
typename num_t>
226 const GRAPH_MATRIX& in_A,
const std::vector<uint32_t>& in_part1,
227 const std::vector<uint32_t>& in_part2)
230 size_t size1 = in_part1.size();
231 size_t size2 = in_part2.size();
236 for (i = 0; i < size1; i++)
237 for (j = 0; j < size2; j++) cut_AB += in_A(in_part1[i], in_part2[j]);
240 for (i = 0; i < size1; i++)
241 for (j = i; j < size1; j++)
242 if (i != j) assoc_AA += in_A(in_part1[i], in_part1[j]);
245 for (i = 0; i < size2; i++)
246 for (j = i; j < size2; j++)
247 if (i != j) assoc_BB += in_A(in_part2[i], in_part2[j]);
249 num_t assoc_AV = assoc_AA + cut_AB;
250 num_t assoc_BV = assoc_BB + cut_AB;
255 return cut_AB / assoc_AV + cut_AB / assoc_BV;
261 template <
class GRAPH_MATRIX,
typename num_t>
263 GRAPH_MATRIX& in_A, std::vector<uint32_t>& out_part1,
264 std::vector<uint32_t>& out_part2, num_t& out_cut_value,
bool forceSimetry)
269 std::vector<bool> partition, bestPartition;
270 std::vector<uint32_t> part1, part2;
271 num_t partCutValue, bestCutValue = std::numeric_limits<num_t>::max();
275 if (in_A.cols() !=
int(nodeCount = in_A.rows()))
283 Adj.setSize(nodeCount, nodeCount);
284 for (i = 0; i < nodeCount; i++)
285 for (j = i; j < nodeCount; j++)
286 Adj(i, j) = Adj(j, i) = 0.5f * (in_A(i, j) + in_A(j, i));
297 partition.resize(nodeCount,
false);
306 for (i = 0; i < nodeCount; i++)
315 partCutValue = nCut(Adj, part1, part2);
317 if (partCutValue < bestCutValue)
319 bestCutValue = partCutValue;
320 bestPartition = partition;
328 carry = partition[i];
329 partition[i] = !partition[i];
331 }
while (carry && i < nodeCount);
335 for (i = 0;
end && i < nodeCount; i++)
end =
end && partition[i];
340 out_cut_value = bestCutValue;
345 for (i = 0; i < nodeCount; i++)
347 if (bestPartition[i])
348 out_part2.push_back(i);
350 out_part1.push_back(i);