Você está na página 1de 14

ALGORITMOS E COMPLEXIDADE

GUIO DAS AULAS PRTICAS


Antnio Manuel Adrego da Rocha Joaquim Joo Estrela Ribeiro Silvestre Madeira
Departamento de Electrnica, Telecomunicaes e Informtica Universidade de Aveiro Ano Lectivo de 2008/2009

GUIO DAS AULAS PRTICAS DE ALGORITMOS E COMPLEXIDADE

Programa das aulas prticas de Algoritmos e Complexidade


Anlise Emprica da Complexidade (2 aulas) Tipos Abstractos de Dados simples baseados em arrays e listas (2 aulas) Pesquisa e Ordenao (2 aulas) Recursividade (2 aulas) Filas e Pilhas rvores Binrias de Pesquisa (1 aula) rvores AVL (1 aula) Filas com Prioridade (1 aula) Grafos (2 aulas)

Bibliografia para as aulas prticas


Estruturas de Dados e Algoritmos em C, Antnio Adrego da Rocha, FCA Editora de Informtica, 2008. ou Programao Avanada usando C, Antnio Adrego da Rocha, FCA Editora de Informtica, 2006.

Material para as aulas prticas


O material necessrio para as aulas prticas disponibilizado na seguinte pgina da Internet: http://sweet.ua.pt/~f706/algoritmos/.

GUIO DAS AULAS PRTICAS DE ALGORITMOS

AULAS 1 E 2
Calcule o nmero de operaes aritmticas (somas ou produtos) executadas pelos algoritmos seguintes: Clculo do factorial n! Clculo do nmero de Fibonacci F(n) usando a verso repetitiva simplificada (ver 1.4 Nmeros de Fibonacci, pginas 7-9) Clculo do quadrado usando a soma de sucessivos nmeros mpares n 2 = Clculo do valor de xn (para n 0) Mudana de base decimal para binrio Clculo da soma de quadrados sucessivos SomaQua = Clculo da soma de potncias sucessivas Soma dos elementos de um vector Soma de matrizes Produto de matrizes Determine experimentalmente a complexidade de cada algoritmo em funo da dimenso da entrada.
SomaPot =

n i =1

isimo mpar

n i =1

i2 xi

n i =1

GUIO DAS AULAS PRTICAS DE ALGORITMOS E COMPLEXIDADE

AULAS 3 E 4
Para perceber a implementao de tipos abstractos de dados na linguagem C, deve comear por ler o captulo 3, analisando a implementao do Tipo Abstracto de Dados COMPLEXO. O Tipo Abstracto de Dados VECTOR constitudo pelo ficheiro de interface vector.h e pelo ficheiro de implementao vector.c e implementa a criao de vectores e de operaes sobre vectores. O TAD tem capacidade de mltipla instanciao e usa um controlo centralizado de erros. Para armazenar as componentes de um vector usado um array, permitindo assim, que os algoritmos matemticos das operaes sobre vectores sejam facilmente implementveis sobre esta estrutura de dados indexada. A figura apresenta o armazenamento de um vector com 5 componentes num array.
(v4,v3,v2,v1,v0) = (2.5,1.0,0.0,3.0,5.5) 5.5 3.0 0.0 1.0 2.5
Vector[0] Vector[1] Vector[2] Vector[3] Vector[4]

Comece por ler com ateno os ficheiros e de seguida compile o mdulo, usando para o efeito o comando cc -c vector.c, sendo que cc um alias do compilador da linguagem C programado da seguinte maneira gcc -ansi -Wall. A compilao deve gerar o ficheiro objecto vector.o. De seguida compile e teste as aplicaes tvector.c e svector.c, que testam as operaes do mdulo vector. O primeiro programa uma aplicao simples, enquanto que o segundo uma aplicao grfica. No se esquea que para compilar as aplicaes, tem que mencionar o ficheiro objecto do TAD (vector.o) no comando de compilao. Tambm fornecida a makefile mkvector, para compilar o mdulo e as aplicaes. Teste convenientemente toda a funcionalidade do TAD. Pretende-se desenvolver o Tipo Abstracto de Dados POLINMIO, usando como estrutura de dados de suporte um array para armazenar os seus coeficientes reais. O TAD deve ter capacidade de mltipla instanciao e controlo centralizado de erros. Para armazenar os coeficientes de um polinmio usado um array, permitindo assim, que os algoritmos matemticos das operaes sobre polinmios sejam facilmente implementveis sobre esta estrutura de dados indexada. Tenha em ateno que um polinmio de grau N tem N+1 coeficientes. A figura ilustra o armazenamento de um polinmio de grau 4 num array.
3.5x4 + 2.5x3 + x2 + 4.5 4.5
Pol[0]

