TCPSPSuite
skyline.hpp
1 //
2 // Created by lukas on 06.12.17.
3 //
4 
5 #ifndef TCPSPSUITE_SKYLINE_HPP
6 #define TCPSPSUITE_SKYLINE_HPP
7 
8 #include "../contrib/intervaltree/src/dynamic_segment_tree.hpp" // for Combine...
9 #include "../instance/job.hpp" // for Job
10 #include "../instance/resource.hpp" // for Resources
11 #include "../util/template_magic.hpp" // for Optiona...
12 #include "generated_config.hpp"
13 
14 #include <boost/container/flat_set.hpp> // for flat_set
15 #include <boost/hana.hpp> // for hana
16 #include <iterator> // for forward...
17 #include <stddef.h> // for size_t
18 #include <utility> // for move, pair
19 #include <vector> // for vector
20 class Instance;
21 
22 namespace hana = boost::hana;
23 
24 namespace ds {
25 using MaxRange = std::pair<unsigned int, unsigned int>;
26 
27 class SkyLineEvent {
28 public:
29  SkyLineEvent(const Instance * instance) : usage(instance) {}
30  SkyLineEvent(){};
31 
32  // Current resource usage *after* the event
33  Resources usage;
34 
35  // where does the event happen
36  unsigned int where;
37 
38  // Does a job start here?
39  bool start;
40 
41  bool
42  operator==(const SkyLineEvent & other) const noexcept
43  {
44  return (this->usage == other.usage) && (this->where == other.where) &&
45  (this->start == other.start);
46  }
47 };
48 
49 // Forward
50 class SkyLineIterator;
51 
52 /*
53  * ArraySkyLineBase
54  */
55 template <bool support_iteration>
56 class ArraySkyLineBase {
57 public:
58  class iterator {
59  public:
60  typedef ptrdiff_t difference_type;
61  typedef SkyLineEvent value_type;
62  typedef const SkyLineEvent & reference;
63  typedef const SkyLineEvent * pointer;
64  typedef std::input_iterator_tag iterator_category;
65 
66  iterator() noexcept;
67  iterator(const iterator & other) noexcept;
68  iterator(iterator && other) noexcept;
69  iterator(ArraySkyLineBase * sl, size_t time_index) noexcept;
70 
71  iterator & operator=(const iterator & other) noexcept;
72  iterator & operator=(iterator && other) noexcept;
73 
74  bool operator==(const iterator & other) const noexcept;
75  bool operator!=(const iterator & other) const noexcept;
76 
77  iterator & operator++() noexcept;
78  iterator operator++(int) noexcept;
79  iterator & operator+=(size_t steps) noexcept;
80  iterator operator+(size_t steps) const noexcept;
81 
82  iterator & operator--() noexcept;
83  iterator operator--(int) noexcept;
84  iterator & operator-=(size_t steps) noexcept;
85  iterator operator-(size_t steps) const noexcept;
86 
87  reference operator*() const noexcept;
88  pointer operator->() const noexcept;
89 
90  /* Conversion to generic iterator */
91  // operator SkyLineIterator() noexcept;
92 
93  private:
94  void update_ev() noexcept;
95  void update_resource_amount(bool went_forward) noexcept;
96 
97  ArraySkyLineBase * sl;
98  size_t time_index;
99  struct event_compare
100  {
101  bool
102  operator()(const std::pair<bool, Job::JobId> & lhs,
103  const std::pair<bool, Job::JobId> & rhs) const noexcept
104  {
105  if (lhs.first != rhs.first) {
106  return !lhs.first;
107  } else {
108  return lhs.second < rhs.second;
109  }
110  }
111  };
112  typename boost::container::flat_set<std::pair<bool, Job::JobId>,
113  event_compare>::iterator event_it;
114 
115  SkyLineEvent ev;
116  };
117 
118 public:
119  ArraySkyLineBase(const Instance * instance);
120 
121  void remove_job(const Job & job) noexcept;
122  void remove_job(Job::JobId jid) noexcept;
123  void insert_job(const Job & job, unsigned int pos) noexcept;
124  void insert_job(Job::JobId jid, unsigned int pos) noexcept;
125  void set_pos(const Job & job, unsigned int pos) noexcept;
126  void set_pos(Job::JobId jid, unsigned int pos) noexcept;
127 
128  Resources get_maximum() noexcept;
129  Resources get_maximum(unsigned int l, unsigned int r) noexcept;
130 
131  using MaxRange = std::pair<unsigned int, unsigned int>;
132 
133  MaxRange get_maximum_range() const noexcept;
134  MaxRange get_maximum_range(unsigned int l, unsigned int r) const noexcept;
135 
136  iterator begin() noexcept;
137  iterator end() noexcept;
138 
139  iterator lower_bound(unsigned int x) noexcept;
140  iterator upper_bound(unsigned int x) noexcept;
141 
142 private:
143  const Instance * const instance;
144 
145  // TODO outer vector should be a small_vector
146  // usage[rid][timepoint]
147  std::vector<std::vector<double>> usage;
148 
149  // TODO inner vectors should be a flat_set?
150  using EventVector =
151  std::vector<boost::container::flat_set<std::pair<bool, Job::JobId>>>;
152  utilities::OptionalMember<EventVector, support_iteration> events;
153 
154  std::vector<unsigned int> start_times;
155 };
156 
157 template <bool ranged, bool single_resource>
158 class TreeSkyLineBase {
159 private:
160  /*
161  * Compute value type for the tree
162  */
163  constexpr static auto
164  compute_value_type()
165  {
166  if constexpr (single_resource) {
167  return hana::type_c<double>;
168  } else {
169  return hana::type_c<Resources>;
170  }
171  }
172 
173  using ValueType = typename decltype(compute_value_type())::type;
174 
175  /*
176  * Compute correct combiner type
177  */
178  constexpr static auto
179  compute_combiner_type()
180  {
181  if constexpr (!ranged) {
182  return hana::type_c<ygg::MaxCombiner<unsigned int, ValueType>>;
183  } else {
184  return hana::type_c<ygg::RangedMaxCombiner<unsigned int, ValueType>>;
185  }
186  }
187 
188  using MaxCombiner = typename decltype(compute_combiner_type())::type;
189  using Combiners = ygg::CombinerPack<unsigned int, ValueType, MaxCombiner>;
190 
191 #ifdef YGG_STORE_SEQUENCE_DST
192  class SequenceInterface {
193  public:
194  using ValueT = ValueType;
195 
196  template <class Node>
197  static ValueT
198  get_value(const Node & n)
199  {
200  return n.usage;
201  }
202  };
203  using TreeOptions = ygg::TreeOptions<
204  ygg::TreeFlags::MULTIPLE, ygg::TreeFlags::CONSTANT_TIME_SIZE,
205  ygg::TreeFlags::template BENCHMARK_SEQUENCE_INTERFACE<SequenceInterface>>;
206 #else
207  using TreeOptions = ygg::DefaultOptions;
208 #endif
209 
210  class Node
211  : public ygg::DynSegTreeNodeBase<unsigned int, ValueType, ValueType,
212  Combiners, ygg::UseDefaultZipTree> {
213  public:
214  // TODO reference these? Use the direct values?
215  ValueType usage;
216  unsigned int start;
217  unsigned int length;
218  };
219 
220  class JobNodeTraits : public ygg::DynSegTreeNodeTraits<Node> {
221  public:
222  static unsigned int get_lower(const Node & job);
223  static unsigned int get_upper(const Node & job);
224  static const ValueType & get_value(const Node & job);
225  };
226  using Tree = ygg::DynamicSegmentTree<Node, JobNodeTraits, Combiners,
227  TreeOptions, ygg::UseDefaultZipTree>;
228  Tree t;
229 
230 public:
231  class iterator {
232  private:
233  using SubIterator = decltype(t.begin());
234 
235  public:
236  typedef ptrdiff_t difference_type;
237  typedef SkyLineEvent value_type;
238  typedef const SkyLineEvent & reference;
239  typedef const SkyLineEvent * pointer;
240  typedef std::forward_iterator_tag iterator_category;
241 
242  iterator();
243  iterator(const iterator & other);
244  iterator(iterator && other);
245  iterator(Tree * t, const Instance * instance, SubIterator sub_it);
246 
247  iterator & operator=(const iterator & other);
248  iterator & operator=(iterator && other);
249 
250  ~iterator(){};
251 
252  bool operator==(const iterator & other) const;
253  bool operator!=(const iterator & other) const;
254 
255  iterator & operator++();
256  iterator operator++(int);
257  iterator & operator+=(size_t steps);
258  iterator operator+(size_t steps) const;
259 
260  iterator & operator--();
261  iterator operator--(int);
262  iterator & operator-=(size_t steps);
263  iterator operator-(size_t steps) const;
264 
265  reference operator*() const;
266  pointer operator->() const;
267 
268  /* Conversion to generic iterator */
269  // operator SkyLineIterator() noexcept;
270 
271  private:
272  void update_event() noexcept;
273  void update_resource_amount(bool went_forward) noexcept;
274 
275  Tree * tree;
276  SubIterator sub_it;
277  SkyLineEvent ev;
278  const Node * ev_node;
279  };
280 
281  TreeSkyLineBase(const Instance * instance);
282 
283  void remove_job(const Job & job) noexcept;
284  void remove_job(Job::JobId jid) noexcept;
285  void insert_job(const Job & job, unsigned int pos) noexcept;
286  void insert_job(Job::JobId jid, unsigned int pos) noexcept;
287  void set_pos(const Job & job, unsigned int pos) noexcept;
288  void set_pos(Job::JobId jid, unsigned int pos) noexcept;
289 
290  ValueType get_maximum();
291  ValueType get_maximum(unsigned int l, unsigned int r);
292 
293  using MaxRange = std::pair<unsigned int, unsigned int>;
294 
295  MaxRange get_maximum_range() const noexcept;
296  MaxRange get_maximum_range(unsigned int l, unsigned int r) const noexcept;
297 
298  iterator begin();
299  iterator end();
300 
301  iterator lower_bound(unsigned int x);
302  iterator upper_bound(unsigned int x);
303 
304 private:
305  const Instance * const instance;
306  std::vector<Node> nodes;
307 };
308 } // namespace ds
309 
310 // The actual interface has been factored out
311 #include "skyline_interface.hpp"
312 
313 namespace ds {
314 /*
315  * Naming
316  */
317 using TreeSkyLine = TreeSkyLineBase<false, false>;
318 using RangedTreeSkyLine = TreeSkyLineBase<true, false>;
319 using SingleTreeSkyLine = TreeSkyLineBase<false, true>;
320 using SingleRangedTreeSkyLine = TreeSkyLineBase<true, true>;
321 
322 using ArraySkyLine = ArraySkyLineBase<false>;
323 using IteratorArraySkyLine = ArraySkyLineBase<true>;
324 
325 } // namespace ds
326 
327 #endif // TCPSPSUITE_SKYLINE_HPP
Instance
a TCPSP instance
Definition: instance.hpp:24
Job
A job of an TCPSP instance.
Definition: job.hpp:21