Você está na página 1de 38

Grafos

Grafos
1. Definição
2. Exemplo
3. Grafos orientados
4. Grafos não orientados
5. Grafos ponderados
6. Outras definições
7. Representação de grafos: matrizes e
listas
8. Operações elementares: busca em
profundidade e largura
9. Algoritmo do menor caminho - Dijkstra
Definição de grafo
 Um grafo consiste de 2 conjuntos:
 V (finito e não vazio):
conjunto de vértices (nós)
 E:
conjunto de pares de vértices (arestas)
Exemplo de grafo
G = (V,E)
V = {1,2,3}
E = {(1,2),(2,3)}

3
1
Grafos orientados (Dígrafos)
Cada aresta é representada por um par
direcionado.
<u,v> e <v,u> são arestas diferentes.

 Exemplo:
V = {1,2,3}
E = {<1,2>,<2,1>,<2,3>}

1 2 3
Grafos não orientados
 Uma aresta é representada por pares de
vértices não ordenados.
(u,v) e (v,u) representam a mesma aresta

 Exemplo:
V = {1,2,3}
E = {(1,2),(2,3)}

1 2 3
Grafos Ponderados (redes)
 Grafo em que cada aresta tem um peso
que pode representar:
 Distância entre vértices
 Custo de ir de um vértice a outro
Definição – Grau de um vértice
 Grau de um vértice é o número de arestas
incidentes no vértice.
 Para grafos orientados:
 Grau de entrada
 Grau de saída

1 2 3

Grau de entrada do vértice 2 = 1


Grau de saída do vértice 2 = 2
Grau do vértice 2 = 3
Definição – Vértices adjacentes
 Dado grafo G com vértices u e v
 se a aresta (u,v) pertence ao conjunto E de
arestas do grafo, u e v são adjacentes
Representação de Grafos
 Matriz de adjacência

G = (V,E) é grafo com n vértices, n ≥ 1

A nxn é a matriz de adjacência de G com as


propriedades:
 A[i,j] = 1 ⇔ a aresta (i,j) (ou <i,j>) está em
E(G)
 A[i,j] = 0 se não existe aresta de i a j
Representação de Grafos - Matrizes
 Matriz de adjacência – exemplo

1 0 1 1 0
2 3 A= 1 0 0 1
1 0 0 1
4 0 1 1 0
Grau de um vértice = somatória de sua linha

0 1 0
3 A= 1 0 1
1 2 0 0 0
Grau de saída = soma da linha
Grau de entrada = soma da coluna
Representação de Grafos - Listas
 Listas de adjacências: vetor de listas de
adjacentes.
Exemplo:

1 1 2 3
2 3 2 1 4
3 1 4
4
4 2 3
Exercícios
 Calcular grau de um vértice
 Verificar se 2 vértices são adjacentes
Definição – Grafo completo
 Grafo completo: existe uma aresta entre
quaisquer pares de vértices.

Número máximo de arestas para n vértices:


 Não orientado: n(n-1)/2
 Orientado: n(n-1)
Exercício
 Verificar se um grafo é completo
Outras definições
 Subgrafo de um grafo G: é um grafo G’ tal
que
 V(G’) ⊆ V(G)
 E(G’) ⊆ E(G)

1 1 2 1
2 3 2 3 4 3
2
4 G’ G’’ G’’’
G
Outras definições
 Caminhos: um caminho entre os vértices
u e v no grafo G é uma seqüência
u, i1, i2, ...,ik, v tal que
 (u,i1), (i1,i2),..., (ik,v) são arestas em E(G),
se G for não orientado
 <u,i1>,<i1,i2>,..., <ik,v> são arestas em
E(G), se G for orientado
Outras definições
 Comprimento de um caminho é igual ao número
de arestas nesse caminho.
 Caminho simples é um caminho em que todos os
vértices exceto primeiro e último aparecem uma
única vez.
 Ciclo é um caminho simples em que o primeiro e
o último vértices são os mesmos.
 Vértices conectados: os vértices u e v de um
grafo são conectados se existe um caminho entre
eles.
Operações Elementares
 Visitar todos os vértices de um grafo G
que são alcançados a partir de um vértice
v:
 Busca em profundidade
 Busca em largura
Busca em profundidade
Busca iniciando de um vértice v:
 Seleciona w adjacente de v ainda não visitado e
