Algoritmos e Estruturas de Dados (AED, LEE 2º Sem 2015/16) · Teoria de Grafos e Algoritmos em...

46
Algoritmos e Estruturas de Dados LEE – 2015/16 Teoria de Grafos e Algoritmos em Grafos – 2ª Parte Grafos – DFS AED (IST/DEEC) 62 Notar que a estratégia de procura de Tremaux, mais não é que procura em profundidade primeiro. O algoritmo procede sempre abrindo uma porta e afastando- se da origem, até que chega a um ponto em que não pode abrir mais portas, tendo então que recuar até ao último ponto onde deixou, pelo menos, uma porta por abrir. Se ao recuar nunca encontrar portas por abrir, acabará regressando ao ponto de partida, dado que o fio que desenrolou no caminho descendente, lhe permite esse regresso.

Transcript of Algoritmos e Estruturas de Dados (AED, LEE 2º Sem 2015/16) · Teoria de Grafos e Algoritmos em...

Algoritmos e Estruturas de Dados LEE – 2015/16

Teoria de Grafos e Algoritmos em Grafos – 2ª Parte

Grafos – DFS

AED (IST/DEEC) 62

}  Notar que a estratégia de procura de Tremaux, mais não é que procura em profundidade primeiro.

}  O algoritmo procede sempre abrindo uma porta e afastando-se da origem, até que chega a um ponto em que não pode abrir mais portas, tendo então que recuar até ao último ponto onde deixou, pelo menos, uma porta por abrir.

}  Se ao recuar nunca encontrar portas por abrir, acabará regressando ao ponto de partida, dado que o fio que desenrolou no caminho descendente, lhe permite esse regresso.

Grafos – Implementação de DFS (matriz de adjacências)

AED (IST/DEEC) 63

#define dfsR search void dfsR(Graph *G, Edge *e) { int t, w = e->w; pre[w] = cnt++; for (t = 0; t < G->V; t++) if (G->adj[w][t] != 0) if (pre[t] == -1) dfsR(G, EDGE(w, t)); } Função a ser chamada a

partir de uma função de procura genérica (“ADT style”) que inicializa o contador cnt a zero e todas as entradas da tabela indexada pelos vértices pre a –1.

Grafos – Descrição da Implementação

AED (IST/DEEC) 64

}  A tabela pre está associada com as lâmpadas. Se pre[i] valer –1, significa que a luz está apagada para esse vértice.

}  Quando se encontra uma aresta para um vértice em que pre não vale –1, um vértice já visitado, essa aresta não é seguida.

}  Finalmente, a própria estrutura da recursão estabelece o mecanismo equivalente a desenrolar o novelo de fio.

}  Quando um vértice não possui mais vértices adjacentes com pre igual a –1, a chamada recursiva termina, devolvendo o controlo de execução para o vértice que o antecedeu na recursão.

}  O retorno da recursão é equivalente a voltar a enrolar o fio.

#define dfsR search void dfsR(Graph *G, Edge *e) { int t, w = e->w; pre[w] = cnt++; for (t = 0; t < G->V; t++) if (G->adj[w][t] != 0) if (pre[t] == -1) dfsR(G, EDGE(w, t)); }

#define dfsR search void dfsR(Graph *G, Edge *e) { link t; int w = e->w; pre[w] = cnt++; for (t = G->adj[w]; t != NULL; t = t->next) if (pre[t->v] == -1) dfsR(G, EDGE(w, t->v)); }

Grafos – Implementação de DFS (lista de adjacências)

AED (IST/DEEC) 65

Grafos – Comparação

AED (IST/DEEC) 66

}  Na implementação por matriz de adjacências, para cada vértice examinam-se todos as arestas que lhe são incidentes por ordem de numeração dos vértices de saída. }  Avança sempre pelo primeiro (de índex mais baixo) que não tenha sido

visitado e lhe é adjacente.

}  Na implementação por listas de adjacências, são imediatamente considerados os vértices adjacentes e a ordem de inspecção pode não coincidir com a numeração. }  Avança sempre pelo primeiro da lista de adjacências que não tenha sido

ainda visitado.

Grafos – ADT para procura

AED (IST/DEEC) 67

static int cnt, pre[maxV];

void GRAPHsearch(Graph *G)

{

int v;

cnt = 0;

for (v = 0; v < G->V; v++)

pre[v] = -1;

for (v = 0; v < G->V; v++)

if (pre[v] == -1)

search(G, EDGE(v, v));

}

GRAPHsearch é uma função ADT para procura genérica em grafos, realizando os seguintes passos:

Encontra um vértice não marcado. Visita (e marca como visitados) todos os vértices no sub-grafo ligado a que o primeiro vértice pertence.

A função de procura não é especificada a este nível de abstracção.

Grafos – Propriedades da procura

AED (IST/DEEC) 68

}  Propriedade – Uma função de procura em grafos marca cada vértice do grafo se e só se a função de procura que usa marcar cada vértice do sub-grafo ligado que contiver o vértice inicial. }  Demonstração trivial por indução no número de sub-grafos ligados

máximos.

}  Propriedade – A DFS num grafo representado por matriz de adjacências requer um tempo proporcional a V2. }  Cada entrada da matriz de adjacências é inspeccionada uma só vez.

}  Propriedade – A DFS num grafo representado por listas de adjacências requer um tempo proporcional a V + E. }  Inicialização proporcional a V, após o que se fazem V chamadas

recursivas e cada elemento das listas de adjacências é inspeccionado uma só vez.

Grafos – Tabelas indexadas por vértices

AED (IST/DEEC) 69

}  Muitas funções sobre grafos requerem a existência, o uso ou construção de tabelas indexadas pelos vértices dos grafos que processam.

}  Tais tabelas são incluídas em vários níveis de abstracção }  Como variáveis globais – ex: pre em DFS. }  Na representação do próprio grafo – ex: grau de um vértice }  Como parâmetros passados, fornecidos pelos próprios clientes – ex: ao

calcular alguma tabela que seja função dos vértices.

}  A inicialização destas tabelas é tipicamente feita colocando todas as entradas a –1, por forma a poderem paralelamente ser usadas com a mesma utilidade da tabela pre, atrás apresentada.

Grafos - BFS

AED (IST/DEEC) 70

}  Se o objectivo for encontrar o caminho mais curto entre um par de vértices, caso exista, a DFS não é muito útil.

}  A DFS poderá encontrar um caminho, mas não dá garantias de que seja o mais curto, a menos que se determinem todos explicitamente para posterior avaliação.

}  A procura em largura primeiro (“BFS – Breadth First Search”) é baseada exactamente nesse objectivo.

}  Quando temos mais que uma aresta para percorrer, escolhemos uma e guardamos as outras para explorar mais tarde. }  Em DFS usamos uma pilha (LIFO) – avança para longe da entrada

