• Nenhum resultado encontrado

Processamento de consultas contínuas contendo preferências condicionais

4.2 Algoritmos baseados em grafos

de remoção e de inserção. Deste modo, o custo para processar tal operador é de O(1). O operador TOPK, por sua vez, é processado pelo algoritmo IncAncestorsTopk cujo custo está relacionado com o número de iterações dos laços de repetição. O número de iterações do laço mais externo é igual ao nível de preferência máximo da teoria-pc, já o laço interno é executado uma vez para cada tupla de R. Desta maneira, a complexidade do algoritmo IncAncestorsTopk é O(nm).

4.2 Algoritmos baseados em grafos

Os algoritmos baseados em grafos mantêm um BTG com as tuplas da relação em memória que é atualizado a cada instante. Dada uma relação R e uma teoria-pc Γ, o BTG de R é representado pela estrutura Graph(Anc#, Succ#, Best). O conjunto Anc#(t) contém as tuplas que dominam t, o conjunto Succ#(t) representa as tuplas dominadas por t e Best é o conjunto das tuplas dominantes. Esta seção apresenta uma adaptação do algoritmo baseado em grafos proposto em Petit et al. (2012) para que seja considerada a ordem de preferência sobre o conjunto de todas as tuplas do esquema relacional. Esta adaptação se faz necessária para que todos os algoritmos analisados neste capítulo tenham a mesma semântica e possam ser comparados mais adequadamente.

Operação de remoção

O algoritmo GraphDelete (Algoritmo 12) é responsável pela tarefa de remoção. Para cada tupla removida t ∈ ∆, o algoritmo veriĄca se t é uma tupla dominante e a remove do conjunto de tuplas dominantes Best. Em seguida, o algoritmo remove as arestas relacionadas à tupla t. Lembrando que as arestas são representadas pelas entradas nas estruturas Anc# e Succ#.

Algoritmo 12 Ű GraphDelete(∆)

Entrada: Conjunto de tuplas removidas ∆−

Atualização: Arestas do grafo (Anc# e Succ#), conjunto de tuplas dominantes Best

1: for all t ∈ ∆do //Para cada tupla t removida

2: if t ∈ Best then //Checa se t é dominante 3: Best ← Best − ¶t♢ //Remove t do conjunto Best 4: for allt∈ Anc#(t) do //Para cada tupla tque domina t 5: Succ#(t) ← Succ#(t) − ¶t♢ //Remove t do conjunto de tuplas dominadas por t′ 6: for allt′′∈ Succ

#(t) do //Para cada tupla t′′ dominada por t 7: Anc#(t′′) ← Anc#(t′′) − ¶t♢ //Remove t do conjunto de tuplas que domina t′′ 8: Anc#.del(t) //Remove a entrada t de Anc#

Operação de inserção

O algoritmo GraphInsert (Algoritmo 13) realiza a tarefa de inserção. O algoritmo compara cada tupla t inserida com cada tupla tjá existente na relação R. Quando t domina t, o algoritmo acrescenta uma aresta de t para te remove tdo conjunto Best, caso tseja um tupla dominante. Por outro lado, se tdomina t, o algoritmo adiciona uma aresta de tpara t e marca t como dominada. Após as iterações do laço mais interno, a tupla t é inserida no conjunto Best, se a mesma não foi dominada.

A adaptação em relação ao trabalho original de Petit et al. (2012) aconteceu exatamente na tarefa de inserção. No trabalho original o teste de dominância considerava apenas as tuplas existentes na relação. Nesta adaptação o teste de dominância usa a estratégia de busca que considera a ordem de preferência imposta sobre Tup(R), assim como acontece na abordagem em listas de antecessores.

Algoritmo 13 Ű GraphInsert(Γ, ∆+)

Entrada: Teoria-pc Γ e conjunto de tuplas inseridas ∆+

Atualização: Arestas do grafo (Anc# e Succ#), conjunto de tuplas dominantes Best

1: for all t ∈ ∆+ do //Para cada tupla t inserida

2: dominated ← false //Pressupõe que t não será dominada

3: for allt∈ R do //Para cada tupla tjá existente

4: if t ≻Γtthen //Testa se t domina t

5: Succ#(t) ← Succ#(t) ∪ ¶t′♢ //Insere tentre as tuplas dominadas por t 6: Anc#(t) ← Anc#(t) ∪ ¶t♢ //Insere t entra as tuplas que dominam t′ 7: if t∈ Best then //VeriĄca se tera dominante

8: Best ← Best − ¶t //Remove tdo conjunto de tuplas dominantes

9: else if t′ ≻Γt then //Testa se tdomina t

10: dominated ← true //Marca t como dominada 11: Succ#(t) ← Succ#(t) ∪ ¶t♢ //Insere t entre as tuplas dominadas por t′ 12: Anc#(t) ← Anc#(t) ∪ ¶t′♢ //Insere tentra as tuplas que dominam t

13: if notdominated then //VeriĄca se t não foi dominada

14: Best ← Best ∪ ¶t♢ //Adiciona t entra as tuplas dominantes

Obtenção das top-k tuplas

O algoritmo IncGraphTopk (Algoritmo 14) realiza o processamento do operador

TOPK por meio de uma ordenação topológica no grafo (KAHN, 1962). O algoritmo cria

cópias das estruturas Best e Anc# para Beste Anc′#, respectivamente. Esta cópia tem o objetivo de preservar as estruturas Best e Anc# que são alteradas durante a ordenação topológica. A lista L é utilizada para ordenar as tuplas, de forma que uma tupla t é adicionada à L somente se todas as tuplas que dominam t já estiverem em L.

Inicialmente, o conjunto Bestcontém as tuplas com nível de preferência igual a zero, ou seja, as tuplas dominantes. A cada iteração, as tuplas do conjunto Bestcom nível

4.2. Algoritmos baseados em grafos 85

Algoritmo 14 Ű IncGraphTopk(R, k)

Entrada: Relação R e número de top-k tuplas desejadas k Saída: Top-k tuplas da relação R

1: Best← Best //Copia Best para Best

2: Anc

#← Anc# //Copia Anc#para Anc′#

3: L ← NewList() //Cria lista L para ordenar tuplas 4: while (♣L♣ < k) and (♣L♣ < ♣R♣) do //Enquanto ♣L♣ < k e ♣L♣ < ♣R♣ 5: N ← ¶♢ //Tuplas a serem processadas na próxima iteração 6: for allt ∈ Bestdo //Para cada tupla t dominante (na iteração atual) 7: L.append(t) //Adiciona t à lista L 8: for all t∈ Succ#(t) do //Para cada tupla tdominada por t

9: Anc

#(t) ← Anc′#(t) − ¶t♢ //Remove a aresta de t para t′ 10: if ♣Anc#(t)♣ = 0 then //VeriĄca se t′ deixou de ser dominada 11: N ← N ∪ ¶t′♢ //Insere tem N

12: Best← N //Move tuplas de N para Best

13: return L.getFirst(k) //Retorna as k primeiras tuplas de L

de todas as iterações, a lista L possuirá as tuplas de R ordenadas pelo nível de preferência. Ao Ąnal, o algoritmo retorna as k primeiras tuplas de L. O Exemplo 13 apresenta uma possível execução dos algoritmos baseados em grafo.

Exemplo 13 (Execução do algoritmo IncGraphTopk). Considere novamente a relação

acoes e a teoria-pc Γ do Exemplo 12. No instante i, o BTG da relação é representado pelas seguintes estruturas:

• Anc#(t1) = Anc#(t6) = ¶♢; • Anc#(t2) = ¶t1♢; • Anc#(t3) = Anc#(t4) = ¶t1, t2♢; • Anc#(t5) = ¶t1, t2, t3♢; • Succ#(t1) = ¶t2, t3, t4, t5♢; • Succ#(t2) = ¶t3, t4, t5♢; • Succ#(t3) = ¶t5♢

• Succ#(t4) = Succ#(t5) = Succ#(t6) = ¶♢; • Best = ¶t1, t6♢.

Considere novamente a remoção das tuplas t3 e t6 no instante i + 1. A execução do algoritmo GraphDelete ocorre da seguinte maneira:

1) Remoção da tupla t6:

a) A tupla t6 é removida do conjunto Best;

b) Nenhuma aresta é alterada pelo fato de t6 ser incomparável às demais tuplas; c) A tupla t6 é removida das estruturas Anc# e Succ#.

