CYCLUS
Loading...
Searching...
No Matches
matl_buy_policy.h
Go to the documentation of this file.
1#ifndef CYCLUS_SRC_TOOLKIT_MATL_BUY_POLICY_H_
2#define CYCLUS_SRC_TOOLKIT_MATL_BUY_POLICY_H_
3
4#include <string>
5#include <boost/shared_ptr.hpp>
6
7#include "composition.h"
8#include "material.h"
9#include "res_buf.h"
10#include "total_inv_tracker.h"
11#include "trader.h"
13
14namespace cyclus {
15namespace toolkit {
16
17/// MatlBuyPolicy performs semi-automatic inventory management of a material
18/// buffer by making requests and accepting materials in an attempt to fill the
19/// buffer fully every time step according to an (s, S) inventory policy (see
20/// [1]).
21///
22/// For simple behavior, policies virtually eliminate the need to write any code
23/// for resource exchange. Just assign a few policies to work with a few buffers
24/// and focus on writing the physics and other behvavior of your agent. Typical
25/// usage goes something like this:
26///
27/// @code
28/// class YourAgent : public cyclus::Facility {
29/// public:
30/// ...
31///
32/// void EnterNotify() {
33/// cyclus::Facility::EnterNotify(); // always do this first
34///
35/// policy_.Init(this, &inbuf_, "inbuf-label").Set(incommod, comp).Start();
36/// }
37/// ...
38///
39/// private:
40/// MatlBuyPolicy policy_;
41/// ResBuf<Material> inbuf_;
42/// ...
43/// }
44/// @endcode
45///
46/// The policy needs to be initialized with its owning agent and the material
47/// buffer that is is managing. It also needs to be activated by calling the
48/// Start function for it to begin participation in resource exchange. And
49/// don't forget to add some commodities to request by calling Set. All policy
50/// configuration should usually occur in the agent's EnterNotify member
51/// function.
52///
53/// [1] Zheng, Yu-Sheng. "A simple proof for optimality of (s, S) policies in
54/// infinite-horizon inventory systems." Journal of Applied Probability
55/// (1991): 802-810.
56///
57/// @warn When a policy's managing agent is deallocated, you MUST either
58/// call the policy's Stop function or delete the policy. Otherwise SEGFAULT.
59class MatlBuyPolicy : public Trader {
60 public:
61 /// Creates an uninitialized policy. The Init function MUST be called before
62 /// anything else is done with the policy.
64
65 virtual ~MatlBuyPolicy();
66
67 /// Configures the policy to keep buf filled to a certain fraction of its
68 /// capacity every time step.
69 /// @param manager the agent
70 /// @param buf the resource buffer
71 /// @param name a unique name identifying this policy
72 /// @param throughput a constraining value for total transaction quantities in
73 /// a single time step
74 /// @param inv_policy the inventory policy to use. Options are "sS", "RQ".
75 /// Each inventory policy options has two additional required parameters. An
76 /// (s,S) inventory policy orders material only when the buffer is below the
77 /// minimum value, s, and orders only enough to bring the buffer to the
78 /// maximum value, S. An (s,S) policy allows partial orders. Set s as req_at
79 /// and S as fill. An (R,Q) inventory policy requests material when the
80 /// buffer is below the minimum value, R, and places an exclusive request for
81 /// size Q. Set R as req_at and Q as fill.
82 /// @param req_at, the inventory minimum (s, and R) for (s,S) and (R,Q),. If
83 /// the buffer has less than or equal to value, new material will be
84 /// requested based on the policy in place.
85 /// @param fill_behav, the quantity govering the fill strategy for inventory
86 /// policies. For (s,S), this is the maximum value, and material will be
87 /// ordered up to this amount. For (R,Q), this is the quantity of material
88 /// that will be ordered (exclusive).
89 /// @param cumulative_cap the cumulative capacity of material to be received
90 /// in one active cycle. A cumulative cap inventory policy allows for a
91 /// cumulative capacity of material to be received in one active cycle. Once
92 /// the cumulative capacity is recieved, the agent enters a dormant period.
93 /// Also requires dormant distributions using dormant_dist.
94 /// @param quantize If quantize is greater than zero, the policy will make
95 /// exclusive, integral quantize kg requests. Otherwise, single requests will
96 /// be sent to fill the buffer's empty space.
97 /// @warning, (s, S) policy values are ambiguous for buffers with a capacity
98 /// in (0, 1]. However that is a rare case.
99 /// The following features, if used, will set the policy to so that agents
100 /// cycle through "on" phases, where the buf will attemp to be filled, and
101 /// "off" or dormant phases, where no requests will be made regardless of
102 /// capacity. The "on" and "off" phases are sampled and rounded to the
103 /// nearest integer number of time steps from a truncated normal
104 /// distribution from a mean, standard deviation, min, and max value.
105 /// Note that the (s, S) policy is not currently compatible with active and
106 /// Active and dormant buying perionds
107 /// Active parameters:
108 /// @param active_dist an IntDistribution object that will be used to sample
109 /// the number of time steps in the "on" phase. If not set, a fixed
110 /// distribution with a value of 1 will be used.
111 /// @param dormant_dist an IntDistribution object that will be used to sample
112 /// the number of time steps in the "off" phase. If not set, a fixed
113 /// distribution with a value of 0 will be used (no dormant, always on)
114 /// @param size_dist a DoubleDistribution object that will be used to sample
115 /// the size of the request as a fraction of the available capacity at the
116 /// current time step. If not set, a fixed distribution with a value of
117 /// 1.0 will be used.
118 /// Note that active and dormant periods are note currently compatible with
119 /// (s, S) inventory management
120 /// @{
121 MatlBuyPolicy& Init(Agent* manager, ResBuf<Material>* buf, std::string name,
128 MatlBuyPolicy& Init(Agent* manager, ResBuf<Material>* buf, std::string name,
130 double quantize);
131 MatlBuyPolicy& Init(Agent* manager, ResBuf<Material>* buf, std::string name,
133 double throughput, std::string inv_policy,
134 double fill_behav, double req_at);
135 MatlBuyPolicy& Init(Agent* manager, ResBuf<Material>* buf, std::string name,
136 TotalInvTracker* buf_tracker, std::string inv_policy,
137 double fill_behav, double req_at);
140 double cumulative_cap,
142 /// @}
143
144 /// Instructs the policy to fill its buffer with requests on the given
145 /// commodity of composition c and the given preference. This must be called
146 /// at least once or the policy will do nothing. The policy can request on an
147 /// arbitrary number of commodities by calling Set multiple times. Re-calling
148 /// Set to modify the composition or preference of a commodity that has been
149 /// set previously is allowed.
150 /// @param commod the commodity name
151 /// @param c the composition to request for the given commodity
152 /// @param pref the preference value for the commodity
153 /// @{
154 MatlBuyPolicy& Set(std::string commod);
155 MatlBuyPolicy& Set(std::string commod, Composition::Ptr c);
156 MatlBuyPolicy& Set(std::string commod, Composition::Ptr c, double pref);
157 /// @}
158
159 /// Registers this policy as a trader in the current simulation. This
160 /// function must be called for the policy to begin participating in resource
161 /// exchange. Init MUST be called prior to calling this function. Start is
162 /// idempotent.
163 void Start();
164
165 /// Unregisters this policy as a trader in the current simulation. This
166 /// function need only be called if a policy is to be stopped *during* a
167 /// simulation (it is not required to be called explicitly at the end). Stop
168 /// is idempotent.
169 void Stop();
170
171 /// the total amount available to request
172 inline double TotalAvailable() const {
173 return std::min({throughput_,
174 fill_to_ - buf_->quantity(),
175 buf_->space(),
176 buf_tracker_->space()});
177 }
178
179 /// whether a request can be made
180 inline bool MakeReq() const { return buf_tracker_->quantity() <= req_at_; }
181
182 /// whether trades will be denoted as exclusive or not
183 inline bool Excl() const { return quantize_ > 0; }
184
185
186 /// the amount requested per each request
187 inline double ReqQty(double amt) const {
188 return Excl() ? quantize_ : amt;
189 }
190
191 /// the number of requests made per each commodity
192 inline int NReq(double amt) const {
193 return Excl() ? static_cast<int>(amt / quantize_) : 1;
194 }
195
196 /// Returns corresponding commodities from which each material object
197 /// was received for the current time step. The data returned by this function
198 /// are ONLY valid during the Tock phase of a time step.
199 inline const std::map<Material::Ptr, std::string>& rsrc_commods() {
200 return rsrc_commods_;
201 };
202
203 inline bool no_cycle_end_time() {
204 return (next_dormant_end_ < 0 || next_active_end_ < 0);
205 }
206
207 inline bool dormant(int time) {
208 return (time >= next_active_end_ && time < next_dormant_end_);
209 }
210
211 inline bool use_cumulative_capacity() { return cumulative_cap_ > 0; }
212
213 /// Trader Methods
214 /// @{
215 virtual std::set<RequestPortfolio<Material>::Ptr> GetMatlRequests();
216 virtual void AcceptMatlTrades(
217 const std::vector<std::pair<Trade<Material>, Material::Ptr> >& resps);
218 /// }@
219
220 void SetNextActiveTime();
221 void SetNextDormantTime();
222 double SampleRequestSize();
224
225 private:
226 struct CommodDetail {
227 Composition::Ptr comp;
228 double pref;
229 };
230
231 void set_manager(Agent* m);
232 void set_total_inv_tracker(TotalInvTracker* t = NULL);
233 void set_inv_policy(std::string p, double x,
234 double y = std::numeric_limits<double>::max());
235 /// requires buf_ already set
236 void set_fill_to(double x);
237 /// requires buf_ already set
238 void set_req_at(double x);
239 void set_cumulative_cap(double x);
240 void set_quantize(double x);
241 void set_throughput(double x);
242 void init_active_dormant();
243
244 ResBuf<Material>* buf_;
245 TotalInvTracker* buf_tracker_;
246 std::string name_, inv_policy;
247 double fill_to_, req_at_, quantize_, throughput_, cumulative_cap_,
248 cycle_total_inv_;
249
250 int next_active_end_= 0;
251 int next_dormant_end_= 0;
252
253 IntDistribution::Ptr active_dist_;
254 IntDistribution::Ptr dormant_dist_;
255 DoubleDistribution::Ptr size_dist_;
256
257 std::map<Material::Ptr, std::string> rsrc_commods_;
258 std::map<std::string, CommodDetail> commod_details_;
259};
260
261} // namespace toolkit
262} // namespace cyclus
263
264#endif
The abstract base class used by all types of agents that live and interact in a simulation.
Definition agent.h:49
boost::shared_ptr< Composition > Ptr
Definition composition.h:43
boost::shared_ptr< DoubleDistribution > Ptr
boost::shared_ptr< IntDistribution > Ptr
boost::shared_ptr< Material > Ptr
Definition material.h:75
A simple API for agents that wish to exchange resources in the simulation.
Definition trader.h:24
virtual Agent * manager()
Definition trader.h:28
MatlBuyPolicy performs semi-automatic inventory management of a material buffer by making requests an...
void Stop()
Unregisters this policy as a trader in the current simulation.
MatlBuyPolicy & Init(Agent *manager, ResBuf< Material > *buf, std::string name, TotalInvTracker *buf_tracker, double throughput, double cumulative_cap, IntDistribution::Ptr)
int NReq(double amt) const
the number of requests made per each commodity
MatlBuyPolicy & Set(std::string commod)
Instructs the policy to fill its buffer with requests on the given commodity of composition c and the...
virtual std::set< RequestPortfolio< Material >::Ptr > GetMatlRequests()
Trader Methods.
void Start()
Registers this policy as a trader in the current simulation.
MatlBuyPolicy & Init(Agent *manager, ResBuf< Material > *buf, std::string name, TotalInvTracker *buf_tracker, double throughput, IntDistribution::Ptr active_dist=NULL, IntDistribution::Ptr dormant_dist=NULL, DoubleDistribution::Ptr size_dist=NULL)
virtual void AcceptMatlTrades(const std::vector< std::pair< Trade< Material >, Material::Ptr > > &resps)
default implementation for material trade acceptance
bool Excl() const
whether trades will be denoted as exclusive or not
MatlBuyPolicy & Init(Agent *manager, ResBuf< Material > *buf, std::string name, TotalInvTracker *buf_tracker)
Configures the policy to keep buf filled to a certain fraction of its capacity every time step.
const std::map< Material::Ptr, std::string > & rsrc_commods()
Returns corresponding commodities from which each material object was received for the current time s...
double TotalAvailable() const
the total amount available to request
bool MakeReq() const
whether a request can be made
MatlBuyPolicy()
Creates an uninitialized policy.
double ReqQty(double amt) const
the amount requested per each request
ResBuf is a helper class that provides semi-automated management of a collection of resources (e....
Definition res_buf.h:62
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
Definition agent.cc:14
T OptionalQuery(InfileTree *tree, std::string query, T default_val)
a query method for optional parameters
A Trade is a simple container that associates a request for a resource with a bid for that resource.
Definition trade.h:16