16 #ifndef PAAL_STEINER_NETWORK_ORACLE_HPP
17 #define PAAL_STEINER_NETWORK_ORACLE_HPP
21 #include <boost/range/as_array.hpp>
32 using AuxVertex = min_cut_finder::Vertex;
33 using Violation = double;
36 using Candidate = std::pair<AuxVertex, AuxVertex>;
41 template <
typename Problem>
43 auto const &g = problem.get_graph();
44 auto const &index = problem.get_index();
45 m_min_cut.
init(num_vertices(g));
47 for (
auto e : boost::as_array(edges(g))) {
48 auto u =
get(index, source(e, g));
49 auto v =
get(index, target(e, g));
53 for (
auto res : problem.get_restrictions_vec()) {
65 template <
typename Problem,
typename LP>
67 ->decltype(problem.get_restrictions_vec()) {
69 fill_auxiliary_digraph(problem, lp);
70 return problem.get_restrictions_vec();
77 template <
typename Problem>
80 find_violation(candidate.first, candidate.second, problem);
81 if (problem.get_compare().g(violation, 0)) {
91 template <
typename Problem,
typename LP>
95 find_violation(violation.first, violation.second, problem);
98 auto const &g = problem.get_graph();
99 auto const &index = problem.get_index();
101 problem.get_max_restriction(violation.first, violation.second);
103 for (
auto const &e : problem.get_edges_in_solution()) {
104 if (is_edge_in_violating_cut(e, g, index)) {
110 for (
auto const &e : problem.get_edge_map()) {
111 if (is_edge_in_violating_cut(e.second, g, index)) {
116 lp.
add_row(std::move(expr) >= restriction);
125 template <
typename Edge,
typename Graph,
typename Index>
126 bool is_edge_in_violating_cut(Edge edge,
const Graph &g,
127 const Index &index) {
128 auto u =
get(index, source(edge, g));
129 auto v =
get(index, target(edge, g));
136 template <
typename Problem,
typename LP>
137 void fill_auxiliary_digraph(Problem &problem,
const LP &lp) {
138 auto const &g = problem.get_graph();
139 auto const &index = problem.get_index();
140 m_min_cut.
init(num_vertices(g));
142 for (
auto const &e : problem.get_edge_map()) {
146 if (problem.get_compare().g(col_val, 0)) {
147 auto u =
get(index, source(e.second, g));
148 auto v =
get(index, target(e.second, g));
153 for (
auto const &e : problem.get_edges_in_solution()) {
154 auto u =
get(index, source(e, g));
155 auto v =
get(index, target(e, g));
168 template <
typename Problem>
169 double find_violation(AuxVertex src, AuxVertex trg,
170 const Problem &problem) {
171 double min_cut_weight = m_min_cut.
find_min_cut(src, trg);
172 double restriction = problem.get_max_restriction(src, trg);
173 return restriction - min_cut_weight;
176 min_cut_finder m_min_cut;
181 #endif // PAAL_STEINER_NETWORK_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
The common LP solvers base class. Responsible for:
void add_violated_constraint(Candidate violation, const Problem &problem, LP &lp)
Violations checker for the separation oracle in the steiner network problem.
Violation check_violation(Candidate candidate, const Problem &problem)
double find_min_cut(Vertex src, Vertex trg)
double get_col_value(col_id col) const
row_id add_row(const double_bounded_expression &constraint=double_bounded_expression{}, const std::string &name="")
bool check_if_solution_exists(Problem &problem)
void init(int vertices_num)
auto get_violation_candidates(const Problem &problem, const LP &lp) -> decltype(problem.get_restrictions_vec())
std::pair< Vertex, Vertex > get_last_cut() const