All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Pages
xor_bids.hpp
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 //=======================================================================
15 #ifndef PAAL_XOR_BIDS_HPP
16 #define PAAL_XOR_BIDS_HPP
17 
21 #include "paal/utils/functors.hpp"
23 
24 #include <boost/algorithm/cxx11/all_of.hpp>
25 #include <boost/concept_check.hpp>
26 #include <boost/concept/requires.hpp>
27 #include <boost/optional/optional.hpp>
28 #include <boost/range/adaptor/filtered.hpp>
29 #include <boost/range/algorithm/copy.hpp>
30 #include <boost/range/iterator.hpp>
31 
32 #include <iterator>
33 #include <type_traits>
34 #include <utility>
35 
36 namespace detail {
37  // forward declaration for making this class a friend of xor_bids_gamma_oracle
38  template<class GetBids, class GetValue, class GetItems, class Gamma>
40 }
41 
42 namespace paal {
43 namespace auctions {
44 
45  namespace concepts {
46 
47  template <
48  class Bidders,
49  class Items,
50  class GetBids,
51  class GetValue,
52  class GetItems,
53  class GetCopiesNum
54  >
55  class xor_bids {
56  Bidders bidders;
57  Items items;
58  GetBids get_bids;
59  GetValue get_value;
60  GetItems get_items;
61  GetCopiesNum get_copies_num;
62 
63  xor_bids() {}
64 
65  public:
66  BOOST_CONCEPT_USAGE(xor_bids)
67  {
68  auto&& bids = get_bids(*std::begin(bidders));
69  BOOST_CONCEPT_ASSERT((boost::ForwardRangeConcept<
70  decltype(bids)>));
71  auto bid = std::begin(bids);
72  using value_t = puretype(get_value(*bid));
73  static_assert(std::is_arithmetic<value_t>::value,
74  "get_value return type is not arithmetic!");
75  auto&& bid_items = get_items(*bid);
76  using bundle_t = puretype(bid_items);
77  static_assert(std::is_move_constructible<bundle_t>::value,
78  "bundle_t is not move constructible!");
79  static_assert(std::is_default_constructible<bundle_t>::value,
80  "bundle_t is not default constructible!");
81  BOOST_CONCEPT_ASSERT((boost::ForwardRangeConcept<
82  decltype(bid_items)>));
83  }
84  };
85  }
86 
87  namespace detail {
88 
89  template <class Bidder, class GetBids, class GetValue, class GetItems>
90  struct xor_bids_traits {
91  using bid_iterator =
92  typename boost::range_iterator<typename std::result_of<
93  GetBids(Bidder)>::type>::type;
94  using bid = typename std::iterator_traits<bid_iterator>::reference;
95  using value = pure_result_of_t<GetValue(bid)>;
96  using items = typename std::result_of<GetItems(bid)>::type;
97  using items_val = typename std::decay<items>::type;
98  using item = range_to_ref_t<items>;
99  template <class GetPrice>
100  using price = pure_result_of_t<GetPrice(item)>;
101  };
102 
103  template <class GetBids, class GetValue, class GetItems>
105 
106  GetBids m_get_bids;
107  GetValue m_get_value;
108  GetItems m_get_items;
109 
110  template <class Bidder>
112 
113  public:
114  xor_bids_value_query(GetBids get_bids, GetValue get_value, GetItems get_items)
115  : m_get_bids(get_bids), m_get_value(get_value), m_get_items(get_items) {}
116 
117  template <
118  class Bidder,
119  class ItemSet,
120  class Traits = traits<Bidder>,
121  class Value = typename Traits::value
122  >
123  Value operator()(Bidder&& bidder, const ItemSet& item_set) const
124  {
125  using Bid = typename Traits::bid;
126  using Item = typename Traits::item;
127 
128  auto is_contained = [&](Bid b)
129  {
130  return boost::algorithm::all_of(
131  m_get_items(std::forward<Bid>(b)),
132  [&](Item i) { return item_set.count(std::forward<Item>(i)) > 0; }
133  );
134  };
135  return accumulate_functor(
136  m_get_bids(std::forward<Bidder>(bidder)) |
137  boost::adaptors::filtered(is_contained),
138  Value(0),
139  m_get_value,
141  );
142  }
143  };
144  };
145 
162  template<
163  class Bidders,
164  class Items,
165  class GetBids,
166  class GetValue,
167  class GetItems,
168  class GetCopiesNum = utils::return_one_functor
169  >
171  Bidders&& bidders,
172  Items&& items,
173  GetBids get_bids,
174  GetValue get_value,
175  GetItems get_items,
176  GetCopiesNum get_copies_num = GetCopiesNum{}
177  ) ->
179  std::forward<Bidders>(bidders),
180  std::forward<Items>(items),
181  detail::xor_bids_value_query<GetBids, GetValue, GetItems>(get_bids, get_value, get_items),
182  get_copies_num
183  ))
184  {
185  BOOST_CONCEPT_ASSERT((concepts::xor_bids<Bidders, Items, GetBids, GetValue, GetItems, GetCopiesNum>));
187  std::forward<Bidders>(bidders),
188  std::forward<Items>(items),
189  detail::xor_bids_value_query<GetBids, GetValue, GetItems>(get_bids, get_value, get_items),
190  get_copies_num
191  );
192  }
193 
194  namespace detail {
195 
196  template <class GetBids, class GetValue, class GetItems>
198 
199  GetBids m_get_bids;
200  GetValue m_get_value;
201  GetItems m_get_items;
202 
203  template <class Bidder>
205 
206  template <class Bidder, class GetPrice, class Base = traits<Bidder>>
207  struct price_traits : Base {
208  using price = typename Base::template price<GetPrice>;
210  };
211 
212  public:
213  xor_bids_demand_query(GetBids get_bids, GetValue get_value,
214  GetItems get_items) : m_get_bids(get_bids),
215  m_get_value(get_value), m_get_items(get_items) {}
216 
217  template <class Bidder, class GetPrice>
218  auto operator()(Bidder&& bidder, GetPrice get_price) const
219  {
220  using Traits = price_traits<Bidder, GetPrice>;
221  using Items = typename Traits::items_val;
222  using Res = std::pair<Items, typename Traits::utility>;
223 
224  Res best = {Items{}, 0};
225  auto&& bids = m_get_bids(std::forward<Bidder>(bidder));
226  for (auto bid = std::begin(bids); bid != std::end(bids); ++bid) {
227  auto const value = m_get_value(*bid);
228  auto const price =
229  sum_functor(m_get_items(*bid), get_price);
230  auto const util = value - price;
231  if (util > best.second)
232  best = {m_get_items(*bid), util};
233  }
234  return best;
235  }
236  };
237 
238  }
239 
256  template<
257  class Bidders,
258  class Items,
259  class GetBids,
260  class GetValue,
261  class GetItems,
262  class GetCopiesNum = utils::return_one_functor
263  >
265  Bidders&& bidders,
266  Items&& items,
267  GetBids get_bids,
268  GetValue get_value,
269  GetItems get_items,
270  GetCopiesNum get_copies_num = GetCopiesNum{})
271  {
272  BOOST_CONCEPT_ASSERT((concepts::xor_bids<Bidders, Items, GetBids,
273  GetValue, GetItems, GetCopiesNum>));
275  std::forward<Bidders>(bidders),
276  std::forward<Items>(items),
277  detail::xor_bids_demand_query<GetBids, GetValue, GetItems>(get_bids,
278  get_value, get_items),
279  get_copies_num
280  );
281  }
282 
283  namespace detail {
284 
285  template<class GetBids, class GetValue, class GetItems>
287 
288  GetBids m_get_bids;
289  GetValue m_get_value;
290  GetItems m_get_items;
291 
292  template <
293  class GetBids_,
294  class GetValue_,
295  class GetItems_,
296  class Gamma_
297  >
298  friend class ::detail::test_xor_bids_gamma_oracle;
299 
300  template <class Bidder>
302 
303  template <class Bidder, class GetPrice, class Base = traits<Bidder>>
304  struct price_traits : public Base {
305  using price = typename Base::template price<GetPrice>;
306  using frac =
308  using best_bid =
309  boost::optional<std::pair<typename Base::bid_iterator, frac>>;
310  };
311 
312  template <
313  class Bidder,
314  class GetPrice,
315  class Threshold,
316  class IsBetter,
317  class BestBid = typename price_traits<Bidder, GetPrice>::best_bid
318  >
319  BestBid
320  calculate_best(
321  Bidder&& bidder,
322  GetPrice get_price,
323  Threshold threshold,
324  IsBetter is_better
325  ) const
326  {
327  BestBid result{};
328  auto&& bids = m_get_bids(std::forward<Bidder>(bidder));
329  for (auto bid = std::begin(bids); bid != std::end(bids); ++bid) {
330  auto const value = m_get_value(*bid);
331  if (value <= threshold) continue;
332  auto const price = sum_functor(m_get_items(*bid),
333  get_price);
334  auto const frac =
335  data_structures::make_fraction(price, value - threshold);
336  if (is_better(frac, result))
337  result = std::make_pair(bid, frac);
338  }
339  return result;
340  }
341 
342  template <
343  class Bidder,
344  class GetPrice,
345  class Threshold,
346  class Traits = price_traits<Bidder, GetPrice>,
347  class BestBid = typename Traits::best_bid
348  >
349  BestBid
350  minimum_frac(Bidder&& bidder, GetPrice get_price, Threshold threshold)
351  const
352  {
353  return calculate_best(
354  std::forward<Bidder>(bidder),
355  get_price,
356  threshold,
357  [&](typename Traits::frac frac, const BestBid& result)
358  {
359  return !result || frac < result->second;
360  }
361  );
362  }
363 
364  template <class Result, class OutputIterator>
365  auto output(const Result& result, OutputIterator out) const
366  {
367  auto bid = result.first;
368  auto frac = result.second;
369  boost::copy(m_get_items(*bid), out);
370  return frac;
371  }
372 
373  public:
374  xor_bids_gamma_oracle(GetBids get_bids, GetValue get_value, GetItems get_items)
375  : m_get_bids(get_bids), m_get_value(get_value), m_get_items(get_items) {}
376 
377  template <
378  class Bidder,
379  class GetPrice,
380  class Threshold,
381  class Traits = price_traits<Bidder, GetPrice>
382  >
383  boost::optional<std::pair<typename Traits::items_val, typename Traits::frac>>
384  operator()(Bidder&& bidder, GetPrice get_price, Threshold threshold) const
385  {
386  auto const best = minimum_frac(std::forward<Bidder>(bidder),
387  get_price, threshold);
388  if (!best) return boost::none;
389  return std::make_pair(m_get_items(*best->first), best->second);
390  }
391  };
392  };
393 
410  template<
411  class Bidders,
412  class Items,
413  class GetBids,
414  class GetValue,
415  class GetItems,
416  class GetCopiesNum = utils::return_one_functor
417  >
419  Bidders&& bidders,
420  Items&& items,
421  GetBids get_bids,
422  GetValue get_value,
423  GetItems get_items,
424  GetCopiesNum get_copies_num = GetCopiesNum{}
425  )
427  std::forward<Bidders>(bidders),
428  std::forward<Items>(items),
429  detail::xor_bids_gamma_oracle<GetBids, GetValue, GetItems>(get_bids, get_value, get_items),
430  1,
431  get_copies_num
432  ))
433  {
434  BOOST_CONCEPT_ASSERT((concepts::xor_bids<Bidders, Items, GetBids, GetValue, GetItems, GetCopiesNum>));
436  std::forward<Bidders>(bidders),
437  std::forward<Items>(items),
438  detail::xor_bids_gamma_oracle<GetBids, GetValue, GetItems>(get_bids, get_value, get_items),
439  1,
440  get_copies_num
441  );
442  }
443 
457  template<class Bidders, class GetBids, class GetItems, class OutputIterator>
459  Bidders&& bidders,
460  GetBids get_bids,
461  GetItems get_items,
462  OutputIterator output
463  ) {
464  for (auto&& bidder: bidders) {
465  for (auto&& bid: get_bids(std::forward<decltype(bidder)>(bidder))) {
466  boost::copy(get_items(std::forward<decltype(bid)>(bid)), output);
467  }
468  }
469  }
470 
471 }
472 }
473 #endif // PAAL_XOR_BIDS_HPP
auto make_xor_bids_to_demand_query_auction(Bidders &&bidders, Items &&items, GetBids get_bids, GetValue get_value, GetItems get_items, GetCopiesNum get_copies_num=GetCopiesNum{})
detail
Definition: xor_bids.hpp:264
auto make_xor_bids_to_value_query_auction(Bidders &&bidders, Items &&items, GetBids get_bids, GetValue get_value, GetItems get_items, GetCopiesNum get_copies_num=GetCopiesNum{}) -> decltype(make_value_query_auction_components(std::forward< Bidders >(bidders), std::forward< Items >(items), detail::xor_bids_value_query< GetBids, GetValue, GetItems >(get_bids, get_value, get_items), get_copies_num))
detail
Definition: xor_bids.hpp:170
std::string Bidder
[Demand Query Auction Components Example]
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...
auto make_value_query_auction_components(Args &&...args) -> decltype(value_query_components::make_components(std::forward< Args >(args)...))
make function for value query components
auto make_xor_bids_to_gamma_oracle_auction(Bidders &&bidders, Items &&items, GetBids get_bids, GetValue get_value, GetItems get_items, GetCopiesNum get_copies_num=GetCopiesNum{}) -> decltype(make_gamma_oracle_auction_components(std::forward< Bidders >(bidders), std::forward< Items >(items), detail::xor_bids_gamma_oracle< GetBids, GetValue, GetItems >(get_bids, get_value, get_items), 1, get_copies_num))
detail
Definition: xor_bids.hpp:418
#define puretype(t)
for given expression returns its type with removed const and reference
This file contains set of simple useful functors or functor adapters.
fraction< A, B > make_fraction(A a, B b)
make function for fraction
Definition: fraction.hpp:149
T accumulate_functor(const Range &rng, T init, Functor f, BinaryOperation bin_op=BinaryOperation{})
combination of boost::accumulate and boost::adaptors::transformed
auto make_demand_query_auction_components(Args &&...args)
make function for demand query components
void extract_items_from_xor_bids(Bidders &&bidders, GetBids get_bids, GetItems get_items, OutputIterator output)
extract all items appearing in all bids. This function doesn&#39;t eliminate duplicates, this is left out to the caller.
Definition: xor_bids.hpp:458
auto sum_functor(const Range &rng, Functor f)
sum of functor values over the range elements
Implementation of fractions, which are used only for comparison purposes, and thus they can be used w...
typename std::decay< typename std::result_of< F >::type >::type pure_result_of_t
return pure type of function (decays const and reference)
puretype(std::declval< T1 >()+std::declval< T2 >()) promote_with_t
return type obtained after adding values of given types
auto make_gamma_oracle_auction_components(Args &&...args) -> decltype(gamma_oracle_components::make_components(std::forward< Args >(args)...))
make function for gamma oracle components
typename boost::range_reference< Range >::type range_to_ref_t
for given range returns type of its reference
simple class to represent fraction
Definition: fraction.hpp:31