(Grafos) - Unisinos
(Grafos) - Unisinos
(Grafos) - Unisinos
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Estruturas Avançadas de Dados II<br />
(<strong>Grafos</strong>)<br />
Patricia Jaques<br />
Adaptado de Professor Gilberto Irajá Müller<br />
Última atualização 18/04/2013
Introdução<br />
! Porque estudar <strong>Grafos</strong><br />
! Importante ferramenta matemática com aplicação em diversas<br />
áreas do conhecimento<br />
! Genética, química, pesquisa operacional, telecomunicações,<br />
engenharia elétrica, redes de computadores, conexão de vôos<br />
aéreos, restrições de precedência, fluxo de programas, dentre<br />
outros<br />
! Utilizados na definição e/ou resolução de problemas
Grafo<br />
! Conjunto de Vértices e uma coleção de Arestas<br />
conectando pares de vértices
Grafo: informalmente<br />
Um grafo é uma forma de representar<br />
relações entre pares de objetos
Exemplo<br />
! Vértices: códigos de aeroportos<br />
! Arestas: rotas aéreas e distâncias
Introdução<br />
! O rio Pregel divide o centro da cidade de<br />
Königsberg (Prússia no século XVII, atual<br />
Kaliningrado, Rússia) em quatro regiões.<br />
! Atravessar todas as pontes, voltando ao<br />
lugar de saída, sem repetir alguma
Introdução<br />
! As pontes de Königsberg<br />
! Resolvido em 1736 por Leonhard Euler<br />
! Euler provou que não existia caminho<br />
que possibilitasse tais restrições<br />
! Necessário um modelo para representar o<br />
problema<br />
! Abstração de detalhes irrelevantes:<br />
! Área de cada ilha<br />
! Formato de cada ilha<br />
! Tipo da ponte, etc.
Introdução<br />
! As pontes de Königsberg<br />
! Euler generalizou o problema<br />
através de um modelo de<br />
grafos;<br />
! Euler mostrou que não existe<br />
o trajeto proposto utilizando o<br />
modelo em grafos.<br />
! Talvez esse seja o<br />
primeiro modelo de<br />
grafos.
Introdução<br />
! O problema das 3 casas<br />
! É possível conectar os 3 serviços às 3 casas sem<br />
haver cruzamento de tubulação?<br />
água luz telefone
Introdução<br />
! Quantas cores são<br />
necessárias para<br />
colorir o mapa do<br />
Brasil, sendo que<br />
estados adjacentes<br />
não podem ter a<br />
mesma cor?
Introdução<br />
! Questões sobre o caminho mínimo<br />
De forma a reduzir seus custos operacionais, uma empresa de transporte<br />
de cargas deseja oferecer aos motoristas de sua frota um mecanismo que<br />
os auxilie a selecionar o melhor caminho (o de menor distância) entre<br />
quaisquer duas cidades por ela servidas, de forma a que sejam<br />
minimizados os custos de transporte.
Introdução<br />
! Questões sobre o caminho mínimo
Modelagem de <strong>Grafos</strong><br />
! Estamos interessados em objetos e<br />
nas relações entre eles<br />
! Quem são eles nos problemas<br />
apresentados?<br />
! Como representar graficamente?
Introdução<br />
• No problema das casas<br />
• Vértices são casas e serviços<br />
• Arestas são as tubulações entre casas e serviços<br />
! O problema das 3 casas<br />
! É possível conectar os 3 serviços às 3 casas sem<br />
haver cruzamento de tubulação?<br />
A teoria<br />
dos grafos<br />
mostra que<br />
não é<br />
possível!<br />
água luz telefone
Introdução<br />
• No problema da coloração de mapas<br />
• Vértices são estados<br />
• Arestas relacionam estados vizinhos<br />
• 4 cores são necessárias para colorir qualquer<br />
mapa
Introdução<br />
! Questões sobre o caminho mínimo<br />
De forma a reduzir seus custos operacionais, uma empresa de<br />
transporte de cargas deseja oferecer aos motoristas de sua frota um<br />
mecanismo que os auxilie a selecionar o melhor caminho (o de menor<br />
distância) entre quaisquer duas cidades por ela servidas, de forma a que<br />
sejam minimizados os custos de transporte.<br />
• No problema do caminho<br />
mais curto<br />
• Vértices são as cidades<br />
• Arestas são as ligações entre<br />
as cidades
Modelagem de <strong>Grafos</strong><br />
! Três desenvolvimentos isolados despertaram o interesse<br />
pela área<br />
! Formulação do problema das 4 cores<br />
(De Morgan 1852).<br />
! Qual a quantidade mínima de cores para colorir um mapa de tal<br />
forma que países fronteiriços possuam cores diferentes?<br />
! Apresenta-se um exemplo em que 3 cores não são suficientes.<br />
! Uma prova de que 5 cores é suficiente foi formulada.<br />
! Conjecturou-se então que 4 cores seriam suficientes.<br />
! Esta questão ficou em aberto até 1976 quando Appel e Haken<br />
provaram para 4 cores
Modelagem de <strong>Grafos</strong><br />
! Três desenvolvimentos isolados despertaram o<br />
interesse pela área<br />
! Problema do ciclo Hamiltoniano (Hamilton 1859)<br />
! Um caminho hamiltoniano é um caminho que permite passar<br />
por todos os vértices de um grafo, sem repetição (uma única<br />
vez).<br />
Problema do caixeiro viajante<br />
Existem n cidades. Cada par de cidades pode ser adjacente<br />
ou não arbitrariamente. Partindo de uma cidade qualquer, o<br />
problema consiste em determinar um trajeto que passe<br />
exatamente uma vez em cada cidade e retorne ao ponto de<br />
partida.
Modelagem de <strong>Grafos</strong><br />
! Três desenvolvimentos isolados despertaram o<br />
interesse pela área<br />
! Teoria das árvores<br />
- Em 1847 Kirchhoff propôs a teoria<br />
de árvores (subconjunto da teoria de<br />
grafos) para resolver problemas de<br />
circuitos elétricos.
Conceitos e Características
Conceitos e Características<br />
! Dois tipos de elementos<br />
! Vértices ou nós ou nodos<br />
! Arestas ou caminho ou arco<br />
v1<br />
v3<br />
v4<br />
v2<br />
v5<br />
v6
Conceitos e Características<br />
! Grafo<br />
! G = (V, E)<br />
! V é um conjunto finito não-vazio de vértices<br />
! E é um conjunto de pares não ordenados de<br />
elementos distintos de V, chamados de arestas<br />
! Cada aresta e pertencente ao conjunto E será<br />
denotada pelo par de vértices (x,y) que a forma
Conceitos e Características<br />
! Grafo
Tipos de arestas<br />
! Arestas orientadas (arestas dirigidas)<br />
! Pares de vértices ordenados<br />
! Origem e Destino<br />
! Arestas não-orientadas (não dirigidas)<br />
! Não há ordem dos vértices
Tipos de grafos<br />
! Grafo orientado (ou dígrafo)<br />
! Todas as arestas são orientadas<br />
! Grafo não orientado<br />
! Não há arestas orientadas
Tipos de grafos<br />
! Grafo ponderado<br />
! arestas possuem um<br />
rótulo numérico que<br />
indica seu peso.<br />
! Peso = medida genérica<br />
! Grafo rotulado<br />
(em vértices ou arestas)<br />
! Quando os vértices ou arestas<br />
possuem rótulos
Tipos de arestas: contextos reais<br />
Não orientado<br />
Vértices<br />
Cidades<br />
Autores<br />
Arestas<br />
Estradas<br />
Co-autoria<br />
Computadores Conexões de<br />
rede<br />
Orientado<br />
Vértices<br />
Cidades<br />
Disciplinas<br />
Página web<br />
Arestas<br />
Vôos<br />
Pré-requisitos<br />
Links<br />
Ponderado (arestas possuem pesos)<br />
Vértices Arestas -<br />
Peso<br />
Cidades Estradas -<br />
Distância
Exercício<br />
! O grafo das palavras é definido assim:<br />
! cada vértice é uma palavra da língua portuguesa e<br />
! duas palavras são adjacentes se diferem em exatamente uma posição.<br />
! Por exemplo, rato e ralo são adjacentes, enquanto ralo e rota não são.<br />
! Faça um grafo definido pelas palavras abaixo:<br />
! Palavras: ralo ramo rata rato remo reta reto rota
Terminologia<br />
! Vértices finais<br />
! U e V são vértices finais de a<br />
! Arestas incidentes<br />
! a, d e b incidem em V<br />
! Vértices adjacentes<br />
! U e V são adjacentes<br />
! Grau de um vértice<br />
! X tem grau 5 (nro de arestas incidentes)<br />
! <strong>Grafos</strong> orientados<br />
! Grau de entrada<br />
! Grau de saída<br />
! Arestas paralelas<br />
! h e i (mesmos vértices finais)<br />
! Laço<br />
! j (único vértice final)
Terminologia<br />
! Grafo simples<br />
! Não possui:<br />
! Arestas paralelas<br />
X<br />
h<br />
i<br />
Z<br />
j<br />
! h e i<br />
! Laços<br />
! j<br />
X<br />
h<br />
i<br />
Z<br />
j
Terminologia<br />
! Subgrafo de um Grafo G<br />
! É um outro grafo H cujos vértices e arestas são<br />
subconjuntos dos vértices e arestas de G.<br />
31
Conceitos e Características<br />
! Grafo simples<br />
v1<br />
v3<br />
V = {v1, v2, v3, v4, v5, v6}<br />
v4<br />
e1<br />
v5<br />
v2<br />
v6<br />
E = {{v1,v2},{v1,v3},{v1,v4},{v2,v4},{v3,v4},{v4,v5}}<br />
e1 é incidente a v4 e v5
Exercício<br />
! Desenhe o grafo simples a seguir:<br />
! V = {1,2,3,4,5,6};<br />
! E ={(1,2),(1,3),(3,2),(3,6),(5,3),(5,1),(5,6),(4,6), (4,5),(6,1),<br />
(6,2),(3,4)}
Terminologia<br />
! Caminho<br />
! Seqüência alternada de vértices e arestas<br />
! Se for um grafo simples: é possível representar como uma<br />
sequencia de vértices<br />
! Inicia e termina em um vértice<br />
! Cada aresta é precedida e seguida por seus pontos finais<br />
! Caminho simples<br />
! Vértices e arestas distintos<br />
! Exemplo<br />
! P1 = (V,b,X,h,Z)<br />
! Contra-exemplo<br />
! P2 = (U,c,W,e,X,g,Y,f,W,d,V)
Exercício<br />
! A partir do grafo dirigido abaixo:<br />
a) Quais são os vértices adjacentes ao vértice 3?<br />
b) Qual o caminho mais curto do nó 3 para o nó 6?<br />
c) Qual o caminho de comprimento 8 do nó 1 para o nó 6?
Terminologia<br />
! Ciclo<br />
! Caminho em que os vértices de início e fim são<br />
os mesmos<br />
! laço: ciclo de tamanho 1<br />
! Ciclo simples<br />
! Vértices e arestas distintos, exceto o primeiro<br />
e o último<br />
! Exemplo<br />
! C1 = (V,b,X,g,Y,f,W,c,U,a,↵)<br />
! Contra-exemplo<br />
! C2 = (U,c,W,e,X,g,Y,f,W,d,V,a, ↵)
Grafo Conexo<br />
! Grafo não dirigido<br />
! Um grafo não dirigido é conexo se existir um caminho<br />
entre quaisquer dois vértices do grafo.<br />
37
Grafo dirigido<br />
! Grafo fortemente conexo<br />
! No caso de grafos orientados (dígrafos), um grafo é<br />
fortemente conexo se existe um caminho de a para b<br />
e de b para a, para cada par a,b de vértices do grafo.<br />
38
Grafo dirigido<br />
! Grafo fracamente conexo<br />
! Um dígrafo é dito fracamente conexo se, ao<br />
substituirmos os arcos (setas) por arestas (retas),<br />
temos um grafo não-dirigido conexo.<br />
! Esse grafo não-dirigido gerado é chamado de “grafo não<br />
orientado subjacente”.<br />
39
Terminologia<br />
! Floresta<br />
! Grafo acíclico (sem ciclos)<br />
! Árvore<br />
! Grafo conexo e acíclico<br />
! ou Floresta conexa
Terminologia<br />
! Grafo Acíclico<br />
! grafo que não contém um ciclo<br />
! Evitar usar a expressão "o grafo é cíclico"<br />
no lugar de "o grafo não é acíclico”<br />
! para não confundir com grafo cíclico (ou<br />
grafo ciclo => grafo regular de grau 2)<br />
! Grafo Acíclico Orientado (GAOS)<br />
! directed acyclic graph (DAG)<br />
! grafo orientado que não possui ciclo
Propriedades<br />
! Propriedade 1<br />
Σ v deg(v) = 2m<br />
! Cada ponto final é contado<br />
duas vezes<br />
! Propriedade 2<br />
! Para um grafo simples não<br />
orientado<br />
m ≤ n(n-1)/2<br />
! Cada vértice tem grau máximo<br />
de (n-1)<br />
Notação<br />
n número de vértices<br />
m número de arestas<br />
deg(v) grau do vértice v<br />
Exemplo<br />
n = 4<br />
m = 6<br />
deg(v) = 3<br />
v
Exercício<br />
a) o grafo é simples?<br />
b) o grafo é conexo?<br />
c) é possível encontrar dois caminhos entre 3 e 6?<br />
d) é possível encontrar um ciclo?<br />
e) é possível encontrar uma aresta cuja remoção transforma o grafo em um<br />
grafo acíclico?<br />
f) é possível encontrar uma aresta cuja remoção transforma o grafo em<br />
desconexo?
Implementação<br />
Estruturas de dado para <strong>Grafos</strong>
Conceitos e Características<br />
! Representação de <strong>Grafos</strong> por Computador<br />
Embora seja conveniente a representação de<br />
grafos através de diagramas de pontos ligados<br />
por linhas, tal representação é inadequada se<br />
desejamos armazenar grandes grafos em um<br />
computador
Como representar?
Complexidade das Operações para Lista de<br />
Arestas<br />
Operação<br />
vertices<br />
edges<br />
incidentEdges(v)<br />
opposite(v, e)<br />
endVertices(e)<br />
Descrição<br />
retorna todos os vértices do grafo<br />
retorna todos as arestas do grafo<br />
retorna as arestas incidentes no vértice v<br />
retorna vértice adjacente ao vértice v pela aresta<br />
e<br />
retorna vértices finais da aresta e<br />
n = número de vértices<br />
m = número de arestas
TAD Grafo: Estruturas de dados usuais<br />
! Matriz de adjacência<br />
! Lista de arestas<br />
! Lista de adjacência
Matriz de adjacência<br />
! Através de uma matriz, permite determinar<br />
vértices adjacentes<br />
! Espaço: n 2
Matriz de adjacência<br />
! Para dígrafo
Matriz de Adjacência (versão simples)<br />
public class GrafoMatriz {<br />
private boolean matriz[][];<br />
private int tam;<br />
public GrafoMatriz(int tam) {<br />
this.tam = tam;<br />
matriz = new boolean[tam][tam];<br />
}<br />
public void addAresta(int i, int j) {<br />
if (i >= 0 && i < tam && j >= 0 && j < tam) {<br />
matriz[i][j] = true;<br />
matriz[j][i] = true;<br />
}<br />
}<br />
(C) Christopher Rosa Pohlmann 51
Matriz de Adjacência (versão simples)<br />
continuação<br />
public void removeAresta(int i, int j) {<br />
if (i >= 0 && i < tam && j >= 0 && j < tam) {<br />
matriz[i][j] = false;<br />
matriz[j][i] = false;<br />
}<br />
}<br />
public boolean isAresta(int i, int j) {<br />
if (i >= 0 && i < tam && j >= 0 && j < tam)<br />
return matriz[i][j];<br />
else<br />
return false;<br />
}<br />
}<br />
(C) Christopher Rosa Pohlmann 52
TAD Matriz de adjacência<br />
! Matriz de referências para<br />
objetos aresta. Índices da<br />
matriz associam o vértice i ao<br />
vértice j
Matriz de Adjacência<br />
u<br />
a<br />
v<br />
b<br />
w<br />
0 u 1 v 2 w<br />
a<br />
0 1 2<br />
0 ∅ ∅<br />
1 ∅<br />
2 ∅ ∅<br />
b<br />
54
class Vertice {<br />
private T dados;<br />
public Vertice(T d) {<br />
this.dados = d;<br />
}<br />
public T getDados() {<br />
return this.dados;<br />
}<br />
public void setDados(T d) {<br />
this.dados = d;<br />
}<br />
public String toString() {<br />
return this.dados.toString();<br />
}<br />
public boolean equals(Object obj) {<br />
if (obj==null) return false;<br />
else if (obj instanceof Vertice) {<br />
T dadosObj = ((Vertice) obj).getDados();<br />
return dados.equals(dadosObj);<br />
}<br />
else return false;<br />
}<br />
}<br />
(C) Christopher Rosa Pohlmann 55
public class Aresta {<br />
private A dados;<br />
private Vertice v1, v2;<br />
public Aresta(A dados, Vertice v1, Vertice v2) {<br />
this.dados = dados;<br />
this.v1 = v1;<br />
this.v2 = v2;<br />
}<br />
public A getDados() {<br />
return dados;<br />
}<br />
public void setDados(A dados) {<br />
this.dados = dados;<br />
}<br />
public Vertice getV1() {<br />
return v1;<br />
}<br />
public void setV1(Vertice v1) {<br />
this.v1 = v1;<br />
}<br />
public Vertice getV2() {<br />
return v2;<br />
}<br />
public void setV2(Vertice v2) {<br />
this.v2 = v2;<br />
}<br />
public String toString() {<br />
return "[" + v1 + ", " + v2 + "]";<br />
}<br />
56
public class GrafoMatriz {<br />
private ArrayList arestas; // lista de arestas do grafo<br />
private ArrayList vertices; // lista de vértices do grafo<br />
private Aresta matriz[][]; // matriz de adjacência: linhas e colunas representam vértices<br />
// células representam arestas existentes entre os respectivos vértices<br />
// Construtor. Apenas inicializa as estruturas de dados<br />
public GrafoMatriz(int n) {<br />
this.arestas = new ArrayList();<br />
this.vertices = new ArrayList();<br />
this.matriz = (Aresta[][]) Array.newInstance(Aresta.class, n, n);;<br />
}<br />
// Insere um novo vértice com dado 'v'<br />
public void addVertice(V v) throws ArrayIndexOutOfBoundsException {<br />
// se matriz já está completamente ocupada, gera exceção<br />
if (matriz.length==vertices.size()) throw new ArrayIndexOutOfBoundsException();<br />
else {<br />
// cria novo vértice<br />
Vertice objVertice = new Vertice(v);<br />
this.vertices.add(objVertice);<br />
}<br />
}<br />
57
Insere uma nova aresta com vértices finais 'v1' e 'v2' e dado 'a'<br />
public boolean addAresta(V v1, V v2, A a) {<br />
// obtendo índice da aresta na matriz<br />
int i = this.vertices.indexOf(new Vertice(v1));<br />
int j = this.vertices.indexOf(new Vertice(v2));<br />
if (i!=-1 && j!=-1) { // se vértices encontrados (i e j terão as posiçòes dos vértices na lista<br />
// criando objeto aresta<br />
Aresta objAresta = new Aresta(a, vertices.get(i), vertices.get(j));<br />
// adicionando a aresta a lista de arestas<br />
this.arestas.add (objAresta);<br />
// fazendo a matriz referenciar a aresta<br />
// para arestas não-dirigidas, deve-se setar posição (i,j) e (j,i)<br />
this.matriz[i][j] = objAresta;<br />
this.matriz[j][i] = objAresta;<br />
return true;<br />
}<br />
return false;<br />
}<br />
58
Remove o vértice 'v'. Retorna true se 'v' foi encontrado e removido, false caso contrário<br />
public boolean delVertice(V v) {<br />
int posVertice = this.vertices.indexOf(new Vertice(v));<br />
V objVertice = this.vertices.remove(posVertice).getDados();<br />
// a fazer<br />
// importante lembrar que quando um vértice for removido, a matriz tem que ser redimensionada<br />
// e, por consequencia, as arestas dentro destas<br />
return (objVertice!=null);<br />
}<br />
// Remove a aresta de dado 'a'. Retorna true se 'a' foi encontrada e removida, false caso contrár<br />
public boolean delAresta(A a) {<br />
Aresta objAresta = null;<br />
// deletando aresta da lista de arestas<br />
int k=0;<br />
while ( k
Retorna uma lista contendo todos os vértices adjacentes (vizinhos) a um vértice 'v'<br />
public ArrayList getVizinhos(V v) {<br />
ArrayList objAresta = new ArrayList();<br />
// descobre linha/coluna da matriz que guarda arestas que contém o vértice 'v’<br />
// como um vértice incidente<br />
int posVertice = this.vertices.indexOf(new Vertice(v));<br />
// percorre linha da matriz do vértice v<br />
for (int i = 0; i < this.matriz[posVertice].length; i++) {<br />
if (this.matriz[posVertice][i] != null) {<br />
// para cada célula da linha correspondente ao vértice na matriz,<br />
// verifica se há uma aresta (!=null)<br />
// se for diferente de null, testa se o dado de v1 é diferente de v,<br />
// se sim o vértice adjacente está em v1,<br />
// caso contrário está em v2<br />
if (matriz[posVertice][i]!=null && !matriz[posVertice][i].getV1().getDados().equals(v))<br />
objAresta.add(matriz[posVertice][i].getV1());<br />
else if (matriz[posVertice][i]!=null) objAresta.add(matriz[posVertice][i].getV2());<br />
}<br />
}<br />
return objAresta;<br />
}<br />
60
Testa se os vértices 'v1' e 'v2' são adjacentes (vizinhos)<br />
public boolean isAdjacente(V v1, V v2) {<br />
int i = this.vertices.indexOf(new Vertice(v1));<br />
int j = this.vertices.indexOf(new Vertice(v2));<br />
if (i==-1 || j==-1) return false;<br />
else return this.matriz[i][j] != null;<br />
}<br />
61
Complexidade das Operações para<br />
Matriz de Adjacências<br />
Operação Tempo Descrição<br />
vertices O(n) retorna todos os vértices do grafo<br />
edges O(m) retorna todos as arestas do grafo<br />
incidentEdges(v) O(n) retorna as arestas incidentes no vértice v<br />
opposite(v,e) O(1) retorna vértice adjacente ao vértice v pela<br />
aresta e<br />
endVertices(e) O(1) retorna vértices finais da aresta e<br />
n = número de vértices<br />
m = número de arestas
Exercício<br />
Dada a matriz de adjacência ao lado, desenhe o seu respectivo grafo.<br />
(C) Christopher Rosa Pohlmann 63
Conceitos e Características<br />
! Representação de <strong>Grafos</strong> – Lista de Arestas<br />
Uma maneira simples de armazenar grafos é listando as arestas.<br />
Cada aresta sabe os seus vértices finais.<br />
u<br />
y<br />
x<br />
d<br />
f<br />
c<br />
e<br />
a<br />
v<br />
b<br />
w<br />
a: (u,v)<br />
b: (v,w)<br />
c: (w,x)<br />
d: (y,x)<br />
f: (u,y)
TAD Lista de arestas<br />
! Duas listas: arestas e vértices<br />
! Acesso direto das arestas para os<br />
vértices
TAD Lista de arestas<br />
! Desvantagem<br />
! Acessar arestas incidentes a um<br />
vértice requer busca exaustiva de<br />
arestas
Lista de Arestas<br />
u<br />
a<br />
c<br />
v<br />
b<br />
w<br />
d<br />
z<br />
u v w z<br />
a<br />
b c d
Complexidade das Operações para Lista de<br />
Arestas<br />
Operação<br />
Tempo Descrição<br />
vertices O(n) retorna todos os vértices do grafo<br />
edges O(m) retorna todos as arestas do grafo<br />
incidentEdges(v) O(m) retorna as arestas incidentes no vértice v<br />
opposite(v,e) O(1) retorna vértice adjacente ao vértice v pela aresta e<br />
endVertices(e) O(1) retorna vértices finais da aresta e<br />
n = número de vértices<br />
m = número de arestas
Lista de adjacência<br />
! Listas de vértices adjacentes<br />
! Espaço: n + m<br />
! Resolve desvantagens da Lista de Arestas
TAD Lista de adjacência<br />
! Estende a lista de arestas<br />
provendo acesso dos vértices<br />
para suas arestas incidentes<br />
(acesso entre vértices)
Lista de Adjacência<br />
u<br />
a<br />
v<br />
b<br />
w<br />
u v w<br />
a<br />
b
class Vertice {<br />
private T dados;<br />
private ArrayList listaIncidencia;<br />
public ArrayList getListaIncidencia() {<br />
return listaIncidencia;<br />
}<br />
public void setListaIncidencia(ArrayList<br />
listaIncidencia) {<br />
this.listaIncidencia = listaIncidencia;<br />
}<br />
(C) Christopher Rosa Pohlmann 72
public class GrafoLista {<br />
private HashMap arestas; // lista de arestas<br />
private HashMap vertices; // lista de vértices<br />
public GrafoLista() {<br />
this.arestas = new HashMap();<br />
this.vertices = new HashMap();<br />
}<br />
// Insere um novo vértice com o dado 'v'.<br />
public void addVertice(V v) {<br />
// cria novo vértice<br />
Vertice objVertice = new Vertice(v);<br />
this.vertices.put(v,objVertice);<br />
}<br />
(C) Christopher Rosa Pohlmann 73
Insere uma nova aresta com vértices finais 'v1' e 'v2' e dado 'a'<br />
public void addAresta(V v1, V v2, A a) {<br />
Vertice objVertice1 = this.vertices.get(v1);<br />
Vertice objVertice2 = this.vertices.get(v2);<br />
// criando a nova aresta<br />
Aresta objAresta = new Aresta<br />
(a, objVertice1, objVertice2);<br />
// obtendo a lista de incidência dos vértices finais para<br />
// inserir a nova aresta<br />
// a nova aresta deve ser inserida na lista de incidência<br />
// de cada vértice final (v1 e v2)<br />
ArrayList listaIncidencia = objVertice1<br />
.getListaIncidencia();<br />
listaIncidencia.add(objAresta);<br />
ArrayList listaIncidencia2 = objVertice2<br />
.getListaIncidencia();<br />
listaIncidencia2.add(objAresta);<br />
// inserindo na lista de arestas<br />
this.arestas.put(a,objAresta);<br />
}<br />
(C) Christopher Rosa Pohlmann 74
Remove o vértice 'v'. Retorna true se 'v' foi encontrado e removido, false caso contrário<br />
public boolean delVertice(V v) {<br />
// removendo vértice da lista de vértices<br />
Vertice objVertice = this.vertices.get(v);<br />
if (objVertice!=null) {<br />
// obtendo a lista de incidência do vértice para deletar suas arestas<br />
ArrayList listaIncidencia = objVertice<br />
.getListaIncidencia();<br />
Object arestasDaLista [] = listaIncidencia.toArray();<br />
for (int i = 0; i < arestasDaLista.length; i++) {<br />
Aresta objAresta = (Aresta)arestasDaLista[i];<br />
// chama método delAresta() que deleta a aresta na lista de<br />
// incidência de seus 2 vértices finais<br />
delAresta (objAresta);<br />
}<br />
this.vertices.remove(v);<br />
}<br />
return (objVertice != null);<br />
}<br />
// Remove a aresta de dado 'a'. Retorna true se 'a' foi encontrada e removida,<br />
// false caso contrário<br />
public boolean delAresta(A a) {<br />
// obtendo aresta que liga os respectivos vértices<br />
Aresta objAresta = arestas.get(a);<br />
if (objAresta!=null) {<br />
delAresta (objAresta);<br />
return true;<br />
}<br />
return false;<br />
}<br />
(C) Christopher Rosa Pohlmann 75
Remove o objeto Aresta 'objAresta'.<br />
// Método delAresta é sobrecarregado: pode receber tanto o rótulo da aresta<br />
// como uma referência para o objeto aresta<br />
private void delAresta (Aresta objAresta){<br />
// obtendo objeto vértice final da aresta<br />
Vertice vertice = this.vertices.get(objAresta.getV1().getDados());<br />
// obtendo a lista de incidencia do vértice para deletar a aresta<br />
ArrayList listaIncidencia = vertice<br />
.getListaIncidencia();<br />
listaIncidencia.remove(objAresta);<br />
// obtendo outro objeto vértice final da aresta<br />
vertice = this.vertices.get(objAresta.getV2().getDados());<br />
// obtendo a lista de incidencia do vértice para deletar a aresta<br />
listaIncidencia = vertice<br />
.getListaIncidencia();<br />
listaIncidencia.remove(objAresta);<br />
}<br />
// deletando a aresta da lista de arestas<br />
this.arestas.remove(objAresta.getDados());<br />
(C) Christopher Rosa Pohlmann 76
Retorna uma lista contendo todos os vértices adjacentes (vizinhos) a um vértice 'v'<br />
public ArrayList getVizinhos(V v) {<br />
ArrayList vizinhos = new ArrayList();<br />
// obtendo vértice da lista de vértices<br />
Vertice objVertice = this.vertices.get(v);<br />
}<br />
if (objVertice!=null) {<br />
// obtendo a lista de incidencia do vértice para obter suas arestas<br />
// e seus vizinhos<br />
ArrayList listaIncidencia = objVertice<br />
.getListaIncidencia();<br />
for (int i = 0; i < listaIncidencia.size(); i++) {<br />
Aresta objAresta = listaIncidencia.get(i);<br />
Vertice objV1 = objAresta.getV1();<br />
Vertice objV2 = objAresta.getV2();<br />
if (objV1.getDados().equals(v)) vizinhos.add(objV2);<br />
else vizinhos.add(objV1);<br />
}<br />
}<br />
return vizinhos;<br />
(C) Christopher Rosa Pohlmann 77
Testa se os vértices 'v1' e 'v2' são adjacentes (vizinhos)<br />
public boolean isAdjacente(V v1, V v2) {<br />
// obtendo vértice da lista de vértices<br />
Vertice objVertice = this.vertices.get(v1);<br />
if (objVertice!=null){<br />
// obtendo a lista de incidencia do vértice para obter suas arestas<br />
// e seus vizinhos<br />
ArrayList listaIncidencia = objVertice<br />
.getListaIncidencia();<br />
for (int i = 0; i < listaIncidencia.size(); i++) {<br />
Aresta objAresta = listaIncidencia.get(i);<br />
Vertice objV1 = objAresta.getV1();<br />
Vertice objV2 = objAresta.getV2();<br />
if (v1.equals(objV1.getDados()) && v2.equals(objV2.getDados()))<br />
return true;<br />
else if (v1.equals(objV2.getDados()) && v2.equals(objV1.getDados()))<br />
return true;<br />
}<br />
}<br />
return false;<br />
}<br />
(C) Christopher Rosa Pohlmann 78
Complexidade das Operações para<br />
Lista de Adjacências<br />
Operação Tempo Descrição<br />
vertices O(n) retorna todos os vértices do grafo<br />
edges O(m) retorna todos as arestas do grafo<br />
incidentEdges(v) O(deg(v)) retorna as arestas incidentes no vértice v<br />
opposite(v,e) O(1) retorna vértice adjacente ao vértice v pela aresta e<br />
endVertices(e) O(1) retorna vértices finais da aresta e<br />
n = número de vértices<br />
m = número de arestas
TADs Grafo: Resumo<br />
! Lista de arestas<br />
! Acesso direto das arestas para os<br />
vértices incididos (apenas)<br />
! Lista de adjacência<br />
! Estende a lista de arestas provendo<br />
acesso dos vértices para suas<br />
arestas incidentes (acesso entre<br />
vértices)<br />
! Matriz de adjacência<br />
! Estende a lista de arestas provendo<br />
adjacências entre vértices em uma<br />
matriz<br />
arestas<br />
vértices<br />
arestas<br />
vértices
TADs Grafo: Complexidade de tempo
Qual representação usar?<br />
! Matriz de adjacência<br />
! Ok se grafo for denso<br />
! Lista de Adjacências<br />
! Melhor representação para grafos esparsos<br />
! <strong>Grafos</strong> Densos<br />
! o número de arestas é próximo de n 2 , ou seja, existe<br />
quase uma ligação entre cada 2 vértices<br />
! <strong>Grafos</strong> Esparsos<br />
! número de arestas muito menor que n 2<br />
82
Exercício<br />
! A complexidade da operação incidentEdges(v)<br />
(que retorna as arestas incidentes no vértice v)<br />
em um grafo representado por Matriz de<br />
Adjacência é O(n). Em um grafo representado<br />
por Lista de Adjacência é O(deg(v)). Explique<br />
por que isso acontece.<br />
(C) Christopher Rosa Pohlmann 83
Bibliografia<br />
! Silberchatz, A; Korth, H. F., Sudarshan, S. Sistema de Banco de<br />
Dados. 3ª. Edição, Makron Books, 1999.<br />
! Lafore, Robert. Estruturas de Dados & Algoritmos em Java.<br />
Editora Ciência Moderna, 2004.<br />
! Thomas H. Cormen - Algoritmos: Teoria e Prática<br />
! Michael T. Goodrich - Projeto De Algoritmos