All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Pages
local_search.hpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c) 2013 Piotr Wygocki
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 //=======================================================================
16 #ifndef PAAL_LOCAL_SEARCH_HPP
17 #define PAAL_LOCAL_SEARCH_HPP
18 
20 
22 #include "paal/utils/infinity.hpp"
24 
25 #include <boost/fusion/include/vector.hpp>
26 #include <boost/range/algorithm/max_element.hpp>
27 
28 #include <utility>
29 #include <algorithm>
30 #include <functional>
31 
32 namespace paal {
33 namespace local_search {
34 
35 namespace detail {
36  template <typename Delta>
37  bool positive_delta(Delta && d) {
38  return d > typename std::decay<Delta>::type{};
39  }
40 }
41 
47 
56  template <typename componentsAndSolution>
57  bool operator()(componentsAndSolution &compsAndSol) const {
58  auto &solution = compsAndSol.second;
59  auto &comps = compsAndSol.first;
60  auto && adjustmentSet = comps.template call<GetMoves>(solution);
61 
62  for (auto && move : adjustmentSet) {
63  if (detail::positive_delta(comps.template call<Gain>(solution, move))) {
64  if (comps.template call<Commit>(solution, move)) {
65  return true;
66  }
67  }
68  }
69 
70  return false;
71  }
72 };
73 
86  template <typename SearchJoin> bool operator()(SearchJoin &join) const {
87  return m_satisfy(m_pred, join);
88  }
89 
90  private:
92  data_structures::Satisfy m_satisfy;
93 };
94 
99 struct max_functor {
100 
115  template <typename componentsAndSolution, typename AccumulatorFunctor,
116  typename AccumulatorData, typename Continuation>
117  bool operator()(componentsAndSolution &compsAndSol,
118  AccumulatorFunctor accumulatorFunctor,
119  AccumulatorData accumulatorData,
120  Continuation continuation) const {
121  auto &comps = compsAndSol.first;
122  auto &solution = compsAndSol.second;
123  auto && adjustmentSet = comps.template call<GetMoves>(solution);
124 
125  //thanks to this checks move doesn't have to be default constructible
126  if (boost::empty(adjustmentSet)) {
127  return continuation(accumulatorFunctor, accumulatorData);
128  }
129 
130  auto maxMove = *std::begin(adjustmentSet);
131  auto maxGain = comps.template call<Gain>(solution, maxMove);
132 
133  for (auto && move : boost::make_iterator_range(
134  ++std::begin(adjustmentSet), std::end(adjustmentSet))) {
135  auto gain = comps.template call<Gain>(solution, move);
136  if (gain > maxGain) {
137  maxMove = move;
138  maxGain = gain;
139  }
140  }
141 
142  if (maxGain > accumulatorData) {
143  auto commit = std::bind(std::ref(comps.template get<Commit>()),
144  std::ref(solution), maxMove);
145  return continuation(commit, maxGain);
146  } else {
147  return continuation(accumulatorFunctor, accumulatorData);
148  }
149  }
150 };
151 
165  template <typename SearchJoin> bool operator()(SearchJoin &join) const {
166  return m_fold(m_fun, utils::always_false{}, 0, join);
167  }
168 
169  private:
170  max_functor m_fun;
172 };
173 
188  template <typename SearchJoin> bool operator()(SearchJoin &join) const {
189  return m_fold(m_fun, utils::always_false{}, minus_infinity{}, join);
190  }
191 
192  private:
193  max_functor m_fun;
195 };
196 
197 namespace detail {
198 
199 template <typename Solution, typename... SearchComponentsPack>
201 
202 template <typename Solution, typename SearchComponents,
203  typename... SearchComponentsPack>
205  Solution, SearchComponents,
206  SearchComponentsPack...> : public local_search_concepts<
207  Solution, SearchComponentsPack...> {
208  BOOST_CONCEPT_ASSERT(
210 };
211 
212 template <typename Solution> struct local_search_concepts<Solution> {};
213 
214 }
215 
228 template <typename SearchStrategy, typename ContinueOnSuccess,
229  typename ContinueOnFail, typename Solution, typename... components>
230 bool local_search(Solution &solution, SearchStrategy searchStrategy,
231  ContinueOnSuccess succ, ContinueOnFail fail,
232  components... comps) {
233  detail::local_search_concepts<Solution, components...> concepts;
234  boost::ignore_unused_variable_warning(concepts);
235 
236  using search_components_v =
237  boost::fusion::vector<std::pair<components, Solution &>...>;
238 
239  search_components_v search_comps(
240  std::pair<components, Solution &>(std::move(comps), solution)...);
241 
242  bool success{ false }, ret{ false };
243 
244  while ((success = searchStrategy(search_comps)) || fail(solution)) {
245  ret |= success;
246  if (success && !succ(solution)) {
247  break;
248  }
249  }
250  return success | ret;
251 }
252 
262 template <typename Solution, typename... components>
263 bool first_improving(Solution &solution, components... comps) {
264  return local_search(solution, first_improving_strategy{},
266  std::move(comps)...);
267 }
268 
280 template <typename Solution, typename... components>
281 bool best_improving(Solution &solution, components... comps) {
282  return local_search(solution, best_improving_strategy{},
284  std::move(comps)...);
285 }
286 
301 template <typename Solution, typename ContinueOnSuccess, typename... components>
302 bool best(Solution &solution, ContinueOnSuccess on_success,
303  components... comps) {
304  return local_search(solution, best_strategy{}, std::move(on_success),
305  utils::always_false{}, std::move(comps)...);
306 }
307 
308 } // local_search
309 } // paal
310 
311 #endif // PAAL_LOCAL_SEARCH_HPP
This strategy chooses the best possible move and if it is improving applies it to the solution...
Find for StaticLazyJoin.
This strategy chooses the best possible move and applies it to the solution. Note that this strategy ...
functor return false
Definition: functors.hpp:222
class for polymorphic join on boost fusion sequence
data_structures::components< GetMoves, Gain, Commit > components
Definition for the components class for local search usually this class is not directly used...
bool first_improving(Solution &solution, components...comps)
bool operator()(SearchJoin &join) const
operator()
bool best(Solution &solution, ContinueOnSuccess on_success, components...comps)
This local search chooses the best possible move and applies it to the solution. Note that this strat...
bool best_improving(Solution &solution, components...comps)
This local search chooses the best possible move and if the move is improving applies it to the solut...
bool operator()(componentsAndSolution &compsAndSol, AccumulatorFunctor accumulatorFunctor, AccumulatorData accumulatorData, Continuation continuation) const
operator()
this predicates returns true if there is a move with positive gain and the commit was successful ...
if the sign = true, class represents plus_infinity: object bigger than everything if the sign = false...
Definition: infinity.hpp:27
bool operator()(componentsAndSolution &compsAndSol) const
operator()
bool local_search(Solution &solution, SearchStrategy searchStrategy, ContinueOnSuccess succ, ContinueOnFail fail, components...comps)
detail
functor used in fold in order to find the most improving move.
This strategy uses find_positive_predicate as stop condition.
functor return true
Definition: functors.hpp:227
bool operator()(SearchJoin &join) const
operator()
bool operator()(SearchJoin &join) const
operator()