0.0
Pol[1]

1.0
Pol[2]

2.5
Pol[3]

3.5
Pol[4]

A funcionalidade pretendida especificada pelo ficheiro de interface polinomio.h, sendo tambm fornecido o esqueleto do ficheiro de implementao polinomio.c. So tambm fornecidas as aplicaes tpolinomio.c e spolinomio.c e a makefile mkpolinomio, para compilar o mdulo e as aplicaes. Teste convenientemente toda a funcionalidade do TAD. Pretende-se desenvolver o Tipo Abstracto de Dados MATRIZ, usando como estrutura de dados de suporte um array bidimensional para armazenar os seus elementos inteiros. O TAD deve ter capacidade de mltipla instanciao e controlo centralizado de erros.

GUIO DAS AULAS PRTICAS DE ALGORITMOS

A funcionalidade pretendida especificada pelo ficheiro de interface matriz.h, sendo tambm fornecido o esqueleto do ficheiro de implementao matriz.c. Comece por ler com ateno os ficheiros e complete o mdulo. As operaes de transposio de uma matriz, de soma e de produto de matrizes implementam-se atravs das expresses indicadas de seguida:

Matriz_Transposta[j, i ] = Matriz[i, j], com 1 i NL e 1 j NC. Matriz_Soma[i, j] = Matriz_A[i, j] + Matriz_B[i, j] , com 1 i NL e 1 j NC.
Matriz_Produto[i, j] =
NCA K =1

Matriz_A[i, k ] Matriz_B[k, j] , com 1 i NLA e 1 j NCB.

So tambm fornecidas as aplicaes tmatriz.c e smatriz.c e a makefile mkmatriz, para compilar o mdulo e as aplicaes. Teste convenientemente toda a funcionalidade do TAD. Sugesto: Para poder manipular as matrizes com acesso indexado do tipo Matriz[i][j], implemente na memria dinmica uma estrutura de dados matricial, como se indica na figura. Os excertos de cdigo necessrios para criar e destruir uma sequncia bidimensional com NLNC elementos inteiros so apresentados na Figura 2.5 (pgina 39).
PtMatriz int **PtMatriz;
0 1 . . . NL-1 0 1 2 . . . NC-1

Pretende-se desenvolver o Tipo Abstracto de Dados CONJUNTO, usando como estrutura de dados de suporte uma lista biligada para armazenar os seus elementos de modo ordenado. Implemente um mdulo, com capacidade de mltipla instanciao e com controlo de erros, para conjuntos de caracteres alfabticos maisculos. A funcionalidade pretendida especificada pelo ficheiro de interface conjunto.h, sendo tambm fornecido o esqueleto do ficheiro de implementao conjunto.c. Comece por ler com ateno os ficheiros e complete o mdulo. So tambm fornecidas as aplicaes tconjunto.c e sconjunto.c e a makefile mkconjunto, para compilar o mdulo e as aplicaes. Teste convenientemente toda a funcionalidade do TAD. Para armazenar os elementos de conjunto deve ser usada uma lista biligada, mantendo os seus elementos sempre ordenados. Desta forma optimiza-se os algoritmos associados s operaes habituais sobre conjuntos. A figura apresenta o armazenamento do conjunto {A, K, L, X} numa lista biligada.
cabea do conjunto PtSeg PtAnt PtEle PtSeg PtAnt PtEle PtSeg PtAnt PtEle PtSeg PtAnt PtEle

