Sei sulla pagina 1di 4

Relatrio do Primeiro Projecto

Anlise e Sintese de Algoritmos


Grupo 100 2013-2014

Alexandre Ferreira, 76465 Ricardo Abreu, 76370

Introduo

O nosso trabalho consistia em analisar uma rede de partilhas de informao entre vrias pessoas. Cada pessoa envia informaes para uma determinada lista de pessoas, eventualmente algumas pessoas acabam por criar grupos entre si. Isto , a informao passa a percorrer um determinado ciclo fixo de pessoas (grupo). Estes grupos so os chamados SCCs: Strongly Connected Components O objectivo do nosso programa era, dada uma determinada rede de partilha, calcular 3 parametros sobre essa mesma rede: - o numero de grupos - o tamanho do maior grupo - o numero de grupos privados (grupos que partilham informao apenas dentro do grupo)

Descrio da soluo Os trs parmetros pedidos como output vo ser inteiros globais chamados numeroGrupos, maiorGrupo e numeroPrivados. Estas variveis so inicializadas a 0, sendo atualizadas ao longo da execuo. Este tipo de rede de partilha pode ser representado como um grafo direccionado. Onde as pessoas so os vrtices e as partilhas os arcos direccionados. Como a primeira linha do ficheiro input tem o nmero de pessoas(nv) e o nmero de ligaes entre elas (np), comeamos por guardar esses dois valores. Ao sabermos estes dois valores, chamamos a funo Init que responsvel por inicializar todas as nossas estruturas de dados auxiliares. Como optamos por usar vectores, alocamos memria para (nv+1) inteiros pois isso facilita o acesso por ndices (primeira pessoa no indice 1, em vez do tradicional indice 0). Aps a inicializao das estruturas, executamos a funo CreateAdjList. A nossa lista de adjacncias um vector de listas ligadas, em que em cada ndice esto todos os arcos correspondentes ao vrtice desse ndice. Esta funo faz o parsing das restantes linhas do input, e para cada linha, aloca memria (malloc) para mais um elementos de uma lista(Node).

Uma vez criada a lista de adjacncias, a execuo do algoritmo de Tarjan fica possvel. Escolhemos guardar os valores de descoberta num vector de inteiros (d[]) inicializado a -1(esta operao ocorre na funo Init). Fizemos o mesmo para os valores low(low[]). Cada um destes vectores usa a varivel global tempo para preencher os seus valores. O Tarjan_Visit uma implementao padro do algoritmo de Tarjan para descobrir os SCCs. Chamamos a funo Tarjan_Visit para todos os vertices que ainda no tenham sido encontrados (d=-1). A funo vai percorrer as adjacncias do vrtice atual(usando a lista previamente criada lista[]), e se encontrar algum que no tenha sido descoberto, executa a funo Tarjan_Visit nesse vrtice. Se a funo no encontrar nenhuma adjacncia no descoberta, verifica se existem adjacncias na pilha. A nossa pilha um vetor de inteiros com nv posies e um ndice global, controlado por duas funes (Push e Pop). Temos um vetor SCC de inteiros e de tamanho nv+1, que comea vazio, mas que ir ser preenchido com o nmero do SCC correspondente a cada vrtice. Quando a funo chega raz de um SCC (low[u] == d[u]), executa as seguintes operaes: - Um ciclo que retira elementos da pilha at ser retirada a raz do SCC atual e conta o nmero de elementos retirados (auxi). Cada elemento colocado no vetor PilhaSCC[], que funciona da mesma maneira que a outra pilha. Para alm disso, alterado o valor no ndice desse vrtice no vetor SCC[]. - A funo CheckPartilha responsvel por verificar se o SCC tem ligaes para fora (se privado ou no). Se no forem encontradas ligaes para fora, incrementada a varivel numeroPrivados. No final, a funo tambm trata de limpar a pilha dos SCCs. - Compara o valor guardado em auxi com o valor previamente guardado em maiorGrupo. -Incrementa a varivel numeroGrupos.

Anlise Terica Consideremos nv=n e np=e. Na funo Init, existe um ciclo for de n iteraes, que o responsvel pela inicializao dos vectores d[] e low[]: O(n). A funo CreateAdjList percorre todas as linhas do input. O (e). A funo Tarjan_Visit corrida em todos os vrtices: O(n). Dentro desta funo existem ainda dois ciclos. O primeiro while, garante que a lista de adjancencia de cada vrtice analisada apenas uma vez: O(e). O segundo while, responsvel por definir o SCC, tem uma complexidade O(n). Alm disso, esta funo chama ainda a funo checkPartilha. Esta funo tem uma complexidade O(n+e) pois ao todo vai percorrer todos os vrtices e todas as ligaes. Concluindo o nosso programa tem uma complexidade O(n+e). Resultados da Avaliao Experimental A nossa primeira submisso invlida pois ainda tinha alguns printf() de debug. Aps a segunda submisso, da qual passamos a 13 dos 16 testes (3 testes falhados por TimeLimitExceeded, introduzimos algumas melhorias de forma a tornar o programa mais eficiente: -Na funo CreateAdjList optmos por adicionar elementos no incio da lista, perdendo assim o ciclo de procura do ltimo elemento da lista. -lem disso implementmos um vector SCC[] que nos permite saber imediatamente a que SCC pertence um determinado vrtice. -Altermos a funo checkPilha() para em vez de percorrer a pilha at encontrar o valor desejado, acede a posicao dada numa outra estrututra auxiliar chamado infoPilha, tambmum vector. O Push e o Pop passam a controlar tambm a infoPilha.

Potrebbero piacerti anche