3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

hoist out basic union find

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-05-21 11:10:42 -07:00
parent 6f575689b1
commit f100d4feda
2 changed files with 70 additions and 66 deletions

View file

@ -173,5 +173,71 @@ public:
#endif
};
class basic_union_find {
unsigned_vector m_find;
unsigned_vector m_size;
unsigned_vector m_next;
void ensure_size(unsigned v) {
while (v >= get_num_vars()) {
mk_var();
}
}
public:
unsigned mk_var() {
unsigned r = m_find.size();
m_find.push_back(r);
m_size.push_back(1);
m_next.push_back(r);
return r;
}
unsigned get_num_vars() const { return m_find.size(); }
unsigned find(unsigned v) const {
if (v >= get_num_vars()) {
return v;
}
while (true) {
unsigned new_v = m_find[v];
if (new_v == v)
return v;
v = new_v;
}
}
unsigned next(unsigned v) const {
if (v >= get_num_vars()) {
return v;
}
return m_next[v];
}
bool is_root(unsigned v) const {
return v >= get_num_vars() || m_find[v] == v;
}
void merge(unsigned v1, unsigned v2) {
unsigned r1 = find(v1);
unsigned r2 = find(v2);
if (r1 == r2)
return;
ensure_size(v1);
ensure_size(v2);
if (m_size[r1] > m_size[r2])
std::swap(r1, r2);
m_find[r1] = r2;
m_size[r2] += m_size[r1];
std::swap(m_next[r1], m_next[r2]);
}
void reset() {
m_find.reset();
m_next.reset();
m_size.reset();
}
};
#endif /* _UNION_FIND_H_ */