Vous êtes sur la page 1sur 22

Union Find Disjoint Sets

UPC 2013
Manejar grupos eficientemente
Union-Find Disjoint Sets
Estructura de datos.
Permite identificar o rastrear elementos
particionados en diferentes grupos o sets.
Util para detectar ciclos dentro de un grafo.
Internamente utiliza un arreglo de padres.
Maneja 4 funciones:
Inicializacin (initSet)
Unin (unionSet)
Busqueda (findSet) Decir quin es su padre
MismoSet (isSameSet)
Un poco de lo bsico
Qu queremos?

UnionSet(4 , 3)
UnionSet(3, 8)
UnionSet(6, 5)
UnionSet(9, 4)
UnionSet(2, 1)
IsSameSet(0, 7)
IsSameSet(8, 9)
UnionSet(5, 0)
UnionSet(7, 2)
UnionSet(6, 1)
UnionSet(1, 0)
IsSameSet(0, 7)

Un poco de lo bsico
Vamos a asumir que la conexin es una relacin de
equivalencia. Es decir:
Es reflexiva: p est conectado con p
Es simtrica: si p est conectado con q, q est
conectado con p
Es transitiva: si p est conectado con q y q est
conectado con r, entonces p est conectado con r
3 componentes conexos
Un poco de lo bsico
3 componentes conexos 2 componentes conexos
Primera estrategia: Quick Find
Arreglo id[] de tamao N
Interpretacin: p y q estn conectados si tienen el mismo
id.

Primera estrategia: Quick Find
public class QuickFindUF
{
private int[] id;
public QuickFindUF(int N)
{
id = new int[N];
for (int i = 0; i < N; i++)
id[i] = i;
}
public boolean connected(int p, int q)
{ return id[p] == id[q]; }

public void union(int p, int q)
{
int pid = id[p];
int qid = id[q];
for (int i = 0; i < id.length; i++)
if (id[i] == pid) id[i] = qid;
}
}
Pregunta:
Tiempo O( ) de:
- QuickFindUF (inicializacin)
- Connected
- Union
Primera estrategia: Quick Find
Algoritmo Inicializacin Union Consulta
QuickFind N N 1
Desventajas de QuickFind:
Vemos que es muy lento en las uniones!
Si tengo que agregar N elementos: O(n
2
)
Segunda estrategia: Quick Union
Arreglo id[] de tamao N
Interpretacin: id[i] es padre de i
El Root de i es id[id[id[ id[i] ]]] (sigue hasta que no
cambie, el algoritmo asegura que no haya ciclos)

Segunda estrategia: Quick Union
public class QuickUnionUF
{
private int[] id;
public QuickUnionUF(int N){
id = new int[N];
for (int i = 0; i < N; i++) id[i] = i;
}
private int root(int i){
while (i != id[i]) i = id[i];
return i;
}
public boolean connected(int p, int q){
return root(p) == root(q);
}
public void union(int p, int q){
int i = root(p);
int j = root(q);
id[i] = j;
}
}
Pregunta:
Tiempo O( ) de:
- QuickUnionUF (inicializacin)
- Root
- Connected
- Union
Segunda estrategia: Quick Union
Algoritmo Inicializacin Union Consulta
QuickFind N N 1
QuickUnion N N

N
Desventajas de QuickFind:
Vemos que es muy lento en las uniones!
Si tengo que agregar N elementos: O(n
2
)

Desventajas de QuickUnion:
Los rboles podran quedar muy grandes
La consulta puede ser muy cara

Mejoras: Weighted QuickUnion
Modificamos el mtodo de union:

int i = root(p);
int j = root(q);
if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; }
else { id[j] = i; sz[i] += sz[j]; }

Con ese cambio nos aseguramos que la
profundidad de un nodo es a lo ms lgN


LA Mejora: Path Compression
LA Mejora: Path Compression
Finalmente
Algoritmo Inicializacin Union Consulta
QuickFind N N 1
QuickUnion N N

N
WeightedQU N lgN lgN
WQU c/. PathC. N lg* N lg* N
Mira lo bueno que es:
Si comparamos QU vs WQU
c/. Path C. para una entrada
de 10
9
uniones y 10
9
Consultas pasamos de 30
aos a 6 segundos



La implementacin
La mejor parte
Init Set (Inicializar los Sets)
Inicializa los set como
independientes.
Todos con padres
asignados a ellos
mismos.
vector<int> pset(INI_VEC);
void initSet(int _size) {
pset.clear();
pset.resize(_size);
for (int i=0; i<_size;i++)
pset[i]=i;
}

A
pset = A
B
pset = B
C
pset = C
D
pset = D
E
pset = E
Union Set (Une dos sets)
Une dos Sets.
Ambos referencian al
mismo padre.
void unionSet(int i, int j) {
pset[findSet(i)]=findSet(j);
}
int findSet(int i) {
return (pset[i] == i) ? i :
(pset[i] =
findSet(pset[i]));
}


A
pset = A
B
pset = B
C
pset = C
D
pset = D
E
pset = E
unionSet(A,B)
A
pset = B
B
pset = B
unionSet(A,C)
C
pset = C
A
pset = B
B
pset = C
unionSet(D,B)
D
pset = C
C
pset = C
A
pset = B
B
pset = C
Find Set
Si el padre de i es el mismo i
Retorna I
De lo contrario
Busca el padre y lo actualiza
recursivamente
int findSet(int i) {
return (pset[i] == i) ? i :
(pset[i] =
findSet(pset[i]));
}

D
pset = C
C
pset = C
A
pset = B
B
pset = C
findSet(A)
D
pset = C
C
pset = C
A
pset = C
B
pset = C
E
pset = E
Is Same Set
Comparan los padres,
llamando la funcin
findSet recursivamente.
bool isSameSet(int i, int j) {
return
findSet(i)==findSet(j);
}

D
pset = C
C
pset = C
A
pset = C
B
pset = C
E
pset = E
isSameSet(A,E)
= false
Bibliografa
Algorithms, Fourth Edition. Rober Sedgewick and Kevin
Waune. Princeton 2009
Halim, Steven & Halim Felix. Competitive Programing 2.
2011

Vous aimerez peut-être aussi