7#include <boost/math/special_functions/next.hpp>
35 if (conditioner_ != NULL)
delete conditioner_;
39 if (conditioner_ != NULL) conditioner_->Condition(
graph_);
43 std::for_each(
graph_->request_groups().begin(),
44 graph_->request_groups().end(),
45 std::bind(&GreedySolver::GetCaps,
this, std::placeholders::_1));
47 std::for_each(
graph_->supply_groups().begin(),
48 graph_->supply_groups().end(),
49 std::bind(&GreedySolver::GetCaps,
this, std::placeholders::_1));
61 std::for_each(
graph_->request_groups().begin(),
62 graph_->request_groups().end(),
63 std::bind(&GreedySolver::GreedilySatisfySet,
this,
64 std::placeholders::_1));
66 obj_ += unmatched_ * pseudo_cost;
79 << std::min(ucap, vcap);
81 return std::min(ucap, vcap);
86 if (n->group == NULL) {
88 "An notion of node capacity requires a nodegroup.");
91 if (n->unit_capacities[a].size() == 0) {
92 return n->qty - curr_qty;
95 std::vector<double>& unit_caps = n->unit_capacities[a];
96 const std::vector<double>& group_caps = grp_caps_[n->group];
97 std::vector<double> caps;
98 double grp_cap, u_cap, cap;
100 for (
int i = 0; i < unit_caps.size(); i++) {
101 grp_cap = group_caps[i];
102 u_cap = unit_caps[i];
103 cap = grp_cap / u_cap;
110 if (grp_cap == std::numeric_limits<double>::max()) {
111 caps.push_back(std::numeric_limits<double>::max());
118 cap = *std::min_element(caps.begin(), caps.end());
120 cap = *std::max_element(caps.begin(), caps.end());
122 return std::min(cap, n->qty - curr_qty);
126 for (
int i = 0; i != g->nodes().size(); i++) {
127 n_qty_[g->nodes()[i]] = 0;
129 grp_caps_[g.get()] = g->capacities();
133 std::vector<ExchangeNode::Ptr>& nodes = prs->nodes();
134 std::stable_sort(nodes.begin(), nodes.end(),
AvgPrefComp);
136 std::vector<ExchangeNode::Ptr>::iterator req_it = nodes.begin();
137 double target = prs->qty();
141 std::vector<Arc>::const_iterator arc_it;
142 std::vector<Arc> sorted;
143 double remain, tomatch, excl_val;
146 <<
" amount of a resource.";
148 while ((match <= target) && (req_it != nodes.end())) {
152 if (
graph_->node_arc_map().count(*req_it) > 0) {
153 const std::vector<Arc>& arcs =
graph_->node_arc_map().at(*req_it);
154 sorted = std::vector<Arc>(arcs);
155 std::stable_sort(sorted.begin(), sorted.end(),
ReqPrefComp);
156 arc_it = sorted.begin();
158 while ((match <= target) && (arc_it != sorted.end())) {
159 remain = target - match;
160 const Arc& a = *arc_it;
164 tomatch = std::min(remain,
Capacity(a, n_qty_[u], n_qty_[v]));
167 if (arc_it->exclusive()) {
168 excl_val = a.excl_val();
172 double dist = boost::math::float_distance(tomatch, excl_val);
180 if (tomatch >
eps()) {
182 <<
" amount of a resource.";
183 UpdateCapacity(u, a, tomatch);
184 UpdateCapacity(v, a, tomatch);
185 n_qty_[u] += tomatch;
186 n_qty_[v] += tomatch;
187 graph_->AddMatch(a, tomatch);
190 UpdateObj(tomatch, u->prefs[a]);
198 unmatched_ += target - match;
201void GreedySolver::UpdateObj(
double qty,
double pref) {
210 using cyclus::ValueError;
212 std::vector<double>& unit_caps = n->unit_capacities[a];
213 std::vector<double>& caps = grp_caps_[n->group];
214 assert(unit_caps.size() == caps.size());
215 for (
int i = 0; i < caps.size(); i++) {
216 double prev = caps[i];
219 caps[i] = (prev == std::numeric_limits<double>::max())
220 ? std::numeric_limits<double>::max()
221 : prev - qty * unit_caps[i];
226 std::stringstream ss;
227 ss <<
"A bid for " << n->commod <<
" was set at " << n->qty
228 <<
" but has been matched to a higher value " << qty
229 <<
". This could be due to a problem with your "
230 <<
"bid portfolio constraints.";
231 throw ValueError(ss.str());
An arc represents a possible connection between two nodes in the bipartite resource exchange graph.
boost::shared_ptr< ExchangeNode > vnode() const
boost::shared_ptr< ExchangeNode > unode() const
boost::shared_ptr< ExchangeNodeGroup > Ptr
ExchangeSolver(bool exclusive_orders=kDefaultExclusive)
double PseudoCost()
Calculates the ratio of the maximum objective coefficient to minimum unit capacity plus an added cost...
A GreedyPreconditioner conditions an ExchangeGraph for a GreedySolver by ordering the RequestGroups a...
virtual double SolveGraph()
the GreedySolver solves an ExchangeGraph by iterating over each RequestGroup and matching requests wi...
GreedySolver()
GreedySolver constructor.
double Capacity(const Arc &a, double u_curr_qty, double v_curr_qty)
the capacity of the arc
void Condition()
Uses the provided (or a default) GreedyPreconditioner to condition the solver's ExchangeGraph so that...
void Init()
Initialize member values based on the given graph.
boost::shared_ptr< RequestGroup > Ptr
For failed object state expectations.
Code providing rudimentary logging capability for the Cyclus core.
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
void Capacity(cyclus::Arc const &, double, double)
bool IsNegative(double d)
returns true if a double is less than 0 - eps()
bool AvgPrefComp(ExchangeNode::Ptr l, ExchangeNode::Ptr r)
A comparison function for sorting a container of Nodes by the nodes preference in decensing order (i....
bool ReqPrefComp(const Arc &l, const Arc &r)
double Capacity(const Arc& a, double u_curr_qty, double v_curr_qty) { return 0; }
@ LEV_DEBUG1
debugging information - least verbose
double eps()
a generic epsilon value
static const double float_ulp_eq
distance in ULP within which floating point numbers should be considered equal.
boost::shared_ptr< ExchangeNode > Ptr