15 #ifndef PAAL_BOUNDED_DEGREE_MST_ORACLE_HPP
16 #define PAAL_BOUNDED_DEGREE_MST_ORACLE_HPP
21 #include <boost/optional.hpp>
22 #include <boost/range/as_array.hpp>
35 using AuxEdge = min_cut_finder::Edge;
36 using AuxVertex = min_cut_finder::Vertex;
37 using AuxEdgeList = std::vector<AuxEdge>;
38 using Violation = boost::optional<double>;
41 using Candidate = std::pair<AuxVertex, AuxVertex>;
42 using CandidateList = std::vector<Candidate>;
47 template <
typename Problem,
typename LP>
50 fill_auxiliary_digraph(problem, lp);
51 initialize_candidates(problem);
52 return m_candidate_list;
59 template <
typename Problem>
61 double violation = find_violation(candidate.first, candidate.second);
62 if (problem.get_compare().g(violation, 0)) {
72 template <
typename Problem,
typename LP>
74 const Problem &problem,
LP &lp) {
76 find_violation(violating_pair.first, violating_pair.second);
79 auto const &g = problem.get_graph();
80 auto const &index = problem.get_index();
83 for (
auto const &e : problem.get_edge_map().right) {
84 auto u =
get(index, source(e.second, g));
85 auto v =
get(index, target(e.second, g));
99 template <
typename Problem,
typename LP>
100 void fill_auxiliary_digraph(
const Problem &problem,
const LP &lp) {
101 auto const &g = problem.get_graph();
102 auto const &index = problem.get_index();
103 m_vertices_num = num_vertices(g);
104 m_min_cut.
init(m_vertices_num);
105 m_src_to_v.resize(m_vertices_num);
106 m_v_to_trg.resize(m_vertices_num);
108 for (
auto const &e : problem.get_edge_map().right) {
112 if (!problem.get_compare().e(col_val, 0)) {
113 auto u =
get(index, source(e.second, g));
114 auto v =
get(index, target(e.second, g));
122 for (
auto v : boost::as_array(vertices(g))) {
123 auto aux_v =
get(index, v);
124 m_src_to_v[aux_v] = m_min_cut
135 template <
typename Problem>
136 void initialize_candidates(
const Problem &problem) {
137 auto const &g = problem.get_graph();
138 auto const &index = problem.get_index();
139 auto src = *(std::next(vertices(g).first, rand() % m_vertices_num));
140 auto aux_src =
get(index, src);
141 m_candidate_list.clear();
142 for (
auto v : boost::as_array(vertices(g))) {
144 auto aux_v =
get(index, v);
145 m_candidate_list.push_back(std::make_pair(aux_src, aux_v));
146 m_candidate_list.push_back(std::make_pair(aux_v, aux_src));
155 template <
typename Problem,
typename LP,
typename Vertex>
156 double degree_of(
const Problem &problem,
const Vertex &v,
const LP &lp) {
159 for (
auto e : boost::as_array(out_edges(v, problem.get_graph()))) {
160 auto col_id = problem.edge_to_col(e);
175 double find_violation(AuxVertex src, AuxVertex trg) {
176 double orig_cap = m_min_cut.
get_capacity(m_src_to_v[src]);
178 m_min_cut.
set_capacity(m_src_to_v[src], m_vertices_num);
181 m_min_cut.
set_capacity(m_v_to_trg[trg], m_vertices_num);
183 double min_cut_weight = m_min_cut.
find_min_cut(m_src, m_trg);
184 double violation = m_vertices_num - 1 - min_cut_weight;
200 AuxEdgeList m_src_to_v;
201 AuxEdgeList m_v_to_trg;
203 CandidateList m_candidate_list;
205 min_cut_finder m_min_cut;
210 #endif // PAAL_BOUNDED_DEGREE_MST_ORACLE_HPP
std::pair< Edge, Edge > add_edge_to_graph(Vertex src, Vertex trg, double cap, double rev_cap=0.)
bool is_in_source_set(Vertex v) const
const CandidateList & get_violation_candidates(const Problem &problem, const LP &lp)
void set_capacity(Edge e, double cap)
The common LP solvers base class. Responsible for:
Violations checker for the separation oracle in the bounded degree minimum spanning tree problem...
double find_min_cut(Vertex src, Vertex trg)
double get_capacity(Edge e) const
double get_col_value(col_id col) const
row_id add_row(const double_bounded_expression &constraint=double_bounded_expression{}, const std::string &name="")
void add_violated_constraint(Candidate violating_pair, const Problem &problem, LP &lp)
Vertex add_vertex_to_graph()
int source_set_size() const
void init(int vertices_num)
std::pair< Vertex, Vertex > get_last_cut() const
Violation check_violation(Candidate candidate, const Problem &problem)