a) Como as tuplas t1 e t2 dominam t3 (Anc#(t3) = ¶t1, t2♢), o algoritmo remove t3 de

Succ#(t1) e de Succ#(t2). Portanto, Succ#(t1) = ¶t2, t3, t4, t5♢ − ¶t3♢= ¶t2, t4, t5♢ e

Succ#(t2) = ¶t3, t5♢ − ¶t3♢= ¶t5♢;

b) Como t3 domina t5 (Succ#(t3) = ¶t5♢), o algoritmo remove t3 de Anc#(t5). Portanto,

Anc#(t5) = ¶t1, t2, t3♢ − ¶t3♢= ¶t1, t2♢;

c) A tupla t3 é removida das estruturas Anc# e Succ#.

Já a execução do algoritmo GraphInsert acontece do seguinte modo: 1) Inserção da tupla t7:

a) A tupla t7 domina a tupla t5, então Anc#(t5) = ¶t1, t2♢ ∪ ¶t7♢ = ¶t1, t2, t7♢ e

Succ#(t7) = ¶t5♢;

b) Como t7 não é dominada, a mesma é adicionada ao conjunto Best. 2) Inserção da tupla t8:

a) A tupla t8 é dominada pela tupla t1, então Anc#(t8) = ¶t1♢ e Succ#(t1) = ¶t2, t4, t5♢ ∪ ¶t8♢= ¶t2, t4, t5, t8♢;

