• Nenhum resultado encontrado

Fundamentação teórica

3.3 Novos algoritmos desenvolvidos

Exemplo 9 (Base de conhecimento). Considere novamente a teoria-pc Γ e suas fórmulas

essenciais mostradas no Exemplo 8. A base de conhecimento KΓ sobre esta teoria-pc é composta pelas seguintes comparações essenciais:

b1: (liga = espanhola) ∧ (funcao = atacante) ≻ (liga = brasileira) ∧ (funcao =

defensor)[funcao, liga, nome]

b2: (liga = espanhola) ∧ (funcao = armador) ≻ (liga = brasileira) ∧ (funcao =

defensor)[funcao, liga, nome]

b3: (liga = espanhola) ∧ (funcao = armador) ≻ (liga = brasileira) ∧ (funcao =

atacante)[funcao, liga, nome]

b4: (funcao = atacante) ≻ (funcao = defensor)[funcao, nome]

b5: (funcao = armador) ≻ (funcao = defensor)[funcao, nome]

b6: (funcao = armador) ≻ (funcao = atacante)[funcao, nome]

b7: (liga = espanhola) ∧ (funcao = atacante) ≻ (liga = brasileira) ∧ (funcao =

atacante)[liga, nome]

O Teorema 4 garante que qualquer comparação feita usando o conjunto completo de comparações K

Γ também pode ser feita utilizando a base de conhecimento KΓ contendo apenas as comparações essenciais. Portanto, uma vez construída a base de conhecimento KΓ, o teste de dominância entre duas tuplas pode ser feito percorrendo as comparações de

KΓ.

Teorema 4. Seja Γ uma teoria-pc sobre um esquema relacional R. Se t ≻K∗ Γ t

então

t ≻KΓ t

para todo par de tupla t, tTup(R) (RIBEIRO; PEREIRA; DIAS, 2016).

3.3 Novos algoritmos desenvolvidos

A primeira otimização foi o desenvolvimento de novas versões dos algoritmos BNL** e R-BNL**, chamadas de BNL-KB e R-BNL-KB, respectivamente. Estas otimizações realizam o teste de dominância usando a base de conhecimento, evitando assim as chamadas recursivas do teste de dominância baseado em busca.

Além da modiĄcação nos algoritmos BNL** e R-BNL**, foram desenvolvidos novos algoritmos que utilizam a base de conhecimento em conjunto com uma técnica de particionamento. No caso dos algoritmos baseados na técnica BNL, cada tupla da relação precisa ser comparada com todas as demais. A técnica de particionamento agrupa as tuplas em partições de acordo com os atributos ceteris paribus das comparações (aqueles não presentes no conjunto de atributos indiferentes). Desta maneira, os atributos ceteris paribus das tuplas de uma partição possuem os mesmos valores e as tuplas desta partição podem ser comparadas diretamente por meio das fórmulas da comparação.

O algoritmo PartitionBest (Algoritmo 3) utiliza a técnica de particionamento para processar o operador BEST. A função Partition (Algoritmo 4) é usada de forma

incremental para obter as tuplas dominantes. Para cada comparação b ∈ KΓ é feita uma chamada a esta função que elimina as tuplas dominadas de acordo com b. Ao Ąnal, o conjunto D+ conterá apenas as tuplas dominantes de R.

Algoritmo 3 Ű PartitionBest(Γ, R) Entrada: Relação R, teoria-pc Γ

Saída: Conjunto de tuplas dominantes em R de acordo com Γ

1: D+ ← R //Copia tuplas de R para D+

2: for all b ∈ KΓ do //Para cada comparação b de KΓ

3: D+, D← Partition(D+, b) //Particiona D+ usando a comparação b

4: return D+ //Retorna as tuplas dominantes

A função Partition recebe uma relação de tuplas T e separa estas tuplas em dominantes (D+) e dominadas (D). O primeiro passo da função é construir a tabela

