All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Pages
winner_determination_in_MUCA.hpp
1 /*
2  * @file winner_determination_in_MUCA.hpp
3  * @brief
4  * @author Robert Rosolek
5  * @version 1.0
6  * @date 2014-1-7
7  */
8 #ifndef PAAL_WINNER_DETERMINATION_IN_MUCA_HPP
9 #define PAAL_WINNER_DETERMINATION_IN_MUCA_HPP
10 
14 #include "paal/utils/concepts.hpp"
17 
18 #include <boost/concept/requires.hpp>
19 #include <boost/optional/optional.hpp>
20 #include <boost/property_map/property_map.hpp>
21 #include <boost/range/algorithm/transform.hpp>
22 #include <boost/range/concepts.hpp>
23 #include <boost/range/iterator.hpp>
24 
25 #include <iterator>
26 #include <memory>
27 #include <tuple>
28 #include <unordered_map>
29 #include <utility>
30 #include <vector>
31 
32 namespace paal {
33 namespace auctions {
34 
35 namespace detail {
36  template <class Value, class ItemSet>
37  struct bidder_info {
38  Value m_best_items_val;
39  ItemSet m_best_items;
40  };
41 
42  template <
43  class GammaOracleAuction,
45  >
48  using item_set = typename Base::items_t;
50  using result = std::pair<typename Base::bidder_t, item_set>;
51  };
52 }
53 
73 template<
74  class GammaOracleAuction,
75  class OutputIterator,
76  class PriceMap,
77  class Epsilon
78 >
79 BOOST_CONCEPT_REQUIRES(
81 
82  ((boost::ForwardRangeConcept<
83  typename gamma_oracle_auction_traits<GammaOracleAuction>::bidders_universe_t
84  >))
85 
87  typename gamma_oracle_auction_traits<GammaOracleAuction>::items_t
88  >))
89 
91  OutputIterator,
92  std::pair<
93  typename gamma_oracle_auction_traits<GammaOracleAuction>::bidder_t,
94  typename gamma_oracle_auction_traits<GammaOracleAuction>::items_t
95  >
96  >))
97 
98  ((boost::ReadWritePropertyMapConcept<
99  PriceMap,
100  typename gamma_oracle_auction_traits<GammaOracleAuction>::item_t
101  >))
102 
104 
105 (void))
107  GammaOracleAuction&& auction,
108  OutputIterator result,
109  PriceMap price,
110  Epsilon epsilon
111 ) {
112  using Price = typename boost::property_traits<PriceMap>::value_type;
113 
114  using Traits =
116  using Value = typename Traits::value;
117  using BidderInfo = typename Traits::bidder_info;
118  using BidderIter = typename Traits::bidder_iterator_t;
119  using Frac = typename Traits::frac_t;
120  using Res = typename Traits::result_t;
121 
122  Price items_num = 0;
123  for (auto item = std::begin(auction.template get<items>());
124  item != std::end(auction.template get<items>());
125  ++item
126  ) {
127  ++items_num;
128  auto const copies = auction.template call<get_copies_num>(*item);
129  put(price, *item, 1.0 / copies);
130  }
131  Price price_sum = items_num;
132 
133  // TODO allow to change the allocator
134  std::vector<BidderInfo> bidders_info_vec(bidders_number(auction));
135 
136  auto last_assigned_bidder_info = bidders_info_vec.end();
137  BidderIter last_assigned_bidder;
138  Value total_value = 0, last_value{};
139  auto const b = get_minimum_copies_num(auction);
140  auto const multiplier = std::exp(Value(b) + 1) * items_num;
141  auto const gamma_ = auction.template get<gamma>();
142  auto get_threshold = [=](const BidderInfo& b)
143  {
144  return (1 + 2 * gamma_) * b.m_best_items_val;
145  };
146  do {
147  Res best = boost::none;
148  auto get_frac = [](Res r) { return r->second; };
149  auto bidder_info = bidders_info_vec.begin();
150  auto bidder = std::begin(auction.template get<bidders>());
151  for (; bidder_info != bidders_info_vec.end(); ++bidder_info, ++bidder) {
152  auto const threshold = get_threshold(*bidder_info);
153  auto result = auction.template call<gamma_oracle>(
154  *bidder, utils::make_property_map_get(price), threshold
155  );
156  if (!result) continue;
157  if (!best || get_frac(result) < get_frac(best)) {
158  best = std::move(result);
159  last_assigned_bidder_info = bidder_info;
160  last_assigned_bidder = bidder;
161  last_value = get_frac(result).den + threshold;
162  }
163  }
164  if (!best) break;
165  auto& best_items = best->first;
166  for (auto item = std::begin(best_items); item != std::end(best_items); ++item) {
167  auto const copies = auction.template call<get_copies_num>(*item);
168  auto const old_price = get(price, *item);
169  auto const new_price =
170  old_price * std::pow(multiplier, 1.0 / (copies+ 1));
171  put(price, *item, new_price);
172  price_sum += copies* (new_price - old_price);
173  }
174  total_value += last_value - last_assigned_bidder_info->m_best_items_val;
175  last_assigned_bidder_info->m_best_items = std::move(best_items);
176  last_assigned_bidder_info->m_best_items_val = last_value;
177  } while (price_sum + epsilon < multiplier);
178 
179  const bool nothing_assigned =
180  last_assigned_bidder_info == bidders_info_vec.end();
181  if (nothing_assigned) return;
182 
183  auto output = [&](
184  puretype(last_assigned_bidder_info) bidder_info,
185  BidderIter bidder
186  ) {
187  *result = std::make_pair(*bidder, std::move(bidder_info->m_best_items));
188  ++result;
189  };
190  if (last_value > total_value - last_value) {
191  output(last_assigned_bidder_info, last_assigned_bidder);
192  return;
193  }
194  auto bidder_info = bidders_info_vec.begin();
195  auto bidder = std::begin(auction.template get<bidders>());
196  for (; bidder_info != bidders_info_vec.end(); ++bidder_info, ++bidder)
197  if (bidder != last_assigned_bidder)
198  output(bidder_info, bidder);
199 }
200 
213 template <
214  class GammaOracleAuction,
215  class OutputIterator,
216  class Epsilon = double
217 >
219  GammaOracleAuction&& auction,
220  OutputIterator result,
221  Epsilon epsilon = 1e-8
222 ) {
225  using ItemVal = typename Traits::item_val_t;
226 
227  std::unordered_map<ItemVal, Value> umap;
229  std::forward<GammaOracleAuction>(auction),
230  result,
231  boost::make_assoc_property_map(umap),
232  epsilon
233  );
234 }
235 
236 
237 }
238 }
239 
240 #endif /* PAAL_WINNER_DETERMINATION_IN_MUCA_HPP */
Utils for the Boost PropertyMap.
Concept class for output iterator concept. We don&#39;t use boost::OutputIterator concept as it excludes ...
Definition: concepts.hpp:61
auto bidders_number(Auction &&auction)
Returns the number of bidders in an auction.
promote_with_t< T, double > promote_with_double_t
return type after promotion with double
Concept class for floating point types.
Definition: concepts.hpp:36
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...
void determine_winners_in_gamma_oracle_auction(GammaOracleAuction &&auction, OutputIterator result, PriceMap price, Epsilon epsilon)
detail
#define puretype(t)
for given expression returns its type with removed const and reference
Types associated with gamma oracle auction.
property_map_get< Map > make_property_map_get(Map map)
make for property_map_get
Concept class for move constructible types.
Definition: concepts.hpp:47
simple class to represent fraction
Definition: fraction.hpp:31
paal::auctions::auction_traits< Auction >::copies_num_t get_minimum_copies_num(Auction &&auction)
Returns minimum number of copies of an item in an auction.