CES11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Prticas

  • Slides: 19
Download presentation
CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas - 2019 Capítulo V Grafos

CES-11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Práticas - 2019 Capítulo V Grafos

n O presente trabalho corresponde ao laboratório do Exame de CES-11/2019 n Além deste

n O presente trabalho corresponde ao laboratório do Exame de CES-11/2019 n Além deste trabalho, o referido exame terá ainda uma prova feita em sala de aula n Para compor a nota do Exame, o peso do trabalho será igual ao peso da prova

Objetivos deste laboratório: 1. Ler de um arquivo os dados de um digrafo e

Objetivos deste laboratório: 1. Ler de um arquivo os dados de um digrafo e armazena-los numa estrutura de listas de adjacências O digrafo deve ter uma informação inteira e positiva em cada um de seus arcos (custo) Cada um dos vértices do digrafo deve ter um campo para indicar se já foi ou não visitado, e outro campo para o número de visitação, campos estes a serem usados em eventuais buscas em profundidade 2. Escrever na tela sua estrutura de listas de

3. Encontrar e escrever na tela, usando o algoritmo de Dijkstra, os caminhos mais

3. Encontrar e escrever na tela, usando o algoritmo de Dijkstra, os caminhos mais baratos e os respectivos custos do vértice 1 para todos os outros vértices 4. Encontrar e escrever na tela os vértices e os arcos de cada um de seus componentes fortemente conexos 5. Transformá-lo num grafo não-orientado e escrever na tela sua nova estrutura de listas de adjacências; para isso Eliminar os arcos de um vértice para si mesmo

6. Verificar se o grafo resultante do passo anterior é conexo 7. Se for

6. Verificar se o grafo resultante do passo anterior é conexo 7. Se for conexo, encontrar e escrever na tela, usando o algoritmo de Prim, todos os arcos de uma de suas árvores de cobertura de custo mínimo Calcular o valor desse custo. 8. Estender os passos anteriores para vários digrafos lidos

Exercício 5. 1: Leitura e armazenamento de digrafos Fazer um programa para: n Ler

Exercício 5. 1: Leitura e armazenamento de digrafos Fazer um programa para: n Ler de um arquivo os dados sobre um digrafo com informações inteiras e positivas em seus arcos (custos) n Armazenar o digrafo numa estrutura de listas de adjacências n Escrever na tela todo o conteúdo de sua estrutura de listas de adjacências

Declarações para digrafos: 1 12 7 3 2 typedef 13 int vertice; 20 struct

Declarações para digrafos: 1 12 7 3 2 typedef 13 int vertice; 20 struct Celula. Adj; 5 struct Celula. Vertice; struct Grafo; struct Celula. Adj { vertice vert; int custo; Celula. Adj *prox; }; visit nvisit 1 -1 -1 2 12 2 -1 -1 5 20 ● 3 -1 -1 1 7 4 -1 -1 5 10 ● 5 -1 -1 G Espaco. Vertices 15 12 4 10 4 15 ● 4 12 ● 3 13 ● nvert 5 conexo -1

struct Celula. Vertice { A serem logic visit; preenchidos em busca prof int nvisit;

struct Celula. Vertice { A serem logic visit; preenchidos em busca prof int nvisit; Celula. Adj *listadj; A ser alocado }; dinamicamente (malloc) 1 12 7 3 2 struct Grafo { Celula. Vertice *Espaco. Vertices; int nvert; logic conexo; visit nvisit }; 1 -1 -1 A ser preenchido 2 -1 -1 mais adiante /* Variaveis 3 -1 -1 globais */ 4 -1 -1 Grafo G; 5 -1 -1 FILE *filein; G Espaco. Vertices 15 4 10 13 20 12 5 2 12 4 15 ● 5 20 ● 1 7 4 12 ● 5 10 ● 3 13 ● nvert 5 conexo -1

/* Prototipos de funcoes */ void Ler. Grafo (Grafo *); void Escrever. Grafo (Grafo

/* Prototipos de funcoes */ void Ler. Grafo (Grafo *); void Escrever. Grafo (Grafo *); /* Programa Principal: */ int main () { /* Leitura e escrita do grafo */ filein = fopen ("Dados. Grafo. dat", "r"); Ler. Grafo (&G); printf ("n. Grafo G em fase inicialn"); Escrever. Grafo (&G); printf ("nn"); system ("pause"); return 0; }

Exemplo: para o digrafo Possível arquivo de entrada: 5 1 2 12 1 4

Exemplo: para o digrafo Possível arquivo de entrada: 5 1 2 12 1 4 15 2 5 20 3 1 7 3 4 12 4 5 10 5 3 13 6 3 20 -1 4 20 2 4 0 1 4 40 0 Encerra a leitura quando o primeiro vértice for zero 1 12 7 3 2 Número de vértices 2 12 2 -1 -1 5 20 ● 3 -1 -1 1 7 4 -1 -1 5 10 ● 5 -1 -1 G Espaco. Vertices 4 5 Arcos: 2 vértices e custo 1 -1 -1 12 10 13 20 visit nvisit 15 4 15 ● 4 12 ● 3 13 ● nvert 5 conexo -1

Exemplo: para o digrafo Possível arquivo de entrada: 5 1 2 12 1 3

Exemplo: para o digrafo Possível arquivo de entrada: 5 1 2 12 1 3 7 1 4 15 2 5 20 3 4 12 3 5 13 4 5 10 6 3 20 -1 4 20 2 4 0 1 4 40 0 Arcos errados e repetidos: 1 12 7 3 2 Devem ser ignorados 2 12 2 -1 -1 5 20 ● 3 -1 -1 1 7 4 -1 -1 5 10 ● 5 -1 -1 G Espaco. Vertices 4 5 Não encerrar o programa se aparecerem 1 -1 -1 12 10 13 20 visit nvisit 15 4 15 ● 4 12 ● 3 13 ● nvert 5 conexo -1

Possível saída na tela: visit nvisit 1 -1 -1 G 2 12 4 2

Possível saída na tela: visit nvisit 1 -1 -1 G 2 12 4 2 -1 -1 5 20 3 -1 -1 1 7 4 -1 -1 5 10 ● 5 -1 -1 3 13 ● Espaco. Vertices nvert 5 15 1 ● 12 ● 4 12 ● 20 conexo -1 7 3 2 15 12 10 13 5 4

Exercício 5. 2: Construção da lista de contraadjacências de cada vértice (substitui o digrafo

Exercício 5. 2: Construção da lista de contraadjacências de cada vértice (substitui o digrafo reverso) n Contra-adjacente de um vértice v é um vértice do qual v é adjacente n No programa anterior: Acrescentar o campo listcontradj ao tipo Celula. Vertice struct Celula. Vertice { logic visit; int nvisit; Celula. Adj *listadj, *listcontradj; };

Exemplo: no digrafo anterior 1 12 7 2 nvisit 1 -1 -1 sua estrutura

Exemplo: no digrafo anterior 1 12 7 2 nvisit 1 -1 -1 sua estrutura com as contra-adjacências: 3 -1 -1 4 -1 -1 2 Nesta figura omite-se os custos dos arcos nas contra-adjacências 13 2 12 3 5 20 1 1 7 5 5 5 -1 -1 Espaco. Vertices 3 4 15 ● 4 12 ● ● 10 13 ● 3 4 ● 2 nvert 4 10 5 1 G 12 3 20 visit 15 5 conexo -1

Exercício 5. 3: Encontrar, usando o algoritmo de Dijkstra, os caminhos mais baratos e

Exercício 5. 3: Encontrar, usando o algoritmo de Dijkstra, os caminhos mais baratos e os respectivos custos do vértice 1 para todos os outros vértices. Sugestão: implementar o algoritmo e a estratégia apresentados no Capítulo VII das aulas teóricas Poderão ser acrescentados novos campos às structs Celula. Vertice e Celula. Adj

Exercício 5. 4: Encontrar os componentes fortemente conexos do digrafo lido n Numerar cada

Exercício 5. 4: Encontrar os componentes fortemente conexos do digrafo lido n Numerar cada vértice e cada arco do digrafo com o número do componente fortemente conexo ao qual pertence n Escrever na tela os vértices e os arcos de cada um desses componentes Usar o algoritmo de Kosaraju apresentado no Capítulo VII das aulas teóricas Poderão ser acrescentados novos campos às structs Celula. Vertice e Celula. Adj

Exercício 5. 5: Transformar o digrafo lido num grafo não-orientado e escrever na tela

Exercício 5. 5: Transformar o digrafo lido num grafo não-orientado e escrever na tela sua nova estrutura de listas de adjacências n Para isso: Eliminar os arcos de um vértice para si mesmo Para todo arco (v→w) tal que não exista no digrafo o seu inverso (w→v), incluir este último no grafo

Exercício 5. 6: Teste de conectividade para grafos não-orientados n No programa do exercício

Exercício 5. 6: Teste de conectividade para grafos não-orientados n No programa do exercício anterior, testar se o grafo não-orientado obtido é conexo ou não-conexo n Numa busca em profundidade, encontrando somente uma árvore na floresta, o grafo é conexo; caso contrário é não-conexo n Pode ser conveniente incluir no programa mais de uma função que faça busca em profundidade Uma função para cada propósito

Exercício 5. 7: Se o grafo for conexo: n Encontrar e escrever na tela,

Exercício 5. 7: Se o grafo for conexo: n Encontrar e escrever na tela, usando o algoritmo de Prim, todos os arcos de uma de suas árvores de cobertura de custo mínimo n Calcular o valor desse custo. Exercício 5. 8: Estender o exercício anterior para vários digrafos lidos n Agora o arquivo de dados deve ter as informações sobre os vários digrafos a serem manipulados pelo programa.