enquanto puder. }  Em BFS usamos um fila (FIFO) – só avança para longe da entrada depois

de ter investigado todos corredores que dela saem.

Grafos – Implementação de BFS (matriz de adjacências)

AED (IST/DEEC) 71

# define bfs search

void bfs(Graph *G, Edge *e)

{

int v;

QUEUEput(e);

while (!QUEUEempty())

if (pre[(e = QUEUEget())->w] == -1)

{

pre[e->w] = cnt++;

st[e->w] = e->v;

for (v = 0; v < G->V; v++)

if (G->adj[e->w][v] == 1)

if (pre[v] == -1)

QUEUEput(EDGE(e->w, v));

}

}

Cria uma fila (FIFO) com todas as arestas incidentes de vértices visitados e de vértices ainda não visitados. Toma a primeira aresta da fila até encontrar uma que aponte para um vértice não visitado. Visita esse vértice, colocando na fila todas as arestas que apontam para vértices não visitados. Tabela st guarda informação sobre o vértice antecessor.

Grafos – Exemplo de execução (BFS)

AED (IST/DEEC) 80

0

5

2

1

3

6 7

4

Grafos – Propriedades da BFS (1)

AED (IST/DEEC) 81

}  Propriedade – Durante a BFS, os vértices entram e saem da fila FIFO por ordem crescente da sua distância ao vértice inicial.

}  Demonstração – Verifica-se uma propriedade mais forte: a fila consiste sempre de zero ou mais vértices distando k passos do vértice inicial, seguidos de zero ou mais vértices distando k+1 passos dos vértice inicial, para algum valor de k. }  É fácil provar esta propriedade por indução.

Grafos – Propriedades da BFS (2)

AED (IST/DEEC) 82

}  Propriedade – A BFS visita todos os vértices e arestas de um grafo em tempo proporcional a V2 para a representação por matriz de adjacências e proporcional a V+E para a representação por listas de adjacências.

}  Demonstração: }  Tal como em DFS, a implementação inspecciona completamente a linha

da matriz de adjacências ou a lista de pares adjacentes associada com cada vértice visitado.

}  Basta mostrar que todos os vértices são visitados. }  Todos os vértices que podem ser alcançados a partir do início estão

}  (i) Na árvore criada pela procura, (ii) na fila, ou (iii) são alcançáveis a partir dos vértices que estão na fila.

}  Todos os vértices se deslocam de (iii) para (ii) e depois para (i), sendo que em cada iteração do ciclo while (i) aumenta a sua cardinalidade.

Grafos – Implementação melhorada de BFS – (matriz de adjacências)

AED (IST/DEEC) 83

void bfs(Graph *G, Edge *e) { int v, w; QUEUEput(e); pre[e->w] = cnt++; while (!QUEUEempty()) { e = QUEUEget(); w = e->w; st[w] = e->v; for (v = 0; v < G->V; v++) if ((G->adj[w][v] == 1) && (pre[v] == -1)) { QUEUEput(EDGE(w, v)); pre[v] = cnt++; } } }

Guarda apenas os vértices por visitar

Grafos – Problemas que BFS resolve

AED (IST/DEEC) 84

}  Caminho mais curto entre v e w }  Tomar v como o vértice inicial e aplicar BFS até que pre[w] deixe de

ser –1.

}  Caminhos mais curtos a partir de um vértice fonte }  Tomar o vértice fonte como inicial e executar a BFS até ao fim.

}  Todos os caminhos mais curtos }  Como a BFS permite encontrar o caminho mais curto de um vértice

inicial para todos os outros, basta aplicar BFS para cada um dos vértices do grafo dado como ponto de partida.

}  A complexidade desta solução é cúbica no número de vértices para representação por matrizes de adjacências.

Grafos – Procura generalizada (1)

AED (IST/DEEC) 85

}  Tanto a DFS como a BFS são casos particulares de procura generalizada em grafos.

}  A implementação da BFS que se apresentou, introduz a pista essencial de resolução de qualquer outro mecanismo de procura. }  Isto é, tudo depende da forma como se inserem novos vértices na fila,

assumindo que se retira sempre o vértice que encabeça a fila.

}  Substitua-se o conceito de fila pelo conceito de “franja”, ou fronteira. }  Todos os vértices que estão na franja são os não visitados, candidatos à

próxima visita.

Grafos – Procura generalizada (GS) (2)

AED (IST/DEEC) 86

}  Assim sendo, a estratégia genérica de procura em grafos é a seguinte: }  Tomar um qualquer vértice como inicial e criar a “franja” colocando lá

esse vértice. }  Enquanto a “franja” não estiver vazia

}  Mover ao longo de uma aresta a partir da “franja”. }  Se o vértice a que se chega não tiver sido visitado, visitá-lo e colocar na

“franja” todos os vértices não visitados que lhe são adjacentes.

}  Esta estratégia garante que todos os vértices de um grafo ligado serão visitados. }  Quando usamos uma pilha para modelar a “franja” temos DFS. }  Quando usamos uma fila, temos BFS.

Grafos – Implementação de procura generalizada – (lista de adjacências)

AED (IST/DEEC) 87

#define pfs search void pfs(Graph *G, Edge *e) { link t; int v, w; GQput(e); pre[e->w] = cnt++; while (!GQempty()) { e = GQget(); w = e->w; st[w] = e->v; for (t = G->adj[w]; t != NULL; t = t->next) if (pre[v = t->v] == -1) { GQput(EDGE(w, v)); pre[v] = cnt++; } else if (st[v] == -1) GQupdate(EDGE(w, v)); } }

Grafos – Propriedade da GS

AED (IST/DEEC) 88

}  Propriedade }  Procura generalizada em grafos visita todos os vértices e arestas de um

grafo num tempo proporcional a V2 para matrizes de adjacências e proporcional a V+E para listas de adjacências;

}  + mais, no pior caso, o tempo necessário para V inserções, V remoções e E actualizações numa fila generalizada de tamanho V.

}  Demonstração }  A primeira parte não depende da implementação da fila generalizada,

pelo que se aplica trivialmente. }  O tempo extra explicitado decorre naturalmente da implementação de

uma fila generalizada.

Grafos Ponderados

AED (IST/DEEC) 90

}  Grafos em que as arestas têm pesos

}  Problemas simples em grafos ponderado com interesse prático:

}  Ligar todos os vértices com o menor custo

}  Obtenção do caminho de menor custo entre vértices (extensível para dígrafos)

