Esempio n. 1
0
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
Esempio n. 2
0
    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
Esempio n. 3
0
 def __init__(self):
     self.tourEuler = []
     self.tourEulerVertices = []
     self.ciclo = []
     self.passeio = PasseioGrafo()
     self.grafoAux = GrafoTAD(0)
     self.check = False
     self.verticeCiclo = 0
Esempio n. 4
0
 def __init__(self):
     self.grafoArvore = GrafoTAD(0)
     self.arestas = []
     self.passeio = PasseioGrafo()
Esempio n. 5
0
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)
Esempio n. 6
0
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