'A'

'K'

'L'

'X'

Sugesto: Para se familiarizar com listas biligadas e os seus algoritmos de manipulao, comece por ler o item 2.4.2 Listas biligadas (pginas 48-53).

GUIO DAS AULAS PRTICAS DE ALGORITMOS E COMPLEXIDADE

AULAS 5 E 6
Pretende-se determinar experimentalmente a complexidade do algoritmo de pesquisa sequencia.
int SequentialSearch (int pseq[], unsigned int n, int pval) { unsigned int IndActual; for (IndActual = 0; IndActual < n; IndActual++) if (pseq[IndActual] == pval) return IndActual; return -1; } /* pesquisa sem sucesso */

Pretende-se determinar experimentalmente a complexidade do algoritmo de pesquisa binria, nas suas duas variantes possveis apresentadas de seguida.
int BinarySearch (int pseq[], unsigned int n, int pval) { int Minimo = 0, Maximo = n-1, Medio; while (Minimo <= Maximo) { /* clculo da posio mdia */ Medio = ((unsigned int) Minimo + (unsigned int) Maximo) >> 1; if (pseq[Medio] == pval) return Medio; /* pesquisa com sucesso */ /* Actualizao dos limites do intervalo de pesquisa */ if (pseq[Medio] < pval) Minimo = Medio + 1; else Maximo = Medio - 1; /* pesquisa sem sucesso */

} }

return -1;

int BinarySearch (int pseq[], unsigned int n, int pval) { int Minimo = 0, Maximo = n-1, Medio; while (Minimo <= Maximo) { /* clculo da posio mdia */ Medio = ((unsigned int) Minimo + (unsigned int) Maximo) >> 1; /* Actualizao dos limites do intervalo de pesquisa */ if (pseq[Medio] < pval) Minimo = Medio + 1; else if (pseq[Medio] > pval) Maximo = Medio - 1; else return Medio; /* pesquisa com sucesso */ /* pesquisa sem sucesso */

} }

return -1;

GUIO DAS AULAS PRTICAS DE ALGORITMOS

Os resultados obtidos devero ser analisados relativamente ao comportamento individual de cada um dos algoritmos implementados com o crescimento do nmero de elementos da sequncia a pesquisar. Para alm de verificar experimentalmente o comportamento dos algoritmos no melhor caso e no pior caso, os testes devero ilustrar o comportamento dos algoritmos no caso mdio. Neste caso, devero ser considerados os seguintes tipos de situaes e de testes: Pesquisa com 100% de sucesso. O elemento procurado est sempre presente no array: sucessivamente procurado, um a um, cada um dos elementos do array; Pesquisa com 50% de sucesso. O elemento procurado pode no estar presente no array: so alternada e sucessivamente procurados elementos que pertencem e no pertencem ao array. Faa a simulao dos algoritmos para sequncias com N = 2K1 nmeros inteiros pares e determine o nmero mdio de comparaes efectuadas para os dois casos mdios da pesquisa. Aps a simulao dos algoritmos faa a anlise terica dos casos mdios dos algoritmos de pesquisa para arrays com 2K 1 elementos. Compare os resultados experimentais com os resultados tericos, para sequncias com N = 2K1 elementos (com 10 K 20).
K N P A(N) 100% T A (N) 100% P A(N) 50% T A (N) 50%

10 11 12 13 14 15 16 17 18 19 20

1023 2047 4095 8191 16383 32767 65535 131071 262143 524287 1048575

##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.##

##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.##

##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.##

##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.## ##.##

