Aleph-w  1.9
General library for algorithms and data structures
tpl_union.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 # ifndef TPL_UNION_H
28 # define TPL_UNION_H
29 
30 # include <tpl_dynArray.H>
31 # include <tpl_dynSetTree.H>
32 
33 
53 {
54 protected:
55 
58  size_t num_blocks;
59 
60  virtual size_t root(size_t i)
61  {
62  while (i != id(i))
63  {
64  id(i) = id(id(i));
65  i = id(i);
66  }
67 
68  return i;
69  }
70 
71  size_t depth(size_t i) noexcept
72  {
73  const int & parent = id(i);
74  if (parent == i)
75  return 1;
76 
77  return 1 + depth(parent);
78  }
79 
80 public:
81 
83  Fixed_Relation(size_t n = 0) : num_blocks(n)
84  {
85  if (num_blocks == 0)
86  return;
87 
88  id.reserve(num_blocks);
89  sz.reserve(num_blocks);
90  for (size_t i = 0; i < num_blocks; ++i)
91  {
92  id(i) = i;
93  sz(i) = 1;
94  }
95  }
96 
107  void set_n(size_t n) { new (this) Fixed_Relation(n); }
108 
110  size_t size() const noexcept { return id.size(); }
111 
114  size_t get_num_blocks() const noexcept { return num_blocks; }
115 
128  bool are_connected(size_t i, size_t j) noexcept
129  {
130  return root(i) == root(j);
131  }
132 
139  void join(size_t i, size_t j) noexcept
140  {
141  i = root(i);
142  j = root(j);
143  if (i == j)
144  return;
145 
146  if (sz(i) < sz(j))
147  {
148  id(i) = j;
149  sz(j) += sz(i);
150  }
151  else
152  {
153  id(j) = i;
154  sz(i) += sz(j);
155  }
156  --num_blocks;
157  }
158 };
159 
160 
179 class Relation : public Fixed_Relation
180 {
181  void verify_if_add_new_points(size_t n)
182  {
183  size_t l = size();
184  if (n < l)
185  return;
186 
187  id.reserve(l, n);
188  sz.reserve(l, n);
189  for (int i = l; i <= n; ++i)
190  {
191  id(i) = i;
192  sz(i) = 1;
193  }
194  num_blocks += n - l + 1;
195  }
196 
197  virtual size_t root(size_t i)
198  {
199  verify_if_add_new_points(i);
200  return Fixed_Relation::root(i);
201  }
202 
203 public:
204 
206  Relation(size_t n = 0) : Fixed_Relation(n) {}
207 };
208 
209 
226  template <typename T, class Compare = Aleph::less<T>>
227 class Relation_T : public Relation
228 {
229  struct Pair
230  {
231  T item;
232  size_t i;
233 
234  Pair() noexcept {}
235 
236  Pair(const T & __item, size_t __i)
237  noexcept(std::is_nothrow_copy_assignable<T>::value)
238  : item(__item), i(__i) { /* empty */ }
239  };
240 
241  struct Cmp
242  {
243  bool operator () (const Pair & p1, const Pair & p2) const noexcept
244  {
245  return Compare() (p1.item, p2.item);
246  }
247  };
248 
249  DynSetAvlTree<Pair, Cmp> items_tree;
250 
251  // retorna el id del item; sea porque lo encuentra o porque lo inserta
252  size_t test_and_insert_new_item(const T & item)
253  {
254  size_t N = size();
255  Pair p(item, N);
256  Pair * ptr = items_tree.search_or_insert(p);
257  return ptr->i;
258  }
259 
260 public:
261 
263  bool are_connected(const T & p, const T & q)
264  {
265  size_t i = test_and_insert_new_item(p);
266  size_t j = test_and_insert_new_item(q);
267 
268  return Relation::are_connected(i, j);
269  }
270 
272  void join(const T & p, const T & q)
273  {
274  size_t i = test_and_insert_new_item(p);
275  size_t j = test_and_insert_new_item(q);
276  Relation::join(i, j);
277  }
278 };
279 
280 # endif // TPL_UNION_H
void reserve(const size_t l, const size_t r)
Definition: tpl_dynArray.H:998
size_t size() const noexcept
Return the number of items of set (not of relation)
Definition: tpl_union.H:110
Definition: tpl_union.H:179
Definition: tpl_union.H:52
void join(size_t i, size_t j) noexcept
Definition: tpl_union.H:139
size_t get_num_blocks() const noexcept
Definition: tpl_union.H:114
bool are_connected(size_t i, size_t j) noexcept
Definition: tpl_union.H:128
bool are_connected(const T &p, const T &q)
Retorna true is i y j están conectados.
Definition: tpl_union.H:263
void join(const T &p, const T &q)
Une p con q.
Definition: tpl_union.H:272
Definition: tpl_union.H:227
void set_n(size_t n)
Definition: tpl_union.H:107
Fixed_Relation(size_t n=0)
Initialize an empty binary relation of integers between 0 and n - 1.
Definition: tpl_union.H:83
Key * search_or_insert(const Key &key)
Definition: tpl_dynSetTree.H:254
Relation(size_t n=0)
Intialize an empty relation of n elementos between [0..n)
Definition: tpl_union.H:206

Leandro Rabindranath León