Sie sind auf Seite 1von 15

Estructuras de Datos.

Estructuras de Datos para Conjuntos Disjuntos


Santiago Zanella
2008

Introducci
on

Para ciertas aplicaciones se requiere mantener n elementos distintos agrupandolos en una


coleccion de conjuntos disjuntos, permitiendo dos operaciones: (1) la union de dos conjuntos de la coleccion y (2) conocer en que conjunto se encuentra un elemento dado. Entre
estas aplicaciones se cuentan el algoritmo de Kruskal para la determinacion del arbol de
expansion mnimo de un grafo, la inferencia de tipos, la determinacion de las componentes
conexas de un grafo, el reconocimiento de objetos en imagenes, etc...

Definici
on de la Estructura

Una estructura de datos de conjuntos disjuntos (disjoint-set data structure) mantiene una
coleccion
S = {S1 , S2 , . . . , Sk }
de conjuntos disjuntos entre s
i, j {1, . . . , k} | i 6= j Si Sj =
con elementos dentro de un cierto universo
U = {x1 , . . . , xn }
Cada conjunto de la coleccion se identifica por un representante que puede ser un miembro cualquiera del conjunto. Solo se requiere que al consultar por el representante de un
conjunto dos veces consecutivas sin modificar el conjunto el resultado sea el mismo.
Sin perder generalidad se puede asumir que U = {1, . . . , n}. Si no fuera as se puede encontrar una funcion biyectiva que realice la traduccion entre U y el conjunto {1, . . . , n}.
Sean x, y U se desea implementar las siguientes operaciones:
1

MakeSet(x): Crea un nuevo conjunto cuyo u


nico miembro (y representante) es x. Se
requiere que x no este en ning
un conjunto de la estructura.
S
pre: x U ki=1 Si
pos: S = S {x}
Union(x, y): Une los conjuntos que contienen a x y a y, digamos Sx y Sy . El representante
del conjunto resultante puede ser cualquier miembro de Sx Sy . Como se requiere
que la coleccion sea disjunta, se eliminan los conjuntos Sx y Sy de la coleccion S.
pre: x Sx y Sy Sx 6= Sy
pos: S = S (Sx Sy ) {Sx , Sy }
Find(x): Encuentra el representante del u
nico conjunto al que pertenece x o 0 si x no
esta en ning
un conjunto de la coleccion.
pre: x U
S
pos: (x Si i = 1, . . . , k F ind(x) Si ) (x
/ ki=1 Si F ind(x) = 0)

En lo que sigue se intentara analizar el costo de diferentes implementaciones de la estructura al ejecutar una secuencia de m de estas operaciones, de las cuales n son operaciones
MakeSet, q son operaciones Union y f son operaciones Find (Ver Tabla 1).
Como los conjuntos son disjuntos, cada operacion Union reduce el n
umero de conjuntos
en 1. Luego de n 1 operaciones Union solamente queda un conjunto, por lo tanto el
n
umero de operaciones Union es a lo sumo n 1.
N
umero de Operaciones

MakeSet
Union
Find
n
q n 1 f = m (n + q)

Tabla 1: N
umero de operaciones de cada tipo en la secuencia .
Se considerara ademas que en cada una de las operaciones Union(x, y), x e y son los
representantes de los conjuntos a los que pertencen.

Aplicaci
on

Una aplicacion simple de la estructura de conjuntos disjuntos es determinar si dos vertices


de un grafo no-dirigido pertenecen o no a la misma componente conexa.
1 procedure co nnect ed co mpo nent s (G)
2
foreach v V(G)
2

3
MakeSet ( v ) ;
4
end
5
foreach ( u , v ) E(G)
6
i f Find ( u ) 6= Find ( v ) then
7
Union ( u , v ) ;
8
end
9
end
10 end
1 procedure same
2
i f Find ( u )
3
return
4
else
5
return
6
end
7 end

component ( u , v )
= Find ( v ) then
True ;
False ;

Ejemplo
a

Figura 1: Un grafo no-dirigido con 8 vertices y 3 componentes conexas.

Paso
0
1
2
3
4
5