faz busca a partir de w
 Se todos os vértices adjacentes de v foram
visitados, volta para vértice anterior visitado que
tem vértice w não visitado e inicia busca a partir
de w
 Se todos os vértices já tiverem sido visitados, a
busca termina.
Busca em profundidade - Exemplo

B C

D E F G

Busca em profundidade - ABDHEFCG


Busca em profundidade
Estruturas de dados necessárias:
 Vetor para guardar rótulos dos vértices:
char R[MAX];
 Vetor para guardar se um vértice foi visitado:
typedef enum {FALSE,TRUE} boolean;
boolean visita[MAX]; /* inicialmente FALSE */
 Matriz de adjacência:
typedef int matriz[MAX][MAX];
Busca em profundidade
void buscaprof(int v, matriz M, int n)
/* visita inicialmente FALSE */
{
int i;
visita[v]=TRUE;
printf(“%c”,R[v]);
for (i=0;i<n;i++)
if (!visita[i] && M[v][i])
buscaprof(i,M,n);
}
Busca em largura
 Visita v e adjacentes de v não visitados
 Visita vértices adjacentes não visitados
dos novos vértices

B C Busca em largura - ABCDEFGH

D E F G

H
Busca em largura
void buscalargura(int v,matriz M, int n)
{ tfila f; int i;
visita[v]=TRUE;
inicia(&f); insere(&f,v);
while (!vazia(&f)) {
remove(&f,&v);printf(“%c”,R[v]);
for (i=0;i<n;i++)
if (!visita[i]&& M[v][i]) {
insere(&f,i);visita[i]=TRUE;
}
}
}
Algoritmo do menor caminho
 De Dijkstra
 Retorna o custo do menor caminho do vértice ini até o
vértice fim.
 Estruturas de dados:
 Matriz peso: peso[i][j] contém o peso da aresta (i,j)
 Vetor distancia:
 Distancia[i]: custo do menor caminho de vértice ini até i
 Vetor fazparte: se fazparte[i] for true, nó i já tem distância
mínima conhecida (a partir do nó atual)
 Vetor precede:
 Precede[i] contém o nó que precede o nó i no menor caminho
encontrado.
 No final do algoritmo:
 Distancia[fim] contém a menor distância de ini a fim
 A partir de precede[fim], pode-se obter o caminho de menor
custo.
Exemplo de grafo

0 100
10
30
1 4

10
50 60
0 1 2 3 4
2 3 0 ~ 10 ~ 30 100
20
1 ~ ~ 50 ~ ~
Peso = 2 10
3 20 60
4
Algoritmo
int caminhomenorcusto(
int ini, int fim, int precede[MAX], int peso[MAX][MAX])
{
int i,novadist,menor,datual,k,atual;
boolean fazparte[MAX];
int distancia[MAX];

for (i=0;i<MAX;i++){
fazparte[i]=FALSE;
distancia[i]=MAXINT;
}
fazparte[ini]=TRUE;
distancia[ini]=0;
atual=ini;
Algoritmo (cont.)
while (atual!=fim) {
menor=MAXINT; datual=distancia[atual];
for (i=0;i<MAX;i++)
if(!fazparte[i]){
novadist=datual+peso[atual][i];
if (novadist<distancia[i]){
precede[i]=atual;
distancia[i]=novadist;
if (distancia[i]<menor){
menor=distancia[i];k=i;
}
}
}
atual=k;fazparte[atual]=TRUE;
}
return distancia[atual];
}
Exemplo de execução
 atual = 0 0 1 2 3 4
 fazparte 0 1 2 3 4 0 ~ 10 ~ 30 100
T F F F F 1 ~ ~ 50 ~ ~
 distancia 0 1 2 3 4
2 10
0 ~ ~ ~ ~
 menor = ~ 3 20 60
 datual= 0 (distancia[atual]) 4
 i=1
 novadist = 0 + peso[0][1] = 0 + 10 = 10
 distancia 0 1 2 3 4
0 10 ~ ~ ~ (novadist)
 precede 0 1 2 3 4 (atual)
0
 menor = 10
 k= 1
Exemplo de execução
0 1 2 3 4
 atual = 0
 fazparte 0 1 2 3 4 0 ~ 10 ~ 30 100