hash de partições P# por meio da função CreatePartitions (Algoritmo 5). Em seguida, as tuplas de cada partição P ∈ P# são separadas em três grupos: aquelas que possuem os valores preferidos (P+), aquelas que possuem os valores não preferidos (P) e as tuplas incomparáveis (P). As tuplas de Psão dominantes em P porque elas não podem ser comparadas usando b. Como as tuplas de uma mesma partição possuem os mesmos valores para os atributos ceteris paribus, as tuplas de P+ dominam as tuplas de P. Se P+ for vazio, signiĄca que todas as tuplas de P são dominantes de acordo com b. Caso contrário, as tuplas de P+ e Psão armazenadas no conjunto de tuplas dominantes (D+) e as tuplas de Psão armazenadas no conjunto de tuplas dominadas (D).

Algoritmo 4 Ű Partition(T, b)

Entrada: Conjunto de tuplas T , comparação b

Saída: Conjunto de tuplas dominantes (D+) e conjunto de tuplas dominadas (D) em T de

acordo com b

1: P#← CreatePartitions(T, b) //Cria as partições em P#

2: D+ ← ¶♢ //Conjunto de tuplas dominantes (D+)

3: D− ← ¶♢ //Conjunto de tuplas dominadas (D)

4: for all p ∈ P# do //Para cada partição p de P#

5: P ← P#(p) //Obtém as tuplas da partição p 6: P+← ¶t ∈ P ♣ t ♣= Fb+♢ //Tuplas com valores preferidos 7: P← ¶t ∈ P ♣ t ♣= F

b ♢ //Tuplas com valores não preferidos

8: P← P − P+− P− //Tuplas incomparáveis 9: if P+= ¶♢ then //Checa se não existem tuplas em P+

10: D+ ← D+∪ P //Neste caso, todas são dominantes

11: else //Senão, as tuplas de P+ dominam as tuplas de P

12: D+ ← D+∪ P+∪ P∗ //Tuplas dominantes

13: D← D∪ P//Tuplas dominadas

14: return D+, D

A função CreatePartitions toma cada tupla t ∈ T e a insere na partição adequada dentro da tabela hash P#. Primeiro a função obtém o identiĄcador de partição p usando

3.3. Novos algoritmos desenvolvidos 69 os atributos de t não presentes em Wb. Em seguida, a função veriĄca se a partição p já existe. Em caso aĄrmativo, t é adicionada à partição existente e, em caso negativo, a função cria uma nova partição contendo t. O Exemplo 10 apresenta uma execução do algoritmo PartitionBest.

Algoritmo 5 Ű CreatePartitions(T, b) Entrada: Conjunto de tuplas T , comparação b

Saída: Tabela hash com partições de T de acordo com b

1: P#← NewHashTable(T, b) //Cria tabela hash

2: for all t ∈ T do //Para cada tupla t ∈ T

3: p ← t/Wb //Obtém identiĄcador da partição p 4: if p ∈ P# then //VeriĄca se a partição p já existe 5: P#(p) ← P#(p) ∪ ¶t♢ //Adiciona t à partição existente 6: else

7: P#(p) ← ¶t♢ //Cria uma nova partição contendo t 8: return P#

Exemplo 10 (Execução do algoritmo PartitionBest). Considere novamente a relação

jogadores da Figura 10(a). Considere também a teoria-pc Γ apresentada no Exemplo 8. A Figura 10(b) mostra as partições criadas durante a execução do algoritmo PartitionBest tendo como parâmetros a relação jogadores e a teoria-pc Γ.

nome funcao liga t1 Messi atacante espanhola t2 Ribeiro armador espanhola t3 Oscar armador brasileira t4 Willian atacante brasileira t5 Silva defensor espanhola

(a) Relação jogadores

