All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Macros Pages
fractional_winner_determination_in_MUCA.hpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c) 2013 Robert Rosolek
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_FRACTIONAL_WINNER_DETERMINATION_IN_MUCA_HPP
16 #define PAAL_FRACTIONAL_WINNER_DETERMINATION_IN_MUCA_HPP
17 
21 #include "paal/lp/glp.hpp"
24 #include "paal/utils/concepts.hpp"
25 #include "paal/utils/functors.hpp"
27 
28 #include <boost/concept/requires.hpp>
29 #include <boost/property_map/property_map.hpp>
30 #include <boost/range/combine.hpp>
31 #include <boost/range/counting_range.hpp>
32 
33 #include <iterator>
34 #include <random>
35 #include <tuple>
36 #include <type_traits>
37 
38 namespace paal {
39 namespace auctions {
40 
41 namespace detail {
42 
43  template <class Bidder, class BidId, class Bundle>
44  struct bid {
45  Bidder m_bidder;
46  BidId m_bid_id;
47  Bundle m_bundle;
48  bid(Bidder bidder, BidId bid_id, Bundle bundle) :
49  m_bidder(bidder), m_bid_id(bid_id), m_bundle(bundle) {}
50  };
51 }
52 
53 
74 template <
75  class DemandQueryAuction,
76  class OutputIterator,
77  class ItemToLpIdMap,
78  class SeparationOracle = paal::lp::random_violated_separation_oracle
79 >
80 BOOST_CONCEPT_REQUIRES(
81 
83 
84  ((boost::ForwardRangeConcept<
85  typename demand_query_auction_traits<DemandQueryAuction>::bidders_universe_t
86  >))
87 
88  ((boost::ForwardRangeConcept<
89  typename demand_query_auction_traits<DemandQueryAuction>::items_t
90  >))
91 
93  typename demand_query_auction_traits<DemandQueryAuction>::items_t
94  >))
95 
97  OutputIterator,
98  std::tuple<
99  typename demand_query_auction_traits<DemandQueryAuction>::bidder_t,
100  typename demand_query_auction_traits<DemandQueryAuction>::items_t,
101  double
102  >
103  >))
104 
105  ((boost::ReadWritePropertyMapConcept<
106  ItemToLpIdMap,
107  typename demand_query_auction_traits<DemandQueryAuction>::item_t
108  >)),
109 
110  // TODO concept check for SeparationOracle
111 
112 (void))
114  DemandQueryAuction&& auction,
115  OutputIterator result,
116  ItemToLpIdMap item_to_id,
117  double epsilon,
118  SeparationOracle separation_oracle = SeparationOracle{}
119 ) {
120  using traits_t = demand_query_auction_traits<DemandQueryAuction>;
121  using bundle_t = typename traits_t::items_t;
122  using bidder_t = typename traits_t::bidder_t;
123  using bid_t = detail::bid<bidder_t, lp::row_id, bundle_t>;
124  using result_t = typename traits_t::result_t;
125 
126  lp::glp dual;
127  dual.set_optimization_type(lp::MINIMIZE);
128 
129  // add items variables to the dual
130  auto&& items_ = auction.template get<items>();
131  for (auto item = std::begin(items_); item != std::end(items_); ++item) {
132  auto const copies = auction.template call<get_copies_num>(*item);
133  auto const id = dual.add_column(copies, 0, lp::lp_traits::PLUS_INF, "");
134  put(item_to_id, *item, id);
135  }
136 
137  // add bidders variables to the dual
138  // TODO allow to change the allocator
139  std::vector<lp::col_id> bidder_to_id(bidders_number(auction));
140  for (auto& id: bidder_to_id)
141  id = dual.add_column(1, 0, lp::lp_traits::PLUS_INF, "");
142 
143  // TODO allow to change the allocator
144  std::vector<bid_t> generated_bids;
145 
146  auto item_to_id_func = utils::make_property_map_get(item_to_id);
147  auto get_price = utils::compose(
148  [&](lp::col_id id) { return dual.get_col_value(id); },
149  item_to_id_func
150  );
151 
152  boost::optional<result_t> res;
153  boost::optional<bidder_t> last_bidder;
154 
155  auto how_much_violated =
156  utils::make_tuple_uncurry([&](bidder_t bidder, lp::col_id bidder_id)
157  {
158  //check if there is a violated constraint for bidder
159  last_bidder = bidder;
160  res = auction.template call<demand_query>(bidder, get_price);
161  auto const util = res->second;
162  auto const alpha = util - dual.get_col_value(bidder_id);
163  if (alpha > epsilon) return boost::optional<double>(alpha);
164  return boost::optional<double>{};
165  });
166 
167  auto add_violated =
168  utils::make_tuple_uncurry([&](bidder_t bidder, lp::col_id bidder_id) {
169  assert(last_bidder);
170  if (bidder != *last_bidder) {
171  res = auction.template call<demand_query>(bidder, get_price);
172  }
173 
174  auto& items = res->first;
175  auto const util = res->second;
176 
177  // add violated constraint
178  auto const price = sum_functor(items, get_price);
179  auto const value = util + price;
180  auto const expr = accumulate_functor(items,
181  lp::linear_expression(bidder_id), item_to_id_func);
182  auto const bid_id = dual.add_row(expr >= value);
183  generated_bids.emplace_back(bidder, bid_id, std::move(items));
184  });
185 
186  auto get_candidates = utils::make_dynamic_return_constant_functor(
187  boost::combine(auction.template get<bidders>(), bidder_to_id));
188 
189  // TODO check if max_violated strategy doesn't give better performance
190  auto find_violated = separation_oracle(get_candidates, how_much_violated, add_violated);
191 
192  auto solve_lp = [&]()
193  {
194  auto const res = dual.resolve_simplex(lp::DUAL);
195  assert(res == lp::OPTIMAL);
196  return res;
197  };
198 
199  paal::lp::row_generation(find_violated, solve_lp);
200 
201  // emit results
202  for (auto& bid: generated_bids) {
203  auto const fraction = dual.get_row_dual_value(bid.m_bid_id);
204  if (fraction <= epsilon) continue;
205  *result = std::make_tuple(std::move(bid.m_bidder),
206  std::move(bid.m_bundle), fraction);
207  ++result;
208  }
209 }
210 
223 template <class DemandQueryAuction, class OutputIterator>
225  DemandQueryAuction&& auction,
226  OutputIterator result,
227  double epsilon = 1e-7
228 ) {
230  using ItemVal = typename traits_t::item_val_t;
231 
232  std::unordered_map<ItemVal, lp::col_id> map;
234  std::forward<DemandQueryAuction>(auction),
235  result,
236  boost::make_assoc_property_map(map),
237  epsilon
238  );
239 }
240 
241 }
242 }
243 
244 #endif /* PAAL_FRACTIONAL_WINNER_DETERMINATION_IN_MUCA_HPP */
Utils for the Boost PropertyMap.
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
void fractional_determine_winners_in_demand_query_auction(DemandQueryAuction &&auction, OutputIterator result, ItemToLpIdMap item_to_id, double epsilon, SeparationOracle separation_oracle=SeparationOracle{})
detail
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.
auto make_tuple_uncurry(F f)
make for tuple_uncurry
Definition: functors.hpp:217
auto make_dynamic_return_constant_functor(T t)
make function for dynamic_return_constant_functor
Definition: functors.hpp:121
problem_type row_generation(TryAddViolated try_add_violated, SolveLp solve_lp)
std::string Bidder
[Demand Query Auction Components Example]
auto compose(F f, G g)
functor composition: x -&gt; f(g(x))
Definition: functors.hpp:153
This file contains set of simple useful functors or functor adapters.
T accumulate_functor(const Range &rng, T init, Functor f, BinaryOperation bin_op=BinaryOperation{})
combination of boost::accumulate and boost::adaptors::transformed
double get_col_value(col_id col) const
Definition: lp_base.hpp:228
auto sum_functor(const Range &rng, Functor f)
sum of functor values over the range elements
property_map_get< Map > make_property_map_get(Map map)
make for property_map_get
row_id add_row(const double_bounded_expression &constraint=double_bounded_expression{}, const std::string &name="")
Definition: lp_base.hpp:109
Concept class for move constructible types.
Definition: concepts.hpp:47
Types associated with demand query auction.