CYCLUS
exchange_translator.h
Go to the documentation of this file.
1 #ifndef CYCLUS_SRC_EXCHANGE_TRANSLATOR_H_
2 #define CYCLUS_SRC_EXCHANGE_TRANSLATOR_H_
3 
4 #include <sstream>
5 
6 #include "bid.h"
7 #include "bid_portfolio.h"
8 #include "error.h"
9 #include "exchange_graph.h"
11 #include "logger.h"
12 #include "request.h"
13 #include "request_portfolio.h"
14 #include "trade.h"
15 
16 namespace cyclus {
17 
18 template <class T> class ExchangeContext;
19 class Trader;
20 
21 /// @class ExchangeTranslator
22 ///
23 /// @brief An ExchangeTranslator facilitates translation from a resource
24 /// specific exchange to a resource-neutral exchange, upon which generic solvers
25 /// can be applied. Specifically, the ExchangeTranslator constructor takes a
26 /// resource-specific exchange context and provides a Translate() method to make
27 /// a resource-neutral ExchangeGraph. State is maintained in the
28 /// ExchangeTranslator class, mapping Requests and Bids to ExchangeNodes in the
29 /// ExchangeGraph. Accordingly, the solution to the ExchangeGraph, i.e., it's
30 /// Matches, can be back-translated to the original Requests and Bids via a
31 /// BackTranslateSolution() method.
32 template <class T>
34  public:
35  /// @brief default constructor
36  ///
37  /// @param ex_ctx the exchance context
39  ex_ctx_ = ex_ctx;
40  }
41 
42  /// @brief translate the ExchangeContext into an ExchangeGraph
44  ExchangeGraph::Ptr graph(new ExchangeGraph());
45 
46  // add each request group
47  const std::vector<typename RequestPortfolio<T>::Ptr>& requests =
48  ex_ctx_->requests;
49  typename std::vector<typename RequestPortfolio<T>::Ptr>::const_iterator
50  rp_it;
51  for (rp_it = requests.begin(); rp_it != requests.end(); ++rp_it) {
52  CapacityConstraint<T> c((*rp_it)->qty(), (*rp_it)->qty_converter());
53  (*rp_it)->AddConstraint(c);
54 
55  RequestGroup::Ptr rs = TranslateRequestPortfolio(xlation_ctx_, *rp_it);
56  graph->AddRequestGroup(rs);
57  }
58 
59  // add each bid group
60  const std::vector<typename BidPortfolio<T>::Ptr>& bidports = ex_ctx_->bids;
61  typename std::vector<typename BidPortfolio<T>::Ptr>::const_iterator bp_it;
62  for (bp_it = bidports.begin(); bp_it != bidports.end(); ++bp_it) {
63  ExchangeNodeGroup::Ptr ns = TranslateBidPortfolio(xlation_ctx_, *bp_it);
64  graph->AddSupplyGroup(ns);
65 
66  // add each request-bid arc
67  const std::set<Bid<T>*>& bids = (*bp_it)->bids();
68  typename std::set<Bid<T>*>::const_iterator b_it;
69  for (b_it = bids.begin(); b_it != bids.end(); ++b_it) {
70  Bid<T>* bid = *b_it;
71  Request<T>* req = bid->request();
72  AddArc(req, bid, graph);
73  }
74  }
75 
76  return graph;
77  }
78 
79  /// @brief adds a bid-request arc to a graph, if the preference for the arc is
80  /// non-negative
81  void AddArc(Request<T>* req, Bid<T>* bid, ExchangeGraph::Ptr graph) {
82  double pref =
83  ex_ctx_->trader_prefs.at(req->requester())[req][bid];
84  // TODO: make the following check `pref <=0` and remove the `else if` block
85  // before release 1.5
86  if (pref < 0) {
87  CLOG(LEV_DEBUG1) << "Removing arc because of negative preference.";
88  return;
89  } else if (pref == 0) {
90  std::stringstream ss;
91  ss << "0-valued preferences have been deprecated. "
92  << "Please make preference value positive."
93  << "This message will go away in before the next release (1.5).";
94  throw ValueError(ss.str());
95  }
96  // get translated arc
97  Arc a = TranslateArc(xlation_ctx_, bid, pref);
98  a.unode()->prefs[a] = pref; // request node is a.unode()
99  int n_prefs = a.unode()->prefs.size();
100 
101  CLOG(LEV_DEBUG5) << "Updating preference for one of "
102  << req->requester()->manager()->prototype()
103  << "'s trade nodes:";
104  CLOG(LEV_DEBUG5) << " preference: " << a.unode()->prefs[a];
105 
106  graph->AddArc(a);
107  }
108 
109  /// @brief Provide a vector of Trades given a vector of Matches
110  void BackTranslateSolution(const std::vector<Match>& matches,
111  std::vector< Trade<T> >& ret) {
112  std::vector<Match>::const_iterator m_it;
113  CLOG(LEV_DEBUG1) << "Back traslating " << matches.size()
114  << " trade matches.";
115  for (m_it = matches.begin(); m_it != matches.end(); ++m_it) {
116  ret.push_back(BackTranslateMatch(xlation_ctx_, *m_it));
117  }
118  }
119 
121  return xlation_ctx_;
122  }
123 
124  ExchangeTranslationContext<T>& translation_ctx() { return xlation_ctx_; }
125 
126  private:
127  ExchangeContext<T>* ex_ctx_;
128  ExchangeTranslationContext<T> xlation_ctx_;
129 };
130 
131 /// @brief Adds a request-node mapping
132 template <class T>
135  translation_ctx.request_to_node[r] = n;
136  translation_ctx.node_to_request[n] = r;
137 }
138 
139 /// @brief Adds a bid-node mapping
140 template <class T>
142  Bid<T>* b, ExchangeNode::Ptr n) {
143  translation_ctx.bid_to_node[b] = n;
144  translation_ctx.node_to_bid[n] = b;
145 }
146 
147 /// @brief translates a request portfolio by adding request nodes and
148 /// accounting for capacities. Request unit capcities must be added when arcs
149 /// are known
150 template <class T>
153  const typename RequestPortfolio<T>::Ptr rp) {
154  RequestGroup::Ptr rs(new RequestGroup(rp->qty()));
155  CLOG(LEV_DEBUG2) << "Translating request portfolio of size " << rp->qty();
156 
157  typename std::vector<Request<T>*>::const_iterator r_it;
158  for (r_it = rp->requests().begin();
159  r_it != rp->requests().end();
160  ++r_it) {
161  Request<T>* r = *r_it;
163  new ExchangeNode(r->target()->quantity(),
164  r->exclusive(),
165  r->commodity(),
166  r->requester()->manager()->id()));
167  rs->AddExchangeNode(n);
168 
169  AddRequest(translation_ctx, *r_it, n);
170  }
171 
172  CLOG(LEV_DEBUG4) << "adding " << rp->constraints().size()
173  << " request capacities";
174  typename std::set< CapacityConstraint<T> >::const_iterator c_it;
175  for (c_it = rp->constraints().begin();
176  c_it != rp->constraints().end();
177  ++c_it) {
178  rs->AddCapacity(c_it->capacity());
179  }
180 
181  return rs;
182 }
183 
184 /// @brief translates a bid portfolio by adding bid nodes and accounting
185 /// for capacities. Bid unit capcities must be added when arcs are known
186 template <class T>
189  const typename BidPortfolio<T>::Ptr bp) {
191 
192  std::map<typename T::Ptr, std::vector<ExchangeNode::Ptr> > excl_bid_grps;
193 
194  typename std::set<Bid<T>*>::const_iterator b_it;
195  for (b_it = bp->bids().begin();
196  b_it != bp->bids().end();
197  ++b_it) {
198  Bid<T>* b = *b_it;
200  new ExchangeNode(b->offer()->quantity(),
201  b->exclusive(),
202  b->request()->commodity(),
203  b->bidder()->manager()->id()));
204  bs->AddExchangeNode(n);
205  AddBid(translation_ctx, *b_it, n);
206  if (b->exclusive()) {
207  excl_bid_grps[b->offer()].push_back(n);
208  }
209  }
210 
211  typename std::map<typename T::Ptr, std::vector<ExchangeNode::Ptr> >::iterator
212  m_it;
213  for (m_it = excl_bid_grps.begin();
214  m_it != excl_bid_grps.end();
215  ++m_it) {
216  bs->AddExclGroup(m_it->second);
217  }
218 
219  CLOG(LEV_DEBUG4) << "adding " << bp->constraints().size()
220  << " bid capacities";
221 
222  typename std::set< CapacityConstraint<T> >::const_iterator c_it;
223  for (c_it = bp->constraints().begin();
224  c_it != bp->constraints().end();
225  ++c_it) {
226  bs->AddCapacity(c_it->capacity());
227  }
228 
229  return bs;
230 }
231 
232 /// @brief translates an arc given a bid and subsequent data, and also
233 /// updates the unit capacities for the associated nodes on the arc
234 template <class T>
236  Bid<T>* bid) {
237  return TranslateArc<T>(translation_ctx, bid, 1);
238 }
239 
240 template <class T>
242  Bid<T>* bid, double pref) {
243  Request<T>* req = bid->request();
244  ExchangeNode::Ptr unode = translation_ctx.request_to_node.at(req);
245  ExchangeNode::Ptr vnode = translation_ctx.bid_to_node.at(bid);
246  Arc arc(unode, vnode);
247  arc.pref(pref);
248 
249  typename T::Ptr offer = bid->offer();
250  typename BidPortfolio<T>::Ptr bp = bid->portfolio();
251  typename RequestPortfolio<T>::Ptr rp = req->portfolio();
252 
253  // bid is v
254  TranslateCapacities(offer, bp->constraints(), vnode, arc, translation_ctx);
255  // req is u
256  TranslateCapacities(offer, rp->constraints(), unode, arc, translation_ctx);
257 
258  return arc;
259 }
260 
261 /// @brief simple translation from a Match to a Trade, given internal state
262 template <class T>
265  const Match& match) {
266  ExchangeNode::Ptr req_node = match.first.unode();
267  ExchangeNode::Ptr bid_node = match.first.vnode();
268 
269  Trade<T> t;
270  t.request = translation_ctx.node_to_request.at(req_node);
271  t.bid = translation_ctx.node_to_bid.at(bid_node);
272  t.amt = match.second;
273  return t;
274 }
275 
276 /// @brief updates a node's unit capacities given, a target resource and
277 /// constraints
278 template<typename T>
280  typename T::Ptr offer,
281  const typename std::set< CapacityConstraint<T> >& constr,
283  const Arc& a,
284  const ExchangeTranslationContext<T>& ctx) {
285  typename std::set< CapacityConstraint<T> >::const_iterator it;
286  for (it = constr.begin(); it != constr.end(); ++it) {
287  CLOG(cyclus::LEV_DEBUG1) << "Additing unit capacity: "
288  << it->convert(offer, &a, &ctx) / offer->quantity();
289  n->unit_capacities[a].push_back(it->convert(offer, &a, &ctx) /
290  offer->quantity());
291  }
292 }
293 
294 } // namespace cyclus
295 
296 #endif // CYCLUS_SRC_EXCHANGE_TRANSLATOR_H_
boost::shared_ptr< T > offer() const
Definition: bid.h:77
RequestGroup::Ptr TranslateRequestPortfolio(ExchangeTranslationContext< T > &translation_ctx, const typename RequestPortfolio< T >::Ptr rp)
translates a request portfolio by adding request nodes and accounting for capacities.
boost::shared_ptr< BidPortfolio< T > > Ptr
Definition: bid_portfolio.h:34
double b(int nuc)
Computes the scattering length [cm] from the coherent and incoherent components.
Definition: pyne.cc:11180
An arc represents a possible connection between two nodes in the bipartite resource exchange graph...
void BackTranslateSolution(const std::vector< Match > &matches, std::vector< Trade< T > > &ret)
Provide a vector of Trades given a vector of Matches.
Trader * bidder() const
Definition: bid.h:80
boost::shared_ptr< RequestPortfolio< T > > Ptr
debugging information
Definition: logger.h:61
bool exclusive() const
Definition: request.h:114
For values that are too big, too small, etc.
Definition: error.h:41
boost::shared_ptr< RequestGroup > Ptr
std::pair< Arc, double > Match
std::map< Request< T > *, ExchangeNode::Ptr > request_to_node
boost::shared_ptr< T > target() const
Definition: request.h:97
Request< T > * request
Definition: trade.h:17
A ExchangeNodeGroup is a collection of ExchangeNodes, and is the ExchangeGraph representation of a Bi...
RequestPortfolio< T >::Ptr portfolio() const
Definition: request.h:109
Trade< T > BackTranslateMatch(const ExchangeTranslationContext< T > &translation_ctx, const Match &match)
simple translation from a Match to a Trade, given internal state
A CapacityConstraint provides an ability to determine an agent&#39;s constraints on resource allocation g...
The ExchangeContext is designed to provide an ease-of-use interface for querying and reaggregating in...
boost::shared_ptr< ExchangeNode > Ptr
double qty() const
, all requests in a portfolio must have the same quantity, which is checked during AddRequest() ...
#define CLOG(level)
Definition: logger.h:39
bool exclusive() const
Definition: bid.h:86
boost::shared_ptr< ExchangeNodeGroup > Ptr
ExchangeTranslator(ExchangeContext< T > *ex_ctx)
default constructor
const std::vector< Request< T > * > & requests() const
void AddArc(Request< T > *req, Bid< T > *bid, ExchangeGraph::Ptr graph)
adds a bid-request arc to a graph, if the preference for the arc is non-negative
void AddRequest(ExchangeTranslationContext< T > &translation_ctx, Request< T > *r, ExchangeNode::Ptr n)
Adds a request-node mapping.
void TranslateCapacities(typename T::Ptr offer, const typename std::set< CapacityConstraint< T > > &constr, ExchangeNode::Ptr n, const Arc &a, const ExchangeTranslationContext< T > &ctx)
updates a node&#39;s unit capacities given, a target resource and constraints
boost::shared_ptr< ExchangeGraph > Ptr
std::map< ExchangeNode::Ptr, Bid< T > * > node_to_bid
BidPortfolio< T >::Ptr portfolio()
Definition: bid.h:83
A Bid encapsulates all the information required to communicate a bid response to a request for a reso...
Definition: bid.h:20
ExchangeNodeGroup::Ptr TranslateBidPortfolio(ExchangeTranslationContext< T > &translation_ctx, const typename BidPortfolio< T >::Ptr bp)
translates a bid portfolio by adding bid nodes and accounting for capacities.
ExchangeTranslationContext< T > & translation_ctx()
debugging information
Definition: logger.h:59
debugging information - most verbose
Definition: logger.h:62
const ExchangeTranslationContext< T > & translation_ctx() const
void AddBid(ExchangeTranslationContext< T > &translation_ctx, Bid< T > *b, ExchangeNode::Ptr n)
Adds a bid-node mapping.
std::string commodity() const
Definition: request.h:103
double amt
Definition: trade.h:19
ExchangeNodes are used in ExchangeGraphs to house information about a given translated Bid or Request...
Bid< T > * bid
Definition: trade.h:18
An ExchangeTranslationContext is a simple holder class for any information needed to translate a Reso...
const std::set< Bid< T > * > & bids() const
Definition: bid_portfolio.h:99
ExchangeGraph::Ptr Translate()
translate the ExchangeContext into an ExchangeGraph
std::map< Bid< T > *, ExchangeNode::Ptr > bid_to_node
Code providing rudimentary logging capability for the Cyclus core.
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or.org/Osi/browser/trunk.
Definition: agent.cc:14
double pref() const
A Trade is a simple container that associates a request for a resource with a bid for that resource...
Definition: trade.h:16
Request< T > * request() const
Definition: bid.h:74
debugging information - least verbose
Definition: logger.h:58
An ExchangeTranslator facilitates translation from a resource specific exchange to a resource-neutral...
An ExchangeGraph is a resource-neutral representation of a ResourceExchange.
Arc TranslateArc(const ExchangeTranslationContext< T > &translation_ctx, Bid< T > *bid)
translates an arc given a bid and subsequent data, and also updates the unit capacities for the assoc...
std::map< ExchangeNode::Ptr, Request< T > * > node_to_request
const std::set< CapacityConstraint< T > > & constraints() const
Trader * requester() const
Definition: request.h:100
const std::set< CapacityConstraint< T > > & constraints() const
A RequestGroup is a specific ExchangeNodeGroup with a notion of an total requested quantity...
A Request encapsulates all the information required to communicate the needs of an agent in the Dynam...
Definition: request.h:29