def BFS_wallbraker(g: UndirectedGraph, source: Vertex, distances: dict) -> Edge: seen = set() min = float('infinity') wall = ((-1, -1), (-1, -1)) queue = Fifo() queue.push((source, 0)) seen.add(source) while len(queue) > 0: vertex, n = queue.pop() u, v = vertex # Comprobacion de vecinos tras los muros for x, y in [(1, 0), (0, 1), (-1, 0), (0, -1)]: neigh = (u + x, v + y) if neigh not in g.succs((u, v)) and neigh in distances: tdistance = n + distances[neigh] if tdistance < min: min = tdistance wall = ((u, v), neigh) for suc in g.succs(vertex): if suc not in seen: seen.add(suc) queue.push((suc, n + 1)) return wall
def algoritmo2(g: UndirectedGraph) -> Tuple[int, Dict[Tuple[int, int], int]]: color_dic = {} n_colores = 0 maxHeap = MaxHeapMap() for v in g.V: maxHeap[v] = (0, len(g.succs(v)), v[0], v[1]) while len(maxHeap) > 0: v_actual = maxHeap.extract_opt() colores = [color_dic.get(vecino) for vecino in g.succs(v_actual)] c = 0 while True: if c not in colores: color_dic[v_actual] = c for vecino in g.succs(v_actual): if vecino in maxHeap: maxHeap[vecino] = (maxHeap[vecino][0] + 1, maxHeap[vecino][1], maxHeap[vecino][2], maxHeap[vecino][3]) break c += 1 if c > n_colores: n_colores = c return n_colores + 1, color_dic
def recorredor_anchura(g: UndirectedGraph, source: "T", r: int, c: int): #Crear e inicializar matriz distances = [] for row in range(r): distances.append([0] * c) queue = Fifo() seen = set() #Añadir el punto inicial a la cola queue.push((source, source)) seen.add(source) while len(queue) > 0: u, v = queue.pop() #Miramos los sucesores del elemento extraido de la cola for s in g.succs(v): #Si no lo hemos visitado ya lo añadimos a los visitados y anotamos en la matriz su distancia al origen if s not in seen: seen.add(s) distances[s[0]][s[1]] = distances[v[0]][ v[1]] + 1 #En la posición del sucesor el antecesor mas 1 queue.push((v, s)) return distances
def algoritmo1(g: UndirectedGraph) -> Tuple[int, Dict[Tuple[int, int], int]]: vertices = sorted(g.V, key=lambda x: (-len(g.succs(x)), -x[0], -x[1])) dic = {v: -1 for v in g.V} n_colores = 0 for v in vertices: colores_vecinos = set() for vecino in g.succs(v): color = dic[vecino] if color != -1: colores_vecinos.add(color) for color in range(n_colores): if color not in colores_vecinos: dic[v] = color break else: dic[v] = n_colores n_colores += 1 return n_colores, dic
def min_distances(g: UndirectedGraph, ini: Vertex) -> Dict: distances = {} queue = Fifo() seen = set() queue.push((ini, ini, 0)) seen.add(ini) while len(queue) > 0: u, v, n, = queue.pop() distances[v] = n for suc in g.succs(v): if suc not in seen: seen.add(suc) queue.push((v, suc, n + 1)) return distances
def recorredor_aristas_anchura(g: UndirectedGraph, v_inicial: Vertex) -> List[Edge]: aristas = [] queue = Fifo() seen = set() queue.push((v_inicial, v_inicial)) seen.add(v_inicial) while len(queue) > 0: u, v = queue.pop() aristas.append((u, v)) for suc in g.succs(v): if suc not in seen: seen.add(suc) queue.push((v, suc)) return aristas
def shortest_path(g: UndirectedGraph, source: Vertex, target: Vertex): aristas = [] queue = Fifo() seen = set() queue.push((source, source)) seen.add(source) while len(queue) > 0: u, v = queue.pop() aristas.append((u, v)) for suc in g.succs(): if suc not in seen: seen.add(suc) queue.push((v, suc)) return recover_path(aristas, target)
def anchura(g: UndirectedGraph, source: tuple) -> list: visitados = set() aristas = [] queue = Fifo() queue.push((source, source)) visitados.add(source) while len(queue) > 0: u, v = queue.pop() for suc in g.succs(v): if suc not in visitados: visitados.add(suc) aristas.append((v, suc)) queue.push((v, suc)) return aristas
def mod_anchura(g: UndirectedGraph, source: tuple) -> list: visitados = set() n = int(sqrt(len(g.V))) matriz = [[0] * n for i in range(n)] queue = Fifo() queue.push((source, 0)) visitados.add(source) while len(queue) > 0: u, n = queue.pop() for sucx, sucy in g.succs(u): if (sucx, sucy) not in visitados: visitados.add((sucx, sucy)) matriz[sucx][sucy] = n + 1 queue.push(((sucx, sucy), n + 1)) return matriz
def algoritmo2(g: UndirectedGraph) -> Tuple[int, Dict[Tuple[int, int], int]]: dic = {v: -1 for v in g.V} vertices_nocoloreados = HeapMap( opt=max, data={k: (0, len(g.succs(k)), k[0], k[1]) for k in g.V}) n_colores = 0 while len(vertices_nocoloreados) > 0: v = vertices_nocoloreados.extract_opt() colores_vecinos = set() for vecino in g.succs(v): color = dic[vecino] if color != -1: colores_vecinos.add(color) else: n, s, x, y = vertices_nocoloreados[vecino] vertices_nocoloreados[vecino] = n + 1, s, x, y for color in range(n_colores): if color not in colores_vecinos: dic[v] = color break else: dic[v] = n_colores n_colores += 1 return n_colores, dic
def algoritmo1(g: UndirectedGraph) -> Tuple[int, Dict[Tuple[int, int], int]]: vertices_ordenados = sorted(g.V, key=lambda i: (-len(g.succs(i)), -i[0], -i[1])) n_colores = 0 color_dic = {} for v in vertices_ordenados: color = 0 colorvecinos = [color_dic.get(vecino) for vecino in g.succs(v)] # cuenta cuantos color tienen los vecinos while color in colorvecinos: if color is not None: color += 1 # asigna el numero de colores totales - 1 if color > n_colores: n_colores = color # asigna el menor color entre los colores de los vecinos color_dic[v] = color return n_colores + 1, color_dic #cantidad colores y diccionario de colores
def shortest_path(grafo: UndirectedGraph, source: Vertex, target: Vertex) -> List[Edge]: # sys.setrecursionlimit(10000) # en el caso de que el laberinto sea más grande, por lo tanto, la recursión más larga edges = [] queue = Fifo() seen = set() queue.push((source, source)) seen.add(source) while len(queue) > 0: u, v = queue.pop() edges.append((u, v)) for suc in grafo.succs(v): if suc not in seen: seen.add(suc) queue.push((v, suc)) return recover_path(edges, target)
def BFS(g: UndirectedGraph, source: Vertex, target: Vertex) -> List[Edge]: seen = set() edges = [] queue = Fifo() edges.append((source, source)) queue.push((source, source)) seen.add(source) while len(queue) > 0: u, v = queue.pop() edges.append((u, v)) if (u, v) == target: return edges for suc in g.succs(v): if suc not in seen: seen.add(suc) queue.push((v, suc)) return edges
def vertex_path(lab: UndirectedGraph, v_ini: Vertex) -> List[Vertex]: q = Fifo() seen = set() vertices = [] q.push(v_ini) seen.add(v_ini) while len(q) > 0: at = q.pop() vertices.append(at) for suc in lab.succs(at): if suc not in seen: seen.add(suc) q.push(suc) return vertices
def edge_path(lab: UndirectedGraph, v_ini: Vertex) -> List[Vertex]: q = Fifo() seen = set() aristas = [] q.push((v_ini, v_ini)) seen.add(v_ini) while len(q) > 0: (u, v) = q.pop() aristas.append((u, v)) for suc in lab.succs(v): if suc not in seen: seen.add(suc) q.push((v, suc)) return aristas
def prim2(v_ini, aristas_prim): aristas_ordenadas = [] for arista, w in sorted(aristas_prim.items(), key=lambda x: x[1]): aristas_ordenadas.append(arista) mfs = MergeFindSet() g_prim = UndirectedGraph(E=aristas_ordenadas) path = [] for v in range(len(puntos)): mfs.add(v) seen = set() q = Fifo() q.push(v_ini) seen.add(v_ini) menor_arista = menor_arista_iter(v_ini, g_prim, aristas_prim) aristas_vecinas_ordenadas = [] for i in menor_arista: aristas_vecinas_ordenadas.append(i) # print(aristas_vecinas_ordenadas) while len(q) > 0: u = q.pop() for suc in g_prim.succs(u): if suc not in seen: seen.add(suc) q.push(suc) # if mfs.find(u) != mfs.find(v): # no hace ciclo # seen.add(u,v) return path, g_prim
class TestShortest(unittest.TestCase): def setUp(self): self.iberia = UndirectedGraph(V=cities, E=roads) self.unconnected = Digraph(E={0: [1,2], 1:[2,3], 2:[5, 6], 3: [5], 4: [2], 5: [6]}) self.unconnected_weight = WeightingFunction((((u,v), 1) for (u,v) in self.unconnected.E)) self.bfsp = BreadthFirstShortestPaths() def test_bfs_length(self): self.assertEqual(self.bfsp.distance(self.iberia, "Gandia", "Cullera"), 1) self.assertEqual(self.bfsp.distance(self.iberia, "València", "Daroca"), 5) self.assertEqual(self.bfsp.distance(self.unconnected, 0, 4), None) self.assertEqual(self.bfsp.distance(self.unconnected, 0, 6), 2) def test_bfs_shortest_path(self): self.assertEqual(self.bfsp.shortest_path(self.iberia, "Gandia", "Cullera"), ["Gandia", "Cullera"]) sol = self.bfsp.shortest_path(self.iberia, "València", "Daroca") for i in range(len(sol)-1): self.assertEqual(sol[i+1] in self.iberia.succs(sol[i]), True) self.assertEqual(sol[0]=="València" and sol[-1]=="Daroca", True) self.assertEqual(len(sol), len(["València", "Sagunt", "Segorbe", "Teruel", "Monreal del Campo", "Daroca"])) self.assertEqual(self.bfsp.shortest_path(self.unconnected, 0, 4), None) self.assertEqual(self.bfsp.shortest_path(self.unconnected, 0, 6), [0, 2, 6]) def test_bfs_shortest_path_backpointers_one_to_all(self): t = self.bfsp.some_to_some_backpointers(self.iberia, ['Gandia'], self.iberia.V) bp = dict(t) self.assertEqual(Backtracer(bp).backtrace('Cullera'), ["Gandia", "Cullera"]) t = self.bfsp.one_to_all_backpointers(self.iberia, 'València') bp = dict(t) sol = Backtracer(bp).backtrace('Daroca') for i in range(len(sol)-1): self.assertEqual(sol[i+1] in self.iberia.succs(sol[i]), True) self.assertEqual(sol[0]=="València" and sol[-1]=="Daroca", True) self.assertEqual(len(sol), len(["València", "Sagunt", "Segorbe", "Teruel", "Monreal del Campo", "Daroca"])) t = self.bfsp.one_to_all_backpointers(self.unconnected, 0) bp = dict(t) self.assertEqual(Backtracer(bp).backtrace(4), None) self.assertEqual(Backtracer(bp).backtrace(6), [0, 2, 6]) def test_bfs_shortest_path_backpointers_some_to_all(self): t = self.bfsp.some_to_some_backpointers(self.iberia, ['Gandia', 'Vigo'], self.iberia.V) bp = dict(t) self.assertEqual(Backtracer(bp).backtrace('Cullera'), ["Gandia", "Cullera"]) sol = Backtracer(bp).backtrace('Ourense') for i in range(len(sol)-1): self.assertEqual(sol[i+1] in self.iberia.succs(sol[i]), True) self.assertEqual(len(sol), len(["Vigo", "Ribadavia", "Ourense"])) t = self.bfsp.some_to_some_backpointers(self.iberia, ['València', 'Madrid'], self.iberia.V) bp = dict(t) sol = Backtracer(bp).backtrace('Daroca') self.assertEqual(sol[-1]=="Daroca", True) for i in range(len(sol)-1): self.assertEqual(sol[i+1] in self.iberia.succs(sol[i]), True) self.assertEqual(len(sol), len(["València", "Sagunt", "Segorbe", "Teruel", "Monreal del Campo", "Daroca"])) sol = Backtracer(bp).backtrace('Cuenca') self.assertEqual(sol[-1]=="Cuenca", True) for i in range(len(sol)-1): self.assertEqual(sol[i+1] in self.iberia.succs(sol[i]), True) self.assertEqual(len(sol), len(["Madrid", "Arganda del Rey", "Tarancón", "Cuenca"])) t = self.bfsp.some_to_some_backpointers(self.unconnected, [0, 1], self.unconnected.V) bp = dict(t) self.assertEqual(Backtracer(bp).backtrace(4), None) self.assertEqual(Backtracer(bp).backtrace(6), [0, 2, 6]) self.assertEqual(Backtracer(bp).backtrace(3), [1, 3])
def vecinosV(g: UndirectedGraph): for e in g.V: print("Vertice: {}, nr vecinos = {}".format(e, len(g.succs(e))))
''' Created on 20 sept. 2017 @author: al341802-Miguel Matey Sanz ''' from algoritmia.datastructures.digraphs import UndirectedGraph lc = [('Villaarriba', 'Villaconejos'), ('Villaarriba', 'Villaabajo'), ('Villaabajo', 'Villavilla'), ('Villaconejos', 'Villavilla'), ('Villaabajo', 'Villorrio'), ('Villorrio', 'Villita')] g = UndirectedGraph(E=lc) print(g) for ciudad in g.V: print(ciudad, g.succs(ciudad))