CYCLUS
Loading...
Searching...
No Matches
greedy_solver.h
Go to the documentation of this file.
1#ifndef CYCLUS_SRC_GREEDY_SOLVER_H_
2#define CYCLUS_SRC_GREEDY_SOLVER_H_
3
4#include <boost/shared_ptr.hpp>
5#include "exchange_graph.h"
6#include "exchange_solver.h"
8
9namespace cyclus {
10
11/// @warning Deprecated! Use the Capacity member functions defined in the
12/// GreedySolver class.
13// @{
14void Capacity(cyclus::Arc const&, double, double);
15void Capacity(boost::shared_ptr<cyclus::ExchangeNode>, cyclus::Arc const&,
16 double);
17// @}
18
19/// double Capacity(const Arc& a, double u_curr_qty, double v_curr_qty) {
20/// return 0;
21/// }
22
23/// @brief A comparison function for sorting a container of Arcs by the
24/// requester's (unode's) preference, in decensing order (i.e., most preferred
25/// Arc first). In the case of a tie, a lexicalgraphic ordering of node ids is
26/// used.
27inline bool ReqPrefComp(const Arc& l, const Arc& r) {
28 int lu = l.unode()->agent_id;
29 int lv = l.vnode()->agent_id;
30 int ru = r.unode()->agent_id;
31 int rv = r.vnode()->agent_id;
32 double lpref = l.unode()->prefs[l];
33 double rpref = r.unode()->prefs[r];
34 return (lpref != rpref) ? (lpref > rpref)
35 : (lu > ru || (lu == ru && lv > rv));
36}
37
38/// @brief A comparison function for sorting a container of Nodes by the nodes
39/// preference in decensing order (i.e., most preferred Node first). In the case
40/// of a tie, a lexicalgraphic ordering of node ids is used.
42 int lid = l->agent_id;
43 int rid = r->agent_id;
44 double lpref = AvgPref(l);
45 double rpref = AvgPref(r);
46 return (lpref != rpref) ? (lpref > rpref) : (lid > rid);
47}
48
49class ExchangeGraph;
50class GreedyPreconditioner;
51
52/// @brief The GreedySolver provides the implementation for a "greedy" solution
53/// to a resource exchange graph.
54///
55/// Given an ExchangeGraph, the greedy solver will march through each
56/// RequestGroup in the graph, matching request nodes "greedily" with supply
57/// nodes. Each request node will attempt to be supplied by supplier arcs as
58/// long as those supplier arcs have some excess capacity. The possible
59/// suppliers will be ordered by descending preference. The algorithm terminates
60/// when one of the following conditions is met:
61/// 1) All RequestGroups are satisfied
62/// 2) All SupplySets are at capacity
63///
64/// @warning the GreedySolver is responsible for deleting is conditioner!
66 public:
67 /// GreedySolver constructor
68 /// @param exclusive_orders a flag for enforcing integral, quantized orders
69 /// @param c a conditioner to use before solving a graph instance
70 /// @warning if a NULL pointer is passed as a conditioner argument,
71 /// conditioning will *NOT* occur
72 /// @{
74 explicit GreedySolver(bool exclusive_orders);
76 GreedySolver(bool exclusive_orders, GreedyPreconditioner* c);
77 /// @}
78
79 virtual ~GreedySolver();
80
81 /// Uses the provided (or a default) GreedyPreconditioner to condition the
82 /// solver's ExchangeGraph so that RequestGroups are ordered by average
83 /// preference and commodity weight.
84 ///
85 /// @warning this function is called during the Solve step and should most
86 /// likely not be called independently thereof (except for testing)
87 void Condition();
88
89 /// Initialize member values based on the given graph.
90 void Init();
91
92 /// @brief the capacity of the arc
93 ///
94 /// @throws StateError if either ExchangeNode does not have a
95 /// ExchangeNodeGroup
96 /// @param a the arc
97 /// @param u_curr_qty the current quantity assigned to the unode (if solving
98 /// piecemeal)
99 /// @param v_curr_qty the current quantity assigned to the vnode (if solving
100 /// piecemeal)
101 /// @return The minimum of the unode and vnode's capacities
102 // @{
103 double Capacity(const Arc& a, double u_curr_qty, double v_curr_qty);
104 inline double Capacity(const Arc& a) { return Capacity(a, 0, 0); }
105 // @}
106
107 /// @brief the capacity of a node
108 ///
109 /// @throws StateError if ExchangeNode does not have a ExchangeNodeGroup
110 /// @param n the node
111 /// @param min_cap whether to use the minimum or maximum capacity value. In
112 /// general, nodes that represent bids use the minimum (i.e., the capacities
113 /// represents a less-than constraint) and nodes that represent requests use
114 /// the maximum value (i.e., the capacities represents a greater-than
115 /// constraint).
116 /// @param curr_qty the currently allocated node quantity (if solving
117 /// piecemeal)
118 /// @return The minimum of the node's nodegroup capacities / the node's unit
119 /// capacities, or the ExchangeNode's remaining qty -- whichever is smaller.
120 /// @{
121 double Capacity(ExchangeNode::Ptr n, const Arc& a, bool min_cap,
122 double curr_qty);
123 inline double Capacity(ExchangeNode::Ptr n, const Arc& a, bool min_cap) {
124 return Capacity(n, a, min_cap, 0.0);
125 }
126 inline double Capacity(ExchangeNode::Ptr n, const Arc& a, double curr_qty) {
127 return Capacity(n, a, true, curr_qty);
128 }
129 inline double Capacity(ExchangeNode::Ptr n, const Arc& a) {
130 return Capacity(n, a, true, 0.0);
131 }
132 /// @}
133
134 protected:
135 /// @brief the GreedySolver solves an ExchangeGraph by iterating over each
136 /// RequestGroup and matching requests with the minimum bids possible,
137 /// starting from the beginning of the the respective request and bid
138 /// containers.
139 virtual double SolveGraph();
140
141 private:
142 /// @brief updates the capacity of a given ExchangeNode (i.e., its max_qty and
143 /// the capacities of its ExchangeNodeGroup)
144 ///
145 /// @throws StateError if ExchangeNode does not have a ExchangeNodeGroup
146 /// @throws ValueError if the update results in a negative ExchangeNodeGroup
147 /// capacity or a negative ExchangeNode max_qty
148 /// @param n the ExchangeNode
149 /// @param qty the quantity for the node to update
150 void GetCaps(ExchangeNodeGroup::Ptr prs);
151 void GreedilySatisfySet(RequestGroup::Ptr prs);
152 void UpdateCapacity(ExchangeNode::Ptr n, const Arc& a, double qty);
153 void UpdateObj(double qty, double pref);
154
155 GreedyPreconditioner* conditioner_;
156 std::map<ExchangeNode::Ptr, double> n_qty_;
157 std::map<ExchangeNodeGroup*, std::vector<double>> grp_caps_;
158 double obj_;
159 double unmatched_;
160};
161
162} // namespace cyclus
163
164#endif // CYCLUS_SRC_GREEDY_SOLVER_H_
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)
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...
double Capacity(ExchangeNode::Ptr n, const Arc &a, double curr_qty)
GreedySolver()
GreedySolver constructor.
double Capacity(ExchangeNode::Ptr n, const Arc &a, bool min_cap)
double Capacity(const Arc &a, double u_curr_qty, double v_curr_qty)
the capacity of the arc
double Capacity(const Arc &a)
void Condition()
Uses the provided (or a default) GreedyPreconditioner to condition the solver's ExchangeGraph so that...
double Capacity(ExchangeNode::Ptr n, const Arc &a)
void Init()
Initialize member values based on the given graph.
boost::shared_ptr< RequestGroup > Ptr
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
Definition agent.cc:14
double AvgPref(ExchangeNode::Ptr n)
void Capacity(cyclus::Arc const &, double, double)
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; }
boost::shared_ptr< ExchangeNode > Ptr