T F F F F 1 ~ ~ 50 ~ ~
 distancia 0 1 2 3 4 2 10
0 ~ ~ ~ ~
3 20 60
 menor = 10
 datual= 0 (distancia[atual]) 4
 i=2
 novadist = 0 + peso[0][2] = 0 + ~ = ~
 distancia 0 1 2 3 4
0 10 ~ ~ ~
 precede 0 1 2 3 4
0
 menor = 10
 k= 1
Exemplo de execução
 atual = 0 0 1 2 3 4
 fazparte 0 1 2 3 4 0 ~ 10 ~ 30 100
T F F F F 1 ~ ~ 50 ~ ~
 distancia 0 1 2 3 4
0 10 ~ ~ ~ 2 10
 menor = 10 3 20 60
 datual= 0 (distancia[atual])
4
 i=3
 novadist = 0 + peso[0][3] = 0 + 30 = 30
 distancia 0 1 2 3 4
0 10 ~ 30 ~ (novadist)
 precede 0 1 2 3 4
0 0 (atual)
 menor = 10
 k= 1
Exemplo de execução
 atual = 0 0 1 2 3 4
 fazparte 0 1 2 3 4 0 ~ 10 ~ 30 100
T F F F F 1 ~ ~ 50 ~ ~
 distancia 0 1 2 3 4
0 10 ~ 30 ~ 2 10
 menor = 10 3 20 60
 datual= 0 (distancia[atual])
4
 i=4
 novadist = 0 + peso[0][4] = 0 + 100 = 100
 distancia 0 1 2 3 4
0 10 ~ 30 100 (novadist)
 precede 0 1 2 3 4
0 0 0 (atual)
 menor = 10
 k= 1
Exemplo de execução
 atual = 1 0 1 2 3 4
 fazparte 0 1 2 3 4 0 ~ 10 ~ 30 100
T T F F F 1 ~ ~ 50 ~ ~
 distancia 0 1 2 3 4
2 10
0 10 ~ 30 100
 menor = ~ 3 20 60
 datual = 10 (distancia[atual]) 4
 i=2
 novadist = 10 + peso[1][2] = 10 + 50 = 60
 distancia 0 1 2 3 4
0 10 60 30 100
 precede 0 1 2 3 4
0 1 0 0
 menor = 60
 k= 2
Exemplo de execução
 atual = 1 0 1 2 3 4
 fazparte 0 1 2 3 4 0 ~ 10 ~ 30 100
T T F F F 1 ~ ~ 50 ~ ~
 distancia 0 1 2 3 4
2 10
0 10 60 30 100
 menor = 60 3 20 60
 datual = 10 (distancia[atual]) 4
 i=3
 novadist = 10 + peso[1][3] = 10 + ~ = ~
 distancia 0 1 2 3 4
0 10 60 30 100
 precede 0 1 2 3 4
0 1 0 0
 menor = 60
 k= 2
Exemplo de execução
 atual = 1 0 1 2 3 4
 fazparte 0 1 2 3 4 0 ~ 10 ~ 30 100
T T F F F 1 ~ ~ 50 ~ ~
 distancia 0 1 2 3 4
2 10
0 10 60 30 100
 menor = 30 3 20 60
 datual = 10 (distancia[atual]) 4
 i=4
 novadist = 10 + peso[1][4] = 10 + ~ = ~
 distancia 0 1 2 3 4
0 10 60 30 100
 precede 0 1 2 3 4
0 1 0 0
 menor = 60
 k= 2
Exemplo de execução
 atual = 2 0 1 2 3 4
 fazparte 0 1 2 3 4 0 ~ 10 ~ 30 100
T T T F F 1 ~ ~ 50 ~ ~
 distancia 0 1 2 3 4
2 10
0 10 60 30 100
 menor = ~ 3 20 60
 datual = 60 (distancia[atual]) 4
 i=4
 novadist = 60 + peso[2][4] = 60 + 10 = 70
 distancia 0 1 2 3 4
0 10 60 30 70
 precede 0 1 2 3 4
0 1 0 2
 menor = 70
 k= 4
Exemplo de execução
 atual = 4 (=fim)
 fazparte 0 1 2 3 4
T T T F T
 distancia 0 1 2 3 4
0 10 60 30 70
70 é a menor distância
 Precede 0 1 2 3 4
0 1 0 2
caminho = 0 1 2 4