Arista Procesada
inicio
(a,b)
(a,e)
(a,g)
(c,d)
(c,i)

{a}
{b}
{a, b}
{a, b, e}
{a, b, e, g}
{a, b, e, g}
{a, b, e, g}

{c}
{c}
{c}
{c}
{c, d}
{c, d, i}

S
{d} {e} {g} {h} {i}
{d} {e} {g} {h} {i}
{d}
{g} {h} {i}
{d}
{h} {i}
{h} {i}
{h}

Tabla 2: Coleccion de conjuntos disjuntos luego de proecesar cada arista.


La Tabla 2 muestra la coleccion S que mantiene la estructura en cada paso del procedimiento. Al finalizar, dos vertices se encuentran en el mismo conjunto de la coleccion
si y solo s se encuentran en la misma componente conexa. Luego, Find(u) = Find(v) si
y solo si u y v estan en la misma componente conexa.

La relacion R donde u R v si y solo s u y v estan en la misma componente conexa es


una relacion de equivalencia. En general, siempre que se divide un grupo de objetos en
conjuntos disjuntos, la relacion R donde x R y si y solo s x e y estan en el mismo conjunto
es una relacion de equivalencia.

Representaci
on por Arreglos

Una manera simple de implementar la estructura es utilizando un arreglo rep de tama


no
n de tal forma que rep[x] indique el representante del conjunto al que pertence x.
Se incializan todas las posiciones del arreglo rep en 0.
La operacion Makeset(x) asigna rep[x] := x. O(1).
La operacion Find(x) simplemente devuelve el valor de rep[x]. O(1).
Para la operacion Union(x, y) se recorre el arreglo rep y se cambian, por ejemplo,
todas las posiciones iguales a y por x. O(n).
1 procedure MakeSet ( x )
2
r ep [ x ] := x ;
3 end
1 function Find ( x )
2
return r ep [ x ] ;
3 end
1 procedure Union ( x , y )
2
for i :=1 to n do
3
i f r ep [ i ] = y then
4
r ep [ i ] := x ;
5
end
6
end
7 end
El costo de m operaciones esta dominado por la cantidad de operaciones Union, cada
una de las cuales tiene costo O(n). El orden de una secuencia de m operaciones resulta
O(n + qn + f ). En el peor caso, q = n 1 = (m) y la secuencia completa tiene un
orden de tiempo de O(m2 ).

(a)

(b)

rep

b
c

c
c

d
f

e
c

f
f

rep

b
c

c
c

d
c

e
c

f
c

g
f
g
c

h
c
h
c

Figura 2: (a) Representacion por arreglos de los conjuntos {c, h, e, b} con c como representante y {f, g, d} con f como representante. (b) Resultado luego de ejecutar Union(c, f ).

Representaci
on por Listas

Se puede mejorar el costo de la operacion Union si en lugar de recorrer todas las entradas
del arreglo rep se recorren solamente aquellas que corresponden a uno de los dos conjuntos.
Esto se puede lograr representando los conjuntos mediante listas usando arreglos.
Se representa la estructura usando un arreglo rep como en el caso anterior, un arreglo next
que indica el sucesor de un elemento en la lista a la que pertenece y un arreglo last que
almacena el u
ltimo elemento de cada lista. El primer elemento de cada lista sirve como
representante del conjunto.
Se incializan todas las posiciones del arreglo rep en 0.
La operacion Makeset(x) crea una nueva lista que contiene solo al elemento x en
O(1).
La operacion Find(x) simplemente devuelve el valor de rep[x]. O(1).
Para la operacion Union(x, y) se recorre, por ejemplo, la lista que comienza en x
cambiando las entradas correspondientes en el arreglo rep por y y luego se concatena
al final de la lista que comienza en y. (Fig. 3)

(a)

(b)

Figura 3: (a) Representacion en forma de lista de los conjuntos {c, h, e, b} y {f, g, d}. (b)
Resultado luego de ejecutar Union(c, f ).

1 procedure MakeSet ( x )
2
r ep [ x ] := x ;
3
next [ x ] := 0 ;
4
l a s t [ x ] := x ;
5 end
1 function Find ( x )
2
return r ep [ x ] ;
3 end
1 procedure Union ( x , y )
2
p := x ;
3
do
4
r ep [ p ] := y ;
5
p := next [ p ] ;
6
while p 6= 0
7
next [ l a s t [ y ] ] := x ;
8
l a s t [ y ] := l a s t [ x ] ;
9 end
Para realizar una operacion Union se recorre toda la lista x, lo que lleva un tiempo
proporcional a la longitud de la lista. Se puede construir una secuencia de m operaciones
que lleve tiempo (m2 ). Considere la secuencia de m operaciones con n = m/2 + 1 y
q = m n = m/2 1 que se muestra en la Tabla 3.
Operacion
MakeSet(x1 )
..
.

N
umero de Actualizaciones a rep
1
..
.

MakeSet(xn )
Union(x1 , x2 )
Union(x2 , x3 )
Union(x3 , x4 )
..
.

1
1
2
3
..
.

Union(xq1 , xq )

q1

Tabla 3: Una secuencia de m operaciones que toma tiempo (m2 ).


Cada operacion MakeSet realiza una actualizacion a rep. La i-esima operacion Union
realiza i actualizaciones. El n
umero de actualizaciones en las q operaciones Union es
q1
X

i = (q 2 )

i=1

El n
umero total de actualizaciones es de orden (n + q 2 ) = (m2 ) porque n = (m) y
q = (m). En promedio cada una de las m operaciones tiene orden (m).

5.1

Uni
on por Tama
no

En la implementacion anterior no se consideraba la longitud de cada lista al realizar una


operacion Union. Que sucede si se considera y se actualizan siempre los representantes de
la lista de menor tama
no? Claramente, la secuencia anterior de operaciones se ejecutara
en orden (m). Aunque el anterior es un caso particular, se observa una mejora en general.
1 procedure Union ( x , y )
2
i f s i z e [ x ] > s i z e [ y ] then
3
swap ( x , y ) ;
4
end
5
6
p := x ;
7
8
do
9
r ep [ p ] := y ;
10
p := next [ p ] ;
11
while p 6= 0
12
next [ l a s t [ y ] ] := x ;
13
s i z e [ y ] := s i z e [ x ] + s i z e [ y ] ;
14 end
Teorema 5.1 Usando la representacion por listas y la tecnica de union por tama
no una
secuencia de m operaciones MakeSet, Union y Find, n de las cuales son operaciones
MakeSet, toma tiempo O(m + n log n).
Demostraci
on Se trata de encontrar para cada elemento x una cota superior del n
umero
de veces que se actualiza rep[x]. Cada vez que se actualiza rep[x] al realizar una operacion
Union(Sx , Sy ) el elemento x se debe encontrar en la lista de menor tama
no: |Sx | |Sy | y
la lista resultante tiene tama
no
|Sx | + |Sy | 2|Sx |
Es decir, cada vez que el conjunto al que pertence un elemento x participa en una union,
y se modifica rep[x], el elemento termina dentro de un conjunto que es al menos dos veces
mayor.
Luego de actualizar log k veces el representante de un elemento, el conjunto en el que
esta debe tener al menos k miembros. Como un conjunto no puede tener mas de n elementos, a lo sumo se actualiza el representante de un elemento log n veces. El n
umero de
7

actualizaciones en todas las operaciones Union es por lo tanto de orden O(q log n). Cada
operacion MakeSet y cada operacion Find toma tiempo O(1), por lo tanto la secuencia
completa toma tiempo O(n + q log n + f ). En el peor caso, cuando n = (m), q = (m)
y f = (m), el orden es O(m log m).

Representaci
on por Arboles

Se puede representar la coleccion S como una coleccion de arboles donde cada arbol representa un conjunto y cada nodo es un miembro del conjunto. El representante de un
conjunto es el nodo raz en el arbol y para cada nodo solo se mantiene un puntero a su
nodo padre en un arreglo llamado f ather (Fig. 4).
c

f
e

f
c

d
g

d
e

b
(a)

