CYCLUS
Loading...
Searching...
No Matches
request_portfolio.h
Go to the documentation of this file.
1#ifndef CYCLUS_SRC_REQUEST_PORTFOLIO_H_
2#define CYCLUS_SRC_REQUEST_PORTFOLIO_H_
3
4#include <functional>
5#include <numeric>
6#include <set>
7#include <string>
8#include <vector>
9
10#include <boost/enable_shared_from_this.hpp>
11#include <boost/shared_ptr.hpp>
12
13#include "capacity_constraint.h"
14#include "error.h"
15#include "logger.h"
16#include "request.h"
17
18namespace cyclus {
19
20class Trader;
21
22/// @brief accumulator sum for request quantities
23template <class T> inline double SumQty(double total, Request<T>* r) {
24 return total += r->target()->quantity();
25}
26
27/// @brief provide coefficients for default mass constraints
28///
29/// Coefficients are determiend by the request portfolio and are provided to the
30/// converter. The arc and exchange context are used in order to reference the
31/// original request so that the request's coefficient can be applied.
32template <class T> struct QtyCoeffConverter : public Converter<T> {
33 QtyCoeffConverter(const std::map<Request<T>*, double>& coeffs)
34 : coeffs(coeffs) {}
35
36 inline virtual double convert(
37 boost::shared_ptr<T> offer,
38 Arc const* a,
39 ExchangeTranslationContext<T> const* ctx) const {
40 return offer->quantity() * coeffs.at(ctx->node_to_request.at(a->unode()));
41 }
42
43 virtual bool operator==(Converter<T>& other) const {
44 QtyCoeffConverter<T>* cast = dynamic_cast<QtyCoeffConverter<T>*>(&other);
45 return cast != NULL && coeffs == cast->coeffs;
46 }
47
48 std::map<Request<T>*, double> coeffs;
49};
50
51/// @class RequestPortfolio
52///
53/// @brief A RequestPortfolio is a group of (possibly constrained) requests for
54/// resources
55///
56/// The portfolio contains a grouping of resource requests that may be mutually
57/// met by suppliers. These requests may share a common set of
58/// constraints. Take, for instance, a facility that needs fuel, of which there
59/// are
60/// two commodity types, fuelA and fuelB. If some combination of the two suffice
61/// the facility's needs, then requests for both would be added to the portfolio
62/// along with a capacity constraint.
63///
64/// The ExchangeTranslator will automatically add a mass-based constraint, that
65/// accounts for mutual requests, if the portfolio has them. , e.g.,
66/// @code
67///
68/// RequestPortfolio<SomeResource>::Ptr rp(new
69/// RequestPortfolio<SomeResource>());
70/// // add some requests
71/// rp->AddRequest(/* args */);
72/// // declare some of them as multi-commodity requests (i.e., any one will
73/// // satisfy this demand).
74/// rp->AddMutualReqs(/* args */);
75///
76/// @endcode
77///
78/// A default constraint will add unity for normal requests in the portfolio,
79/// but will add a weighted coefficient for requests that meet the same mutual
80/// demand. For example, if 10 kg of MOX and 9 kg of UOX meet the same demand
81/// for fuel, coefficients are added such that a full order of either will
82/// determine the demand as "met". In this case, the total demand is 9.5, the
83/// MOX order is given a coefficient of 9.5 / 10, and the UOX order is given a
84/// coefficient of 9.5 / 9.
85template <class T>
87 : public boost::enable_shared_from_this<RequestPortfolio<T>> {
88 public:
89 typedef boost::shared_ptr<RequestPortfolio<T>> Ptr;
90 typedef std::function<double(boost::shared_ptr<T>)> cost_function_t;
92
93 RequestPortfolio() : requester_(NULL), qty_(0) {}
94
95 /// deletes all requests associated with it
97 typename std::vector<Request<T>*>::iterator it;
98 for (it = requests_.begin(); it != requests_.end(); ++it) {
99 delete *it;
100 }
101 }
102
103 /// @brief add a request to the portfolio
104 /// @param target the target resource associated with this request
105 /// @param requester the requester
106 /// @param commodity the commodity associated with this request
107 /// @param preference the preference associated with this request (relative to
108 /// others in the portfolio)
109 /// @param exclusive a flag denoting that this request must be met
110 /// exclusively,
111 /// i.e., in its entirety by a single offer
112 /// @param cost_function The cost function that the requester sets so that the
113 /// bidder may evaluate many potential resources.
114 /// @throws KeyError if a request is added from a different requester than the
115 /// original or if the request quantity is different than the original
116 Request<T>* AddRequest(boost::shared_ptr<T> target, Trader* requester,
117 std::string commodity, double preference,
118 bool exclusive, cost_function_t cost_function) {
119 Request<T>* r =
121 commodity, preference, exclusive, cost_function);
122 VerifyRequester_(r);
123 requests_.push_back(r);
124 mass_coeffs_[r] = 1;
125 qty_ += target->quantity();
126 return r;
127 }
128 /// @brief add a request to the portfolio
129 /// @param target the target resource associated with this request
130 /// @param requester the requester
131 /// @param commodity the commodity associated with this request
132 /// @param preference the preference associated with this request (relative to
133 /// others in the portfolio)
134 /// @param exclusive a flag denoting that this request must be met
135 /// exclusively,
136 /// i.e., in its entirety by a single offer
137 /// @throws KeyError if a request is added from a different requester than the
138 /// original or if the request quantity is different than the original
139 Request<T>* AddRequest(boost::shared_ptr<T> target, Trader* requester,
140 std::string commodity = "",
141 double preference = kDefaultPref,
142 bool exclusive = false) {
143 return AddRequest(target, requester, commodity, preference, exclusive,
144 NULL);
145 }
146
147 /// @brief adds a collection of requests (already having been registered with
148 /// this portfolio) as multicommodity requests
149 /// @param rs the collection of requests to add
150 inline void AddMutualReqs(const std::vector<Request<T>*>& rs) {
151 double avg_qty =
152 std::accumulate(rs.begin(), rs.end(), 0.0, SumQty<T>) / rs.size();
153 double qty;
154 Request<T>* r;
155 for (int i = 0; i < rs.size(); i++) {
156 r = rs[i];
157 qty = r->target()->quantity();
158 mass_coeffs_[r] = r->target()->quantity() / avg_qty;
159 qty_ -= qty;
160 }
161 qty_ += avg_qty;
162 }
163
164 /// @brief add a capacity constraint associated with the portfolio, if it
165 /// doesn't already exist
166 /// @param c the constraint to add
168 constraints_.insert(c);
169 }
170
171 /// @return the agent associated with the portfolio. if no reqeusts have
172 /// been added, the requester is NULL.
173 inline Trader* requester() const { return requester_; }
174
175 /// @return the request quantity associated with the portfolio.
176 ///
177 /// @brief, all requests in a portfolio must have the same quantity, which is
178 /// checked during AddRequest()
179 inline double qty() const { return qty_; }
180
181 /// @return const access to the unconstrained requests
182 inline const std::vector<Request<T>*>& requests() const { return requests_; }
183
184 /// @return const access to the request constraints
185 inline const std::set<CapacityConstraint<T>>& constraints() const {
186 return constraints_;
187 }
188
189 /// returns a capacity converter for this portfolios request quantities
191 return typename Converter<T>::Ptr(new QtyCoeffConverter<T>(mass_coeffs_));
192 }
193
194 private:
195 /// @brief copy constructor is private to prevent copying and preserve
196 /// explicit single-ownership of requests
198 requester_ = rhs.requester_;
199 requests_ = rhs.requests_;
200 constraints_ = rhs.constraints_;
201 qty_ = rhs.qty_;
202 typename std::vector<Request<T>*>::iterator it;
203 for (it = requests_.begin(); it != requests_.end(); ++it) {
204 it->get()->set_portfolio(this->shared_from_this());
205 }
206 }
207
208 /// @brief if the requester has not been determined yet, it is set. otherwise
209 /// VerifyRequester() verifies the the request is associated with the
210 /// portfolio's
211 /// requester
212 /// @throws KeyError if a request is added from a different requester than the
213 /// original
214 void VerifyRequester_(const Request<T>* r) {
215 if (requester_ == NULL) {
216 requester_ = r->requester();
217 } else if (requester_ != r->requester()) {
218 std::string msg = "Insertion error: requesters do not match.";
219 throw KeyError(msg);
220 }
221 }
222
223 /// requests_ is a vector because many requests may be identical, i.e., a set
224 /// is not appropriate
225 std::vector<Request<T>*> requests_;
226
227 /// coefficients for the default mass constraint for known resources
228 std::map<Request<T>*, double> mass_coeffs_;
229
230 /// constraints_ is a set because constraints are assumed to be unique
231 std::set<CapacityConstraint<T>> constraints_;
232
233 /// the total quantity of resources associated with the portfolio
234 double qty_;
235 Trader* requester_;
236};
237
238} // namespace cyclus
239
240#endif // CYCLUS_SRC_REQUEST_PORTFOLIO_H_
An arc represents a possible connection between two nodes in the bipartite resource exchange graph.
A CapacityConstraint provides an ability to determine an agent's constraints on resource allocation g...
A RequestPortfolio is a group of (possibly constrained) requests for resources.
const std::set< CapacityConstraint< T > > & constraints() const
std::function< double(boost::shared_ptr< T >)> cost_function_t
void AddMutualReqs(const std::vector< Request< T > * > &rs)
adds a collection of requests (already having been registered with this portfolio) as multicommodity ...
Converter< T >::Ptr qty_converter()
returns a capacity converter for this portfolios request quantities
~RequestPortfolio()
deletes all requests associated with it
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()
Request< T > * AddRequest(boost::shared_ptr< T > target, Trader *requester, std::string commodity="", double preference=kDefaultPref, bool exclusive=false)
add a request to the portfolio
Request< T > * AddRequest(boost::shared_ptr< T > target, Trader *requester, std::string commodity, double preference, bool exclusive, cost_function_t cost_function)
add a request to the portfolio
void AddConstraint(const CapacityConstraint< T > &c)
add a capacity constraint associated with the portfolio, if it doesn't already exist
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
boost::shared_ptr< T > target() const
Definition request.h:97
static Request< T > * Create(boost::shared_ptr< T > target, Trader *requester, typename RequestPortfolio< T >::Ptr portfolio, std::string commodity, double preference, bool exclusive, cost_function_t cost_function)
a factory method for a request
Definition request.h:45
A simple API for agents that wish to exchange resources in the simulation.
Definition trader.h:24
Code providing rudimentary logging capability for the Cyclus core.
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
Definition agent.cc:14
static const double kDefaultPref
Default preference values are unity.
Definition request.h:18
double SumQty(double total, Request< T > *r)
accumulator sum for request quantities
T OptionalQuery(InfileTree *tree, std::string query, T default_val)
a query method for optional parameters
a simple interface for converting resource objects to unit capacities
boost::shared_ptr< Converter< T > > Ptr
An ExchangeTranslationContext is a simple holder class for any information needed to translate a Reso...
std::map< ExchangeNode::Ptr, Request< T > * > node_to_request
provide coefficients for default mass constraints
virtual bool operator==(Converter< T > &other) const
operator== is available for subclassing, see cyclus::TrivialConverter for an example
std::map< Request< T > *, double > coeffs
QtyCoeffConverter(const std::map< Request< T > *, double > &coeffs)
virtual double convert(boost::shared_ptr< T > offer, Arc const *a, ExchangeTranslationContext< T > const *ctx) const
convert a capacitated quantity for an offer in its exchange context