All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Pages
iterative_rounding_example.cpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //=======================================================================
22 #include "paal/utils/floating.hpp"
23 #include "paal/utils/functors.hpp"
24 
25 #include <boost/graph/adjacency_list.hpp>
26 #include <boost/range/iterator_range.hpp>
27 
28 #include <iostream>
29 #include <unordered_map>
30 
31 namespace ir = paal::ir;
32 
33 template <typename Graph, typename CostMap, typename OutputIter>
34 class vertex_cover {
35 public:
36  vertex_cover(const Graph & g, CostMap cost_map, OutputIter cover) :
37  m_g(g), m_cost_map(cost_map), m_cover(cover) {}
38 
39  using Vertex = typename boost::graph_traits<Graph>::vertex_descriptor;
40  using VertexMap = std::unordered_map<Vertex, paal::lp::col_id>;
41 
42  const Graph &get_graph() const { return m_g; }
43 
44  auto get_cost(Vertex v)->decltype(std::declval<CostMap>()(v)) {
45  return m_cost_map(v);
46  }
47 
48  void bind_col_to_vertex(paal::lp::col_id col, Vertex v) {
49  m_vertex_map.insert(typename VertexMap::value_type(v, col));
50  }
51 
52  paal::lp::col_id vertex_to_column(Vertex v) { return m_vertex_map[v]; }
53 
54  void add_to_cover(Vertex v) {
55  *m_cover = v;
56  ++m_cover;
57  }
58 
59  private:
60  const Graph &m_g;
61  CostMap m_cost_map;
62  OutputIter m_cover;
63  VertexMap m_vertex_map;
64 };
66 
69  template <typename Problem, typename LP>
70  void operator()(Problem &problem, LP &lp) {
71  lp.set_optimization_type(paal::lp::MINIMIZE);
72 
73  // variables for vertices
74  for (auto v :
75  boost::make_iterator_range(vertices(problem.get_graph()))) {
76  problem.bind_col_to_vertex(lp.add_column(problem.get_cost(v)), v);
77  }
78 
79  // x_u + x_v >= 1 for each edge e=(u,v)
80  for (auto e : boost::make_iterator_range(edges(problem.get_graph()))) {
81  auto x_u = problem.vertex_to_column(source(e, problem.get_graph()));
82  auto x_v = problem.vertex_to_column(target(e, problem.get_graph()));
83  lp.add_row(x_u + x_v >= 1);
84  }
85  }
86 };
87 
89  template <typename Problem, typename GetSolution>
90  void operator()(Problem &problem, const GetSolution &solution) {
91  // add vertices with column value equal 1 to cover
92  for (auto v :
93  boost::make_iterator_range(vertices(problem.get_graph()))) {
94  if (m_compare.e(solution(problem.vertex_to_column(v)), 1)) {
95  problem.add_to_cover(v);
96  }
97  }
98  }
99 
100 private:
101  const paal::utils::compare<double> m_compare;
102 };
103 
104 using vertex_cover_ir_components =
108 
110 int main() {
111  using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
112  boost::no_property, boost::no_property>;
113  using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
114 
115  // sample problem
116  std::vector<std::pair<int, int>> edges{ { 0, 1 }, { 0, 2 }, { 1, 2 },
117  { 1, 3 }, { 1, 4 }, { 1, 5 },
118  { 5, 0 }, { 3, 4 } };
119  std::vector<int> costs{ 1, 2, 1, 2, 1, 5 };
120 
121  Graph g(edges.begin(), edges.end(), 6);
122  auto vertex_costs = paal::utils::make_array_to_functor(costs);
123  std::vector<Vertex> result_cover;
124  auto insert_iter = std::back_inserter(result_cover);
125 
127  g, vertex_costs, insert_iter);
128 
129  // solve it
130  auto result =
131  ir::solve_iterative_rounding(problem, vertex_cover_ir_components());
132 
133  // print result
134  if (result.first == paal::lp::OPTIMAL) {
135  std::cout << "Vertices in the cover:" << std::endl;
136  for (auto v : result_cover) {
137  std::cout << "Vertex " << v << std::endl;
138  }
139  std::cout << "Cost of the solution: " << *(result.second) << std::endl;
140  } else {
141  std::cout << "The instance is infeasible" << std::endl;
142  }
143  paal::lp::glp::free_env();
144  return 0;
145 }
[Iterative Rounding Problem Example]
The common LP solvers base class. Responsible for:
Definition: lp_base.hpp:55
col_id add_column(double cost_coef=0, double lb=0., double ub=lp_traits::PLUS_INF, const std::string &name="")
Definition: lp_base.hpp:92
functor return false
Definition: functors.hpp:222
This file contains set of simple useful functors or functor adapters.
auto make_array_to_functor(const Array &a, int offset=0)
make function for array_to_functor
Definition: functors.hpp:364
Column rounding component. A variable is rounded up to 1, if it has value at least half in the soluti...
typename components::type< Args...> IRcomponents
Iterative rounding components.
row_id add_row(const double_bounded_expression &constraint=double_bounded_expression{}, const std::string &name="")
Definition: lp_base.hpp:109
IRResult solve_iterative_rounding(Problem &problem, IRcomponents components, Visitor visitor=Visitor())
Solves an Iterative Rounding problem.
bool e(T a, T b) const
equals
Definition: floating.hpp:33
[Iterative Rounding Problem Example]
int main()
[Iterative Rounding Components Example]