Grafos – Árvores mínimas de suporte

AED (IST/DEEC) 91

}  Definição – Uma árvore mínima de suporte (MST) de um grafo ponderado é o conjunto de arestas ligando todos os vértices, tais que a soma dos pesos das arestas é, pelo menos, tão baixa quanto a soma dos pesos de qualquer outro conjunto de arestas ligando todos os vértices.

}  Deverá ser evidente pela definição que estamos apenas interessados em conjuntos de arestas que constituam uma árvore de suporte.

}  Como se mostra que a definição assim o estabelece?

Grafos – Representação de grafos ponderados (1)

AED (IST/DEEC) 92

}  A representação dos pesos associados às arestas em grafos ponderados pode ser feita por: }  A matriz de adjacências deixa de ser booleana, para passar a conter o

valor associado às arestas – requer sentinela para vértices não adjacentes.

}  Cada elemento da lista de adjacências passa a conter um campo adicional com o peso da aresta, para além do campo identificador do vértice.

}  No caso da representação das arestas ter-se-á que adicionar um campo para o peso. }  typedef struct {int v, int w, double wt;} Edge;

}  Edge EDGE(int, int, double); }  Estas definições são incluídas no ficheiro GRAPH.h anteriormente

introduzido.

Grafos - Implementação de ADT (matriz de adjacências)

AED (IST/DEEC) 93

#include <stdlib.h> #include “GRAPH.h” struct graph {int V; int E; double **adj;}; Graph GRAPHinit(int V) { Graph *G = malloc(sizeof (graph *)); G->V = V; G->E = 0; G->adj = MATRIXdouble(V, V, maxWT); return G; } void GRAPHinsertE(Graph *G, Edge *e) { if (G->adj[e->v][e->w] == maxWT) G->E++; G->adj[e->v][e->w] = e->wt; G->adj[e->w][e->v] = e->wt; }

Grafos Ponderados

Grafos – Propriedades das MST (1)

AED (IST/DEEC) 94

}  Propriedade 1 – Dada uma divisão de vértices de um grafo em dois conjuntos, qualquer árvore mínima de suporte (MST) desse grafo contém uma aresta de menor peso que liga um vértice de um dos conjuntos a algum dos vértices do outro.

}  Demonstração }  Por redução ao absurdo. }  Suponha-se que não há ou que não é de menor peso. }  Se não existir, não é uma árvore de suporte. }  Se não for de menor peso, então seja s a aresta de menor peso que liga

vértices dos dois conjuntos. Esta aresta não pertence à MST. }  Adicione-se a aresta s. O grafo obtido possui agora um ciclo e esse ciclo

contém também a aresta t que liga os dois conjuntos. }  Retirando a aresta t obtém-se uma MST de menor peso. Não é?

Grafos – Exemplo (1)

AED (IST/DEEC) 95

1 2

7 6

8

3

G

5 4

1

4

2

6

8

3

G

5

7

Aresta mais curta ligando os vértices amarelos aos verdes.

Grafos – Propriedades das MST (2)

AED (IST/DEEC) 96

}  Propriedade 2 – Dado um grafo G, considere-se o grafo G’ que se obtém adicionando uma aresta e a G. Adicionar e à MST de G e retirar a maior aresta do ciclo assim criado, gera a MST de G’.

}  Demonstração: }  Se e é maior que todos as outras arestas do ciclo, não pode pertencer à

MST de G’ (ver propriedade anterior): retirando e de tal MST partiria o grafo em dois e e não seria a mais curta aresta entre essas duas partes, porque alguma outra aresta do ciclo faz essa ligação e possui menor peso.

}  Caso contrário, seja t a maior aresta do ciclo criado com a adição de e. Retirando t à MST original gera duas partes em que todas as restantes arestas são menores que t.

}  Logo, a menor aresta que liga essas duas partes é a aresta e.

Nova aresta

Grafos – Exemplo (2)

AED (IST/DEEC) 97

1

4

2

6

5 8

3

G

7

As arestas que não pertencem à árvore mínima de suporte são as de maior peso em algum ciclo do grafo original.

1

4

2

7 6

5 8

3

G Árvore Mínima de Suporte

Ciclo Maior aresta do ciclo

Grafos – Síntese da aula 3

AED (IST/DEEC) 98

}  Procura em profundidade - DFS }  Exemplo de execução; Implementação para matrizes de adjacências e

por listas de adjacências; Comparação; Propriedades

}  Procura em largura – BFS }  Implementação por matrizes de adjacências; Exemplo de execução;

Propriedades; Implementação alternativa para matrizes de adjacências

}  Procura generalizada em grafos }  Descrição; Implementação; Propriedades

}  Árvores de suporte mínimas – MST }  Representação e implementação de ADT para grafos ponderados;

Propriedades das MST’s – exemplos

Grafos – Uma solução para a MST

AED (IST/DEEC) 99

}  Ideia 1 – Construir a árvore mínima de suporte adicionando arestas, tais que cada aresta adicionada é a de menor peso de todas as que ligam um vértice que já está na árvore a um outro que ainda não esteja.

}  Este método é conhecido como o Algoritmo de Prim. }  Propriedade – O algoritmo de Prim calcula correctamente a

MST. }  Demonstração – Aplicar a Propriedade1, usando os vértices já

na árvore parcial como o primeiro conjunto e os que não pertencem a essa árvore como o segundo conjunto.

Grafos – Outra solução para a MST

AED (IST/DEEC) 100

}  Ideia 2 – Construir a árvore mínima de suporte adicionando arestas por ordem crescente do seu valor, desde que a nova aresta não forme um ciclo, parando assim que se tiverem adicionado V-1 arestas.

}  Este método é conhecido com o Algoritmo de Kruskal. }  Propriedade – O algoritmo de Kruskal calcula correctamente

a MST. }  Demonstração (esboço)

}  Mostra-se por indução que o método constrói uma floresta de sub-MST’s.

}  Sempre que se adiciona uma aresta que feche um ciclo, só pode ser a maior desse ciclo – Propriedade 2.

}  Caso contrário, a aresta adicionada liga duas árvores e é a menor a fazer essa ligação – Propriedade1.

Grafos – Outra mais...

AED (IST/DEEC) 101

}  Ideia 3 – Começar por ligar cada vértice ao seu vizinho mais próximo, criando, no máximo, V/2 árvores. Depois, ligar cada árvore à outra árvore que lhe estiver mais próxima. Etc.

}  Este método é conhecido como o Algoritmo de Boruvka.

}  Propriedade – O algoritmo de Boruvka calcula correctamente a MST.

}  Demonstração: Cada aresta escolhida é a mais pequena que liga dois conjuntos disjuntos – Propriedade1.

