Unidade 2: Filas de Prioriadade

Propaganda
Unidade 2: Filas de Prioridade
Nesta Unidade vamos aprender:
1. O que é uma Fila de Prioridade
2. Motivação
3. O Tipo Abstrato de Dados: Fila de
Prioridade
4. Implementação
de uma Fila de
Prioridade usando um Array
5.Implementação de uma Fila de
Prioridade usando listas encadeadas
6. Heaps Binários: Uma estrutura especial
para Filas de Prioridade
1. O que é uma Fila de Prioridade (FP)?
- é uma fila na qual os elementos são
inseridos em qualquer ordem, porém a
remoção de um elemento é sempre feita
por ordem de prioridade.
Definição: Uma Fila de Prioridade é um
Tipo Abstrato de Dados para armazenar
uma coleção de elementos priorizados,
com a seguinte particularidade:
i)
ii)
Inserções podem ser feitas em
qualquer lugar;
Remoções são feitas considerando a
ordem de prioridade.
2. Motivação
Existem várias aplicações para Filas de
Prioridade.
Ex1.: Num aeroporto vários aviões estão
aguardando ordem para pousar. Ao invés
de se usar uma estrutura de Fila comum
(do tipo FIFO), talvez seja mais
conveniente usar uma FP onde a
prioridade seria com
relação
a
quantidade de combustível que resta em
cada avião.
Ex.2: Num Banco, a fila de atendimento
ao caixa poderia ser única, porém as
prioridades poderiam ser estabelecidas de
acordo com a importância do cliente para
o Banco (cliente especial).
Importante: A prioridade pode ser
baseada num atributo simples (ex. Tipo
de conta: comum ou especial), ou baseada
numa série de critérios (ex.: tipo de conta,
idade, tempo de espera, etc)
3. O Tipo Abstrato de Dados Fila de
Prioridade
3.1. O conceito de chave de busca
Quando estudamos algoritmos
de
pesquisa, usamos o conceito de chave de
busca que representa o(s) atributo(s)
pelos quais as buscas serão realizadas.
Numa FP a chave de busca é justamente a
prioridade de um determinado elemento.
Uma FP precisa realizar comparações
entre as prioridades (ordem total).
Suponha que k seja uma chave de busca,
as seguintes propriedades devem ser
obedecidas:
- Reflexividade: k <= k
- Assimetria: se k1 <= k2 e k2 <= k1,
então k1 = k2
- Transitividade: se k1 <= k2 e k2 <= k3,
então k1 <= k3.
3.2. Métodos de uma FP
 size(): retorna o número de elementos
em uma FP.
Input: nenhuma; Output: Integer
 isEmpty(): testa se a FP está vazia
Input: nenhuma; Output: Boolean
 insertItem(e): insere um novo elemento
Input: objeto e; Output: nenhuma
 findMin(): Retorna (mas não remove) o
elemento da FP de menor chave (maior
prioridade). Dá um erro se a FP estiver
vazia.
Input: nenhuma; Output: Objeto
 removeMin(): remove da FP e retorna o
elemento de menor chave (maior
prioridade). Dá um erro caso a FP
esteja vazia.
Input: nenhuma; Output: Objeto.
Exercício: Escreva uma interface Java
para o TAD FP.
Solução:
public interface FilaPrioridade
{
void inserir (Object e);
Object removeMin()
throws Exception;
Object encontraMin()
throws Exception;
boolean ehVazio();
int tamanho();
}
Exemplo: A tabela abaixo mostra uma
série de operações sobre uma FP que está
inicialmente vazia.
Operação
insere(5)
insere(9)
insere(7)
encontraMin()
removeMin()
tamanho()
removeMin()
removeMin()
removeMin()
ehVazio()
Output
5
5
2
7
9
“error”
true
Conteúdo FP
{5}
{5,9}
{5, 7, 9}
{5,7,9}
{7,9}
{7,9}
{9}
{}
{}
{}
No caso de elementos compostos, podemos
definir cada elemento como um par (k, e),
onde k é a chave (prioridade) e e contém
as informações do elemento em si (ex.
nome, endereço, etc.)
Uma possível definição para um item
composto seria:
public class Item {
private Object chave, elem;
protected Item (Object k, Object e) {
chave = k;
elem = e;
}
public Object getChave()
{ return chave; }
public Object getElement()
{ return elem; }
public void setChave(Object k)
{ chave = k; }
public void setElement(Object e)
{ elem = e;}
}
Sobre as comparações das chaves,
dependendo da aplicação a FP vai
comparar vários tipos de dados. Por
exemplo, uma FP pode ter como chave de
prioridade a idade (integer), enquanto
que uma outra FP pode ter como
prioridade a distância entre dois pontos
dispostos num plano.
Solução 1: Escrever um método de
comparação para cada novo tipo de
aplicação!
Solução 2: Escrever uma classe que
realiza a comparação de objetos
(genérica).
Na solução 1, temos o problema de ter
que estar escrevendo código parecido (ex.
Comparação) para cada tipo de dado
diferente que se queira comparar.
Na solução 2, escrevemos o código de
comparação apenas uma vez e usamos
esta classe nas diversas FPs.
Para a solução 2, podemos definir um
TAD comparador com os seguintes
métodos:
 ehMenorQue(a, b): Retorna true se a <
