14.03.2015 Views

(Grafos) - Unisinos

(Grafos) - Unisinos

(Grafos) - Unisinos

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!