Grafos – Alg. de Prim (1) (Implementação)

AED (IST/DEEC) 102

}  É o algoritmo mais simples de implementar e é a escolha acertada para grafos densos.

}  Constrói-se a árvore adicionando o vértice que estiver mais próximo da árvore já construída.

}  A definição do método aponta para uma implementação de força bruta, que não é aconselhável para que seja eficiente.

}  Através da definição de uma estrutura de dados complementar adequada é possível evitar cálculos excessivos.

}  Precisamos }  Indicação do vértice pai, para cada vértice já na árvore. }  Para cada vértice fora da árvore, indicação de qual o vértice na árvore

que lhe está mais próximo. }  Para cada vértice fora da árvore, qual a distância ao vértice da árvore

mais próximo.

Grafos – Alg. de Prim (2) (Implementação)

AED (IST/DEEC) 103

}  A implementação mais simples daquele conjunto de dados é através de uma tabela indexada pelos vértices.

}  Pode-se usar uma estrutura para representar toda a informação identificada acima. Vamos usar tabelas independentes para maior clareza e generalidade.

}  Para determinar o próximo vértice a adicionar, inspeccionam-se todos os vértices fora da árvore, usando cada um como um índice para a terceira tabela com o objectivo de determinar a sua distância à árvore e saber qual o mais próximo.

}  Quando se adiciona um vértice, v, examina-se cada uma das suas arestas v-w, e se w não estiver na árvore actualiza-se a sua distância à árvore, caso v-w tenha um peso inferior à presente distância de w à árvore.

Grafos – Alg. de Prim (3) (Implementação)

AED (IST/DEEC) 104

static int fr[maxV]; #define P G->adj[v][w] void GRAPHmstV(Graph *G, int st[], double val[]) { int v, w, min; for (v = 0; v < G->V; v++) { st[v] = -1; fr[v] = v; val[v] = maxWT; } min = 0; st[0] = 0; val[G->V] = maxWT; for (v = 0; min != G->V; st[v = min] = fr[v]) for (w = 0, min = G->V; w < G->V; w++) if (st[w] == -1) { if (P < val[w]) {val[w] = P; fr[w] = v;} if (val[w] < val[min]) min = w; } }

fr - frente (franja) provisória de cada nó st - aresta final na MST val - distância provisória do nó à MST min - nó à menor distância da MST

Grafos – Exemplo de execução (1)

AED (IST/DEEC) 105

val[*] ← maxWT Ciclo for interior: v ← 0, st[0] ← 0 0-0 – min ← V st[0] == -1 X ←→ já na árvore 0-1 – adj[0][1] < val[1] ü val[1] ← 4, fr[1] ← 0 val[1] < val[min] ü min ← 1 0-2 – adj[0][2] < val[2] X ←→ não adjacentes 0-3 – adj[0][3] < val[3] ü val[3] ← 3, fr[3] ← 0 val[3] < val[min] ü min ← 3 0-4;5;6;7 – não adjacentes v ← min, st[3] ← fr[3]

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

Grafos – Exemplo de execução (2)

AED (IST/DEEC) 106

Ciclo for interior: v ← min = 3, st[3] ← fr[3] 3-0 – min ← V já na árvore 3-1 – adj[3][1] < val[1] X val[1] < val[min] ü min ← 1 3-2 – adj[3][2] < val[2] ü val[2] ← 6, fr[2] ← 3 val[2] < val[min] X 3-3 – já na árvore 3-4 – adj[3][4] < val[4] ü val[4] ← 2, fr[4] ← 3 val[4] < val[min] ü min ← 4 3-5;6;7 – não adjacentes v ← min, st[4] ← fr[4]

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

Grafos – Exemplo de execução (3)

AED (IST/DEEC) 107

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

Grafos – Árvore de procura (Alg. Prim)

AED (IST/DEEC) 108

0

3

1 3

4

4 5 6 7 ∞ ∞ ∞ ∞

2 ∞

6 2

6 3

4

3

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

Grafos – Árvore de procura (Alg. Prim)

AED (IST/DEEC) 116

0

3

1

2

4

3

5 6

7

2

6 3

4

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

4 3

Ordem de entrada do verticas na MST: 0, 3, 4, 6, 1, 7, 2, 5

Grafos – Exemplo com tabela

AED (IST/DEEC) 117

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0 1 2 3 4 5 6 7

2 ∞/2 ∞/2 6/2 ∞/2 ∞/2 7/2 3/2

}  Tomando o vértice 2 como ponto de partida }  Legenda – val/fr

Grafos – Exemplo com tabela

AED (IST/DEEC) 118

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0 1 2 3 4 5 6 7

2 ∞/2 ∞/2 6/2 ∞/2 ∞/2 7/2 3/2

7 ∞/2 ∞/2 6/2 ∞/2 ∞/2 4/7

}  Tomando o vértice 2 como ponto de partida }  Legenda – val/fr

Grafos – Exemplo com tabela

AED (IST/DEEC) 119

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0 1 2 3 4 5 6 7

2 ∞/2 ∞/2 6/2 ∞/2 ∞/2 7/2 3/2

7 ∞/2 ∞/2 6/2 ∞/2 ∞/2 4/7

6 ∞/2 ∞/2 6/2 3/6 7/6

}  Tomando o vértice 2 como ponto de partida }  Legenda – val/fr

Grafos – Exemplo com tabela

AED (IST/DEEC) 120

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0 1 2 3 4 5 6 7

2 ∞/2 ∞/2 6/2 ∞/2 ∞/2 7/2 3/2

7 ∞/2 ∞/2 6/2 ∞/2 ∞/2 4/7

6 ∞/2 ∞/2 6/2 3/6 7/6

4 ∞/2 ∞/2 2/4 6/4

}  Tomando o vértice 2 como ponto de partida }  Legenda – val/fr

Grafos – Exemplo com tabela

AED (IST/DEEC) 121

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0 1 2 3 4 5 6 7

2 ∞/2 ∞/2 6/2 ∞/2 ∞/2 7/2 3/2

7 ∞/2 ∞/2 6/2 ∞/2 ∞/2 4/7

6 ∞/2 ∞/2 6/2 3/6 7/6

4 ∞/2 ∞/2 2/4 6/4

3 3/3 5/3 6/4

}  Tomando o vértice 2 como ponto de partida }  Legenda – val/fr

Grafos – Exemplo com tabela

AED (IST/DEEC) 122

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0 1 2 3 4 5 6 7

2 ∞/2 ∞/2 6/2 ∞/2 ∞/2 7/2 3/2