(b)

Figura 4: Un bosque de conjuntos disjuntos. (a) Dos arboles representando los conjuntos
de la Fig. 3. El arbol de la izquierda representa el conjunto {b, c, e, h}, con c como
el representante, y el arbol de la derecha representa el conjunto {d, f, g} con f como
representante. (b) El resultado luego de Union(c, f ).
Se incializan todas las posiciones del arreglo f ather en -1.
La operacion Makeset(x) crea un nuevo arbol que solo contiene al elemento x en
O(1).
La operacion Find(x) recorre el arbol donde esta x hasta la raz para buscar el
representante del conjunto. El orden temporal esta dado por la altura del arbol.
La operacion Union(x, y) asigna, por ejemplo, f ather[x] := y en O(1). (Fig. 3)
1 procedure MakeSet ( x )
2
f a t h e r [ x ] := 0 ;
3 end
1 function Find ( x )
2
i f f a t h e r [ x ] = 1 then
3
return 0 ;
8

4
5
6
7
8
9 end

end ;
while f a t h e r [ x ] =
6 0 do
x := f a t h e r [ x ] ;
end
return x ;

1 procedure Union ( x , y )
2
f a t h e r [ x ] := y ;
3 end
Hasta el momento, no se obtuvo ninguna mejora sobre la representacion por listas en el
orden de tiempo que lleva ejecutar una secuencia de m operaciones. Es posible crear una
secuencia de aproximadamente m/3 operaciones MakeSet seguidas de aproximadamente
m/3 operaciones Union de tal forma que se obtenga un u
nico conjunto representado
como un arbol lineal una cadena de nodos. Se puede encontrar luego una secuencia de
aproximadamente m/3 operaciones Find cada una de las cuales lleve tiempo (m/3). La
secuencia completa se ejecutara en tiempo (m2 ).

6.1

Heursticas

Utilizando dos simples heursticas en las operaciones Union y Find se puede mejorar el
orden de tiempo para ejecutar una secuencia de m operaciones.
6.1.1

Uni
on por Tama
no

La heurstica de union por tama


no no es mas que una extension de la heurstica de union
por tama
no para la representacion por listas. La idea consiste en modificar la operacion
Union para que agregue el arbol con menos nodos como subarbol del arbol con mas nodos.
6.1.2

Compresi
on de Caminos

Cada vez que se ejecuta una instruccion Find(x) se recorre el camino desde x hasta la raz
del arbol que lo contiene. Se puede mejorar el tiempo que llevaran futuras operaciones si
durante la operacion se convierte cada nodo en el camino de b
usqueda en un hijo de la
raz. (Fig. 5)

6.2

Implementaci
on

La cantidad de nodos en el subarbol de un nodo x se conserva en size[x]. Cuando se aplica


Union sobre dos arboles, el arbol de menor tama
no se convierte en un subarbol de la raz
del arbol con mayor tama
no. En caso de empate se realiza una eleccion arbitraria.

(a)

(b)

f
e

f
e

d
c
b
a

Figura 5: Efecto de la compresion de caminos sobre un arbol lineal. (a) Arbol


original.

(b) Arbol
luego de ejecutar Find(a) utilizando compresion de caminos.

1 procedure MakeSet ( x )
2
s i z e [ x ] := 0 ;
3 end
1 function Find ( x )
2
r := x ;
3
while f a t h e r [ r ] 6= 0 do
4
r := f a t h e r [ r ] ;
5
end
6
/ r e s ahora l a r a z d e l a r b o l /
7
8
p := x ;
9
while p 6= r do
10
t := f a t h e r [ p ] ;
11
f a t h e r [ p ] := r ;
12
p := t ;
13
end
14
return r ;
15 end
1 procedure Union ( x , y )
2
i f s i z e [ x ] > s i z e [ y ] then
3
f a t h e r [ y ] := x ;
4
s i z e [ x ] := s i z e [ x ] + s i z e [ y ] ;
10

5
else
6
f a t h e r [ x ] := y ;
7
s i z e [ y ] := s i z e [ y ] + s i z e [ x ] ;
8
end
9 end

