10 #include <boost/graph/adjacency_list.hpp>
11 #include <boost/graph/boykov_kolmogorov_max_flow.hpp>
12 #include <boost/graph/graph_traits.hpp>
13 #include <boost/graph/one_bit_color_map.hpp>
14 #include <unordered_map>
23 const std::vector<std::pair<int, int>>& edges,
24 const std::vector<int>& weights,
26 std::vector<char>* cut_labels);
31 const std::vector<std::pair<int, int>>& edges,
32 const std::vector<int>& weights,
39 template <
typename node_t,
typename value_t>
43 adjacency_list_traits<boost::vecS, boost::vecS, boost::directedS>
54 typedef boost::adjacency_list<boost::vecS,
68 void AddNode(
const node_t node_idx,
69 const value_t source_capacity,
70 const value_t sink_capacity);
73 void AddEdge(
const node_t node_idx1,
74 const node_t node_idx2,
75 const value_t capacity,
76 const value_t reverse_capacity);
90 std::vector<boost::default_color_type> colors_;
97 template <
typename node_t,
typename value_t>
99 : S_node_(num_nodes), T_node_(num_nodes + 1), graph_(num_nodes + 2) {}
101 template <
typename node_t,
typename value_t>
103 return boost::num_vertices(graph_) - 2;
106 template <
typename node_t,
typename value_t>
108 return boost::num_edges(graph_);
111 template <
typename node_t,
typename value_t>
113 const value_t source_capacity,
114 const value_t sink_capacity) {
115 CHECK_GE(node_idx, 0);
116 CHECK_LE(node_idx, boost::num_vertices(graph_));
117 CHECK_GE(source_capacity, 0);
118 CHECK_GE(sink_capacity, 0);
120 if (source_capacity > 0) {
122 boost::add_edge(S_node_, node_idx, graph_).first;
124 boost::add_edge(node_idx, S_node_, graph_).first;
125 graph_[edge].capacity = source_capacity;
126 graph_[edge].reverse = edge_reverse;
127 graph_[edge_reverse].reverse = edge;
130 if (sink_capacity > 0) {
132 boost::add_edge(node_idx, T_node_, graph_).first;
134 boost::add_edge(T_node_, node_idx, graph_).first;
135 graph_[edge].capacity = sink_capacity;
136 graph_[edge].reverse = edge_reverse;
137 graph_[edge_reverse].reverse = edge;
141 template <
typename node_t,
typename value_t>
143 const node_t node_idx2,
144 const value_t capacity,
145 const value_t reverse_capacity) {
146 CHECK_GE(node_idx1, 0);
147 CHECK_LE(node_idx1, boost::num_vertices(graph_));
148 CHECK_GE(node_idx2, 0);
149 CHECK_LE(node_idx2, boost::num_vertices(graph_));
150 CHECK_GE(capacity, 0);
151 CHECK_GE(reverse_capacity, 0);
154 boost::add_edge(node_idx1, node_idx2, graph_).first;
156 boost::add_edge(node_idx2, node_idx1, graph_).first;
157 graph_[edge].capacity = capacity;
158 graph_[edge_reverse].capacity = reverse_capacity;
159 graph_[edge].reverse = edge_reverse;
160 graph_[edge_reverse].reverse = edge;
163 template <
typename node_t,
typename value_t>
167 colors_.resize(num_vertices);
168 std::vector<edge_descriptor_t> predecessors(num_vertices);
169 std::vector<vertices_size_t> distances(num_vertices);
171 return boost::boykov_kolmogorov_max_flow(
172 graph_, boost::get(&Edge::capacity, graph_),
173 boost::get(&Edge::residual, graph_),
174 boost::get(&Edge::reverse, graph_), predecessors.data(),
175 colors_.data(), distances.data(),
179 template <
typename node_t,
typename value_t>
181 const node_t node_idx)
const {
182 return colors_.at(node_idx) != boost::white_color;
185 template <
typename node_t,
typename value_t>
187 const node_t node_idx)
const {
188 return colors_.at(node_idx) == boost::white_color;
graph_traits_t::vertices_size_type vertices_size_t
bool IsConnectedToSource(const node_t node_idx) const
void AddNode(const node_t node_idx, const value_t source_capacity, const value_t sink_capacity)
graph_traits_t::edge_descriptor edge_descriptor_t
boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, size_t, Edge > graph_t
boost::adjacency_list_traits< boost::vecS, boost::vecS, boost::directedS > graph_traits_t
MinSTGraphCut(const size_t num_nodes)
bool IsConnectedToSink(const node_t node_idx) const
void AddEdge(const node_t node_idx1, const node_t node_idx2, const value_t capacity, const value_t reverse_capacity)
std::unordered_map< int, int > ComputeNormalizedMinGraphCut(const std::vector< std::pair< int, int >> &edges, const std::vector< int > &weights, const int num_parts)
void ComputeMinGraphCutStoerWagner(const std::vector< std::pair< int, int >> &edges, const std::vector< int > &weights, int *cut_weight, std::vector< char > *cut_labels)
edge_descriptor_t reverse