7 ∞/2 ∞/2 6/2 ∞/2 ∞/2 4/7

6 ∞/2 ∞/2 6/2 3/6 7/6

4 ∞/2 ∞/2 2/4 6/4

3 3/3 5/3 6/4

0 4/0 6/4

}  Tomando o vértice 2 como ponto de partida }  Legenda – val/fr

Grafos – Exemplo com tabela

AED (IST/DEEC) 123

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0 1 2 3 4 5 6 7

2 ∞/2 ∞/2 6/2 ∞/2 ∞/2 7/2 3/2

7 ∞/2 ∞/2 6/2 ∞/2 ∞/2 4/7

6 ∞/2 ∞/2 6/2 3/6 7/6

4 ∞/2 ∞/2 2/4 6/4

3 3/3 5/3 6/4

0 4/0 6/4

1 6/4

}  Tomando o vértice 2 como ponto de partida }  Legenda – val/fr

Grafos – Exemplo com tabela

AED (IST/DEEC) 124

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0 1 2 3 4 5 6 7

2 ∞/2 ∞/2 6/2 ∞/2 ∞/2 7/2 3/2

7 ∞/2 ∞/2 6/2 ∞/2 ∞/2 4/7

6 ∞/2 ∞/2 6/2 3/6 7/6

4 ∞/2 ∞/2 2/4 6/4

3 3/3 5/3 6/4

0 4/0 6/4

1 6/4

5

}  Tomando o vértice 2 como ponto de partida }  Legenda – val/fr

Ordem de entrada do verticas na MST: 2, 7, 6, 4, 3, 0, 1, 5

Grafos – Alg. de Prim (Propriedade)

AED (IST/DEEC) 125

}  Propriedade – Com o algoritmo de Prim, pode-se determinar a MST de um grafo denso em tempo linear.

}  Demonstração: }  A simples observação do código permite concluir que o tempo de

execução é proporcional a V2, pelo que é linear para grafos densos. }  Cada vez que se visita um vértice, uma passagem pelos vértices fora da

árvore serve o objectivo duplo de actualizar a distância mínima de cada vértice à árvore e de determinar qual está mais próximo. i.e., qual o próximo a visitar.

}  Descrição: }  Deslocar a aresta mais pequena da franja para a árvore. Visitar o vértice

a que conduz e colocar na franja todas as arestas que dele saem para vértices não visitados, substituindo a aresta mais comprida quando duas arestas da franja apontam para o mesmo vértice.

Grafos – Alg. de Kruskal (1) (Implementação)

AED (IST/DEEC) 126

}  O algoritmo de Prim adiciona uma aresta de cada vez a uma única árvore em construção.

}  O algoritmo de Kruskal também adiciona uma aresta de cada vez, mas possui várias pequenas árvores que se vão agregando à medida que a execução evolui.

}  Tem início numa floresta de V árvores – uma por vértice – e termina quando apenas existe uma árvore – a árvore mínima de suporte.

}  Há que ordenar as arestas com um qualquer algoritmo de ordenação e posteriormente utilizar um dos algoritmos discutidos para o problema da conectividade.

Grafos – Alg. de Kruskal (1) (Implementação)

AED (IST/DEEC) 127

void GRAPHmstE(Graph *G, Edge mst[]) { int i, k; Edge a[maxE]; int E = GRAPHedges(a, G); sort(a, 0, E-1); UFinit(G->V); for (i = 0, k = 0; i < E && k < G->V-1; i++) if (!UFfind(a[i].v, a[i].w)) { UFunion(a[i].v, a[i].w); mst[k++] = a[i]; } }

1.  Ordenação do vector de arestas, a. 2. Criação de V conjuntos com um vértice cada. 3. Se a menor aresta ainda não incluída não ligar dois pares que já estão ligados, inclui-la na árvore.

Grafos – Exemplo de execução (1)

AED (IST/DEEC) 128

Ordenação das arestas: <(3,4); (2,7); (0,3); (4,6); (0,1); (6,7); (1,3); (2,3); (4,5); (5,6); (2,6)>

Partição inicial: {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}

i ← 0; k ← 0 a[i].v = 3; a[i].w = 4 {{0}, {1}, {2}, {3, 4}, {5}, {6}, {7}} mst[k] ← (3,4) k ← 1 i ← 1 a[i].v = 2; a[i].w = 7 {{0}, {1}, {2, 7}, {3, 4}, {5}, {6}} mst[k] ← (2,7) k ← 2

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

Grafos – Exemplo de execução (2)

AED (IST/DEEC) 129

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

0

3

1

6 5

4 7

2

G

3

4

5

2

6

6 7

3

7

3

4

Grafos – Alg. de Kruskal (Propriedade)

AED (IST/DEEC) 130

}  Propriedade – O algoritmo de Kruskal calcula a MST de um grafo num tempo proporcional a ElgE.

}  Demonstração }  Esta propriedade é consequência do facto de o tempo de execução

incluir uma ordenação de E arestas seguida de E operações procura e V-1 operações de união. }  PORQUÊ?

}  Se utilizarmos os melhores algoritmos para cada uma das operações identificadas, tais como “mergesort” para a ordenação e procura-união ponderada com compressão de caminho para a conectividade, o custo da ordenação domina.

Grafos – Alg. de Boruvka (1) (Implementação)

AED (IST/DEEC) 131

}  Tal como o algoritmo de Kruskal, este algoritmo constrói a MST adicionando arestas a uma floresta de sub-árvores, todas elas MST’s.

}  A diferença reside no facto de a adição se processar em fases, em que para cada fase se adicionam várias arestas.

}  Em cada fase determinam-se as arestas mais curtas que ligam cada sub-árvore com outra.

}  Em seguida adicionam-se todas essas arestas. }  Mais uma vez, as funções elementares procura e união serão

cruciais para uma implementação eficiente.

Grafos – Alg. de Boruvka (2) (Implementação)

AED (IST/DEEC) 132

}  Torna-se necessário permitir que a função de procura seja ligeiramente alterada para que associe um índice com cada uma das sub-árvores.

}  Assim sendo, mantém-se uma tabela indexada por vértices indicando, para cada sub-árvore, qual a sua vizinha mais próxima.

}  De seguida executam-se as seguintes operações em cada aresta do grafo: }  Se ligar dois vértices na mesma árvore, ignorá-la. }  Caso contrário, verificar as distâncias do vizinho mais próximo de cada

uma das árvores, actualizando-se se apropriado.

Grafos – Alg. de Boruvka (3) (Implementação)

