CYCLUS
Loading...
Searching...
No Matches
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
16namespace cyclus {
17
18template <class T> class ExchangeContext;
19class 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.
32template <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
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
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) {
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
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
125
126 private:
127 ExchangeContext<T>* ex_ctx_;
129};
130
131/// @brief Adds a request-node mapping
132template <class T>
133inline void AddRequest(ExchangeTranslationContext<T>& translation_ctx,
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
140template <class T>
141inline void AddBid(ExchangeTranslationContext<T>& translation_ctx,
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
150template <class T>
152 ExchangeTranslationContext<T>& translation_ctx,
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
186template <class T>
188 ExchangeTranslationContext<T>& translation_ctx,
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
234template <class T>
236 Bid<T>* bid) {
237 return TranslateArc<T>(translation_ctx, bid, 1);
238}
239
240template <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
262template <class T>
264 translation_ctx,
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
278template<typename T>
280 typename T::Ptr offer,
281 const typename std::set< CapacityConstraint<T> >& constr,
283 const Arc& a,
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_
An arc represents a possible connection between two nodes in the bipartite resource exchange graph.
boost::shared_ptr< BidPortfolio< T > > Ptr
A Bid encapsulates all the information required to communicate a bid response to a request for a reso...
Definition bid.h:21
Request< T > * request() const
Definition bid.h:78
BidPortfolio< T >::Ptr portfolio()
Definition bid.h:87
boost::shared_ptr< T > offer() const
Definition bid.h:81
A CapacityConstraint provides an ability to determine an agent's constraints on resource allocation g...
An ExchangeGraph is a resource-neutral representation of a ResourceExchange.
boost::shared_ptr< ExchangeGraph > Ptr
A ExchangeNodeGroup is a collection of ExchangeNodes, and is the ExchangeGraph representation of a Bi...
boost::shared_ptr< ExchangeNodeGroup > Ptr
An ExchangeTranslator facilitates translation from a resource specific exchange to a resource-neutral...
ExchangeTranslationContext< T > & translation_ctx()
ExchangeTranslator(ExchangeContext< T > *ex_ctx)
default constructor
const ExchangeTranslationContext< T > & translation_ctx() const
void BackTranslateSolution(const std::vector< Match > &matches, std::vector< Trade< T > > &ret)
Provide a vector of Trades given a vector of Matches.
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
ExchangeGraph::Ptr Translate()
translate the ExchangeContext into an ExchangeGraph
A RequestGroup is a specific ExchangeNodeGroup with a notion of an total requested quantity.
boost::shared_ptr< RequestGroup > Ptr
boost::shared_ptr< RequestPortfolio< T > > Ptr
A Request encapsulates all the information required to communicate the needs of an agent in the Dynam...
Definition request.h:29
For values that are too big, too small, etc.
Definition error.h:41
Code providing rudimentary logging capability for the Cyclus core.
#define CLOG(level)
Definition logger.h:39
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
Definition agent.cc:14
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.
void AddRequest(ExchangeTranslationContext< T > &translation_ctx, Request< T > *r, ExchangeNode::Ptr n)
Adds a request-node mapping.
std::pair< Arc, double > Match
@ LEV_DEBUG5
debugging information - most verbose
Definition logger.h:62
@ LEV_DEBUG4
debugging information
Definition logger.h:61
@ LEV_DEBUG1
debugging information - least verbose
Definition logger.h:58
@ LEV_DEBUG2
debugging information
Definition logger.h:59
void AddBid(ExchangeTranslationContext< T > &translation_ctx, Bid< T > *b, ExchangeNode::Ptr n)
Adds a bid-node mapping.
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.
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...
T OptionalQuery(InfileTree *tree, std::string query, T default_val)
a query method for optional parameters
Trade< T > BackTranslateMatch(const ExchangeTranslationContext< T > &translation_ctx, const Match &match)
simple translation from a Match to a Trade, given internal state
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's unit capacities given, a target resource and constraints
The ExchangeContext is designed to provide an ease-of-use interface for querying and reaggregating in...
ExchangeNodes are used in ExchangeGraphs to house information about a given translated Bid or Request...
boost::shared_ptr< ExchangeNode > Ptr
An ExchangeTranslationContext is a simple holder class for any information needed to translate a Reso...
std::map< Request< T > *, ExchangeNode::Ptr > request_to_node
std::map< ExchangeNode::Ptr, Bid< T > * > node_to_bid
std::map< ExchangeNode::Ptr, Request< T > * > node_to_request
std::map< Bid< T > *, ExchangeNode::Ptr > bid_to_node
A Trade is a simple container that associates a request for a resource with a bid for that resource.
Definition trade.h:16
Bid< T > * bid
Definition trade.h:18
Request< T > * request
Definition trade.h:17
double amt
Definition trade.h:19