Para calcular o nmero de comparaes, pode utilizar uma varivel de durao permanente em conjuno com a funo de comparao pretendida. Para esse efeito, encapsula-se a comparao dentro da funo CmpSearchCount, que, alm de efectuar a comparao pretendida, tambm contabiliza o nmero de vezes que invocada. O tipo de comparao desejado indicado pelo parmetro ptipo, usando o identificador: EQUAL (==); BIGGER (>); BEQUAL (>=); LESSER (<); LEQUAL (<=) e NEQUAL (!=). O modo de actuao indicado pelo parmetro pmodo, usando o identificador: INIC para inicializar a varivel contadora; NORM para executar a funo e incrementar o valor da varivel contadora; e REP para reportar o valor da varivel contadora. O modo de actuao indicado pelo parmetro pmodo, usando o identificador: INIC para inicializar a varivel contadora; NORM para executar a funo e incrementar o valor da varivel contadora; e REP para reportar o valor da varivel contadora.

GUIO DAS AULAS PRTICAS DE ALGORITMOS E COMPLEXIDADE unsigned int CmpSearchCount (int *x, int *y, int ptipo, int pmodo) { static unsigned int cont; /* contagem do nmero de comparaes */ if (pmodo == INIC) cont else if (pmodo == NORM) { cont++; switch (ptipo) { case EQUAL : case BIGGER: case BEQUAL: case LESSER: case LEQUAL: case NEQUAL: } } else return cont; } = 0;

return return return return return return

*x *x *x *x *x *x

== *y; > *y; >= *y; < *y; <= *y; != *y;

A estratgia de atravessar a rvore binria de pesquisa rapidamente em detrimento da deteco do valor procurado torna o algoritmo mais eficiente. Por isso, uma forma de optimizar ainda mais a pesquisa binria consiste em diminuir o nmero de comparaes efectuadas em cada iterao, eliminando a pesquisa explcita do valor procurado, e reduzir sucessivamente a sequncia metade onde se encontra o valor procurado, usando apenas um teste condicional dentro do ciclo repetitivo. Finalmente, quando a sequncia tiver um nico elemento, esse elemento testado para determinar se a pesquisa teve ou no teve sucesso. Implemente a funo de pesquisa binria que implementa esta estratgia e teste-a para sequncias com N = 2K elementos.

GUIO DAS AULAS PRTICAS DE ALGORITMOS

AULAS 7 E 8
Implemente os seguintes algoritmos recursivos e calcule o nmero de operaes aritmticas (somas ou produtos) executadas: Clculo do factorial n!
n! = n (n 1)!

Clculo da potncia xn usando os seguintes mtodos:


1, se n = 0 2 = x n/2 , se n par 2 x x n/2 , se n mpar

1 mtodo x n = x x n -1

2 mtodo x n

( ) ( )

Clculo do nmero de Fibonacci

0, se n = 0 F(n) = 1, se n = 1 F(n 1) + F(n 2), se n 2

Clculo da soma de potncias sucessivas SomaPot = recursivo da potncia Clculo do nmero triangular Clculo do nmero quadrtico

n i =1

xi

usando o segundo mtodo do clculo

1, se n = 1 T(n) = T(n 1) + n, se n > 1


1, se n = 1 Q(n) = Q(n 1) + 2n 1, se n > 1

Determine experimentalmente a complexidade de cada algoritmo em funo da dimenso da entrada.

Construa uma funo recursiva para implementar a funo C(n), definida pela seguinte relao de recorrncia.

1 , C(n) = n 1 2 C(i) + n , n i =0

se n = 0 caso contrrio

Construa um programa para simular a execuo da funo C(n), que permita determinar o seu tempo de execuo, usando para esse efeito o mdulo crono (crono.h e crono.c). Efectue a anlise emprica da complexidade da funo implementada, construindo uma tabela com tempos de execuo da funo para diferentes valores de n. Qual a ordem de complexidade da funo recursiva?

GUIO DAS AULAS PRTICAS DE ALGORITMOS E COMPLEXIDADE

10