AED (IST/DEEC) 133

}  Depois de fazer esta avaliação, a tabela dos vizinhos mais próximos contém a informação necessária para ligar sub-árvores.

}  Para índice dos vértices faz-se uma união, ligando os seus vizinhos mais próximos.

}  Em seguida, retiram-se as arestas mais longas que ligam outros pares de vértices nos pares de árvores MST ligadas.

Grafos – Alg. de Boruvka (4) (Implementação)

AED (IST/DEEC) 134

Edge nn[maxV]; void GRAPHmstE(Graph *G, Edge mst[]) { int h, i, j, k, v, w, N; Edge e, a[maxE]; int E = GRAPHedges(a, G); for (UFinit(G->V); E != 0; E = N) { for (k = 0; k < G->V; k++) nn[k] = EDGE(G->V, G->V, 1.0); for (h = 0, N = 0; h < E; h++) { i = find(a[h].v); j = find(a[h].w); if (i == j) continue; if (a[h].wt < nn[i].wt) nn[i] = a[h]; if (a[h].wt < nn[j].wt) nn[j] = a[h]; ...

1. Tabela dos vizinhos mais próximos, nn.

2.  Criação de tabela de arestas, a.

3.  Inicialização da distância aos vizinhos.

4. Determinação da sub-árvore a que pertencem as arestas.

5. Cálculo do vizinho mais próximo.

Grafos – Alg. de Boruvka (5) (Implementação)

AED (IST/DEEC) 135

... a[N++] = a[h]; } for (k = 0; k < G->V; k++) { e = nn[k]; v = e.v; w = e.w; if ((v != G->V) && !UFfind(v, w)) { UFunion(v, w); mst[k] = e; } } } }

6. Deita fora de a as arestas que ligam vértices na mesma sub-árvore!!!

7. Funde duas sub-árvores, se ainda não associadas, usando a aresta mais curta, e.

Grafos – Alg. de Boruvka (Propriedade)

AED (IST/DEEC) 136

}  Propriedade – O algoritmo de Boruvka calcula a MST de um grafo num tempo inferior a E lgV lg*V.

}  Demonstração: }  Dado que o número de sub-árvores na floresta se reduz, pelo menos, a

metade em cada fase, o número de fases não é maior que lg V. }  O tempo de cada fase é, no máximo, proporcional ao custo de E

operações de procura.

}  Observações: }  A expressão acima é bastante conservadora, na medida em que ignora a

redução de arestas ocorrida em cada fase. }  Concebido em 1926 e desde os anos 80 a base para o desenvolvimento

de algoritmos eficientes para MST’s, assim como para algoritmos paralelos

Grafos – Comparação dos métodos (1)

AED (IST/DEEC) 137

Algoritmo Pior caso Comentário

Prim (padrão) V2 Óptimo para grafos densos

Prim (com PFS)* E lg V Pior caso conservador

Kruskal (padrão) E lg E Custo de ordenação domina

Kruskal (ord. parcial)* E + X lg V Depende da aresta maior

Boruvka E lg V Pior caso muito conservador

* Variantes não discutidas * PFS – Priority-First Search * ord. parcial – evitar ordenar todas as arestas, dado que podem não ser necessárias (via heapsort, por exemplo).

Grafos – Comparação dos métodos (2)

AED (IST/DEEC) 138

E V H P K K* e/E B e/E

Densidade - 2

20000 10000 22 9 11 1.00 14 3.30

50000 25000 69 24 31 1.00 38 3.30

100000 50000 169 49 66 1.00 89 3.80

200000 100000 389 108 142 1.00 189 3.60

Densidade - 20

20000 1000 5 20 6 5 0.20 9 4.20

50000 2500 12 130 16 15 0.28 25 4.60

100000 5000 27 34 31 0.30 55 4.60

200000 10000 61 73 68 0.35 123 5.00

Densidade - 100

100000 1000 17 24 30 19 0.06 51 4.60

250000 2500 44 130 81 53 0.05 143 5.20

500000 5000 93 181 113 0.06 312 5,50

1000000 10000 204 377 218 0.06 658 5,60

Densidade – V/2.5

400000 1000 60 20 137 78 0.02 188 4.50

2500000 2500 409 128 1056 687 0.01 1472 5.50

H: Prim – lista de adjacências/Heapsort P: Prim – matriz de adjacências K: Kruskal K*: Kruskal – com ordenação parcial B: Boruvka e/E: arestas examinadas (uniões)

Grafos – Síntese da aula 4

AED (IST/DEEC) 139

}  Árvores de suporte mínimas – MST }  Propostas de solução para cálculo de MST’s

}  Algoritmo de Prim }  Descrição; Implementação; Exemplo de execução; Análise de eficiência

}  Algoritmo de Kruskal }  Descrição; Implementação; Exemplo de execução; Análise de eficiência

}  Algoritmo de Boruvka }  Descrição; Implementação; Exemplo de execução; Análise de eficiência

}  Comparação dos três métodos

Caminhos em Grafos

AED (IST/DEEC) 140

}  Caminho simples }  Dados dois vértices num grafo, saber se estão ligados por um caminho; }  Determinar se o caminho existe ou calculá-lo explicitamente;

}  Caminho de Hamilton }  Dados dois vértices num grafo, saber se existe um caminho que visite

todos os vértices do grafo exactamente uma vez; }  Determinar se o caminho existe ou calculá-lo explicitamente;

}  Caminho de Euler }  Dados dois vértices num grafo, saber se existe um caminho simples que

use todas as arestas do grafo exactamente uma vez; }  Determinar se o caminho existe ou calculá-lo explicitamente.

Grafos - Caminho Simples (Cliente para M. de Adj.)

AED (IST/DEEC) 141

static int visited[maxV]; int GRAPHpath(Graph *G, int v, int w) { int t; for (t = 0; t < G->V; t++) visited[t] = 0; return pathR(G, v, w); } int pathR(Graph *G, int v, int w) { int t; if (v == w) return 1; visited[v] = 1; for (t = 0; t < G->V; t++) if (G->adj[v][t] == 1) if (visited[t] == 0) if (pathR(G, t, w)) return 1; return 0; }

Grafos - Descrição do algoritmo

AED (IST/DEEC) 142

}  Suporta-se num esquema de procura em profundidade primeiro – “depth first search”.

}  A partir de v, encontrando um primeiro vértice adjacente, t, chama-se recursivamente tentando encontrar w a partir de t.

}  O vector visited serve para garantir uma só visita a cada vértice.

Grafos - Exemplo de execução (1)

AED (IST/DEEC) 143

0

3

1

6 5

4 7

2

G

Chamada à função para determinar a existência de caminho entre os vértices 1 e 4 GRAPHpath(G, 1, 4)

0

3

1

