TCPSPSuite
resource.hpp
1 #ifndef RESOURCE_HPP
2 #define RESOURCE_HPP
3 
4 #include "generated_config.hpp"
5 
6 #include <boost/container/small_vector.hpp>
7 #include <type_traits>
8 #include <utility> // for pair
9 #include <vector> // for allocator, vector
10 
11 // one term: coefficient, exponent
12 typedef std::pair<double, double> poly_term;
13 
14 // list of terms
15 // TODO make number of optimized poly-terms a compile-time variable?
16 typedef std::vector<poly_term> polynomial;
17 
18 double apply_polynomial(const polynomial & poly, double x);
19 // TODO add moving variant for efficiency
20 polynomial add_poly(const polynomial & lhs, const polynomial & rhs);
21 
22 // Forwards
23 class Instance;
24 
25 class Availability {
26 public:
27  Availability(double start_amount);
28  Availability(const Availability & other) = default; // copy constructor
29 
30  void set(std::vector<std::pair<unsigned int, double>> && new_points);
31  double get_at(unsigned int point) const noexcept;
32 
33  double get_flat_available() const;
34 
35  std::vector<std::pair<unsigned int, double>>::const_iterator begin() const;
36  std::vector<std::pair<unsigned int, double>>::const_iterator end() const;
37 
38 private:
39  /* Each pair in the points vector is one step of a stepwise function
40  * indicating the availability of a resource. The first member of every point
41  * indicates from which time step on the amount is available, the second
42  * member indicates the amount. The first point (i.e., the first member of the
43  * first point) must be 0. The points must be sorted by ascending time steps.
44  */
45  std::vector<std::pair<unsigned int, double>> points;
46 };
47 
48 class FlexCost {
49 public:
50  FlexCost(polynomial base);
51 
52  void
53  set_flexible(std::vector<std::pair<unsigned int, polynomial>> && new_points);
54 
55  const polynomial & get_at(unsigned int point) const noexcept;
56  const polynomial & get_base() const noexcept;
57 
58  bool is_flat() const;
59 
60  std::vector<std::pair<unsigned int, polynomial>>::const_iterator
61  begin() const;
62  std::vector<std::pair<unsigned int, polynomial>>::const_iterator end() const;
63 
64 private:
65  polynomial base;
66  // Same idea as for Availability
67  std::vector<std::pair<unsigned int, polynomial>> points;
68 };
69 
70 class Resource {
71 public:
72  explicit Resource(unsigned int id);
73 
74  void set_availability(Availability && availability);
75  void set_overshoot_costs(FlexCost && cost);
76  void set_investment_costs(polynomial costs);
77 
78  const Availability & get_availability() const;
79 
80  const FlexCost & get_flex_overshoot() const;
81  const polynomial & get_overshoot_costs(unsigned int pos) const;
82 
83  // This only works if the instance has flat costs!
84  const polynomial & get_overshoot_costs() const;
85  bool is_overshoot_flat() const;
86 
87  const polynomial & get_investment_costs() const;
88 
89  unsigned int get_rid();
90  void set_id(unsigned int id);
91 
92  bool
93  operator==(const Resource & other) const
94  {
95  return other.rid == this->rid;
96  // TODO in debug mode, compare everything!
97  }
98 
99  // deepcopy
100  Resource clone() const;
101 
102 private:
103  unsigned int rid;
104  Availability availability;
105  polynomial investment_costs;
106  FlexCost overshoot_costs;
107 };
108 
109 class ResVec
110  : public boost::container::small_vector<double, OPTIMAL_RESOURCE_COUNT> {
111 public:
112  using boost::container::small_vector<double,
113  OPTIMAL_RESOURCE_COUNT>::small_vector;
114 };
115 
116 class Resources {
117 public:
118  Resources();
119  Resources(double usage);
120  Resources(const Instance * instance, const ResVec & usage);
121  Resources(const Instance * instance, const std::vector<double> & usage);
122  Resources(const Instance * instance, ResVec && usage);
123  Resources(const Instance * instance);
124 
125  const ResVec & getUsage() const;
126  ResVec & getUsage();
127 
128  Resources operator+(const Resources & other) const;
129  Resources operator-(const Resources & other) const;
130  Resources operator*(const Resources & other) const;
131  Resources operator/(const Resources & other) const;
132  void operator+=(const Resources & other);
133  void operator-=(const Resources & other);
134  void operator*=(const Resources & other);
135  void operator/=(const Resources & other);
136 
137  bool operator<(const Resources & other) const;
138  bool operator>(const Resources & other) const;
139  bool operator<=(const Resources & other) const;
140  bool operator>=(const Resources & other) const;
141  bool operator!=(const Resources & other) const;
142  bool operator==(const Resources & other) const;
143 
144  template <typename T>
145  inline friend std::enable_if_t<std::is_integral_v<T>, Resources>
146  operator*(const T & scalar, const Resources & resource);
147 
148 private:
149  const Instance * instance;
150  mutable bool cached;
151  mutable double cache;
152 
153  ResVec usage;
154 
155  double getCosts() const;
156 };
157 
158 template <typename T>
159 inline std::enable_if_t<std::is_integral_v<T>, Resources>
160 operator*(const T & scalar, const Resources & resource)
161 {
162  Resources res(resource.instance, resource.usage);
163  for (size_t i = 0; i < resource.usage.size(); i++) {
164  res.usage[i] *= scalar;
165  }
166  return res;
167 }
168 
169 template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
170 Resources
171 operator*(const Resources & resource, const T & scalar)
172 {
173  return scalar * resource;
174 }
175 
176 #endif
Instance
a TCPSP instance
Definition: instance.hpp:24