b e false caso contrário.
Input: par de objetos; Output: Boolean
 ehMenorOuIgualA(a, b): retorna true
se a <= b e false caso contrário.
Input: par de objetos; Output: Boolean
 ehIgualA(a,b): retorna true se a = b,
false caso contrário.
Input: par de objetos; Output: Boolean
 ehMaiorQue(a,b): retorna true if a > b,
false caso contrário.
Input: par de objetos; Output: Boolean
 ehMaiorOuIgualA(a,b): retorna true se
a >= b e false caso contrário.
Input: par de objetos; Output: Boolean
 ehComparavel(a): retorna true se a
pode ser comparado,
Input: Object; Output:Boolean
Exercício: Implemente uma interface
Java para o TAD Comparador.
Exemplo de uso do Comparador:
Comparação de pontos num plano de
acordo com a ordem lexicográfica.
public class Lexicographic
implements Comparador
{
int xa, ya, xb, yb;
// Campara pontos no plano com a
// ordem lexicográfica. Assume que
// um Point2D tem métodos getX() e
// getY() que retornam suas
// coordenadas
private void getXY(Object a,
Object b)
{
if (a == null || b == null)
throw
new
InvalidElementException(“
Argumentos Nulos”);
try {
xa = ((Point2D a).getX();
ya = ((Point2D a).getY();
xb = ((Point2D b).getX();
yb = ((Point2D b).getY();
}
catch (ClassCastException e)
{throw
new
InvalidElementException(“Arg
umento não é um Point2D”);}
}
public boolean ehMenorQue(Object a,
Object b)
{
getXY(a,b);
if (xa == xb)
return (ya < yb);
else
return (xa < xb);
}
public boolean ehMenorOuIgualA
(Object a, Object b)
{
getXY(a,b);
if (xa == xb)
return (ya <= yb);
else
return (xa <= xb);
}
public boolean ehIgualA(Object a,
Object b)
{
getXY(a,b);
return (xa == xb) &&
(ya == yb);
}
public boolean ehComparavel(
Object a)
{
if (a == null)
return false;
else {
try{
Point2D p = (Point2D) a;
}
catch (ClassCastException e){
return false;
}
return true;
}
}
}
4. Implementação
de uma Fila de
Prioridade usando um Array
 Utilização de Arrays ordenados:
Remoção: O primeiro elemento do array é
o de maior prioridade
Inserção: precisaremos inserir um
elemento na sua ordem de prioridade no
array (INEFICIENTE).
 Utilização de Arrays não-ordenados:
Inserção: é simples pois precisamos
apenas de adicionar o elemento no final
do Array
Remoção: temos que encontrar o
elemento de maior prioridade, removê-lo
e deslocar o último elemento do Array
para a posição deixada pelo elemento
removido.
Ex.: Remoção do menor elemento num
Array
30
50
30
50
30
50
10
40
20
40
20
40
20
Algoritmo removeMin()
{
int i;
int maxItem;
int maxIndex;
if (!ehVazio()) {
maxItem = FP[0];
maxIndex = 0;
for (i=1; i < size(); i++) {
if (FP[i] > maxItem) {
maxItem = FP[i];
maxIndex = i;
}
}
tamanhoFP --;
FP[maxIndex] = FP[tamanhoFP];
return maxItem;
}
}
5.Implementação de uma Fila
Prioridade usando listas encadeadas
de
 Os elementos são ordenados em ordem
decrescente de prioridade
 A operação de remoção é simples pois
precisamos apenas remover o primeiro
elemento da lista
 Na operação de inserção, nós temos que
inserir o elemento na posição
apropriada
1. Se a lista está vazia, inserir o elemento
diretamente
2. Se o elemento a ser inserido possui
prioridade maior ou igual ao primeiro
elemento da lista, inserir o elemento no
início da lista
3. Se o elemento a ser inserido tem
prioridade menor do que o primeiro
elemento
da
lista,
proceder
recursivamente até achar a posição
apropriada para a inserção.
Qual a limitação desta implementação?
Download