b) A tupla t8 domina a tupla t4, então Anc#(t4) = ¶t1, t2♢ ∪ ¶t8♢ = ¶t1, t2, t8♢ e

Succ#(t8) = ¶t4♢;

c) A tupla t8 domina a tupla t5, então Anc#(t5) = ¶t1, t2, t7♢ ∪ ¶t8♢= ¶t1, t2, t7, t8♢ e

Succ#(t8) = ¶t4♢ ∪ ¶t5♢= ¶t4, t5♢;

d) A tupla t8 não é adicionada ao conjunto Best pelo fato de ter sido dominada. Por Ąm, a execução do algoritmo IncGraphTopk é realizada da seguinte maneira: 1) O algoritmo cria as cópias Anc

#e Bestpara as estruturas Anc#e Best, respectivamente. O algoritmo também cria a lista L;

2) Como L está vazia, o laço inicia as iterações;

3) Na primeira iteração, as tuplas de Bestsão inseridas em L. Além disto, as tuplas t 2 e

t8 passam a compor o conjunto Best′ na próxima iteração;

4) Na segunda iteração as tuplas t2 e t8 são adicionadas à lista L e o conjunto Best′ para a próxima iteração contém as tuplas t4 e t5;

5) Como L possui mais de três tuplas o laço é interrompido e o algoritmo retorna as três primeiras tuplas da lista L = [t1, t7, t2, t8].

Análise de complexidade

A complexidade do algoritmo GraphDelete é de O(nδ+ n × ♣Anc

#(t)♣ + n × ♣Succ#(t)♣) onde n = ♣R♣ e δ− = ♣∆−♣. Assumindo também um fator de limitação para as estruturas ♣Anc#(t)♣ e ♣Succ#(t)♣, assim como foi feito para a lista de antecessores, a complexidade do algoritmo GraphDelete é de O(nδ). Já a complexidade do algoritmo