arestas.remove(aresta) grafo.removeAresta(arestas[0][0], arestas[0][1]) else: minAresta = None k = k - 1 if caminho == []: break return caminhos if __name__ == '__main__': g = Grafo() g.addVertice('a') g.addVertice('b') g.addVertice('c') g.addVertice('d') g.addVertice('e') g.addVertice('f') g.addAresta('a', 'b', 1) g.addAresta('a', 'c', 1) g.addAresta('a', 'f', 1) g.addAresta('b', 'c', 1) g.addAresta('b', 'd', 1) g.addAresta('c', 'd', 1) g.addAresta('c', 'f', 1) g.addAresta('d', 'e', 1) g.addAresta('e', 'f', 1)
class DesenhaGrafo(): """ Representa a interação entre a camada de interface (GUI) e a estrutura Grafo. """ def __init__(self, canvas, callback): self.grafo = Grafo() self.canvas = canvas self.vertices = [] #coordenadas dos vértices self.arestas = [] #coordenadas das arestas self.selecionados = set() self.selecionadas = [] #TODO: mudar esse nome. Usada para arestas. self.attCallback(callback) self.desenhaGrafo() def attCallback(self, func): """Recebe a funcao opcoes(peso, label) para chamada nessa classe""" self.callback = func def getVerticePos(self, vertice): """Retorna as coordenadas do vertice do grafo""" return self.vertices[vertice] def setVerticePos(self, vertice, coordenadas): """Seta as coordenadas do vertice do grafo""" self.vertices[vertice] = coordenadas self.canvas.move('vertice', *coordenadas) self.canvas.update() def colideVerticeAresta(self, coord, raio, checaVertice = True): """Checa colisao entre o vertice(passado como parametro por meio das coordenadas e raio), os demais vertices e as arestas""" xca, yca, xcb, ycb = coord[0]-raio, coord[1]-raio, coord[0]+raio, coord[1]+raio if checaVertice: for x,y in self.vertices: xa, ya, xb, yb = x-raio, y-raio, x+raio, y+raio if xa <= xca <= xb and ya <= yca <= yb: return (True,True) elif xa <= xcb <= xb and ya <= ycb <= yb: return (True,True) elif xa <= xcb <= xb and ya <= yca <= yb: return (True,True) elif xa <= xca <= xb and ya <= ycb <= yb: return (True,True) #as quatros retas represetam o quadrado que envolve o vertice retaA = Reta((xca,yca,xcb,yca)) retaB = Reta((xca,yca,xca,ycb)) retaC = Reta((xcb,yca,xcb,ycb)) retaD = Reta((xca,ycb,xcb,ycb)) ################################################################# for xra,yra,xrb,yrb,va,vb in self.arestas: #faz a checagem se houve algum cruzamento das retas retaX = Reta((xra,yra,xrb,yrb)) if retaX.checaInter(retaA) or retaX.checaInter(retaB) or retaX.checaInter(retaC) or retaX.checaInter(retaD): return (True,va,vb) return (False,False) def colidePontoVertice(self, coord, raio): """Checa se um ponto colide com algum vertice do grafo, ele retorna o vertice que colodiu""" for n in range(len(self.vertices)): x, y = self.vertices[n][0], self.vertices[n][1] xa, ya, xb, yb = x-raio, y-raio, x+raio, y+raio if xa < coord[0] < xb and ya < coord[1] < yb: return n return -1 def colidePontoAresta(self, coord, raio): """Checa se um ponto colide com alguma aresta do grafo""" for x,y in self.vertices: xca, yca, xcb, ycb = x-raio, y-raio, x+raio, y+raio retaA = Reta((xca,yca,xcb,yca)) retaB = Reta((xca,yca,xca,ycb)) retaC = Reta((xcb,yca,xcb,ycb)) retaD = Reta((xca,ycb,xcb,ycb)) retaX = Reta(coord) if retaX.checaInter(retaA) or retaX.checaInter(retaB) or retaX.checaInter(retaC) or retaX.checaInter(retaD): return True return False def desenhaVertice(self, coordenadas, label=None): """Cria um novo vertice e o printa na tela, caso nao colida com nenhum outro vertice ou uma aresta""" b = self.colideVerticeAresta(coordenadas, cfg.TAM_VERTICE) if not b[0]: self.grafo.addVertice(label) self.vertices.append(coordenadas) self.desenhaGrafo() else: print 'colidiu mah!!!' def apagaVertice(self, coordenadas): """Apaga o vertice que tem (x,y) = coordenadas, caso exista tal vertice""" nvertice = self.colidePontoVertice(coordenadas, cfg.TAM_VERTICE) if nvertice > -1: self.grafo.remVertice(nvertice) del self.vertices[nvertice] self.desenhaGrafo() else: print 'nao colidiu mah!!!' def apagaAresta(self,coordenadas): """Apaga a aresta caso ela contenha (x,y) = coordenadas""" x,y = coordenadas b = self.colideVerticeAresta(coordenadas, cfg.TAM_VERTICE-20, False) if b[0]: self.grafo.remAresta((b[1],b[2])) self.desenhaGrafo() def selecionaVertice(self, coordenadas,peso = -1, dir = 0, add = True): """Seleciona um vertice. Se ja houver um outro vertice selecionado e o modo aresta estiver ativo uma nova aresta é feita entre os vertices selecionados""" nvertice = self.colidePontoVertice(coordenadas, cfg.TAM_VERTICE) if nvertice > -1: if nvertice not in self.selecionados: if len(self.selecionados) > 0: if add == True: aux = self.selecionados.pop() self.grafo.addAresta((aux, nvertice),peso) if dir == 0: self.grafo.addAresta((nvertice, aux),peso) nvertice = -1 else: self.selecionados.add(nvertice) else: self.selecionados.remove(nvertice) nvertice = -1 self.desenhaGrafo() else: self.selecionados.clear() self.desenhaGrafo() print 'num selecionou ninguem!!!' return nvertice def moverTodos(self, posicao): """Move todo o grafo""" print posicao dx, dy = posicao for i, vertice in enumerate(self.vertices): self.vertices[i] = (vertice[0] + dx, vertice[1] + dy) print self.vertices self.desenhaGrafo() def buscaProfundidade(self, verticePos): """Chama o método de busca de pronfudidade do grafo e pisca os vertices passado por ele""" inicial = self.colidePontoVertice(verticePos, cfg.TAM_VERTICE) ordem = self.grafo.buscaProfundidade(inicial) self.animaGrafo(ordem,1.0) print ordem def buscaLargura(self, verticePos): """Chama o método de busca por largura do grafo e pisca os vertices passado por ele""" inicial = self.colidePontoVertice(verticePos, cfg.TAM_VERTICE) ordem = self.grafo.buscaLargura(inicial) self.animaGrafo(ordem,1.0) print ordem def agmPrim(self): """Chama a o metodo de prim do grafo e muda o cor das arestas da arvore geradora minima""" ordem = self.grafo.agmPrim() self.selecionadas.extend(ordem) self.desenhaGrafo() def agmKruskal(self): """Chama a o metodo de Kruskal do grafo e muda o cor das arestas da arvore geradora minima""" ordem = self.grafo.agmKruskal() print ordem self.selecionadas.extend(ordem) self.desenhaGrafo() def colorir(self): """Chama o metodo de coloracao do grafo e os colore na tela""" cores = self.grafo.colorir() self.coloreGrafo(cores) def _gerarCores(self, n): """Gera as coloracoe dos vertices""" print 'gerar', n, 'cores' lista = [] i = 0 repetir = False while i < n: repetir = False novacor = random.randint(0,255), random.randint(0,255), random.randint(0,255) print novacor for cor in lista: dif = abs(cor[0] - novacor[0]) + abs(cor[1] - novacor[1]) + abs(cor[2] - novacor[2]) print dif, if dif < 20: repetir = True break if not repetir: lista.append(novacor) i += 1 return lista def coloreGrafo(self, cores): """Faz a coloracao dos vertices""" ncores = max(cores) listaCores = self._gerarCores(ncores) for indice in range(len(self.vertices)): x, y = self.vertices[indice] self.circuloFull((x,y), cfg.TAM_VERTICE, str(indice), "#%02x%02x%02x" % listaCores[cores[indice]-1]) def circuloFull(self, centro, raio, tag, ccor = None): """Cria um novo circulo de outra cor por cima dos vertices""" x, y = centro cor = cfg.COR_VERTICE gamb = int(tag) #TODO: warning: gambiarra... if gamb in self.selecionados: cor = cfg.COR_SELECIONADA elif ccor is not None: cor = ccor self.canvas.create_oval(x-raio, y-raio, x+raio,y+raio, tag=tag, fill=cor,outline=cor, width=2) def minDijkstra(self,sour,dest): """Chama a o metodo de Dijkstra para menor caminho do grafo e muda o cor das arestas mostrando qual e esse caminho""" ordem = self.grafo.min_dijkstra(sour,dest) print ordem self.selecionadas.extend(ordem) self.desenhaGrafo() def minBellman(self,sour,dest): """Chama a o metodo de Bellman para menor caminho do grafo e muda o cor das arestas mostrando qual e esse caminho""" ordem = self.grafo.minBellman(sour,dest) print ordem self.selecionadas.extend(ordem) self.desenhaGrafo() #TODO: refatorar essa funcao. Muitos parametros. def circulo(self, centro, raio, tag, ccor = None): """Desenha um circulo na tela""" x, y = centro cor = cfg.COR_VERTICE gamb = int(tag) #TODO: warning: gambiarra... if gamb in self.selecionados: cor = cfg.COR_SELECIONADA elif ccor is not None: cor = ccor self.canvas.create_oval(x-raio, y-raio, x+raio,y+raio, tag=tag, outline=cor, width=2) def animaGrafo(self, lista, passo=cfg.ANM_PASSO): """Metódo que faz animacao nos metodos de busca""" self.selecionados.clear() self.desenhaGrafo() self.canvas.update() time.sleep(passo) back = -1 for indice in lista: if back >= 0: self.circulo(self.vertices[back], cfg.TAM_VERTICE, str(indice),ccor=cfg.COR_ANIMACAO2) self.canvas.create_text(self.vertices[back],text=str(back),fill=cfg.COR_TEXTO1) self.circulo(self.vertices[indice], cfg.TAM_VERTICE, str(indice),ccor=cfg.COR_ANIMACAO1) self.canvas.create_text(self.vertices[indice],text=str(indice),fill=cfg.COR_TEXTO1) back = indice self.canvas.update() time.sleep(passo) time.sleep(passo) self.desenhaGrafo() def tremerGrafo(self): """Faz a tela tremer de um modo nao muito bonito""" y=10 for x in range(1,20): self.canvas.move('all',x,y) self.canvas.update() time.sleep(0.1) self.canvas.move('all',-x,-y) self.canvas.update() y-=1 time.sleep(0.1) for x in range(20,1,-1): self.canvas.move('all',x,y) self.canvas.update() time.sleep(0.1) self.canvas.move('all',-x,-y) self.canvas.update() time.sleep(0.1) y+=1 def desenhaGrafo(self): """Faz todo o tratamento para reprintar todo o grafo na tela""" w,h = self.canvas["width"],self.canvas["height"] self.canvas.delete('all') self.canvas.create_rectangle(0, 0, w, h, fill=cfg.COR_TELA) self.arestas = [] #TODO: pensar se seria melhor fazer self.arestas[:] = [] raio = cfg.TAM_VERTICE peso, direcao, label = self.callback() for indice in range(len(self.vertices)): x, y = self.vertices[indice] self.circulo((x,y), cfg.TAM_VERTICE, str(indice)) if label == 0: self.canvas.create_text(self.vertices[indice],text=str(indice), tag = str(indice), activefill="#405252", fill=cfg.COR_TEXTO2) else: self.canvas.create_text(self.vertices[indice],text=self.grafo.labels[indice], tag = str(indice), activefill="#405252", fill=cfg.COR_TEXTO2) for va in range(len(self.grafo.matriz)): arestas = self.grafo.matriz[va] for vb, pesob in arestas: xa, ya = self.vertices[va] xb, yb = self.vertices[vb] #print pesob ang = math.atan2(xb-xa, yb-ya) ang2 = math.atan2(xa-xb, ya-yb) #print int(15*math.cos(ang)), int(15*math.sin(ang)) if peso == 1: self.canvas.create_text(((xb+xa)/2 + int(15*math.sin(ang+1.57)), (ya+yb)/2 + int(15*math.cos(ang+1.57))), text=str(pesob), tag = str(va)+'-'+str(vb), fill=cfg.COR_SELECIONADA) x, y = xa + raio * math.sin(ang), ya + raio * math.cos(ang) x2, y2 = xb + raio * math.sin(ang2), yb + raio * math.cos(ang2) cor = 'white' if (va, vb) in self.selecionadas or (vb, va) in self.selecionadas: cor = cfg.COR_ARESTA2 self.canvas.create_line(x,y,x2,y2, tag=str(va)+'-'+str(vb), fill=cor,width=2, arrow="last") self.arestas.append((x,y,x2,y2,va,vb)) self.selecionadas = [] def info(self): """Fornece informacoes sobre a estrutura.""" info = [] info.append(len(self.vertices)) for a,b in self.vertices: info.append(a) info.append(b) info.extend(self.grafo.info()) return info def carregar(self, info): """Carrega o grafo e desenha na tela""" indice, nvertices = 1, int(info[0]) while (indice < 2 * nvertices + 1): self.vertices.append((int(info[indice]), int(info[indice+1]))) indice += 2 self.grafo.carregar(info[2 * nvertices + 1:]) self.desenhaGrafo()
print("3. Representacao matematica") print("4. Visualizar vertices adjacentes") print("5. Verificar existencia de aresta") print("6. Calcular grau de um vertice") print("7. Aplicar algoritmo de Prim para gerar Arvore minima") print("8. Aplicar algoritmo de Dijsktra") print("9. Sair") key = input() os.system('cls||clear') if (key == '1'): #Insercao de vertices print("Insira a identificacao do vertice") vertex = input() vertex = No(vertex) if (grafo.addVertice(vertex)): print("Vertice adicionado") else: print("Vertice ja adicionado anteriormente") input() elif (key == '2'): #Insercao de arestas print("Vertice 1: ", end="") vertex = input() vertex = grafo.getVertice(vertex) print("\nVertice 2: ", end="") vertex2 = input() vertex2 = grafo.getVertice(vertex2) if (vertex != None and vertex2 != None):
from grafo import Grafo import dijkstra g = Grafo() pesos = True print "O grafo utilizado para o programa a seguir segue em anexo na imagem nsfnet.jpg\n" res = raw_input("Voce deseja o grafo com pesos?(S/n): ") if res == 'n' or res == 'N': pesos = False g.addVertice("WA") g.addVertice("CA1") g.addVertice("CA2") g.addVertice("UT") g.addVertice("CO") g.addVertice("NE") g.addVertice("IL") g.addVertice("TX") g.addVertice("GA") g.addVertice("PA") g.addVertice("MI") g.addVertice("NY") g.addVertice("DC") g.addVertice("NJ") if pesos: print "Usando grafo com pesos"
print('''[ 1 ] Grafo Dirigido\n[ 2 ] Grafo Não Dirigido\n[ 3 ] Entre Com seu grafo''') opc = int(input('Escolha uma Opção: ')) if opc != 1 and opc != 2 and opc != 3: print('ERRO, OPÇÃO INVALIDA') break if opc == 3: grafo = str(input('Entre com o caminho de onde o Grafo se encontra\n')) else: grafo = '../grafos/grafo' + str(opc)+'.txt' with open(grafo, mode='r', encoding='utf-8') as arquivo: tipo = arquivo.readline()[:-1] numero_de_vertices = int(arquivo.readline()) g = Grafo(numero_de_vertices, tipo) for linha in arquivo: dados = linha.split() u = g.addVertice(str(dados[0])) v = g.addVertice(str(dados[1])) # bloco try se o grafo for ponderado try: peso = dados[2] except IndexError as error: peso = 1 g.addAresta(u, v, int(peso)) g.sort() while True: print('Como deseja representar o Grafo?') print('''[ 1 ] Lista de Adjacencias\n[ 2 ] Matriz de Adjacencias\n[ 3 ] Ir para os Algoritmos''') opc = int(input('Escolha uma Opção: ')) if opc == 1: g.lista_de_adjacencias()