Uma forma de resolver problemas recursivos de maneira a evitar o clculo repetido de valores, consiste em calcular os valores de baixo para cima, ou seja, de C(0) para C(n) e utilizar um array para manter os valores entretanto calculados. Este mtodo designa-se por programao dinmica e reduz o tempo de clculo custa da utilizao de mais memria para armazenar valores intermdios. Usando a tcnica de programao dinmica, construa uma funo repetitiva para implementar a funo C(n) e efectue uma anlise emprica da sua complexidade. Qual a ordem de complexidade desta implementao da funo? Analisando a soluo anterior, desenvolva uma funo repetitiva que no necessite de utilizar o array e efectue uma anlise emprica da sua complexidade. Qual a ordem de complexidade desta implementao da funo? Finalmente, faa a anlise formal das trs implementaes da funo C(n) e confirme as ordens de complexidade obtidas experimentalmente.

FILAS E PILHAS
Para se familiarizar com as memrias fila e pilha sugere-se a leitura do Captulo 7 Filas e pilhas. Estude o funcionamento das implementaes dinmicas, baseadas em listas ligadas e analise as implementaes dinmicas genricas. A memria fila (Queue), cuja funcionalidade especificada pelo ficheiro de interface queue.h e implementada pelo ficheiro de implementao queue.c, uma memria abstracta, com capacidade de mltipla instanciao. Comece por compreender a sua funcionalidade e depois acrescente-lhe a funo QueueHead, que copia o elemento que se encontra cabea da fila, sem contudo o retirar da fila. Acrescente tambm a funo QueueEmpty, que determina se a fila est ou no vazia. A memria pilha (Stack), cuja funcionalidade especificada pelo ficheiro de interface stack.h e implementada pelo ficheiro de implementao stack.c, uma memria abstracta, com capacidade de mltipla instanciao. Comece por compreender a sua funcionalidade e depois acrescente-lhe a funo StackTop, que copia o elemento que se encontra no topo da pilha, sem contudo o retirar da pilha. Acrescente tambm a funo StackEmpty, que determina se a pilha est ou no vazia. Compile os mdulos e teste a sua funcionalidade, usando nomeadamente o programa capicua.c que determina se uma sequncia de caracteres um palndromo. Um palndromo uma palavra que se l da mesma maneira, quer seja da esquerda para a direita, quer seja da direita para esquerda. Ou seja, uma palavra que normalmente se designa por capicua. Implemente uma memria fila duplamente terminada (Double-Ended Queue Deque), tambm designada por fila dupla, dinmica genrica cuja funcionalidade especificada pelo ficheiro de interface deque.h.. Uma fila dupla uma fila que permite inserir e retirar elementos, quer da cabea, quer da cauda. A fila dupla implementa as seguintes operaes: criar uma fila dupla DequeCreate; destruir uma fila dupla DequeDestroy; colocar um novo elemento na cabea da fila dupla DequePush; retirar um elemento da cabea da fila dupla DequePop; colocar um novo elemento na cauda da fila dupla DequeInject; retirar um elemento da cauda da fila dupla DequeEject; e determinar se uma fila dupla est ou no vazia DequeEmpty. Tenha em ateno que precisa de usar como estrutura de dados de suporte uma lista biligada, de forma a permitir retirar elementos das duas extremidades da fila dupla.

11

GUIO DAS AULAS PRTICAS DE ALGORITMOS

AULA 9
O Tipo Abstracto de Dados rvore Binria de Pesquisa (ABP) constitudo pelo ficheiro de interface abp.h e pelo ficheiro de implementao abp.c e implementa a manipulao de rvores binrias de pesquisa, com capacidade para armazenar nmeros inteiros. O TAD tem capacidade de mltipla instanciao e usa um controlo centralizado de erros. Para testar o TAD fornecido o programa tabp.c e a makefile mkabp. Comece por testar convenientemente toda funcionalidade do TAD, usando para esse efeito os ficheiros de rvores disponibilizados. Tambm fornecido o programa irabp.c que simula a insero e a remoo de elementos na rvore, fazendo a sua visualizao hierrquica na horizontal, aps cada operao. Simule o programa para as sequncias de elementos dos ficheiros. Acrescente ao Tipo Abstracto de Dados rvore Binria de Pesquisa a seguinte funcionalidade: Uma funo recursiva para obter um ponteiro para o n do menor elemento armazenado na rvore. A funo deve ter o seguinte prottipo:
PtABP ABPMinNode (PtABP pabp);

