def buscaLargura(G: Grafo, s): # controla se o i-ésimo (-1) vértice já foi visitado C = G.qtdVertices() * [ False, ] # nível do i-ésimo (-1) vértice D = G.qtdVertices() * [ -1, ] # antecessor do i-ésimo (-1) vértice A = G.qtdVertices() * [ None, ] C[s - 1] = True D[s - 1] = 0 Q = [s] for u in Q: for v, _ in G.vizinhos(u, com_peso=True): if not C[v - 1]: C[v - 1] = True D[v - 1] = D[u - 1] + 1 A[v - 1] = u Q.append(v) return D, A
def prim_flycombi(grafo,peso,vertice = None): if vertice == None: vertice = grafo.vertice_random() costo = 0 visitados = set() visitados.add(vertice) heap = [] for w in grafo.adyacentes(vertice): arista = grafo.peso(vertice,w) if peso == "tiempo": heapq.heappush(heap,(int(arista.tiempo),vertice,w,arista)) elif peso == "precio": heapq.heappush(heap,(int(arista.precio),vertice,w,arista)) arbol = Grafo() while len(heap) > 0: p,v,w,a = heapq.heappop(heap) if w in visitados: continue arbol.agregar_arista(v,w,a) costo += int(p) visitados.add(w) for x in grafo.adyacentes(w): if x not in visitados: arista = grafo.peso(w,x) if peso == "tiempo": heapq.heappush(heap,(int(arista.tiempo),w,x,arista)) elif peso == "precio": heapq.heappush(heap,(int(arista.precio),w,x,arista)) return arbol,costo
def setUp(self): self.arr_tests = [] self.arr_tests.append(Grafo()) self.arr_tests[0].adiciona_vertice(0) self.arr_tests[0].adiciona_vertice(1) self.arr_tests[0].adiciona_vertice(2) self.arr_tests[0].adiciona_vertice(3) self.arr_tests[0].adiciona_vertice(4) self.arr_tests[0].adiciona_vertice(5) self.arr_tests[0].adiciona_vertice(6) self.arr_tests[0].adiciona_aresta(0, 1) self.arr_tests[0].adiciona_aresta(1, 2) self.arr_tests[0].adiciona_aresta(1, 3) self.arr_tests[0].adiciona_aresta(2, 5) self.arr_tests[0].adiciona_aresta(3, 5) self.arr_tests[0].adiciona_aresta(4, 5) self.arr_tests.append(Grafo()) self.arr_tests[1].adiciona_vertice(0) self.arr_tests[1].adiciona_vertice(1) self.arr_tests[1].adiciona_vertice(2) self.arr_tests[1].adiciona_vertice(3) self.arr_tests[1].adiciona_aresta(0, 1) self.arr_tests[1].adiciona_aresta(1, 2) self.arr_tests[1].adiciona_aresta(2, 3) self.arr_tests[1].adiciona_aresta(3, 1)
def edmonds_karp(G_f: Grafo, s: int, t: int): # controla se o i-ésimo (-1) vértice já foi visitado C = G_f.qtdVertices() * [ False, ] # antecessor do i-ésimo (-1) vértice A = G_f.qtdVertices() * [ None, ] C[s - 1] = True Q = [s] for u in Q: # u=3 for v in G_f.vizinhos(u): # v=4 e = (u, v) if not C[v - 1] and G_f.w[e] > 0: C[v - 1] = True A[v - 1] = u # criar caminho if v == t: p = (t, ) w = t while w != s: w = A[w - 1] p = (w, ) + p return p Q.append(v) return None
def novoGrafo(*itens): g = Grafo() for item in itens: g.inserir(item) return g
def itinerario(grafo_sedes, archivo_recomendaciones, mapa_kml): """Recibe un itinerario que nos indica cuales son las sedes que debemos visitar antes que otras, y con ellas hace un nuevo grafo con el que llama a orden topologico, para luego imprimir su reccorrido segun el itinerario pasado.""" try: with open(archivo_recomendaciones, "r") as recomendaciones: lector = csv.reader(recomendaciones) grafo_recomendaciones = Grafo() for sede_1,sede_2 in lector: if not grafo_recomendaciones.vertice_pertenece(sede_1): grafo_recomendaciones.agregar_vertice(sede_1) if not grafo_recomendaciones.vertice_pertenece(sede_2): grafo_recomendaciones.agregar_vertice(sede_2) if grafo_sedes.vertices_conectados(sede_1, sede_2): grafo_recomendaciones.agregar_arista(sede_1, sede_2, grafo_sedes.obtener_peso_arista(sede_1, sede_2)) except OSError: print("No se pudo abrir el archivo {}".format(archivo_recomendaciones)) return recorrido = orden_topologico(grafo_recomendaciones) if (recorrido): imprimir_recorrido(grafo_sedes, recorrido, 0) crear_kml(grafo_sedes, "itinerario {}".format(archivo_recomendaciones), recorrido, mapa_kml)
def complemento(self): comp= Grafo() for v in self.V: for w in self.V: if v != w and (v, w) not in self.E: comp.conecta(v, w, 1) return comp
def gera_grafo(df) -> Grafo: global grafo grafo = Grafo(df) for i in range(len(colunas)): # Pega o nome da cidade pelo índice cidade_origem = colunas[i] for j in range(len(colunas)): # Pega o peso e o destino da aresta e adiciona no objeto Grafo destino = df.index[j] peso = df.iloc[j][cidade_origem] #aresta = dict(rota=(cidade_origem, destino), peso=peso) if peso != '-': aresta = (int(cidade_origem), int(destino), int(peso)) grafo.adiciona_arestas(aresta) fitness = mlrose.TravellingSales(distances=grafo.arestas) # Define optimization problem object problem_fit = mlrose.TSPOpt(length=8, fitness_fn=fitness, maximize=False) best_state, best_fitness = mlrose.genetic_alg(problem_fit, mutation_prob=0.2, max_attempts=100, random_state=2) print(fitness) return grafo
def ciudades() -> Grafo: """ Ejemplo 2: Ciudades """ albacete = 'Albacete' alicante = 'Alicante' cordoba = 'Córdoba' madrid = 'Madrid' valencia = 'Valencia' # Crear grafo y agregar nodos, esta vez mediante el constructor grafo = Grafo(albacete, alicante, cordoba, madrid, valencia) # Conectar nodos con sus respectivas distancias grafo.connect(albacete, alicante, 96) grafo.connect(albacete, cordoba, 254) grafo.connect(albacete, madrid, 100) grafo.connect(albacete, valencia, 105) grafo.connect(alicante, valencia, 110) grafo.connect(cordoba, madrid, 102) grafo.connect(madrid, valencia, 98) imprimir_camino(grafo, cordoba, alicante) return grafo
def itinerario_cultural(archivo_itinerario, grafo_aeropuertos, aeropuertos): '''Recibe un archivo existente con formato csv, donde la primera linea incluye las ciudades que se desea visitar, y las subsiguientes lineas indican qué ciudades deben ser visitadas antes de qué otras. Imprime por salida estandar el orden en que deben ser visitadas y el recorrido que se debe realizar, para que la cantidad de escalas sea mínima. ''' with open(archivo_itinerario) as itinerario: itinerario = csv.reader(itinerario) ciudades = next(itinerario) grafo_ciudades = Grafo(True, ciudades) for ciudad_a, ciudad_b in itinerario: grafo_ciudades.agregar_arista(ciudad_a, ciudad_b) orden = orden_topologico_dfs(grafo_ciudades) imprimir_camino(orden, ', ') camino_total = [] for i in range(len(orden) - 1): origen, destino = orden[i], orden[i + 1] camino_min = camino_minimo(grafo_aeropuertos, aeropuertos, origen, destino, True) camino_total.extend(camino_min) if i != len(orden) - 2: camino_total.pop() imprimir_camino(camino_min, SEP_CAMINO) return camino_total
def parse(file): ''' Parsea un archivo .pjk (que posee labels y pesos) a una estructura Grafo. Primero se agregan los vértices, siendo: - line[0] el número de vértices, - line[1] el label. Luego se agregan las aristas, siendo: - line[0] el vértice origen, - line[1] el vértice destino, - line[2] el peso. Devuelve el grafo. ''' grafo = Grafo() vert_dict = { } # Diccionario de vértices con su número de vértice usado para with open( file, "r") as f: # luego agregar las aristas según el número de vértice. vertices = int(f.readline().split(' ')[1]) # Cantidad de vertices for line in f: # Agrega los vertices line = line.split('"') grafo[line[1]] = {} vert_dict[int(line[0])] = line[1] if int( line[0] ) == vertices: # Corta cuando llega al número de vertices predefinido break f.readline() for line in f: # Agrega las aristas line = line.split(' ') line = [int(i) for i in line] grafo.agregar_arista(vert_dict[line[0]], vert_dict[line[1]], line[2]) return grafo
def test_vertice_pertenece(self): #creo un grafo no dirigido grafo = Grafo(False) #le agrego un vértice grafo.agregar_vertice("A") #me fijo si el vértice pertenece o no al grafo self.assertTrue(grafo.vertice_pertenece("A"))
def prim(G: Grafo): # vértice arbitrário de G r = randint(1, G.n) # antecessor do i-ésimo (-1) vértice A = G.qtdVertices() * [ None, ] K = G.qtdVertices() * [ float('inf'), ] K[r - 1] = 0 Q = list(zip(K, range(1, G.n + 1))) heapify(Q) V_q = set(range(1, G.n + 1)) # para manter controle dos vértices visitados while len(V_q) > 0: k_u, u = heappop(Q) try: V_q.remove(u) except KeyError: # if `u` was already visited continue for v in G.vizinhos(u): w_uv = G.peso({u, v}) if v in V_q and w_uv < K[v - 1]: A[v - 1] = u K[v - 1] = w_uv heappush(Q, (w_uv, v)) return A
def pruebas_camino_minimo(): print("PRUEBAS CAMINO MINIMO\n") grafo = Grafo() grafo.add_edge(1, 2) grafo.add_edge(2, 3) grafo.add_edge(3, 4) camino = funciones.camino_minimo(grafo, 1, 4) for v in camino[:-1]: print(v, "-> ", end='') print(camino[-1]) camino2 = funciones.camino_minimo(grafo, 2, 4) for v in camino2[:-1]: print(v, "-> ", end='') print(camino2[-1]) grafo.add_edge(2, 4) camino = funciones.camino_minimo(grafo, 1, 4) for v in camino[:-1]: print(v, "-> ", end='') print(camino[-1]) camino2 = funciones.camino_minimo(grafo, 2, 4) for v in camino2[:-1]: print(v, "-> ", end='') print(camino2[-1]) grafo.add(5) camino = funciones.camino_minimo(grafo, 1, 5) print(camino)
def grafoGilbert(n, p, dirigido=False, auto=False): """ Genera grafo aleatorio con el modelo Gilbert :param n: número de nodos (> 0) :param p: probabilidad de crear una arista (0, 1) :param dirigido: el grafo es dirigido? :param auto: permitir auto-ciclos? :return: grafo generado """ # Crear el grafo g g = Grafo() # Validar parámetros if n <= 0 or p < 0 or p > 1: print("Solo valores n>0 y 0<=p<=1") return g print("Gilbert(" + str(n) + ", " + str(p) + ")") # Agregar n nodos for nodo in range(n): g.agreganodo(nodo) # Para todos los pares de nodos diferentes, agregar las posibles aristas con probabilidad p for u in range(n): for v in range(n): if random.random() <= p and u != v: agregada = g.agregaarista(u, v) else: agregada = 0 # Regresar el grafo g return g
def coloracao(grafo: Grafo): # grafo não-dirigido e não-ponderado vertices = sorted(list(grafo.getVertices()), key=lambda x: len(grafo.vizinhos(x)), reverse=True) mapa_de_cores = {} cores_usadas = [] for vertice in vertices: cores_disponiveis = [True] * len(vertices) for vizinho in grafo.vizinhos(vertice): if vizinho in mapa_de_cores: cor = mapa_de_cores[vizinho] cores_disponiveis[cor] = False for cor, disponivel in enumerate(cores_disponiveis): if disponivel: mapa_de_cores[vertice] = cor if cor not in cores_usadas: cores_usadas.append(cor) break print("Número mínimo de cores:", len(cores_usadas)) print("Mapeamento vértice-cor: ", mapa_de_cores) return mapa_de_cores
def cargar_en_grafo(archivoMapa, lineaEspia1, lineaEspia2, lineaAeropuerto, distancia): '''Carga el mapa en un grafo, y devuelve los puntos donde se encuentran el espia 1, 2 y el aeropuerto. Si se produjo un error con el archivoMapa se informa ''' pos_espia_1 = -1 pos_espia_2 = -1 pos_aeropuerto = -1 grafo = Grafo() try: archivo = open(archivoMapa) nroLinea = 0 for linea in archivo: #'p1.x p1.y - p2.x p2.y' puntos = linea.split(' - ') #['p1.x p1.y','p2.x p2.y'] coordenadas = [puntos[0].split(), puntos[1].split() ] #[['p1.x','p1.y'],['p2.x','p2.y'] punto1 = (int(coordenadas[0][0]), int(coordenadas[0][1])) punto2 = (int(coordenadas[1][0]), int(coordenadas[1][1])) peso = distancia(punto1, punto2) grafo.agregar_arista(punto1, punto2, peso) if (nroLinea == lineaEspia1): pos_espia_1 = punto1 if (nroLinea == lineaEspia2): pos_espia_2 = punto1 if (nroLinea == lineaAeropuerto): pos_aeropuerto = punto1 nroLinea += 1 except IOError, e: print MSJ_ERROR, e print MSJ_IOERROR, archivoMapa raise IOError
class Ciclo: def __init__(self, file): self.g = Grafo(file) self.C = dict() def buscar_subciclo(self, v): Ciclo = [] Ciclo.append(v) t = v while True: print(v, self.g.vizinhos(v)) for vizinho in self.g.vizinhos(v): print(v, vizinho) if not self.C[(v, vizinho)]: self.C[(v, vizinho)] = True self.C[(vizinho, v)] = True Ciclo.append(vizinho) v = vizinho print("Coloquei V", v) break if t == v: if len(Ciclo) == 1: return (False, None) break def calcular_ciclo(self): for e in self.g.E: self.C[(e[0], e[1])] = False self.C[(e[1], e[0])] = False self.buscar_subciclo(3)
def cargar_archivo(ruta): g = Grafo() with open(ruta) as archivo: arch = csv.reader(archivo, delimiter='\t') for linea in arch: v1, v2 = linea[0], linea[1] g.agregar_arista(v1, v2) return g
def cria_grafo(inicio: int, fim: int) -> Grafo: """ Lê os dados do grafo do arquivo .txt e retorna a instância do Grafo. :param inicio: id do nó inicial do grafo :param fim: id do nó objetivo do grafo :return: instância da classe Grafo """ # Lê o arquivo com as informações do grafo with open('dist8.txt', 'r') as f: linhas = f.readlines() # Primeira linha do arquivo indica a quantidade de cidades quantidade = int(linhas[0]) # Cria a lista de cidades cidades = [Cidade(i) for i in range(quantidade)] # Obtém a matriz de distância entre as cidades distancias = np.array( [ linhas[i].strip('\n').split(' ') # strip remove o \n no final da linha e split separa os número por espaços for i in range(1, quantidade + 1) ] ).astype(float) # Transforma os números de string pra int # Preenche a lista de vizinhos de cada cidade a partir da matriz de distâncias for i in range(quantidade): for j in range(quantidade): if distancias[i, j] > 0: cidades[i].vizinhos.append(cidades[j]) # Obtém as matriz de heurísticas heuristicas = np.array( [ linhas[i].strip('\n').split(' ') # strip remove o \n no final da linha e split separa os número por espaços for i in range(quantidade + 2, len(linhas)) ] ).astype(float) # Transforma os números de string pra int # Cria instância da classe Grafo com as informações lidas do arquivo grafo = Grafo(cidades, distancias, heuristicas) if inicio < 0 or inicio >= quantidade: print('Valor inválido para o id do nó inicial.', file=sys.stderr) exit(0) if fim < 0 or fim >= quantidade: print('Valor inválido para o id do nó final.', file=sys.stderr) exit(0) grafo.id_inicio = inicio grafo.id_fim = fim return grafo
def inicializacao(self, s): # Inicia a lista de pesos # Preenche a lista de pesos com peso infinito self.peso_caminho = [sys.maxsize] * Grafo.qnt_vertices(self.g1) # Inicia a lista de vertices anteriores # Preenche a lista com None self.lista_anterior = [None] * Grafo.qnt_vertices(self.g1) self.peso_caminho[s - 1] = 0
def __init__(self, mapa, fabricas, juguetes, idEsquinaUbicacion, maximoPeso): ''' Constructor ''' self.grafo = Grafo() self.agenda = dict() self.maximoPeso = int(maximoPeso) self.idUbicacion = idEsquinaUbicacion cargarEsquinasYCalles(self.grafo, mapa) cargarFabricas(self.grafo, self.agenda, fabricas) cargarJuguetes(self.grafo, self.agenda, juguetes)
def procesar_archivos(): aeropuertos = {} vuelos = Grafo(False) with open(sys.argv[1]) as a: a_csv = csv.reader(a) for linea in a_csv: aeropuertos[linea[0]] = aeropuertos.get(linea[0], []) + [linea[1]] with open(sys.argv[2]) as v: v_csv = csv.reader(v) for origen, destino, tiempo, precio, cant_vuelos in v_csv: vuelos.agregar_arista(origen, destino, (int(tiempo), int(precio), int(cant_vuelos))) return aeropuertos, vuelos
def main(): g=Grafo() g["fer"]={} g["fer"]["flor"]="hna" g["fer"]["fds"]="hno" g["fer"]["emilia"]="mama" g["fer"]["tony"]="papa" lista = g.adyacentes("fer") print(lista) if("fer" in g): print("esta fer") else: print("no esta fer")
def _actores(): actores_por_pelicula = {} actores = set() with open("actores_test.csv") as f: for l in f: splitted = l.strip().split(",") actor = splitted[0] actores.add(actor) peliculas = splitted[1:] for peli in peliculas: if peli not in actores_por_pelicula: actores_por_pelicula[peli] = [] actores_por_pelicula[peli].append(actor) g = Grafo() for peli in actores_por_pelicula: if len(actores_por_pelicula[peli]) < 2: continue for i in range(len(actores_por_pelicula[peli])): for j in range(i + 1, len(actores_por_pelicula[peli])): if actores_por_pelicula[peli][i] not in g: g.agregar_vertice(actores_por_pelicula[peli][i]) if actores_por_pelicula[peli][j] not in g: g.agregar_vertice(actores_por_pelicula[peli][j]) g.arista(actores_por_pelicula[peli][i], actores_por_pelicula[peli][j]) return g
def main(): if len(sys.argv) != 3: print("Cantidad de parámetros errónea") return flycombi = Grafo(no_dirigido) with open(sys.argv[1], 'r') as aeropuertos: reader = csv.reader(aeropuertos, delimiter=',') for linea in reader: if linea[0] in ciudades: ciudades[linea[0]].append(linea[1]) else: ciudades[linea[0]] = [linea[1]] flycombi.agregar_vertice(linea[1]) flycombi.agregar_dato(linea[1], 'ciudad', linea[0]) with open(sys.argv[2], 'r') as vuelos: reader = csv.reader(vuelos, delimiter=',') for linea in reader: peso = biblioteca_grafo.Peso(linea[2], linea[3], linea[4]) flycombi.agregar_arista(linea[0], linea[1], peso) for operacion in sys.stdin: if operacion[-1] == '\n': operacion = operacion[:-1] comando = operacion.split(" ", 1) if not identificar_operacion(comando, flycombi): print("Error en comando", comando[0]) return
def __init__(self, cantidad_vertices=0, pesos=[], *args, **kwargs): """ O(1) si los valores de los parámetros son los definidos por defecto. O(|E|*log(|V|)) """ Grafo.__init__(self, *args, **kwargs) for i in xrange(cantidad_vertices): self.add_node() for peso in pesos: if peso[2] < 0: raise Exception('Una arista no puede tener peso negativo.') # O(log(|V|)) self.connect(peso[0], peso[1], peso[2])
def main(): nome_arquivo = input("Digite o caminho do arquivo:") # arquivo para leitura arquivo = open(nome_arquivo, "r") quantidade = int(arquivo.readline()) grafo = Grafo() # salva os objetos criados para economizar espaco e utilizá-los # na criação das arestas vertices_criados = {} primeiro_vertice = Vertice(1) vertices_criados[1] = primeiro_vertice grafo.adiciona_vertice(primeiro_vertice) for i in range(2, quantidade + 1): vertices_criados[i] = Vertice(i) grafo.adiciona_vertice(vertices_criados[i]) for leitura in arquivo: # separa dois valores pelo espaco valores_vertices = leitura.split() v1 = vertices_criados[int(valores_vertices[0])] v2 = vertices_criados[int(valores_vertices[1])] grafo.adiciona_aresta(v1, v2) try: resultado = encontrar_caminho_projetos(grafo, primeiro_vertice) print("A solução para este problema é: ", resultado) except Exception as ex: print(ex)
def database(ruta_aeropuertos, ruta_vuelos): """ Recibe rutas de aeropuertos y vuelos para procesar la información y guardarla en memoria. Devuelve el grafo ya armado. """ with open(ruta_aeropuertos) as aeropuertos, open(ruta_vuelos) as vuelos: lector_aeropuertos = csv.reader(aeropuertos) lector_vuelos = csv.reader(vuelos) grafo_general = Grafo() datos_aeropuertos = { } #Ciudad y posición geográfica de cada aeropuerto. aeropuertos_de_ciudades = { } #Cuando me pasan por comando la ciudad busco los aeropuertos que tiene acá. for ciudad, codigo, latitud, longitud in lector_aeropuertos: grafo_general.agregar_vertice(codigo) datos_aeropuertos[codigo] = datos_aeropuertos.get( codigo, [ciudad, latitud, longitud]) aeropuertos_de_ciudades[ciudad] = aeropuertos_de_ciudades.get( ciudad, []) aeropuertos_de_ciudades[ciudad].append(codigo) for origen, destino, tiempo, precio, cant_vuelos in lector_vuelos: #Arista con formato (precio,tiempo,cant_vuelos) grafo_general.agregar_arista(origen, destino, (precio, tiempo, cant_vuelos)) grafo_general.agregar_arista(destino, origen, (precio, tiempo, cant_vuelos)) return grafo_general, datos_aeropuertos, aeropuertos_de_ciudades
def grafoGeografico(n, r, dirigido=False, auto=False): """ Genera grafo aleatorio con el modelo geográfico simple :param n: número de nodos (> 0) :param r: distancia máxima para crear un nodo (0, 1) :param dirigido: el grafo es dirigido? :param auto: permitir auto-ciclos? :return: grafo generado """ # Crear grafo g g = Grafo() # Validar parámetros if n <= 0 or r < 0 or r > 1: print("Solo valores n>0 y 0<=r<=1") return g print("GeograficoSimple(" + str(n) + "," + str(r) + ")") # Agregar n nodos al grafo g, cada nodo con coordenadas aleatorias for i in range(n): if g.agreganodo(i) == 1: nodo = g.obtenernodo(i) nodo.x = random.random() nodo.y = random.random() # Para cada par de nodos distintos, agregar la arista al grafo g si la distancia es menor que r for i in range(n): for j in range(n): if i != j: d = distancia(g.obtenernodo(i), g.obtenernodo(j)) if d <= r: g.agregaarista(i, j) # Regresar el grafo g return g
def pruebas_beetweeness(): print("\n\nPRUEBA BEETWEENESS\n") grafo = Grafo() grafo.add_edge(1, "centro") grafo.add_edge(2, "centro") grafo.add_edge(3, "centro") grafo.add_edge(4, "centro") grafo.add_edge(5, "centro") grafo.add_edge(2, 5) importantes = funciones.beetweeness(grafo, 2) print(importantes[0]) print(importantes[1])
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 __init__(self, mapa, fabricas, juguetes, idEsquinaUbicacion, maximoPeso): ''' Constructor ''' self.grafo = Grafo() self.agenda = dict() self.maximoPeso = int(maximoPeso) self.idUbicacion = idEsquinaUbicacion cargarEsquinasYCalles(self.grafo,mapa) cargarFabricas(self.grafo, self.agenda, fabricas) cargarJuguetes(self.grafo, self.agenda, juguetes)
def _crear_grafo_desde_archivo(self, archivo): """Crea el grafo y le carga la configuracion del archivo.""" self.grafo = Grafo() try: with open(archivo,"r") as f: #agregado de vertices for i in xrange(int(f.readline())): args = f.readline().split() self.musico_a_id_vertice[args[1]] = args[0] self.grafo.agregar_vertice(args[0], dato_vertice=args[1]) #agregado de aristas for i in xrange(int(f.readline())): args = f.readline().split() self.grafo.agregar_arista(args[1], args[2]) except IOError: raise ArchivoInvalidoError("Error de archivo") except ValueError: raise ArchivoInvalidoError("Las cantidades no son numeros") except IndexError: raise ArchivoInvalidoError("Formato inadecuado") except GrafoError: raise ArchivoInvalidoError("Forma un grafo inadecuado")
class TestStringMethods(unittest.TestCase): def setUp(self): self.grafo = Grafo() def test_atingivel(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.grafo.insertNo(No(6)) self.grafo.insertNo(No(7)) self.assertEqual(len(self.grafo.nos), 7) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 2)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.grafo.insertAresta(Aresta(3, 4)) self.grafo.insertAresta(Aresta(4, 6)) self.assertEqual(len(self.grafo.arestas), 7) self.assertEqual(self.grafo.atingivel(1, 6), True) self.assertEqual(self.grafo.atingivel(1, 7), False) def test_caminho(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.grafo.insertNo(No(6)) self.grafo.insertNo(No(7)) self.assertEqual(len(self.grafo.nos), 7) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 2)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.grafo.insertAresta(Aresta(3, 4)) self.grafo.insertAresta(Aresta(4, 6)) self.assertEqual(len(self.grafo.arestas), 7) self.assertEqual(self.grafo.caminho(1, 6), [1, 5, 4, 6]) self.assertEqual(self.grafo.caminho(1, 3), [1, 2, 3]) def test_conexo(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.grafo.insertNo(No(6)) self.assertEqual(len(self.grafo.nos), 6) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 2)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.grafo.insertAresta(Aresta(3, 4)) self.grafo.insertAresta(Aresta(4, 6)) self.assertEqual(len(self.grafo.arestas), 7) self.assertEqual(self.grafo.conexo(), True) self.grafo.insertNo(No(7)) self.assertEqual(len(self.grafo.nos), 7) self.assertEqual(self.grafo.conexo(), False) def test_ciclico_true(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.grafo.insertNo(No(6)) self.assertEqual(len(self.grafo.nos), 6) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 2)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.grafo.insertAresta(Aresta(3, 4)) self.grafo.insertAresta(Aresta(4, 6)) self.assertEqual(len(self.grafo.arestas), 7) self.assertEqual(self.grafo.ciclico(), True) def test_ciclico_false(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.grafo.insertNo(No(6)) self.assertEqual(len(self.grafo.nos), 6) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.grafo.insertAresta(Aresta(4, 6)) self.assertEqual(len(self.grafo.arestas), 5) print self.grafo self.assertEqual(self.grafo.ciclico(), False) def test_ciclico_n_conexo_true(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.grafo.insertNo(No(6)) self.grafo.insertNo(No(7)) self.grafo.insertNo(No(8)) self.grafo.insertNo(No(9)) self.grafo.insertNo(No(10)) self.assertEqual(len(self.grafo.nos), 10) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.grafo.insertAresta(Aresta(7, 6)) self.grafo.insertAresta(Aresta(8, 9)) self.grafo.insertAresta(Aresta(9, 10)) self.grafo.insertAresta(Aresta(8, 10)) self.assertEqual(len(self.grafo.arestas), 8) self.assertEqual(self.grafo.ciclico(), True) def test_ciclico_n_conexo_false(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.grafo.insertNo(No(6)) self.grafo.insertNo(No(7)) self.grafo.insertNo(No(8)) self.grafo.insertNo(No(9)) self.grafo.insertNo(No(10)) self.assertEqual(len(self.grafo.nos), 10) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.grafo.insertAresta(Aresta(7, 6)) self.grafo.insertAresta(Aresta(8, 9)) self.grafo.insertAresta(Aresta(9, 10)) self.assertEqual(len(self.grafo.arestas), 7) self.assertEqual(self.grafo.ciclico(), False) def test_num_componentes(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.assertEqual(len(self.grafo.nos), 5) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.assertEqual(len(self.grafo.arestas), 4) self.assertEqual(self.grafo.num_componentes(), 1) self.grafo.insertNo(No(6)) self.grafo.insertNo(No(7)) self.assertEqual(len(self.grafo.nos), 7) self.grafo.insertAresta(Aresta(7, 6)) self.assertEqual(len(self.grafo.arestas), 5) self.assertEqual(self.grafo.num_componentes(), 2) self.grafo.insertNo(No(8)) self.grafo.insertNo(No(9)) self.grafo.insertNo(No(10)) self.assertEqual(len(self.grafo.nos), 10) self.grafo.insertAresta(Aresta(8, 9)) self.grafo.insertAresta(Aresta(9, 10)) self.grafo.insertAresta(Aresta(8, 10)) self.assertEqual(len(self.grafo.arestas), 8) self.assertEqual(self.grafo.num_componentes(), 3) def test_bfs(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.grafo.insertNo(No(6)) self.assertEqual(len(self.grafo.nos), 6) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 2)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.grafo.insertAresta(Aresta(3, 4)) self.grafo.insertAresta(Aresta(4, 6)) self.assertEqual(len(self.grafo.arestas), 7) self.grafo.bfs(1) def test_dfs(self): self.grafo.insertNo(No(1)) self.grafo.insertNo(No(2)) self.grafo.insertNo(No(3)) self.grafo.insertNo(No(4)) self.grafo.insertNo(No(5)) self.grafo.insertNo(No(6)) self.assertEqual(len(self.grafo.nos), 6) self.grafo.insertAresta(Aresta(1, 2)) self.grafo.insertAresta(Aresta(1, 5)) self.grafo.insertAresta(Aresta(5, 2)) self.grafo.insertAresta(Aresta(5, 4)) self.grafo.insertAresta(Aresta(2, 3)) self.grafo.insertAresta(Aresta(3, 4)) self.grafo.insertAresta(Aresta(4, 6)) self.assertEqual(len(self.grafo.arestas), 7) self.grafo.dfs(1)
class Sistema(object): """Sistema de consultas para una red de musicos.""" def __init__(self, archivo): """Inicializa el Sistema. Recibe el archivo del grafo. El archivo debe tener el sig. formato: "<Cantidad_de_vertices>" "<id_vertice> <nombre_vertice>" "............................." "<Cantidad_de_aristas>" "<id_arista> <id_vertice_inicial> <id_vertice_final>" "..................................................." """ self.comando = None self.parametros = [] self.funciones_asociadas = { "recomendar": self.comando_recomendar, "difundir": self.comando_difundir, "centralidad": self.comando_centralidad, "debilidad": self.comando_debilidad, "camino": self.comando_camino, "diametro": self.comando_diametro, "agrupamiento": self.comando_agrupamiento, "distancias": self.comando_distancias, "subgrupos": self.comando_subgrupos, "articulacion": self.comando_articulacion } self.grafo = None self.musico_a_id_vertice = {} self._crear_grafo_desde_archivo(archivo) def _crear_grafo_desde_archivo(self, archivo): """Crea el grafo y le carga la configuracion del archivo.""" self.grafo = Grafo() try: with open(archivo,"r") as f: #agregado de vertices for i in xrange(int(f.readline())): args = f.readline().split() self.musico_a_id_vertice[args[1]] = args[0] self.grafo.agregar_vertice(args[0], dato_vertice=args[1]) #agregado de aristas for i in xrange(int(f.readline())): args = f.readline().split() self.grafo.agregar_arista(args[1], args[2]) except IOError: raise ArchivoInvalidoError("Error de archivo") except ValueError: raise ArchivoInvalidoError("Las cantidades no son numeros") except IndexError: raise ArchivoInvalidoError("Formato inadecuado") except GrafoError: raise ArchivoInvalidoError("Forma un grafo inadecuado") def _obtener_id_vertice(self, musico): try: return self.musico_a_id_vertice[musico] except KeyError: raise ParametroInvalidoError\ ("El musico %s no existe" % str(musico)) def _obtener_cantidad(self, numero_en_str): if not numero_en_str.isdigit(): raise ParametroInvalidoError\ ("La cantidad debe ser un numero entero mayor a 0") return int(numero_en_str) def _verificar_cant_parametros(self, f_operador, cantidad): """Compara utilizando la funcion_operador la cantidad de parametros recibidos con la cantidad (rec. por parametro). Si es falsa la comparacion levanta ParametroInvalidoError. """ if f_operador(len(self.parametros), cantidad): return raise ParametroInvalidoError\ ("La cantidad de paremetros no es la esperada") def _leer_entrada(self): """Lee la entrada del usuario y la formatea. Devuelve False si no recibio nada o recibio EOF, True en otro caso. """ try: entrada = raw_input() except EOFError: return False #Ya que puede venir con comas self.parametros = entrada.split(",") entrada = " ".join(self.parametros) #agrego whitespace self.parametros = entrada.split() #me saca todo. try: self.comando = self.parametros.pop(0) except IndexError: return False return True def _ejecutar_comando(self): """Ejecuta el comando leido desde la entrada estandar.""" try: self.funciones_asociadas[self.comando]() except KeyError: raise ComandoInvalidoError\ ("El comando %s no es un comando valido" % self.comando) def ejecutar(self): """Ejecuta el programa.""" while self._leer_entrada(): try: self._ejecutar_comando() except SistemaError, e: print e
class Oficina(object): ''' classdocs ''' def __init__(self, mapa, fabricas, juguetes, idEsquinaUbicacion, maximoPeso): ''' Constructor ''' self.grafo = Grafo() self.agenda = dict() self.maximoPeso = int(maximoPeso) self.idUbicacion = idEsquinaUbicacion cargarEsquinasYCalles(self.grafo,mapa) cargarFabricas(self.grafo, self.agenda, fabricas) cargarJuguetes(self.grafo, self.agenda, juguetes) ''' Obtiene las fabricas que tendra que pasar en navidad Devuelve una tupla = (cantidad de fabricas, lista de fabricas) ''' def seleccionarFabricas(self): lista = sorted(self.agenda, lambda key,key2: getFabrica(self.grafo, self.agenda, key).compare(getFabrica(self.grafo, self.agenda, key2))) #lista.reverse() # porque estaba al reves el comparador optimos = list() # lista donde guardo las fabricas optimas ultimoIngresado = lista.pop() optimos.append(ultimoIngresado) while lista.__len__() > 0: #idFabrica = min(lista, key = lambda x: grafo.obtenerVertice(agenda[x]).getDato().getFabrica(x).getHorarioEntradaCondicional(getFabrica(ultimoIngresado).getHorarioSalida())) idFabrica = lista.pop() fabrica = getFabrica(self.grafo, self.agenda,idFabrica) if fabrica.getHorarioEntrada() >= getFabrica(self.grafo, self.agenda,ultimoIngresado).getHorarioSalida(): optimos.append(idFabrica) ultimoIngresado = idFabrica contador = 0 resultado = list() for op in optimos: contador += 1 resultado.append(getFabrica(self.grafo, self.agenda, op)) return (contador, resultado) ''' Obtiene la cantidad de sonrisas por fabrica Parametro (idFabrica) Devuelve una tupla = (resultado de comando ( 0 = OK, -1 = Error ), (cantidad de sonrisas de la fabrica, lista de juguetes)) ''' def valuarJuguetes(self, idFabrica): if (self.agenda.has_key(idFabrica)): return (0,getFabrica(self.grafo, self.agenda, idFabrica).getSonrisasMaximas(self.maximoPeso)) return (-1, None) ''' Obtiene la cantidad de sonrisas en total que obtedra recorriendo las fabricas optimas para recorrer Devuelve una tupla = (resultado de comando (0 = OK), cantidad de sonrisas totales) ''' def valuarJugutesTotal(self): camino = self.seleccionarFabricas() suma = 0 for fabrica in camino[1]: suma += self.valuarJuguetes(fabrica.getId())[1][0] return (0, suma) ''' Obtiene el camino mas corto a una fabrica idFabrica id de la fabrica a llegar Devuelve una tupla = (resultado de comando( 0 = OK, -1 = No existe la fabrica ), lista de las esquinas a pasar para llegar a la fabrica) ''' def getCaminoOptimoFabrica(self, idFabrica): if (self.agenda.has_key(idFabrica)): resultadoCamino = self.grafo.getCaminoOptimo(self.idUbicacion, self.agenda[idFabrica]) return (0, int(resultadoCamino[0]), self.getEsquinas(resultadoCamino[1])) return (-1, None) def getEsquinas(self, lista): resultado = list() for idEsquina in lista: resultado.append(self.grafo.obtenerVertice(idEsquina).getDato()) return resultado
from grafo import Grafo from bfs import BFS from doble import Doble from ciclos import Ciclos from flujo import Flujo from nociclos import NoCiclos cont = 0 grafo = Grafo() print("El programa puede demorarse hasta dos minuto...") # Probado con 1m y 10m y dan el mismo resultado while cont < 1000000: grafo = grafo.agregar_nodo() cont += 1 f = open("red.txt", "w") f.write(str(grafo)) f.close() bfs = BFS(grafo) f = open("rutaABummer.txt", "w") f.write(str(bfs)) f.close() doble = Doble(grafo) f = open("rutasDobleSentido.txt", "w") f.write(str(doble)) f.close() ciclos = Ciclos(grafo) f = open("ciclos.txt", "w") f.write(str(ciclos)) f.close() flujo = Flujo(grafo)
class Sistema(object): def __init__(self): self.grafo = Grafo() def inicializar(self, nombre_archivo): """(str) -> None. Completa el grafo del sistema con los vertices y aristas presentes en el archivo.""" leer_archivo(self.grafo, nombre_archivo) def recomendar(self, musico, cantidad): """(vertice, int) -> lista de contactos recomendados Se le recomienda una cantidad de contactos a agregar al musico indicado.""" # Musico recomendado: amigos en comun recomendaciones = {} # Recorro los adyacentes a musico. Luego busco los adyacentes a esos y # por cada vertice encontrado se lo agrega a recomendaciones. Si ese # vertice vuelve a aparecer en otro "adyacente de adyacente", le # aumento el valor "amigos en comun" for ady in self.grafo.obtener_adyacencias(musico): for candidato in self.grafo.obtener_adyacencias(ady): # Si el musico ya es amigo del candidato, paso al siguiente if self.grafo.estan_conectados(musico, candidato): continue if candidato in recomendaciones.keys(): recomendaciones[candidato] += 1 else: recomendaciones[candidato] = 1 musicos_rec = recomendaciones.items() musicos_rec.sort(key = lambda musico_rec: musico_rec[1], reverse = True) for i in range(1, int(cantidad) + 1): print musicos_rec[i][0] def difundir(self, musicos): """(lista de musicos) -> lista de musicos que se enteraran de la informacion difundida.""" informados = {} for musico in musicos: if self.grafo.esta_en_grafo(musico): informados[musico] = True while True: cambio = False posibles_informados = {} for musico in informados: amigos_musico = self.grafo.obtener_adyacencias(musico) for amigo in amigos_musico: if amigo not in posibles_informados and \ amigo not in informados: posibles_informados[amigo] = None for candidato in posibles_informados: # Esto itera esobre las claves (es lo mismo que agregar .keys()) contador = 0 contactos = self.grafo.obtener_adyacencias(candidato) long_necesaria = len(contactos) for contacto in contactos: if contacto in informados: contador += 1 if contador > (long_necesaria / 2): cambio = True informados[candidato] = True continue if not cambio: break print informados.keys() def centralidad(self, cantidad): """(int) -> lista de vertices mas centrales Hace BFS de cada vertice del grafo, recorre cada camino mínimo y por cada aparición de un vértice, le suma 1 a su contador. Imprime los vértices con mayor cantidad de ocurrencias en caminos mínimos.""" try: int(cantidad) except: raise RuntimeError("(!)La cantidad debe ser un número entero") if int(cantidad) < 1: raise RuntimeError("(!)La cantidad debe ser un número positivo") contador = {} for vertice in self.grafo.obtener_vertices(): contador[vertice] = 0 for vertice in contador: padre, distancias = bfs(self.grafo, vertice) for alcanzado in distancias: vertice_actual = alcanzado while padre[vertice_actual] != vertice and \ padre[vertice_actual] != None: contador[padre[vertice_actual]] += 1 vertice_actual = padre[vertice_actual] devolucion = contador.items() devolucion.sort(key = lambda contador:contador[1], reverse = True) for x in range(int(cantidad)): print devolucion[x][0] def camino(self, musico1, musico2): """(musico1, musico2) -> None Imprime el camino entre dos musicos.""" padre, distancias = bfs(self.grafo, musico1) imprimir_camino(padre, musico1, musico2) def distancias(self, musico): """ (musico) -> None Imprime la cantidad de musicos que se encuentran a distancia 1, 2, ..., n del musico.""" padre, distancias = bfs(self.grafo, musico) contar_dist = {} for musico, dist in distancias.items(): if dist == float("inf") or dist == 0: continue dist_s = str(dist) if dist_s not in contar_dist: contar_dist[dist_s] = [musico] else: contar_dist[dist_s].append(musico) for distancia in contar_dist: print distancia + ": ", for musico in contar_dist[distancia]: print musico, print def subgrupos(self): """Pre: - Post: imprime en orden decreciente el tamanio de los subgrupos presentes en el grafo. """ vertices_faltantes = self.grafo.obtener_vertices() largo_subgrupos = [] while vertices_faltantes: subgrupo = crear_subgrupo(self.grafo, vertices_faltantes[0]) largo_subgrupos.append(len(subgrupo)) for v in subgrupo: vertices_faltantes.remove(v) largo_subgrupos.sort(reverse = True) for subgrupo in largo_subgrupos: print subgrupo
def _extraer_datos(handler): """Recibe: archivo, Devuelve: 2 grafos Extrae los datos del archivo y los devuelve""" #variables fila = [] nodos_cant = 0 calles_cant = 0 i = 0 #indice generico info_nodo = {} #donde guardo la informacion de los nodos grafo_nodos = Grafo() grafo_calles = Grafo() #Cargo el manejador de csv contenido_csv = csv.reader(handler, delimiter=",") #obtengo la primer linea, que me dice cuantos -NODOS- son fila = contenido_csv.next() nodos_cant = int(fila[0]) #avanzo para obtener la primer fila de -NODOS- fila = contenido_csv.next() #obtengo los datos de los -NODOS- for i in range(nodos_cant-1): #guardo la info del nodo info_nodo[ int(fila[0]) ] = {'x': float(fila[1]), 'y': float(fila[2]), 'lon': float(fila[4]),'lat': float(fila[3])} #avanzo una posicion si no estoy en el ultimo -NODO- if i != nodos_cant: fila = contenido_csv.next() #obtengo la cantidad de -CALLES- fila = contenido_csv.next() calles_cant = int(fila[0]) #avanzo para obtener la primer fila de -CALLES- fila = contenido_csv.next() #obtengo los datos de las -CALLES- for i in range(calles_cant-1): if int(int(fila[4])) not in grafo_nodos: grafo_nodos.agregar_vertice(int(fila[4])) if texto(fila[1]) not in grafo_calles: grafo_calles.agregar_vertice(texto(fila[1])) #Agrego las aristas grafo_nodos.agregar_arista(int(fila[4]),int(fila[5]),int(fila[2])) grafo_calles.agregar_arista(texto(fila[1]),int(fila[4]),int(fila[5])) #Cuando son mano unica if int(fila[3]) == 0: if int(fila[5]) not in grafo_nodos: grafo_nodos.agregar_vertice(int(fila[5])) grafo_nodos.agregar_arista(int(fila[5]),int(fila[4]),int(fila[2])) #devuelvo los grafos e info_nodo if i != calles_cant: fila = contenido_csv.next() return grafo_nodos, grafo_calles ,info_nodo
def __init__(self): self.grafo = Grafo()
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()
def setUp(self): self.grafo = Grafo()