6.3

Impacto de las Heursticas

Utilizando solamente la heurstica de union por tama


no, cada vez que un nodo se mueve a
un nuevo arbol suceden dos cosas:
La distancia del nodo a la raz del arbol donde se encuentra se incrementa en uno.
El nuevo arbol tiene al menos dos veces mas nodos que el anterior.
Si en total existen n elementos en el universo, ning
un nodo puede moverse mas de log n
veces y por lo tanto la distancia de cualquier nodo a la raz de su arbol no puede exceder
log n y cada operacion Find requiere tiempo O(log n).
El impacto de la compresion de caminos es mas difcil de analizar. Cuando se utilizan ambas
heursticas, el orden de complejidad temporal del peor caso es O(m (m, n)), donde (m, n)
es una funcion que se define como una especie de inversa de la funcion de Ackermann y
crece en forma extremadamente lenta. Para cualquier aplicacion practica concevible, resulta (m, n) 4 y por lo tanto el orden de complejidad de la ejecucion de una secuencia
de m operaciones es practicamente lineal.
En lugar de probar que el orden de complejidad temporal del peor caso al ejecutar una
secuencia de m operaciones es O(m (m, n)) se puede probar mas facilmente una cota
ligeramente menos ajustada, como se muestra a continuacion.

6.4

An
alisis de Complejidad

Definici
on F y G
Definimos las funciones F y G como sigue:

1
k=0
F (k) =
2F (k1) k 1
G(n) = min{k N | F (k) n}
La funcion F crece muy rapidamente y la funcion G muy lentamente:
n 265536 = G(n) 5
11

(1)
(2)

n
0
1
2

F (n)
20 = 1
0
22 = 2
20
22 = 4
0
22

22

3
4
5

0
22
22

= 16

= 65536

0
22
22

22

= 265536

Tabla 4: Primeros valores de F .


n
0 n
1 < n
2 < n
4 < n
16 < n
65536 < n

1
2
4
16
65536
265536

G(n)
0
1
2
3
4
5

Tabla 5: Primeros 265536 + 1 valores de G(n).


Definici
on
es la secuencia de operaciones obtenida al eliminar de todas las operaciones Find.
Definici
on F
F es el bosque resultante luego de ejecutar .
Definici
on Ti
Ti es el subarbol con raz en el nodo i dentro de F .
Definici
on Rango
El rango de un vertice i en F , r(i), es la altura de Ti .
Lema 6.1 Todo nodo i tiene al menos 2r(i) descendientes, o equivalentemente |Ti | 2r(i) .
Demostraci
on Por induccion sobre r(i)
Caso Base: r(i) = 0
|Ti | tiene al menos un vertice, i. Por lo tanto |Ti | 1 = 20 = 2r(i) .
Caso Inductivo:
(HI) i F | r(i) k |Ti | 2r(i)
12

Sea i un nodo con rango k. En alg


un momento tuvo rango menor que k y fue unido
con otro arbol con raz en un vertice j de rango k 1 y menos nodos:
|Ti | = |Ti | + |Tj| 2|Tj| 2 2k1 = 2k

Corolario 6.2 Ning


un vertice en F tiene rango mayor que log n .
Lema 6.3 Existen a lo sumo n/2r vertices de rango r en F
Demostraci
on Cada vertice de rango r tiene al menos 2r descendientes. Los nodos de
los subarboles de dos nodos en el bosque con el mismo rango son disjuntos. Hay n nodos
en total, puede a lo sumo haber n/2r nodos de rango r.
Lema 6.4 Si en alg
un momento durante la ejecucion de , w es un descendiente propio
de v, entonces el rango de w es estrictamente menor que el rango de v.
Demostraci
on Si en alg
un momento un vertice w es descendiente propio de otro vertice
v, lo sera hasta que se termine de ejecutar la secuencia (no hay operaciones Find en ) y
en el bosque resultante F su altura sera estrictamente menor.
Teorema 6.5 Una secuencia de m operaciones de las cuales n 2 son operaciones
MakeSet se ejecuta en tiempo O(m G(n)).
Demostraci
on Como antes, con q indicaremos el n
umero de operaciones Union y con f
el n
umero de operaciones Find.
Como cada operacion Union y cada operacion MakeSet se realiza en tiempo de orden
constante y q < n, todas las operaciones MakeSet y Union se realizan en orden O(n).
Para acotar el costo de todas las operaciones Find se utiliza una tecnica de contabilidad.
El costo de ejecutar una sola operacion Find se reparte entre la operacion misma y algunos
vertices en el camino de b
usqueda. El costo total se calcula sumando los costos sobre todas
las operaciones Find y sobre todos los vertices.
Se dividen los rangos de los vertices en F en grupos. Los vertices de rango r se colocan
en el grupo G(r). Los vertices con el mayor rango posible, log n . se colocan en el grupo
G(log n) G(n).
G(0) = {0, 1} G(1) = {2} G(2) = {3, 4} G(3) = {5, 6, . . . , 16} . . .
Para los vertices v en el camino de b
usqueda de una operacion Find(x) (sin contar el
propio x), la poltica para repartir el costo es la siguiente:
13

1. Si v es una raz, o f ather[v] esta en un grupo diferente de v, se le carga una unidad


de costo a la operacion.
2. Si v y su padre estan en el mismo grupo, se le carga una unidad a v
Por el Lema 6.4 los vertices en un camino de b
usqueda desde un nodo hasta la raz del
arbol crecen estrictamente en rango. Como a lo sumo hay G(n) grupos diferentes, ninguna
operacion Find puede tener costo mayor que G(n).
Cada vez que se aplica la segunda regla en un vertice v, se le asigna un nuevo padre que
debe tener un rango mayor por el Lema 6.4. Si v esta en el grupo g > 0, solamente puede
incrementarse su costo F (g) F (g 1) veces por la segunda regla antes de que adquiera
un padre en un grupo de rango mayor a su propio rango (el costo de un vertice en el grupo
0 solo puede incrementarse una vez). Cuando pasa a tener un padre en un grupo de rango
mayor, nunca mas se incrementa su costo porque la segunda regla ya no es aplicable.
Para obtener una cota superior de los costos de los vertices, se multiplica el maximo posible
costo de un vertice en un grupo por el n
umero de vertices en el grupo. Sea N(g) el n
umero
de vertices en el grupo g, por el Lema 6.3:
F (g)

N(g)

n/2r

(3)

r=F (g1)+1

=
=

(n/2F (g1)+1 ) (1 + 1/2 + 1/4 + )


(n/2F (g1)+1 ) 2
n/2F (g1)
n/F (g)

(4)
(5)
(6)
(7)

El maximo costo para un vertice en el grupo g es menor o igual que F (g) F (g 1), luego
el costo maximo de todos los vertices en el grupo g, C(g) resulta
C(g) = (F (g) F (g 1)) N(g)
n
(F (g) F (g 1))
F (g)
F (g 1)
= n
F (g)
n

(8)
(9)
(10)
(11)

Por lo tanto, como no puede haber mas de G(n) grupos, el maximo costo asignado a todos
los vertices es n G(n). Como el maximo costo asignado a una operacion Find es G(n),
el maximo costo asignado a todas las operaciones Find es f G(n). Por u
ltimo, todas las
14

operaciones Find se ejecutan en tiempo O((n + f ) G(n)).


Por todo lo visto, la secuencia se ejecuta en tiempo O((n + f ) G(n)) y como n + f m
en tiempo O(m G(n)).

Referencias
[AHU74] Alfred V. Aho, J. E. Hopcroft, and Jeffrey D. Ullman. The Design and Analysis
of Computer Algorithms. Addison-Wesley, 1974.
[CSRL01] Thomas H. Cormen, Clifford Stein, Ronald L. Rivest, and Charles E. Leiserson.
Introduction to Algorithms. McGraw-Hill Higher Education, 2001.
[Sed92]

Robert Sedgewick. Algorithms in C++. Addison-Wesley, 1992. ISBN: 0-20151059-6.

15

Das könnte Ihnen auch gefallen