Uma funo repetitiva para obter um ponteiro para o n do maior elemento armazenado na rvore. A funo deve ter o seguinte prottipo:
PtABP ABPMaxNode (PtABP pabp);

Uma funo para obter o elemento armazenado na rvore, dado um ponteiro para o seu n. A funo deve ter o seguinte prottipo:
int ABPElement (PtABP pnode);

Uma funo recursiva para determinar a soma dos elementos armazenados na rvore. A funo deve ter o seguinte prottipo:
int ABPTotalSum (PtABP pabp);

Uma funo repetitiva para determinar o nmero de elementos mltiplos de 3 armazenados na rvore. A funo deve ter o seguinte prottipo:
unsigned int ABPMult3Count (PtABP pabp);

Uma funo recursiva para determinar o nmero de elementos mpares armazenados na rvore. A funo deve ter o seguinte prottipo:
unsigned int ABPOddCount (PtABP pabp);

Uma funo repetitiva para determinar a soma dos elementos pares armazenados na rvore. A funo deve ter o seguinte prottipo:
unsigned int ABPEvenSum (PtABP pabp);

Uma funo para determinar a soma dos elementos armazenados na rvore, com nmero de ordem mpar. Ou seja, a soma do primeiro, terceiro, quinto, stimo, etc. menores nmeros inteiros armazenados na rvore. A funo deve ter o seguinte prottipo:
int ABPOddOrderSum (PtABP pabp);

GUIO DAS AULAS PRTICAS DE ALGORITMOS E COMPLEXIDADE

12

Escreva um programa, chamado por exemplo testeabp.c que permita testar estas operaes. O programa constri uma rvore binria de pesquisa a partir de um ficheiro, cujo nome passado como argumento na linha de comando e depois apresenta no monitor, o nmero de ns e a altura da rvore criada. De seguida, o programa indica tambm: o valor do menor elemento armazenado na rvore; o valor do maior elemento armazenado na rvore; a soma dos elementos da rvore; a contagem dos nmeros mltiplos de 3 da rvore; o nmero de nmeros mpares da rvore; a soma dos elementos pares da rvore; e a soma dos elementos com nmero de ordem mpar da rvore.

AULA 10
O Tipo Abstracto de Dados rvore Adelson-Velskii Landis (AVL) constitudo pelo ficheiro de interface avl.h e pelo ficheiro de implementao avl.c e implementa a manipulao de rvores AVL, com capacidade para armazenar nmeros inteiros. O TAD tem capacidade de mltipla instanciao e usa um controlo centralizado de erros. Para testar o TAD fornecido o programa tavl.c e a makefile mkavl. Comece por testar convenientemente toda funcionalidade do TAD, usando para esse efeito os mesmos ficheiros de rvores disponibilizados para a rvore ABP. Tambm fornecido o programa iravl.c que simula a insero e a remoo de elementos na rvore, fazendo a sua visualizao hierrquica na horizontal, aps cada operao. Simule o programa para as sequncias de elementos dos ficheiros. Compare as simulaes com as da rvore ABP.

13

GUIO DAS AULAS PRTICAS DE ALGORITMOS

AULA 11
Comece por ler o Captulo 9 Filas com prioridade, mais concretamente o item 9.5 Fila com prioridade com amontoado (pginas 374-377), para se familiarizar com a implementao de uma fila com prioridade baseada num amontoado binrio (binary heap) e os respectivos algoritmos. O Tipo Abstracto de Dados Fila com Prioridade, que constitudo pelo ficheiro de interface pqueue.h e pelo ficheiro de implementao pqueue.c, implementa a manipulao de filas com prioridade orientada aos mximos, com capacidade para armazenar nmeros inteiros. O TAD tem capacidade de mltipla instanciao e as operaes devolvem um cdigo de erro relativo execuo da operao. Para testar o TAD so fornecidos os programas tpqueue.c e spqueue.c e a makefile mkpqueue. Comece por testar convenientemente toda funcionalidade do TAD, com excepo das operaes PQueueIncrease e PQueueDecrease que esto incompletas. Finalmente, complete a funcionalidade destas duas operaes e teste-as convenientemente.

