ug4
boxsort.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3  * Author: Martin Rupp
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 
34 #ifndef __H__UG__LIB_DISC__AMG_SOLVER__BoxPriorityQueue_H__
35 #define __H__UG__LIB_DISC__AMG_SOLVER__BoxPriorityQueue_H__
36 
37 #include <vector>
38 
39 namespace ug{
40 
41 #ifdef UGASSERT
42 #define MYASSERT(a, b) UGASSERT(a, b)
43 #else
44 #define MYASSERT(a, b) assert(a && ##b)
45 #endif
46 
47 template<typename T>
48 inline size_t get_val(const T &t)
49 {
50  return t.get_val();
51 }
52 
53 inline size_t get_val(size_t i)
54 {
55  return i;
56 }
57 
60 
77 template<typename T>
79 {
80 private:
82 
83 public:
85  {
86 
87  }
92  BoxPriorityQueue(size_t n, const T *arr_) : m_size(0), m_height(0)
93  {
94  create(n, arr_);
95  }
96 
97  BoxPriorityQueue(const std::vector<T> &v) : m_size(0), m_height(0)
98  {
99  create(v.size(), &v[0]);
100  }
103  {
104  }
105 
109  void create(size_t n, const T *arr_)
110  {
111  if(n != m_size)
112  {
113  m_values.resize(n);
114  m_posInBox.resize(n);
115  m_size = n;
116  }
117  m_height = 0;
118  m_box.resize(0);
119  arr = arr_;
120  for(size_t i=0; i<n; i++) m_posInBox[i] = -1;
121  }
122 
123  void create(const std::vector<T> &v)
124  {
125  create(v.size(), &v[0]);
126  }
127 
128  void reset()
129  {
130  m_box.resize(0);
131  }
132 
136  void insert_item(size_t i)
137  {
138  size_check(i);
139  size_t val = get_val(arr[i]);
140  UG_ASSERT(val < (size_t)BOXPRIORITYQUEUE_MAXIMAL_VALUE, "T::get_val() has to be < " << BOXPRIORITYQUEUE_MAXIMAL_VALUE << " but is " << val);
141  if(m_box.size() < val+1)
142  {
143  //size_t s = m_box.size();
144  m_box.resize(val+1);
145  // for(;s<val+1; s++)
146  // m_box[s].reserve(10);
147  }
148 
149 
150  m_box[val].push_back(i);
151  m_values[i] = val;
152  m_posInBox[i] = m_box[val].size()-1;
153  m_height++;
154  }
155 
156  // remove
158  void remove(size_t i)
159  {
160  size_check(i);
161 
162  if(m_posInBox[i] == -1) return;
163  //UG_ASSERT(m_posInBox[i] != -1, "item " << i << " cannot be removed from queue, since it is not in the queue.");
164 
165  size_t val = m_values[i];
166 
167  // swap last of this box and i
168  /*size_t last = m_box[val].back();
169  if(last!=i)
170  assert(m_posInBox[i] < (int)m_box[val].size()-1);
171  m_box[val].pop_back();
172  if(last != i)
173  {
174 
175  m_box[val][m_posInBox[i]] = last;
176  m_posInBox[last] = m_posInBox[i];
177  }*/
178  m_box[val].erase(m_box[val].begin()+m_posInBox[i]);
179  for(size_t j=0; j<m_box[val].size(); j++)
180  {
181  m_posInBox[m_box[val][j]] = j;
182  }
183 
184  m_posInBox[i] = -1;
185 
186  while(m_box.size() && m_box.back().size() == 0)
187  m_box.pop_back();
188  m_height--;
189  }
190 
191  // removeMax
193  size_t remove_max()
194  {
195  UG_ASSERT(m_height > 0 && m_box.size() > 0, "queue empty! (height = " << m_height << ", boxsize = " << m_box.size() << ").");
196 
197  size_t val = m_box.size()-1;
198  size_t i = m_box[val][0];
199  remove(i);
200  return i;
201  }
202 
203  // get_max
205  size_t get_max() const
206  {
207  UG_ASSERT(m_height > 0 || m_box.size() <= 0, "queue empty! (height = " << m_height << ", boxsize = " << m_box.size() << ").");
208 
209  size_t val = m_box.size()-1;
210  return m_box[val][0];
211  }
212 
215  void update(size_t i)
216  {
217  if(m_posInBox[i] != -1 && m_values[i] != get_val(arr[i]))
218  {
219  remove(i);
220  insert_item(i);
221  }
222  }
223 
224  bool is_in(size_t i)
225  {
226  return m_posInBox[i] != -1;
227  }
228 
230  size_t arr_size() const
231  {
232  return m_size;
233  }
234 
236  size_t height() const
237  {
238  return m_height;
239  }
240 
243  /*void print()
244  {
245 
246  for(int i=0; i<m_size; i++)
247  {
248  cout << "Element " << i;
249  if(m_posInBox[i] < 0) cout << " not in box." << endl;
250  else cout << " val = " << m_values[i] << " get_val = " << arr[i].get_val() << " m_posInBox= " << m_posInBox[i] << endl;
251  }
252 
253  cout << m_box.size() << " boxs. content:" << endl;
254  for(int i=0; i<m_box.size(); i++)
255  {
256  cout << "m_box[" << i << "]: ";
257  for(int j=0; j<m_box[i].size(); j++)
258  {
259  cout << " " << m_box[i][j];
260  if(m_values[m_box[i][j]] != i) cout << " <-err ";
261  if( m_posInBox[m_box[i][j]] != j) cout << " <-err2 ";
262  }
263  cout << endl;
264  }
265  cout.flush();
266  }*/
267 
268 private:
269  inline void size_check(size_t i)
270  {
271  UG_ASSERT(i < arr_size(), "accessing element " << i << ", but size of the array is only " << arr_size());
272  }
273  const T *arr; //< pointer to array with elements of type T
274 
276 
277  stdvector<int> m_posInBox; //< item is at box[m_values[i]]
278  stdvector<size_t> m_values; //< m_values[i] is the value used for sorting of element i
279  size_t m_size; //< maximal size of the PQ = size of array arr
280  size_t m_height;
281 };
282 
283 } // namespace ug
284 
285 #endif
updateable priority queue class. this priority queue works on an external array of elements T.
Definition: boxsort.h:79
BoxPriorityQueue(const std::vector< T > &v)
Definition: boxsort.h:97
BoxPriorityQueue(size_t n, const T *arr_)
Definition: boxsort.h:92
~BoxPriorityQueue()
deconstructor
Definition: boxsort.h:102
stdvector< size_t > m_values
Definition: boxsort.h:278
void size_check(size_t i)
Definition: boxsort.h:269
stdvector< stdvector< size_t > > m_box
Definition: boxsort.h:275
void create(size_t n, const T *arr_)
creates the queue on a external array arr_[0]..arr_[n-1]
Definition: boxsort.h:109
void remove(size_t i)
removes index i in arr
Definition: boxsort.h:158
size_t m_size
Definition: boxsort.h:279
size_t remove_max()
returns the index in arr of maximal element of the heap
Definition: boxsort.h:193
void update(size_t i)
Definition: boxsort.h:215
void insert_item(size_t i)
Definition: boxsort.h:136
const T * arr
Definition: boxsort.h:273
size_t get_max() const
returns the index in m_arr of maximal element of the heap
Definition: boxsort.h:205
void reset()
Definition: boxsort.h:128
size_t arr_size() const
returns size of external array
Definition: boxsort.h:230
BoxPriorityQueue(const BoxPriorityQueue< T > &other)
size_t m_height
Definition: boxsort.h:280
void create(const std::vector< T > &v)
Definition: boxsort.h:123
BoxPriorityQueue()
Definition: boxsort.h:84
stdvector< int > m_posInBox
Definition: boxsort.h:277
size_t height() const
returns nr of elements in the heap.
Definition: boxsort.h:236
bool is_in(size_t i)
Definition: boxsort.h:224
Definition: stl_debug.h:45
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
the ug namespace
size_t get_val(const T &t)
Definition: boxsort.h:48
const int BOXPRIORITYQUEUE_MAXIMAL_VALUE
maximal value for T::get_val(). Keep in mind that memory requirements are O(max get_val()).
Definition: boxsort.h:59