Análise do Union-Find
Coleção de conjuntos disjuntos
Queremos uma ED boa para representar uma partição de um conjunto
e as seguintes operações sobre a partição:
MakeSet(x): cria um conjunto unitário com o elementox.
FindSet(x): devolve o identificador do bloco da partição
que contémx.
Union(x,y): substitui os blocos da partição que contêm
xeypela união deles. Idéia:
Usar um elemento do conjunto (orepresentante) como identificador.
Coleção de conjuntos disjuntos
Queremos uma ED boa para representar uma partição de um conjunto
e as seguintes operações sobre a partição:
MakeSet(x): cria um conjunto unitário com o elementox.
FindSet(x): devolve o identificador do bloco da partição
que contémx.
Union(x,y): substitui os blocos da partição que contêm
xeypela união deles.
Idéia:
Usar um elemento do conjunto (orepresentante) como identificador.
Coleção de conjuntos disjuntos
Queremos uma ED boa para representar uma partição de um conjunto
e as seguintes operações sobre a partição:
MakeSet(x): cria um conjunto unitário com o elementox.
FindSet(x): devolve o identificador do bloco da partição
que contémx.
Union(x,y): substitui os blocos da partição que contêm
xeypela união deles. Idéia:
Como analizar?
Uso típico:
n− 1 Union, m FindSet, mn
em sequência arbitrária.
O custo de uma operação pode variar muito - é muito pessimista supor o pior caso em cada uma.
Vale a pena considerar uma sequência completa de operações, em vez de analizar uma a uma.
Isso se chamaAnálise Amortizada.
É um método especialmente útil para analizar estruturas adaptativas, em que uma operação pode preparar caminho para a execução de operações futuras.
Como analizar?
Uso típico:
n− 1 Union, m FindSet, mn
em sequência arbitrária.
O custo de uma operação pode variar muito - é muito pessimista supor o pior caso em cada uma.
Vale a pena considerar uma sequência completa de operações, em vez de analizar uma a uma.
Isso se chamaAnálise Amortizada.
É um método especialmente útil para analizar estruturas adaptativas, em que uma operação pode preparar caminho para a execução de operações futuras.
Como analizar?
Uso típico:
n− 1 Union, m FindSet, mn
em sequência arbitrária.
O custo de uma operação pode variar muito - é muito pessimista supor o pior caso em cada uma.
Vale a pena considerar uma sequência completa de operações, em vez de analizar uma a uma.
Isso se chamaAnálise Amortizada.
É um método especialmente útil para analizar estruturas adaptativas, em que uma operação pode preparar caminho para a execução de operações futuras.
Como analizar?
Uso típico:
n− 1 Union, m FindSet, mn
em sequência arbitrária.
O custo de uma operação pode variar muito - é muito pessimista supor o pior caso em cada uma.
Vale a pena considerar uma sequência completa de operações, em vez de analizar uma a uma.
Isso se chamaAnálise Amortizada.
É um método especialmente útil para analizar estruturas adaptativas, em que uma operação pode preparar caminho para a execução de operações futuras.
Como analizar?
Uso típico:
n− 1 Union, m FindSet, mn
em sequência arbitrária.
O custo de uma operação pode variar muito - é muito pessimista supor o pior caso em cada uma.
Vale a pena considerar uma sequência completa de operações, em vez de analizar uma a uma.
Isso se chamaAnálise Amortizada.
É um método especialmente útil para analizar estruturas adaptativas, em que uma operação pode preparar caminho para a execução de operações futuras.
Não é tão novidade assim
Numa busca em grafos:
1 para cadau∈G.V
2 para cadav∈u.Estrelafaça
Análise ingênua:
Como cada estrela tem tamanhoO(n), os dois laços combinados levamO(n2).
Análise amortizada:
Como na linha 2 cada arco é examinado uma única vez, os dois laços combinados levamO(m).
Não é tão novidade assim
Numa busca em grafos: 1 para cadau∈G.V
2 para cadav∈u.Estrelafaça
Análise ingênua:
Como cada estrela tem tamanhoO(n), os dois laços combinados levamO(n2).
Análise amortizada:
Como na linha 2 cada arco é examinado uma única vez, os dois laços combinados levamO(m).
Não é tão novidade assim
Numa busca em grafos: 1 para cadau∈G.V
2 para cadav∈u.Estrelafaça
Análise ingênua:
Como cada estrela tem tamanhoO(n), os dois laços combinados levamO(n2).
Análise amortizada:
Como na linha 2 cada arco é examinado uma única vez, os dois laços combinados levamO(m).
Não é tão novidade assim
Numa busca em grafos: 1 para cadau∈G.V
2 para cadav∈u.Estrelafaça
Análise ingênua:
Como cada estrela tem tamanhoO(n), os dois laços combinados levamO(n2).
Análise amortizada:
Como na linha 2 cada arco é examinado uma única vez, os dois laços combinados levamO(m).
Não é tão novidade assim
Numa busca em grafos: 1 para cadau∈G.V
2 para cadav∈u.Estrelafaça
Análise ingênua:
Como cada estrela tem tamanhoO(n), os dois laços combinados levamO(n2).
Análise amortizada:
Como na linha 2 cada arco é examinado uma única vez, os dois laços combinados levamO(m).
Não é tão novidade assim
Numa busca em grafos: 1 para cadau∈G.V
2 para cadav∈u.Estrelafaça
Análise ingênua:
Como cada estrela tem tamanhoO(n), os dois laços combinados levamO(n2).
Análise amortizada:
Como na linha 2 cada arco é examinado uma única vez, os dois laços combinados levamO(m).
Implementação 1 do union-find
I Cada conjunto é uma lista ligada, com cabeçalho apontando início e fim - facilitaUnion.
I Cada elemento da lista tem um apontadornomepara o cabeçalho - facilitaFindSet.
MakeSet(x) cria uma lista contendo sóx.
FindSetrespondido direto pelonome.
Union: juntar as duas listas é fácil, mas é preciso atualizar
onomedos membros de um dos conjuntos.
MakeSeteFindSetlevamO(1), mas váriosUnion
Implementação 1 do union-find
I Cada conjunto é uma lista ligada, com cabeçalho apontando início e fim - facilitaUnion.
I Cada elemento da lista tem um apontadornomepara o cabeçalho - facilitaFindSet.
MakeSet(x) cria uma lista contendo sóx.
FindSetrespondido direto pelonome.
Union: juntar as duas listas é fácil, mas é preciso atualizar
onomedos membros de um dos conjuntos.
MakeSeteFindSetlevamO(1), mas váriosUnion
Implementação 1 do union-find
I Cada conjunto é uma lista ligada, com cabeçalho apontando início e fim - facilitaUnion.
I Cada elemento da lista tem um apontadornomepara o cabeçalho - facilitaFindSet.
MakeSet(x) cria uma lista contendo sóx.
FindSetrespondido direto pelonome.
Union: juntar as duas listas é fácil, mas é preciso atualizar
onomedos membros de um dos conjuntos.
MakeSeteFindSetlevamO(1), mas váriosUnion
Implementação 1 do union-find
I Cada conjunto é uma lista ligada, com cabeçalho apontando início e fim - facilitaUnion.
I Cada elemento da lista tem um apontadornomepara o cabeçalho - facilitaFindSet.
MakeSet(x) cria uma lista contendo sóx.
FindSetrespondido direto pelonome.
Union: juntar as duas listas é fácil, mas é preciso atualizar
onomedos membros de um dos conjuntos.
MakeSeteFindSetlevamO(1), mas váriosUnion
Implementação 1 do union-find
I Cada conjunto é uma lista ligada, com cabeçalho apontando início e fim - facilitaUnion.
I Cada elemento da lista tem um apontadornomepara o cabeçalho - facilitaFindSet.
MakeSet(x) cria uma lista contendo sóx.
FindSetrespondido direto pelonome.
Union: juntar as duas listas é fácil, mas é preciso atualizar
onomedos membros de um dos conjuntos.
MakeSeteFindSetlevamO(1), mas váriosUnion
Implementação 1 do union-find
I Cada conjunto é uma lista ligada, com cabeçalho apontando início e fim - facilitaUnion.
I Cada elemento da lista tem um apontadornomepara o cabeçalho - facilitaFindSet.
MakeSet(x) cria uma lista contendo sóx.
FindSetrespondido direto pelonome.
Union: juntar as duas listas é fácil, mas é preciso atualizar
onomedos membros de um dos conjuntos.
MakeSeteFindSetlevamO(1), mas váriosUnion
Melhoria
NaUnion, pendure a lista menor na maior (cabeçalho
precisa guardar o tamanho da lista).
Agora, cada vez que um elemento muda denome,
o conjunto em que ele está pelo menos dobra de tamanho. Assim, seunomemuda no máximo lgnvezes
.
Tempo total den Union:O(nlgn)
.
Melhoria
NaUnion, pendure a lista menor na maior (cabeçalho
precisa guardar o tamanho da lista).
Agora, cada vez que um elemento muda denome,
o conjunto em que ele está pelo menos dobra de tamanho. Assim, seunomemuda no máximo
lgn vezes
.
Tempo total den Union:O(nlgn)
.
Melhoria
NaUnion, pendure a lista menor na maior (cabeçalho
precisa guardar o tamanho da lista).
Agora, cada vez que um elemento muda denome,
o conjunto em que ele está pelo menos dobra de tamanho. Assim, seunomemuda no máximo lgn vezes.
Tempo total den Union:O(nlgn)
.
Melhoria
NaUnion, pendure a lista menor na maior (cabeçalho
precisa guardar o tamanho da lista).
Agora, cada vez que um elemento muda denome,
o conjunto em que ele está pelo menos dobra de tamanho. Assim, seunomemuda no máximo lgn vezes.
Tempo total den Union:O(nlgn).
Melhoria
NaUnion, pendure a lista menor na maior (cabeçalho
precisa guardar o tamanho da lista).
Agora, cada vez que um elemento muda denome,
o conjunto em que ele está pelo menos dobra de tamanho. Assim, seunomemuda no máximo lgn vezes.
Tempo total den Union:O(nlgn). Tempo total:O(m+nlgn)
Implementação 2 do union-find
Cada conjunto é uma árvore apontando para a raíz.
MakeSet(x)
1 x.pai←x
FindSet(x)
1 sex=x.pai 2 devolvax
3 devolvaFindSet(x.pai)
FindSet(x)
1 enquantox.pai,xfaça 2 x←x.pai
3 devolvax
Union(x,y) xeyrepresentantes distintos
1 y.pai←x
Consumo de tempo:doFindSetpode ser muito ruim...Ê(n).
Implementação 2 do union-find
Cada conjunto é uma árvore apontando para a raíz.
MakeSet(x)
1 x.pai←x
FindSet(x)
1 sex=x.pai 2 devolvax
3 devolvaFindSet(x.pai)
FindSet(x)
1 enquantox.pai,xfaça 2 x←x.pai
3 devolvax
Union(x,y) xeyrepresentantes distintos
1 y.pai←x
Consumo de tempo:doFindSetpode ser muito ruim...Ê(n).
Implementação 2 do union-find
Cada conjunto é uma árvore apontando para a raíz.
MakeSet(x)
1 x.pai←x
FindSet(x)
1 sex=x.pai 2 devolvax
3 devolvaFindSet(x.pai)
FindSet(x)
1 enquantox.pai,xfaça 2 x←x.pai
3 devolvax
Union(x,y) xeyrepresentantes distintos
1 y.pai←x
Consumo de tempo:doFindSetpode ser muito ruim...Ê(n).
Implementação 2 do union-find
Cada conjunto é uma árvore apontando para a raíz.
MakeSet(x)
1 x.pai←x
FindSet(x)
1 sex=x.pai 2 devolvax
3 devolvaFindSet(x.pai)
FindSet(x)
1 enquantox.pai,xfaça 2 x←x.pai
3 devolvax
Union(x,y) xeyrepresentantes distintos
1 y.pai←x
Implementação 2 do union-find
Cada conjunto é uma árvore apontando para a raíz.
MakeSet(x)
1 x.pai←x
FindSet(x)
1 sex=x.pai 2 devolvax
3 devolvaFindSet(x.pai)
FindSet(x)
1 enquantox.pai,xfaça 2 x←x.pai
3 devolvax
Union(x,y) xeyrepresentantes distintos
1 y.pai←x
Melhoria 1
Heurística das alturas
MakeSet(x)
1 x.pai←x 2 x.rank← 0
FindSet(x): o mesmo de antes
Union(x,y) xeyrepresentantes distintos
1 sex.rank≥y.rank 2 então y.pai←x
3 entãosex.rank=y.rank
4 entãoentãox.rank←x.rank+ 1 5 senãox.pai←y
Invariante:x.rank≥ altura da árvore pendurada emx. Melhorou:FindSetéÊ(lgn). Total:O(n+mlgn)
Melhoria 1
Heurística das alturas
MakeSet(x)
1 x.pai←x 2 x.rank← 0
FindSet(x): o mesmo de antes
Union(x,y) xeyrepresentantes distintos
1 sex.rank≥y.rank 2 então y.pai←x
3 entãosex.rank=y.rank
4 entãoentãox.rank←x.rank+ 1 5 senãox.pai←y
Invariante:x.rank≥ altura da árvore pendurada emx. Melhorou:FindSetéÊ(lgn). Total:O(n+mlgn)
Melhoria 1
Heurística das alturas
MakeSet(x)
1 x.pai←x 2 x.rank← 0
FindSet(x): o mesmo de antes
Union(x,y) xeyrepresentantes distintos
1 sex.rank≥y.rank 2 então y.pai←x
3 entãosex.rank=y.rank
4 entãoentãox.rank←x.rank+ 1 5 senãox.pai←y
Invariante:x.rank≥ altura da árvore pendurada emx. Melhorou:FindSetéÊ(lgn). Total:O(n+mlgn)
Melhoria 1
Heurística das alturas
MakeSet(x)
1 x.pai←x 2 x.rank← 0
FindSet(x): o mesmo de antes
Union(x,y) xeyrepresentantes distintos
1 sex.rank≥y.rank 2 então y.pai←x
3 entãosex.rank=y.rank
4 entãoentãox.rank←x.rank+ 1 5 senãox.pai←y
Invariante:x.rank≥ altura da árvore pendurada emx.
Melhorou:FindSetéÊ(lgn). Total:O(n+mlgn)
Melhoria 1
Heurística das alturas
MakeSet(x)
1 x.pai←x 2 x.rank← 0
FindSet(x): o mesmo de antes
Union(x,y) xeyrepresentantes distintos
1 sex.rank≥y.rank 2 então y.pai←x
3 entãosex.rank=y.rank
4 entãoentãox.rank←x.rank+ 1 5 senãox.pai←y
Melhoria 1
Heurística das alturas
MakeSet(x)
1 x.pai←x 2 x.rank← 0
FindSet(x): o mesmo de antes
Union(x,y) xeyrepresentantes distintos
1 sex.rank≥y.rank 2 então y.pai←x
3 entãosex.rank=y.rank
4 entãoentãox.rank←x.rank+ 1 5 senãox.pai←y
Invariante:x.rank≥ altura da árvore pendurada emx. Melhorou: éÊ(lgn). Total:O(n+mlgn)
Implementação 3
Heurística da compressão dos caminhos
FindSet(x)
1 ifx.pai,x
2 entãox.pai←FindSet(x.pai) 3 devolvax.pai
Consumo amortizado de tempo de cada operação: O(lg∗n),
onde lg∗n é o número de vezes que temos que aplicar o lg até atingir um número menor ou igual a 1.
Na verdade, é melhor do que isso.
Implementação 3
Heurística da compressão dos caminhos
FindSet(x)
1 ifx.pai,x
2 entãox.pai←FindSet(x.pai) 3 devolvax.pai
Consumo amortizado de tempo de cada operação: O(lg∗n),
onde lg∗n é o número de vezes que temos que aplicar o lg até atingir um número menor ou igual a 1.
Na verdade, é melhor do que isso.
Implementação 3
Heurística da compressão dos caminhos
FindSet(x)
1 ifx.pai,x
2 entãox.pai←FindSet(x.pai) 3 devolvax.pai
Consumo amortizado de tempo de cada operação: O(lg∗n),
O que isso significa
Duas maneiras de entender o lg∗:
lg(0)(n) =n lg(k)(n) = lg(lg(k −1)(n)), k > 0 lg∗(n) = min{k | lg(k)(n) ≤ 1} b0= 1 bk = 2bk −1, k> 0 lg∗(n) = min{k |n< bk}.
O que isso significa
Duas maneiras de entender o lg∗:
lg(0)(n) =n lg(k)(n) = lg(lg(k −1)(n)), k > 0 lg∗(n) = min{k | lg(k)(n) ≤ 1} b0= 1 bk = 2bk −1, k> 0 ∗