Partições b1 P(): ¶ t1 P+, tP2∗ , t3 P, t4 P, t5 P∗ ♢ b2 P(): ¶t1 P, t2 P+, tP3∗ , t4 P, t5 P∗ ♢ b3 P(): ¶t1 P, t2 P+, tP3∗ , t4 P, t5 P∗ ♢ b4 P(liga=brasileira): ¶t3 P∗ ♢ P(liga=espanhola): ¶ t1 P+ , t2 P, t5 P− ♢ b5 P(liga=brasileira): ¶ t3 P+ ♢ P(liga=espanhola): ¶t1 P, t2 P+ ♢ b6 P(liga=brasileira): ¶ t3 P+ ♢ P(liga=espanhola): ¶ t1 P, t2 P+ ♢ b7 P(funcao=armador): ¶t2 P, t3 P∗ ♢

(b) Partições criadas pelo algoritmo PartitionBest

Figura 10 Ű Relação jogadores e partições criadas pelo algoritmo PartitionBest Para cada comparação b da base de conhecimento KΓ, é feita uma chamada à função

Partition. No caso das três primeiras comparações, a função cria uma única partição contendo todas as tuplas. Isto ocorre porque não existem atributos ceteris paribus nas comparações b1, b2 e b3 (Wb1 = Wb2 = Wb3 = ¶nome, funcao, liga♢). Nos dois primeiros particionamentos, nenhuma tupla possui os valores não preferidos e todas permanecem

como dominantes. Na partição criada para a comparação b3, a tupla t2 possui os valores preferidos e a tupla t4 (em negrito) possui os valores não preferidos, portando t2 domina

t4. Como t4 foi dominada, ela não aparece no próximo particionamento.

No caso das comparações b4, b5 e b6, são criadas as partições P(liga=brasileira) e

P(liga=espanhola) de acordo com os valores do atributo liga. Na partição P(liga=espanhola) criada para comparação b4, a tupla t5 (em negrito) é dominada e descartada. O mesmo acontece com a tupla t1 na partição P(liga=espanhola) criada para a comparação b6. O último particionamento é feito para a comparação b7, mas nenhuma tupla é dominada. Assim, o resultado Ąnal do algoritmo contém as tuplas t2 e t3.

O algoritmo PartitionTopk (Algoritmo 6) realiza o processamento do operador

TOPK por meio da técnica de particionamento. A lista L, usada pelo algoritmo, permite

que as tuplas já processadas sejam ordenadas pelo nível de preferência. O algoritmo inicializa L como uma lista vazia e, na primeira iteração do laço mais externo, adiciona as tuplas com nível 0 à lista.

Algoritmo 6 Ű PartitionTopk(Γ, R, k)

Entrada: Relação R, teoria-pc Γ, número de top-k tuplas k Saída: Top-k tuplas de R de acordo com Γ

1: D+ ← R //Copia relação R para D+

2: L ← NewList() //Cria lista L 3: while (♣L♣ < k) and (D+̸= ¶♢) do //Enquanto houverem tuplas a serem processadas 4: T ← ¶♢ //Conjunto para armazenar tuplas dominadas

5: for allb ∈ KΓ do //Para cada comparação b de KΓ

6: D+, D← Partition(D+, b)//Separa as tuplas de D+ em dominantes (D+) e dominadas

(D)

7: T ← T ∪ D//Adiciona as tuplas dominadas em T 8: L ← L.append(D+) //Acrescenta as tuplas dominantes no Ąnal da lista L

9: D+← T //As tuplas dominadas (T ) serão separadas no próximo nível

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

O laço mais interno do algoritmo PartitionTopk tem a função de percorrer todas as comparações de KΓ e mover as tuplas dominadas de D+ para T . A cada nova iteração do laço mais externo, as tuplas dominantes são acrescentadas ao Ąnal da lista L e as tuplas dominadas são processadas novamente para obtenção das tuplas do próximo nível. As iterações do laço mais externo cessam quando a lista L possui pelo menos k tuplas ou quando todas as tuplas já foram processadas. O Exemplo 11 demonstra a execução do algoritmo PartitionTopk.

Exemplo 11 (Execução do algoritmo PartitionTopk). Considere novamente a relação

jogadoresda Figura 10(a) e a teoria-pc Γ do Exemplo 8. O processamento da operação

TOPKΓ,3(jogadores) pelo algoritmo PartitionTopk é realizado conforme os seguintes passos: