CES11 ALGORITMOS E ESTRUTURAS DE DADOS Aulas Prticas

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

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

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

n O presente trabalho corresponde ao laboratório do Exame de CES-11/2016 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 e armazenar um digrafo numa estrutura com listas de

Objetivos deste laboratório: 1. Ler e armazenar um digrafo numa estrutura com listas de adjacências - O digrafo deve ter uma informação inteira e positiva em cada um de seus vértices (duração da tarefa representada pelo vértice) 2. Testar se o digrafo armazenado é cíclico ou acíclico

3. Se o digrafo for acíclico, encarando-o como o cronograma das tarefas de um

3. Se o digrafo for acíclico, encarando-o como o cronograma das tarefas de um projeto: - Calcular o tempo mínimo de término desse projeto Encontrar as tarefas e os arcos dos caminhos críticos do digrafo (pode haver mais de um) 4. Se for cíclico, encontrar os vértices e os arcos de cada um de seus componentes fortemente conexos n Observação: o programa elaborado deverá ler os dados de vários digrafos e, para cada um, realizar os 4 passos anteriores

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 um digrafo, com uma informação inteira e positiva em cada um seus vértices (duração da tarefa representada pelo vértice) n Armazenar o digrafo numa estrutura com listas de adjacências n Imprimir todo o conteúdo de sua estrutura com lista de adjacências

Declarações para digrafos: 15 12 typedef 2 10 int vertice; struct Celula. Adj; 20

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

struct Celula. Vertice { int duracao; Celula. Adj *listadj; }; 15 12 2 struct

struct Celula. Vertice { int duracao; Celula. Adj *listadj; }; 15 12 2 struct Grafo { Celula. Vertice *Espaco. Vertices; int nvert; }; /* Variaveis globais */ Grafo G; A ser alocado dinamicamente (malloc) G 10 20 1 15 2 12 3 10 4 12 5 20 Espaco. Vertices 1 12 3 4 5 2 5 4 4 1 5 3 nvert 5

/* Prototipos de funcoes */ O grafo a ser lido e escrito é G

/* Prototipos de funcoes */ O grafo a ser lido e escrito é G (variável global) void Ler. Grafo (void); void Imprimir. Grafo (void); /* Programa Principal: */ void main () { printf ("Leitura do Grafo G: nn"); Ler. Grafo (); printf ("n. Grafo G em fase inicialn"); Imprimir. Grafo (); printf ("nn"); system ("pause"); return 0; } Observação: no Capítulo VI das aulas teóricas, há um algoritmo para leitura e armazenamento de grafos em listas de adjacências Ele pode ser adaptado para este trabalho

Exemplo: para o digrafo Possível conteúdo impresso: 15 12 Grafo G em fase inicial

Exemplo: para o digrafo Possível conteúdo impresso: 15 12 Grafo G em fase inicial 2 10 1 12 3 4 Numero de vertices: 5 1) duracao: 15 adjs : 2, 4 20 2) duracao: 12 adjs : 5 3) duracao: 10 adjs : 1, 4 4) duracao: 12 adjs : 5 5) duracao: 20 adjs : 3 G 1 15 2 12 3 10 4 12 5 20 Espaco. Vertices 5 2 5 4 4 1 5 3 nvert 5

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

Exercício 5. 2: Construção da lista de contraadjacências de cada vértice (substitui o grafo 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 { int duracao; Celula. Adj *listadj, *listcontradj; };

Exemplo: no grafo anterior 15 12 1 10 2 3 sua estrutura com 2

Exemplo: no grafo anterior 15 12 1 10 2 3 sua estrutura com 2 as contra-adjacências 3 4 5 15 12 10 2 4 3 5 1 4 1 12 20 G Espaco. Vertices 5 5 1 3 2 4 5 20 1 12 3 4 nvert 5

Exercício 5. 3: Teste de aciclicidade para digrafos n No programa do exercício anterior,

Exercício 5. 3: Teste de aciclicidade para digrafos n No programa do exercício anterior, testar se o digrafo lido é cíclico ou acíclico n Para tanto procurar arcos de volta no digrafo durante uma busca em profundidade; encontrando um, o grafo é cíclico, caso contrário, é acíclico Observação: no Capítulo VII das aulas teóricas, há um algoritmo para realizar o teste de aciclicidade – pode-se adaptá-lo Lá usa-se uma variável global aciclico para denotar a aciclicidade, mas neste exercício essa variável deve ser um campo da struct grafo

n Acrescentar o campo aciclico ao tipo grafo : 15 1 struct Grafo {

n Acrescentar o campo aciclico ao tipo grafo : 15 1 struct Grafo { 12 Celula. Vertice *Espaco. Vertices; int nvert; logic aciclico; }; 1 15 2 12 3 10 10 2 4 3 5 12 20 G Espaco. Vertices 5 5 1 3 2 4 5 aciclico 4 1 4 3 20 2 12 False 3 4 nvert 5

Teste de aciclicidade para digrafos n Manter, para o vértice que está sendo visitado,

Teste de aciclicidade para digrafos n Manter, para o vértice que está sendo visitado, uma pilha com todos os seus ancestrais, incluindo ele próprio n Partindo dele, para visitar seus adjacentes, se um deles, já visitado, pertencer a tal pilha, existe o arco de volta n Quando todos os seus adjacentes já tiverem sido visitados, retirá-lo da pilha de ancestrais n Acrescentar o campo, visit ao tipoo. Celula. Vertice: Caso seja encontrado um ciclo marcar campo aciclico de G como struct sendo. Celula. Vertice FALSE { int duracao; logic visit; Celula. Adj *listadj, *listcontradj; };

n Declarações, protótipos e funções para pilhas de vértices: typedef struct noh; typedef noh

n Declarações, protótipos e funções para pilhas de vértices: typedef struct noh; typedef noh *pilha; typedef noh *pontpilha; struct noh {vertice elem; noh *prox; }; void Empilhar (vertice, pilha*); void Desempilhar (pilha*); vertice Topo (pilha); void Inic. Pilha (pilha*); logic Vazia (pilha); void Inic. Pilha (pilha *P) { *P = NULL; } logic Vazia (pilha P) { if (P == NULL) return TRUE; else return FALSE; }

void Empilhar (vertice x, pilha *P) { noh *temp; temp = *P; *P =

void Empilhar (vertice x, pilha *P) { noh *temp; temp = *P; *P = (noh *) malloc (sizeof (noh)); (*P)->elem = x; (*P)->prox = temp; } É necessária ainda uma função para procurar um vértice na pilha de ancestrais void Desempilhar (pilha *P) { noh *temp; if (! Vazia (*P)) { temp = *P; *P = (*P)->prox; free (temp); } else printf ("nt. Delecao em pilha vazian"); } vertice Topo (pilha P) { if (! Vazia (P)) return P->elem; else printf ("nt. Topo de pilha vazian"); return -1; }

Exercício 5. 4: Se o digrafo for acíclico: n Encará-lo como o cronograma das

Exercício 5. 4: Se o digrafo for acíclico: n Encará-lo como o cronograma das tarefas de um projeto n Encontrar e imprimir o tempo mínimo de término de cada tarefa e do projeto como um todo n Marcar os vértices e os arcos pertencentes aos caminhos críticos do digrafo, imprimindo-os 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. 5: Se o digrafo for cíclico: n Encontrar os seus componentes fortemente

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