6 5

4 7

2

G

Grafos - Exemplo de execução (2)

AED (IST/DEEC) 150

}  Sequência de chamadas a “pathR”

1-0 pathR(G, 0, 4) pathR(G, 1, 4)

0-0;1 (0 e 1 já visitados) 0-2 (não adjacentes)

3-0;1 (0 e 1 já visitados)

2-0;1 (não adjacentes)

0-3 pathR(G, 3, 4)

3-2 pathR(G, 2, 4)

2-2 (já visitado) ...

0

3

1

6 5

4 7

2

G

Grafos - Exemplo de execução (3)

AED (IST/DEEC) 151

}  Sequência de chamadas a “pathR”

... 2-3 (3 já visitado) 2-4;5 (não adjacentes)

6-0;1 (não adjacentes) 6-2 (2 já visitado) 6-3 (não adjacentes)

2-6 pathR(G, 6, 4)

6-4 pathR(G, 4, 4)

Grafos - Análise de Complexidade (1)

AED (IST/DEEC) 152

}  Número de execuções de if (G->adj[v][t]==1) para v? for (t = 0; t < G->V; t++)

}  Ou seja, V vezes no pior caso para cada v.

}  Número de execuções de if (visited[t]==0) para v? for (t = 0; t < G->V; t++) if (G->adj[v][t] == 1)

}  Ou seja, sempre que v e t forem adjacentes. No pior caso, V vezes.

Grafos - Análise de Complexidade (2)

AED (IST/DEEC) 153

}  Quantas chamadas a pathR para cada v? for (t = 0; t < G->V; t++) if (G->adj[v][t] == 1) if (visited[t] == 0)

}  Ou seja, para adjacentes de v ainda não visitados. No pior caso, V vezes.

}  Número total de chamadas a “pathR” não é superior a V. }  Porquê?

Grafos - Análise de Complexidade (3)

AED (IST/DEEC) 154

}  Discussão anterior centrou-se na representação por matriz de adjacências.

}  Para listas de adjacências, o teste if (G->adj[v][t] == 1)

}  é substituído pelo teste de fim de lista de adjacentes de v executado, no pior caso, grau(v) vezes; }  grau(v) ≤ V

}  Para todos os vértices, no pior caso, é executado Σv grau(v) = 2E.

}  Tudo o mais permanece.

Grafos - Análise de Complexidade (4)

AED (IST/DEEC) 155

}  Na representação por matrizes de adjacência, o algoritmo tem um tempo de execução da ordem de V2. }  Porquê?

}  Na representação por listas de adjacências, o algoritmo tem um tempo de execução da ordem de E. }  Porquê?

}  Em síntese: }  Pode-se determinar um caminho ligando dois vértices dados de um

grafo em tempo linear.

Grafos - Análise de Complexidade (5)

AED (IST/DEEC) 156

}  Tempo linear significa:

}  tempo proporcional a V2 para matrizes de adjacência;

}  tempo proporcional a E para listas de adjacências.

}  Que representação preferir para este problema?

}  Se o grafo for denso, preferir a solução por matriz de adjacências.

}  Se o grafo for esparso, preferir a solução por listas de adjacências.

Grafos - Caminho de Hamilton (1) Cliente para M. de Adj.

Caminho simples

AED (IST/DEEC) 157

static int visited[maxV]; int pathR(Graph *G, int v, int w, )

{ int t; if (v == w) return 1; visited[v] = 1; for (t = 0; t < G->V; t++) if (G->adj[v][t] == 1) if (visited[t] == 0) if (pathR(G, t, w, )) return 1; return 0; }

int GRAPHpath (Graph *G, int v, int w)

{ int t; for (t = 0; t < G->V; ++t) visited[t] = 0; return pathR(G, v, w, ); }

Caminho de Hamilton

AED (IST/DEEC) 158

static int visited[maxV]; int pathR(Graph *G, int v, int w, int d)

{ int t; if (v == w) {if (d == 0) return 1; else return 0;} visited[v] = 1; for (t = 0; t < G->V; t++) if (G->adj[v][t] == 1) if (visited[t] == 0) if (pathR(G, t, w, d-1)) return 1; visited[v] = 0; return 0; }

int GRAPHpathH(Graph *G, int v, int w)

{ int t; for (t = 0; t < G->V; ++t) visited[t] = 0; return pathR(G, v, w, G->V-1); }

Grafos - Caminho de Hamilton (2) Cliente para M. de Adj.

Grafos - Exemplo de execução (1)

AED (IST/DEEC) 159

0

1

2

4

3

G

}  Chamada à função para determinar a existência de caminho de Hamilton entre os vértices 0 e 4

GRAPHpathH(G, 0, 4)

AED (IST/DEEC) 160

}  Sequência de chamadas a “pathR” pathR(G, 0, 4, 4) 0-0 (0 visitado)

0-1 pathR(G, 1, 4, 3) 1-0; 1 (já visitados) 1-2 pathR(G, 2, 4, 2) 2-0; 1; 2 (já visitados) 2-3;4 (não adjacentes)

(sai limpando 2)

1-3 pathR(G, 3, 4, 2) 3-0 (não adjacentes) 3-1 (já visitado)

3-2 (não adjacentes)

3-3 (já visitado) (...)

0

1

2

4

3

G

Grafos - Exemplo de execução (2)

AED (IST/DEEC) 161

}  Sequência de chamadas a “pathR” (...)

3-4 pathR(G, 4, 4 1)

(d != 0) (sai limpando 4)

(sai limpando 3) 1-4 (não adjacente) (sai limpando 1)

0-2 pathR(G, 2, 4, 3)

2-0 (já visitado) 2-1 pathR(G, 1, 4, 2) 1-0;1;2 (já visitados)

1-3 pathR(G, 3, 4, 1)

3-0 (não adjacente) (...)

0

1

2

4

3

G

Grafos - Exemplo de execução (3)

AED (IST/DEEC) 162

}  Sequência de chamadas a “pathR” (...)

3-1 (já visitado)

3-2 (não adjacentes) 3-3 (já visitado) 3-4 pathR(G, 4, 4, 0) (d == 0, caminho encontrado)

(...)

Caminho encontrado!!!

0

1

2

4

3

G

Grafos - Exemplo de execução (4)

Grafos - Análise de Complexidade

AED (IST/DEEC) 163

}  Propriedade – A procura recursiva por um caminho de Hamilton pode levar tempo exponencial.

}  Esboço de Demonstração }  Considere-se um grafo em que o vértice V-1 está isolado e os restantes

V-1 vértices formam um sub-grafo completo. }  O programa nunca conseguirá encontrar um caminho de Hamilton

(Porquê?). }  No entanto, por indução pode-se estabelecer que examinará todos os

(V-1)! caminhos no sub-grafo completo e em todos eles executará V-1 chamadas recursivas a “graphR”.

}  Logo, o número total de chamadas recursivas é da ordem de V!, ou da ordem de (V/e)V, o que é superior a qualquer polinómio em V.

Grafos – Discussão (1)

AED (IST/DEEC) 164

}  Como é que dois problemas tão próximos no seu enunciado e dois programas tão próximos na sua estrutura, possuem complexidades tão distintas?

}  Quando se procura um caminho simples sabemos que, se existe um caminho entre os vértices v e w, ele é encontrado a partir de algum t adjacente a v.

}  O mesmo é verdade para caminhos de Hamilton.

}  Se não encontrarmos um caminho simples entre t e w, sabemos que não existe um caminho simples entre v e w que passe por t.

Grafos – Discussão (2)

AED (IST/DEEC) 165

}  Para caminhos de Hamilton, pode não existir um caminho que comece por v-t, mas pode existir um caminho que comece por v-x-t, para algum outro vértice x (daí termos de desmarcar vértices visitados).

}  Logo, teremos que executar uma chamada recursiva a partir de t para todos os caminhos possíveis originados em v e que passam em t.

}  O que é o mesmo que dizer que poderemos ter que investigar todos os caminhos possíveis no grafo.

Grafos - Caminhos e Ciclos de Euler (1)

AED (IST/DEEC) 166

}  Propriedade – Um grafo ligado possui um caminho de Euler entre o vértice v e o vértice w se e só se v e w têm grau ímpar e todos os outros vértices têm grau par.

}  Demonstração }  Prova-se por indução no número de arestas.

}  Claramente, o resultado é verdadeiro para um grafo com dois vértices e uma só aresta ligando-os.

}  Seja G um grafo ligado com mais que uma aresta.

}  Existe um caminho de Euler entre v e w se e só se existir um vértice t, adjacente de v, para o qual exista um caminho de Euler até w no grafo G* (G* obtém-se de G removendo a aresta que liga v a t);

Grafos - Caminhos e Ciclos de Euler (2)

AED (IST/DEEC) 167

}  Demonstração (continuação) }  Pela hipótese de indução, existe um caminho de Euler em G* se e só se

todos os vértices têm grau par excepto t e w, que têm grau ímpar.

}  Se existir um caminho de Euler entre t e w em G*, adicionando uma aresta entre v e t faz com que t tenha grau par e com que v tenha grau ímpar, sem afectar o grau dos restantes vértices.

}  Logo, o resultado fica estabelecido.

Grafos - Caminhos e Ciclos de Euler (3)

AED (IST/DEEC) 168

}  Demonstração (continuação) }  Se não existir um caminho de Euler entre t e w em G*, então é porque

}  t tem grau par - (de grau ímpar em G), ou }  w tem grau par - (também de grau par em G), ou }  v tem grau ímpar - (de grau par em G), ou }  outro vértice tem grau ímpar - (também de grau ímpar em G).

}  Em qualquer dos casos, violando a condição enunciada.

Grafos - Caminhos e Ciclos de Euler (4)

AED (IST/DEEC) 169

}  Propriedade – Um grafo ligado possui um ciclo de Euler se e só se todos os seus vértices tiverem grau par.

}  Demonstração }  Consequência imediata da propriedade anterior e do argumento

utilizado na sua demonstração.

}  Grau dos vértices }  Tempo proporcional a E para listas de adjacências. }  Tempo proporcional a V2 para matrizes de adjacências. }  Ou mantém-se uma tabela indexada pelos vértices com o grau de cada

vértice.

Grafos - Caminhos e Ciclos de Euler (5)

AED (IST/DEEC) 170

}  Neste último caso, determinar se existe ou não um caminho ou ciclo de Euler pode ser feito em tempo proporcional a V.

}  Sendo fácil saber se existe, será que é fácil calculá-lo como nos caminhos simples ou será que é tão difícil como com os caminhos de Hamilton?

}  Examinando a demonstração }  Qualquer aresta cuja remoção mantenha o grafo ligado pode ser a

primeira aresta de um caminho de Euler. }  Encontrando uma primeira aresta nestas condições, aplica-se o conceito

recursivamente.

Grafos – Problemas em grafos

AED (IST/DEEC) 171

}  Estes três exemplos servem para ilustrar a gama de variabilidade que pode existir em problemas com grafos. }  Problemas aparentemente iguais com diferentes complexidades. }  Problemas aparentemente complexos com soluções simples.

}  Categorias em termos de complexidade }  Simples, Tratáveis, Intratáveis, Desconhecida.

}  Exemplos de problemas (ver discussão no livro) }  Conectividade simples, conectividade forte em digrafos, fecho transitivo,

árvores mínimas de suporte, caminhos mais curtos com uma única origem, planaridade, emparelhamento, alocação, caminho mais comprido, coloração, conjuntos independentes, cliques, isomorfismo, ciclos de tamanho par em digrafos.

Grafos – Complexidade dos Problemas (1)

AED (IST/DEEC) 172

}  Grafos não direccionados }  Conectividade S }  Conectividade geral T }  Ciclo de Euler S }  Ciclo de Hanilton I }  Emparelhamento em grafos bipartidos S }  Emparelhamento máximo T }  Planaridade T }  Clique máxima I }  Bi-coloração S }  Tri-coloração I }  Caminhos mais curtos S }  Caminhos mais compridos I }  Cobertura de vértices I }  Isomorfismo ?

Grafos – Complexidade dos Problemas (2)

AED (IST/DEEC) 173

}  Digrafos }  Fecho transitivo S }  Conectividade forte S }  Ciclos ímpares S }  Ciclos pares ?

}  Grafos ponderados }  Árvore mínima de suporte S }  Caixeiro viajante I

}  Redes }  Caminhos mais curtos S }  Ciclos negativos I }  Fluxo da rede S }  Atribuição T }  Fluxo de custo mínimo T

Grafos – Síntese da aula 5

AED (IST/DEEC) 174

}  Caminhos em grafos }  Caminhos simples, caminhos de Hamilton e caminhos de Euler

}  Caminhos Simples }  Implementação; Descrição da implementação; Exemplo de execução;

Análise de complexidade

}  Caminhos de Hamilton }  Implementação; Descrição da implementação; Exemplo de execução;

Análise de complexidade

}  Caminhos e Ciclos de Euler }  Caracterização dos grafos que possuem caminho e ciclos de Euler

}  Problemas em grafos }  Síntese de complexidade de alguns problemas em grafos