TPC
Para simular o algoritmo do caminho mais curto de Dijkstra usa-se habitualmente uma fila com prioridade implementada com um amontoado binrio e organizada com prioridade orientada aos mnimos, que armazene elementos estruturados do tipo VERTICE, sendo a prioridade dos elementos estabelecida pelo campo TCost.
/* definio de um elemento da fila com prioridade */ typedef struct dijkstra { unsigned int Vertice; /* vrtice */ int TCost; /* custo do caminho at ao vrtice */ } VERTICE;

Crie uma fila com prioridade para elementos estruturados do tipo VERTICE, cuja funcionalidade descrita no ficheiro de interface pqueue_dijkstra.h e usando o esqueleto do ficheiro de implementao pqueue_dijkstra.c. Implemente as seguintes operaes: Criao de uma fila com prioridade PQueueCreate; Destruio de uma fila com prioridade PQueueDestroy; Insero de um elemento PQueueInsert; Remoo do elemento com menor chave PQueueDeleteMin; Promoo do elemento na fila com prioridade PQueueDecrease; Determinar se a fila com prioridade est ou no vazia PQueueEmpty.

Para testar a funcionalidade desta fila com prioridade pode usar o programa teste1.c, cuja execuo apresentada no ficheiro teste1.txt. Pode tambm usar o programa teste2.c, que simula o algoritmo de Dijkstra para o digrafo apresentado na pgina 388 (sendo o custo infinito representado pelo valor 100), e cuja execuo apresentada no ficheiro teste2.txt.

GUIO DAS AULAS PRTICAS DE ALGORITMOS E COMPLEXIDADE

14

AULAS 12 E 13
Comece por ler o Captulo 10 Grafos (ver 10.3 Implementao do Grafo, 10.4 Caracterizao do Grafo e 10.5 Digrafo dinmico, pginas 397-411). Estude o funcionamento da implementao do digrafo dinmico e analise a sua implementao, para se familiarizar com os algoritmos. O Tipo Abstracto de Dados DIGRAFO constitudo pelo ficheiro de interface digrafo.h e pelo ficheiro de implementao digrafo.c e implementa a manipulao de digrafos dinmicos. Para testar o TAD fornecido o programa de simulao grfica sdigrafo.c e a makefile mkdigrafo. Comece por testar convenientemente toda funcionalidade do TAD. Depois, acrescente-lhe a seguinte funcionalidade: Verificar se o n ni uma fonte, i.e., se tem associados um ou mais arcos emergentes, mas no tem nenhum arco incidente. A funo deve ter o seguinte prottipo:
int DigraphSource (PtDigraph pdigraph, unsigned int pvertice);

Verificar se o n ni um sumidouro, i.e., se tem associados um ou mais arcos incidentes, mas no tem nenhum arco emergente. A funo deve ter o seguinte prottipo:
int DigraphSink (PtDigraph pdigraph, unsigned int pvertice).

As operaes DigraphSource e DigraphSink devolvem o valor 1 em caso afirmativo ou 0 no caso contrrio. Acrescente ao TAD digrafo o algoritmo de Dijkstra, que fornecido no ficheiro dijkstra.c. Para implementar este algoritmo precisa de uma fila com prioridade, orientada aos mnimos, para elementos estruturados do tipo VERTICE (pqueue_dijkstra). Escreva um programa para simular a execuo do algoritmo de Dijkstra sobre um digrafo armazenado num ficheiro. O programa constri um digrafo a partir de um ficheiro, cujo nome passado como argumento na linha de comando, depois pede o vrtice de partida e imprime no monitor o caminho mais curto para cada um dos vrtices alcanveis a partir do vrtice indicado. Acrescente tambm ao TAD digrafo o algoritmo de Bellman-Ford e escreva um programa, semelhante ao anterior, para simular a execuo deste algoritmo.

Você também pode gostar