15 #ifndef PAAL_K_CUT_HPP
16 #define PAAL_K_CUT_HPP
22 #include <boost/graph/adjacency_list.hpp>
23 #include <boost/graph/copy.hpp>
24 #include <boost/graph/iteration_macros.hpp>
25 #include <boost/graph/one_bit_color_map.hpp>
26 #include <boost/graph/stoer_wagner_min_cut.hpp>
27 #include <boost/graph/subgraph.hpp>
28 #include <boost/range/as_array.hpp>
53 template<
typename InGraph,
class OutputIterator,
typename VertexIndexMap,
typename EdgeWeightMap>
54 auto k_cut(
const InGraph& graph,
unsigned int number_of_parts,OutputIterator result,
55 VertexIndexMap index_map, EdgeWeightMap weight_map) ->
56 typename boost::property_traits<EdgeWeightMap>::value_type{
57 using cost_t =
typename boost::property_traits<EdgeWeightMap>::value_type;
58 using Vertex =
typename boost::graph_traits<InGraph>::vertex_descriptor;
60 using Graph = boost::adjacency_list<
61 boost::vecS, boost::vecS, boost::undirectedS, boost::no_property,
62 boost::property<boost::edge_weight_t, cost_t,
63 boost::property<boost::edge_index_t, int>>>;
65 assert(num_vertices(graph) >= number_of_parts);
67 std::vector<int> vertex_to_part(num_vertices(graph));
68 using VertexIndexToVertex =
typename std::vector<Vertex>;
69 using VertexIndexToVertexIndex = std::vector<int>;
70 VertexIndexToVertex vertex_in_subgraph_to_vertex(num_vertices(graph));
71 VertexIndexToVertexIndex vertex_to_vertex_in_subgraph(num_vertices(graph));
78 std::pair<cost_t,int>,
79 std::vector<std::pair<cost_t,int> >
85 auto make_cut = [&](
int id) {
87 for (
auto v: boost::as_array(vertices(graph))) {
88 if (vertex_to_part[
get(index_map, v)] == id) {
89 vertex_in_subgraph_to_vertex[vertex_in_part] = v;
90 vertex_to_vertex_in_subgraph[
get(index_map, v)] = vertex_in_part;
94 Graph part(vertex_in_part);
95 for (
auto edge : boost::as_array(edges(graph))) {
96 auto sour =
get(index_map, source(edge,graph));
97 auto targ =
get(index_map, target(edge,graph));
98 if (vertex_to_part[sour] ==
id &&
99 vertex_to_part[targ] ==
id &&
101 add_edge(vertex_to_vertex_in_subgraph[sour],
102 vertex_to_vertex_in_subgraph[targ],
103 get(weight_map, edge),
107 if (vertex_in_part < 2) {
109 *result = std::make_pair(vertex_in_subgraph_to_vertex[0], id_part);
113 auto parities = boost::make_one_bit_color_map(num_vertices(part),
114 get(boost::vertex_index, part));
115 auto cut_cost = boost::stoer_wagner_min_cut(part,
116 get(boost::edge_weight, part),
117 boost::parity_map(parities));
119 for (
auto i :
irange(num_vertices(part))) {
120 vertex_to_part[
get(index_map, vertex_in_subgraph_to_vertex[i])] =
121 parts +
get(parities, i);
123 cuts.push(std::make_pair(cut_cost, parts));
128 cost_t k_cut_cost = cost_t();
129 while (--number_of_parts) {
130 auto cut = cuts.top();
132 k_cut_cost += cut.first;
133 make_cut(cut.second);
134 make_cut(cut.second + 1);
137 while (!cuts.empty()) {
138 auto cut = cuts.top();
141 for (
auto v: boost::as_array(vertices(graph))) {
142 if (vertex_to_part[
get(index_map, v)] == cut.second ||
143 vertex_to_part[
get(index_map, v)] == cut.second + 1) {
144 *result = std::make_pair(v, id_part);
169 template<
typename InGraph
170 ,
class OutputIterator
174 auto k_cut(
const InGraph& graph,
unsigned int number_of_parts,
175 OutputIterator result,
const boost::bgl_named_params<P, T, R>&
params) ->
176 typename boost::property_traits<
177 puretype(boost::choose_const_pmap(get_param(
params, boost::edge_weight), graph, boost::edge_weight))
179 return k_cut(graph, number_of_parts, result,
180 boost::choose_const_pmap(get_param(
params, boost::vertex_index), graph,boost::vertex_index),
181 boost::choose_const_pmap(get_param(
params, boost::edge_weight), graph,boost::edge_weight)
198 template<
typename InGraph,
class OutputIterator>
199 auto k_cut(
const InGraph& graph,
unsigned int number_of_parts, OutputIterator result) ->
200 typename boost::property_traits<puretype(get(boost::edge_weight,graph))>::value_type{
201 return k_cut(graph, number_of_parts, result, boost::no_named_parameters());
207 #endif // PAAL_K_CUT_HPP
#define puretype(t)
for given expression returns its type with removed const and reference
auto irange(T begin, T end)
irange
This file contains set of simple useful functors or functor adapters.
auto k_cut(const InGraph &graph, unsigned int number_of_parts, OutputIterator result, VertexIndexMap index_map, EdgeWeightMap weight_map) -> typename boost::property_traits< EdgeWeightMap >::value_type
this is solve k_cut problem and return cut_cost example: