def grafoSimplesPonderado(path): ''' Lê do arquivo em path um grafo simples sem peso nas arestas. ''' fileGrafo = open(path, "r") numVertices = int(fileGrafo.readline()) grafo = GrafoTAD(numVertices) # Criação de matriz NxN vazia. matriz = [[0 for x in range(numVertices)] for y in range(numVertices)] linhas = fileGrafo.readlines() for i in range(numVertices): linha = re.split(r'\s', linhas[i]) for j in range(numVertices): try: if re.match(r'\s', linha[j]): raise "Matriz incompleta!" matriz[i][j] = linha[j] except IndexError: raise "Matriz incompleta!" for i in range(numVertices): for j in range(numVertices): if matriz[i][j] != matriz[j][i]: raise "Grafo dirigido não suportado!" elif matriz[i][j] != "0" and matriz[i][j] != "inf": if not grafo.existeAresta(i, j): grafo.insereAresta(i, j, int(matriz[i][j])) return grafo
def gerarMST(self, grafo): ''' Método que gera a MST a partir do grafo retornando as arestas da MST. ''' self.grafoArvore = GrafoTAD(grafo.numVertices) self.arestas = grafo.arestas while len(self.arestas) > 0: #pylint: disable=C1801 arestaIndex = randint(0, len(self.arestas) - 1) aresta = self.arestas[arestaIndex] self.arestas.remove(aresta) self.grafoArvore.insereAresta(aresta.v1, aresta.v2, aresta.peso) ciclo = self.passeio.geraCiclo(self.grafoArvore, aresta.v1) print("Aresta Inserida: (" +str(aresta.v1) + ", " + str(aresta.v2) + ")") if ciclo != None and len(ciclo) > 0: #pylint: disable=C1801 # Verificar qual a aresta de menor custo do ciclo. arestaPesada = ciclo[0] for arestaCiclo in ciclo: if arestaCiclo.peso > arestaPesada.peso: arestaPesada = arestaCiclo arestaRemovida = self.grafoArvore.retiraAresta(arestaPesada.v1, arestaPesada.v2) print("Aresta Removida: (" + str(arestaRemovida.v1) + ", " + str(arestaRemovida.v2) + ")") print("Arvore: " + self.stringCiclo(self.grafoArvore.arestas)) print("---") return self.grafoArvore.arestas
def __init__(self): self.tourEuler = [] self.tourEulerVertices = [] self.ciclo = [] self.passeio = PasseioGrafo() self.grafoAux = GrafoTAD(0) self.check = False self.verticeCiclo = 0
def __init__(self): self.grafoArvore = GrafoTAD(0) self.arestas = [] self.passeio = PasseioGrafo()
class AlmMST: ''' Classe do algoritmo que gera a MST com uma abordagem não gulosa. ''' def __init__(self): self.grafoArvore = GrafoTAD(0) self.arestas = [] self.passeio = PasseioGrafo() def gerarMST(self, grafo): ''' Método que gera a MST a partir do grafo retornando as arestas da MST. ''' self.grafoArvore = GrafoTAD(grafo.numVertices) self.arestas = grafo.arestas while len(self.arestas) > 0: #pylint: disable=C1801 arestaIndex = randint(0, len(self.arestas) - 1) aresta = self.arestas[arestaIndex] self.arestas.remove(aresta) self.grafoArvore.insereAresta(aresta.v1, aresta.v2, aresta.peso) ciclo = self.passeio.geraCiclo(self.grafoArvore, aresta.v1) print("Aresta Inserida: (" +str(aresta.v1) + ", " + str(aresta.v2) + ")") if ciclo != None and len(ciclo) > 0: #pylint: disable=C1801 # Verificar qual a aresta de menor custo do ciclo. arestaPesada = ciclo[0] for arestaCiclo in ciclo: if arestaCiclo.peso > arestaPesada.peso: arestaPesada = arestaCiclo arestaRemovida = self.grafoArvore.retiraAresta(arestaPesada.v1, arestaPesada.v2) print("Aresta Removida: (" + str(arestaRemovida.v1) + ", " + str(arestaRemovida.v2) + ")") print("Arvore: " + self.stringCiclo(self.grafoArvore.arestas)) print("---") return self.grafoArvore.arestas def stringCiclo(self, ciclo): #pylint: disable=R0201 ''' Método que retorna uma representação em string do ciclo gerado. ''' if ciclo != None: toPrint = "" for aresta in ciclo: toPrint += "(" + str(aresta.v1) + ", " + str(aresta.v2) + ") " return toPrint return "" def imprime(self): ''' Método que imprime o ciclo encontrado junto de seu peso total. ''' toPrint = "" totalPeso = 0 for arestaArvore in self.grafoArvore.arestas: toPrint += "(" + str(arestaArvore.v1) + ", " + str(arestaArvore.v2) + ") " totalPeso += arestaArvore.peso toPrint += "- Peso Total: " + str(totalPeso) print(toPrint)
class Heierholzer: ''' Classe que implementa o algoritmo de Hierholzer. ''' def __init__(self): self.tourEuler = [] self.tourEulerVertices = [] self.ciclo = [] self.passeio = PasseioGrafo() self.grafoAux = GrafoTAD(0) self.check = False self.verticeCiclo = 0 def adicionarArestas(self, conjunto): ''' Adiciona o conjunto de arestas conjunto ao Tour de Euler sendo gerado. ''' print("--------------------") print("Ciclo: " + self.stringCiclo(conjunto)) if len(self.tourEulerVertices) > 0: #pylint: disable=C1801 if conjunto[0] == self.tourEulerVertices[ len(self.tourEulerVertices) - 1]: # Se o novo ciclo tiver como nó raiz o mesmo do antigo ciclo. for aresta in conjunto: self.tourEuler.append(aresta) self.tourEulerVertices.append(aresta.v1) else: index = 0 concluido = False for arestaEuler in self.tourEuler: for elemento in conjunto: if arestaEuler.v2 == elemento.v1: # Procura um canto onde possa inserir o novo ciclo, ou seja, uma aresta # que liga um vertice do ciclo antigo com o novo. # Os fors abaixo servem pra reordenar o ciclo de forma possa ser # adicionado no tour. for indexConjuntoI in range( conjunto.index(elemento), len(conjunto)): index += 1 self.tourEuler.insert(index, conjunto[indexConjuntoI]) self.tourEulerVertices.insert( index, conjunto[indexConjuntoI].v1) for indexConjuntoF in range( 0, conjunto.index(elemento)): index += 1 self.tourEuler.insert(index, conjunto[indexConjuntoF]) self.tourEulerVertices.insert( index, conjunto[indexConjuntoF].v1) concluido = True break if concluido: break index += 1 else: # Se o tour estiver vazio adiciona sem checagem de nada. for aresta in conjunto: self.tourEuler.append(aresta) self.tourEulerVertices.append(aresta.v1) print("Tour: " + self.stringCiclo(self.tourEuler)) def obterTourEuler(self, grafo, verticeRoot): ''' Método que gera o Tour de Euler, se disponível no grafo grafo a partir do vértice verticeRoot. ''' self.grafoAux = grafo self.tourEuler = [] self.tourEulerVertices = [] self.verticeCiclo = verticeRoot self.ciclo = self.passeio.geraCiclo(self.grafoAux, self.verticeCiclo) # Gera um ciclo com o nó passado por parametro como nó inicio/fim. if len(self.ciclo) == 0: #pylint: disable=C1801 # Se não retornar um ciclo significa que o grafo # não é Euleriano. return None self.adicionarArestas(self.ciclo) # Adicionar as arestas no tour de Euler. for aresta in self.ciclo: # Remove as arestas que foram pro tour do grafo, # para calculo de novos ciclos. self.grafoAux.retiraAresta(aresta.v1, aresta.v2) while not self.grafoAux.isNulo(): # Roda enquanto o grafo tiver alguma aresta. self.check = False for vertice in self.tourEulerVertices: if not self.grafoAux.isListAdjVazia(vertice): # Pega o primeiro vizinho para gerar o novo ciclo. self.verticeCiclo = self.grafoAux.primeiroListaAdj( vertice).v2 # Check representa se há algum nó que pode ser # utilizado como nó raiz. self.check = True break if not self.check: # Se não existir um possivel nó raiz o grafo # não é Euleriano. return None self.ciclo = self.passeio.geraCiclo(self.grafoAux, self.verticeCiclo) if len(self.ciclo) == 0: #pylint: disable=C1801 return None self.adicionarArestas(self.ciclo) for aresta in self.ciclo: self.grafoAux.retiraAresta(aresta.v1, aresta.v2) return self.tourEuler def stringCiclo(self, ciclo): #pylint: disable=R0201 ''' Imprime o ciclo ciclo. ''' toPrint = "" for aresta in ciclo: toPrint += "(" + str(aresta.v1) + ", " + str(aresta.v2) + ") " return toPrint