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> class ExchangeTranslator {
33 public:
34 /// @brief default constructor
35 ///
36 /// @param ex_ctx the exchance context
37 ExchangeTranslator(ExchangeContext<T>* ex_ctx) { ex_ctx_ = ex_ctx; }
38
39 /// @brief translate the ExchangeContext into an ExchangeGraph
42
43 // add each request group
44 const std::vector<typename RequestPortfolio<T>::Ptr>& requests =
45 ex_ctx_->requests;
46 typename std::vector<typename RequestPortfolio<T>::Ptr>::const_iterator
47 rp_it;
48 for (rp_it = requests.begin(); rp_it != requests.end(); ++rp_it) {
49 CapacityConstraint<T> c((*rp_it)->qty(), (*rp_it)->qty_converter());
50 (*rp_it)->AddConstraint(c);
51
52 RequestGroup::Ptr rs = TranslateRequestPortfolio(xlation_ctx_, *rp_it);
53 graph->AddRequestGroup(rs);
54 }
55
56 // add each bid group
57 const std::vector<typename BidPortfolio<T>::Ptr>& bidports = ex_ctx_->bids;
58 typename std::vector<typename BidPortfolio<T>::Ptr>::const_iterator bp_it;
59 for (bp_it = bidports.begin(); bp_it != bidports.end(); ++bp_it) {
60 ExchangeNodeGroup::Ptr ns = TranslateBidPortfolio(xlation_ctx_, *bp_it);
61 graph->AddSupplyGroup(ns);
62
63 // add each request-bid arc
64 const std::set<Bid<T>*>& bids = (*bp_it)->bids();
65 typename std::set<Bid<T>*>::const_iterator b_it;
66 for (b_it = bids.begin(); b_it != bids.end(); ++b_it) {
67 Bid<T>* bid = *b_it;
68 Request<T>* req = bid->request();
69 AddArc(req, bid, graph);
70 }
71 }
72
73 return graph;
74 }
75
76 /// @brief adds a bid-request arc to a graph, if the preference for the arc is
77 /// non-negative
78 void AddArc(Request<T>* req, Bid<T>* bid, ExchangeGraph::Ptr graph) {
79 double pref = ex_ctx_->trader_prefs.at(req->requester())[req][bid];
80 // TODO: make the following check `pref <=0` and remove the `else if` block
81 // before release 1.5
82 if (pref < 0) {
83 CLOG(LEV_DEBUG1) << "Removing arc because of negative preference.";
84 return;
85 } else if (pref == 0) {
86 std::stringstream ss;
87 ss << "0-valued preferences have been deprecated. "
88 << "Please make preference value positive."
89 << "This message will go away in before the next release (1.5).";
90 throw ValueError(ss.str());
91 }
92 // get translated arc
93 Arc a = TranslateArc(xlation_ctx_, bid, pref);
94 a.unode()->prefs[a] = pref; // request node is a.unode()
95 int n_prefs = a.unode()->prefs.size();
96
97 CLOG(LEV_DEBUG5) << "Updating preference for one of "
98 << req->requester()->manager()->prototype()
99 << "'s trade nodes:";
100 CLOG(LEV_DEBUG5) << " preference: " << a.unode()->prefs[a];
101
102 graph->AddArc(a);
103 }
104
105 /// @brief Provide a vector of Trades given a vector of Matches
106 void BackTranslateSolution(const std::vector<Match>& matches,
107 std::vector<Trade<T>>& ret) {
108 std::vector<Match>::const_iterator m_it;
109 CLOG(LEV_DEBUG1) << "Back traslating " << matches.size()
110 << " trade matches.";
111 for (m_it = matches.begin(); m_it != matches.end(); ++m_it) {
112 ret.push_back(BackTranslateMatch(xlation_ctx_, *m_it));
113 }
114 }
115
117 return xlation_ctx_;
118 }
119
121
122 private:
123 ExchangeContext<T>* ex_ctx_;
125};
126
127/// @brief Adds a request-node mapping
128template <class T>
129inline void AddRequest(ExchangeTranslationContext<T>& translation_ctx,
131 translation_ctx.request_to_node[r] = n;
132 translation_ctx.node_to_request[n] = r;
133}
134
135/// @brief Adds a bid-node mapping
136template <class T>
137inline void AddBid(ExchangeTranslationContext<T>& translation_ctx, Bid<T>* b,
139 translation_ctx.bid_to_node[b] = n;
140 translation_ctx.node_to_bid[n] = b;
141}
142
143/// @brief translates a request portfolio by adding request nodes and
144/// accounting for capacities. Request unit capcities must be added when arcs
145/// are known
146template <class T>
148 ExchangeTranslationContext<T>& translation_ctx,
149 const typename RequestPortfolio<T>::Ptr rp) {
150 RequestGroup::Ptr rs(new RequestGroup(rp->qty()));
151 CLOG(LEV_DEBUG2) << "Translating request portfolio of size " << rp->qty();
152
153 typename std::vector<Request<T>*>::const_iterator r_it;
154 for (r_it = rp->requests().begin(); r_it != rp->requests().end(); ++r_it) {
155 Request<T>* r = *r_it;
156 ExchangeNode::Ptr n(new ExchangeNode(r->target()->quantity(),
157 r->exclusive(),
158 r->commodity(),
159 r->requester()->manager()->id()));
160 rs->AddExchangeNode(n);
161
162 AddRequest(translation_ctx, *r_it, n);
163 }
164
165 CLOG(LEV_DEBUG4) << "adding " << rp->constraints().size()
166 << " request capacities";
167 typename std::set<CapacityConstraint<T>>::const_iterator c_it;
168 for (c_it = rp->constraints().begin(); c_it != rp->constraints().end();
169 ++c_it) {
170 rs->AddCapacity(c_it->capacity());
171 }
172
173 return rs;
174}
175
176/// @brief translates a bid portfolio by adding bid nodes and accounting
177/// for capacities. Bid unit capcities must be added when arcs are known
178template <class T>
180 ExchangeTranslationContext<T>& translation_ctx,
181 const typename BidPortfolio<T>::Ptr bp) {
183
184 std::map<typename T::Ptr, std::vector<ExchangeNode::Ptr>> excl_bid_grps;
185
186 typename std::set<Bid<T>*>::const_iterator b_it;
187 for (b_it = bp->bids().begin(); b_it != bp->bids().end(); ++b_it) {
188 Bid<T>* b = *b_it;
189 ExchangeNode::Ptr n(new ExchangeNode(b->offer()->quantity(),
190 b->exclusive(),
191 b->request()->commodity(),
192 b->bidder()->manager()->id()));
193 bs->AddExchangeNode(n);
194 AddBid(translation_ctx, *b_it, n);
195 if (b->exclusive()) {
196 excl_bid_grps[b->offer()].push_back(n);
197 }
198 }
199
200 typename std::map<typename T::Ptr, std::vector<ExchangeNode::Ptr>>::iterator
201 m_it;
202 for (m_it = excl_bid_grps.begin(); m_it != excl_bid_grps.end(); ++m_it) {
203 bs->AddExclGroup(m_it->second);
204 }
205
206 CLOG(LEV_DEBUG4) << "adding " << bp->constraints().size()
207 << " bid capacities";
208
209 typename std::set<CapacityConstraint<T>>::const_iterator c_it;
210 for (c_it = bp->constraints().begin(); c_it != bp->constraints().end();
211 ++c_it) {
212 bs->AddCapacity(c_it->capacity());
213 }
214
215 return bs;
216}
217
218/// @brief translates an arc given a bid and subsequent data, and also
219/// updates the unit capacities for the associated nodes on the arc
220template <class T>
222 Bid<T>* bid) {
223 return TranslateArc<T>(translation_ctx, bid, 1);
224}
225
226template <class T>
228 Bid<T>* bid, double pref) {
229 Request<T>* req = bid->request();
230 ExchangeNode::Ptr unode = translation_ctx.request_to_node.at(req);
231 ExchangeNode::Ptr vnode = translation_ctx.bid_to_node.at(bid);
232 Arc arc(unode, vnode);
233 arc.pref(pref);
234
235 typename T::Ptr offer = bid->offer();
236 typename BidPortfolio<T>::Ptr bp = bid->portfolio();
237 typename RequestPortfolio<T>::Ptr rp = req->portfolio();
238
239 // bid is v
240 TranslateCapacities(offer, bp->constraints(), vnode, arc, translation_ctx);
241 // req is u
242 TranslateCapacities(offer, rp->constraints(), unode, arc, translation_ctx);
243
244 return arc;
245}
246
247/// @brief simple translation from a Match to a Trade, given internal state
248template <class T>
250 const ExchangeTranslationContext<T>& translation_ctx, const Match& match) {
251 ExchangeNode::Ptr req_node = match.first.unode();
252 ExchangeNode::Ptr bid_node = match.first.vnode();
253
254 Trade<T> t;
255 t.request = translation_ctx.node_to_request.at(req_node);
256 t.bid = translation_ctx.node_to_bid.at(bid_node);
257 t.amt = match.second;
258 return t;
259}
260
261/// @brief updates a node's unit capacities given, a target resource and
262/// constraints
263template <typename T>
264void TranslateCapacities(typename T::Ptr offer,
265 const typename std::set<CapacityConstraint<T>>& constr,
267 const Arc& a,
269 typename std::set<CapacityConstraint<T>>::const_iterator it;
270 for (it = constr.begin(); it != constr.end(); ++it) {
272 << "Additing unit capacity: "
273 << it->convert(offer, &a, &ctx) / offer->quantity();
274 n->unit_capacities[a].push_back(it->convert(offer, &a, &ctx) /
275 offer->quantity());
276 }
277}
278
279} // namespace cyclus
280
281#endif // CYCLUS_SRC_EXCHANGE_TRANSLATOR_H_
const std::string prototype() const
Returns the agent's prototype.
Definition agent.h:342
virtual const int id() const
The agent instance's unique ID within a simulation.
Definition agent.h:349
An arc represents a possible connection between two nodes in the bipartite resource exchange graph.
double pref() const
boost::shared_ptr< ExchangeNode > unode() const
const std::set< CapacityConstraint< T > > & constraints() const
const std::set< Bid< T > * > & bids() const
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
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
const std::set< CapacityConstraint< T > > & constraints() const
const std::vector< Request< T > * > & requests() const
double qty() const
, all requests in a portfolio must have the same quantity, which is checked during AddRequest()
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
bool exclusive() const
Definition request.h:114
std::string commodity() const
Definition request.h:103
boost::shared_ptr< T > target() const
Definition request.h:97
RequestPortfolio< T >::Ptr portfolio() const
Definition request.h:109
Trader * requester() const
Definition request.h:100
A simple API for agents that wish to exchange resources in the simulation.
Definition trader.h:24
virtual Agent * manager()
Definition trader.h:28
For values that are too big, too small, etc.
Definition error.h:37
Code providing rudimentary logging capability for the Cyclus core.
#define CLOG(level)
Definition logger.h:40
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:74
@ LEV_DEBUG4
debugging information
Definition logger.h:73
@ LEV_DEBUG1
debugging information - least verbose
Definition logger.h:70
@ LEV_DEBUG2
debugging information
Definition logger.h:71
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...
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:15
Bid< T > * bid
Definition trade.h:17
Request< T > * request
Definition trade.h:16
double amt
Definition trade.h:18