def create_labyrinth(rows: int, cols: int) -> UndirectedGraph: # Paso 1 = Creamos una lista con los vertices de nuestro grafo vertices = [(r, c) for r in range(rows) for c in range(cols)] # Paso 2 = Creamos un MergeFindSet vacio y le vamos añadiendo UNO A UNO # los vertices de la lista creada en el paso 1 mfs = MergeFindSet() for v in vertices: mfs.add(v) # Paso 3 = Creamos una lista llamada "edges" con los pares de vertices # vecinos, y la barajamos edges = [] for (r, c) in vertices: if r + 1 < rows: edges.append(((r, c), (r + 1, c))) if c + 1 < cols: edges.append(((r, c), (r, c + 1))) random.shuffle(edges) # Paso 4 = Creamos una lista vacia que contiene los pasillos del laberinto corridors = [] # Paso 5 = Recorremos la lista de bordes, y para cada arista (u, v), # encuentra la clase a la que pertenece cada uno de los vertices # usando "find()". u y v son VERTICES, u = (r,c) y v = (r2,c2) for (u, v) in edges: if mfs.find(u) != mfs.find(v): mfs.merge(u, v) corridors.append((u, v)) # Paso 6 = Devolvemos el resultado return UndirectedGraph(E=corridors)
def create_labyrinth(rows, cols): # general expressions of all vertexes vertices = [(row, col) for row in range(rows) for col in range(cols)] mfs = MergeFindSet() edges = [] for v in vertices: # print(v) mfs.add(v) # add the bottom row and right column to edge list and shuffle it for row, col in vertices: if row + 1 < rows: edges.append([(row, col), (row + 1, col)]) if col + 1 < cols: edges.append([(row, col), (row, col + 1)]) shuffle(edges) # # # # for i in edges: # a, b = i # print(a, b) ### corridors = [] # if the edges are not in the same set, merge them in the same one and add them to corridors for u, v in edges: if mfs.find(u) != mfs.find(v): mfs.merge(u, v) corridors.append((u, v)) # for u, v in corridors: # print("Path: {} -> {}".format(u, v)) return UndirectedGraph(E=corridors)
def create_labyrinth(rows, cols): #Intentar Edges con expresion generatriz #Paso 1 vertices = [(i, j) for i in range(rows) for j in range(cols)] #Paso 2 mfs = MergeFindSet() for v in vertices: mfs.add(v) #Paso 3 edges = [] for r in range(rows): for c in range(cols): if r + 1 < rows: edges.append(((r, c), (r + 1, c))) if c + 1 < cols: edges.append(((r, c), (r, c + 1))) random.shuffle(edges) #Paso 4 corridors = [] #Paso 5 for (u, v) in edges: if mfs.find(u) != mfs.find(v): mfs.merge(u, v) corridors.append((u, v)) #Paso 6 return UndirectedGraph(E=corridors)
def crea_laberinto_mod(nfil, ncol, n): ##Problema3 vertices = [(i, j) for (i) in range(nfil) for (j) in range(ncol)] mfs = MergeFindSet() for v in vertices: mfs.add(v) aristasV = [((f, c), (f + 1, c)) for f in range(nfil - 1) for c in range(ncol)] aristasH = [((f, c), (f, c + 1)) for f in range(nfil) for c in range(ncol - 1)] aristas = aristasV + aristasH shuffle(aristas) nCamino = n pasillos = [] for (u, v) in aristas: if mfs.find(u) != mfs.find(v): if nCamino == 0: mfs.merge(u, v) else: nCamino -= 1 pasillos.append((u, v)) return UndirectedGraph(E=pasillos)
def create_labyrinth(num_rows: int, num_cols: int, n: int = 0) -> UndirectedGraph: vertices: List[Tuple] = [] for r in range(num_rows): for c in range(num_cols): vertices.append((r, c)) mfs = MergeFindSet() for v in vertices: mfs.add(v) edges: List[Edge] = [] for r, c in vertices: if r > 0: edges.append(((r, c), (r - 1, c))) if c > 0: edges.append(((r, c), (r, c - 1))) shuffle(edges) corridors: List[Edge] = [] for e in edges: (v, u) = e if mfs.find(v) != mfs.find(u): mfs.merge(v, u) corridors.append(e) else: if n > 0: corridors.append((u, v)) n -= 1 return UndirectedGraph(E=corridors)
def create_labyrinth(rows, cols): # vertex creation vertexes = [(row, col) for row in range(rows) for col in range(cols)] mfs = MergeFindSet() edges = [] for v in vertexes: mfs.add(v) # add bottom row and right column to the edge list and shuffle for row, col in vertexes: if row + 1 < rows: edges.append(((row, col), (row + 1, col))) if col + 1 < cols: edges.append(((row, col), (row, col + 1))) random.shuffle(edges) corridors = [] # create corridors list for u, v in edges: if mfs.find(u) != mfs.find(v): mfs.merge(u, v) corridors.append((u, v)) return corridors
def create_labyrinth_mod(rows: int, cols: int, n: int = 0) -> UndirectedGraph: vertex = [(r, c) for r in range(rows) for c in range(cols)] mfs = MergeFindSet() for v in vertex: mfs.add(v) edges = [] for (i, j) in vertex: edges.append(((i, j), (i, j + 1))) if j + 1 < cols else "" edges.append(((i, j), (i + 1, j))) if i + 1 < rows else "" random.shuffle(edges) corridors = [] discarded_edges = [] for (u, v) in edges: if mfs.find(u) != mfs.find(v): mfs.merge(u, v) corridors.append((u, v)) else: discarded_edges.append((u, v)) graph_wo_mod = UndirectedGraph(E=corridors) new_corridors = corridors[:] new_corridors.extend(discarded_edges[:n]) graph_mod = UndirectedGraph(E=new_corridors) return graph_wo_mod, graph_mod
def create_labyrinth(rows, cols): #Definition #Step 1 vertices = [(r, c) for r in range(rows) for c in range(cols)] #Step 2 mfs = MergeFindSet() for v in vertices: mfs.add(v) #Step 3 edges = [] for (r, c) in vertices: if r + 1 < rows: edges.append(((r, c), (r + 1, c))) if c + 1 < cols: edges.append(((r, c), (r, c + 1))) shuffle(edges) #Step 4 corridors = [] #Step 5 for (u, v) in edges: if mfs.find(u) != mfs.find(v): mfs.merge(u, v) corridors.append((u, v)) #Step 6 return UndirectedGraph(E=corridors)
def kruskal2(aristas): aristas_ordenadas = sorted(aristas.items(), key=lambda x: x[1]) mfs = MergeFindSet() limite = [2] * len(puntos) path = [] for v in range(len(puntos)): mfs.add(v) for edge, w in aristas_ordenadas: u = edge[0] v = edge[1] if limite[u] > 0 and limite[ v] > 0: # puedo meter la arista si no tiene ciclo if mfs.find(u) != mfs.find(v): # no hace ciclo mfs.merge(u, v) path.append(edge) limite[u] -= 1 limite[v] -= 1 vertice_extra = [] for i, x in enumerate(limite): if x == 1: vertice_extra.append(i) path.append(tuple(vertice_extra)) g = UndirectedGraph(E=path) return path, g
def create_labyrinth(rows, cols): # generar vertices vertices = [(row, col) for row in range(rows) for col in range(cols)] mfs = MergeFindSet() edges = [] for v in vertices: mfs.add(v) # anadir la fila de abajo y la columna derecha a la lista de aristas y barajarla for row, col in vertices: if row + 1 < rows: edges.append(((row, col), (row + 1, col))) if col + 1 < cols: edges.append(((row, col), (row, col + 1))) # borrar las aristas prohibidas edges = list(set(edges) - set(aristas_p)) random.shuffle(edges) corridors = [] for u, v in edges: if mfs.find(u) != mfs.find(v): mfs.merge(u, v) corridors.append((u, v)) return corridors, vertices
def create_labyrinth(rows: int, cols: int, n: int = 0) -> UndirectedGraph: vertices = [(r, c) for r in range(rows) for c in range(cols)] mfs = MergeFindSet() for v in vertices: mfs.add(v) edges = [] for r, c in vertices: if r + 1 < rows: edges.append(((r, c), (r + 1, c))) if c + 1 < cols: edges.append(((r, c), (r, c + 1))) random.shuffle(edges) corridors = [] for (u, v) in edges: if mfs.find(u) != mfs.find(v): corridors.append((u, v)) mfs.merge(u, v) elif n > 0: corridors.append((u, v)) n -= 1 return UndirectedGraph(E=corridors)
def create_labyrinth(rows, cols, n=0): # Crea una lista, vertices, con los vértices del grafo (nuestras celdas del laberinto). vertices = [] for row in range(rows): for col in range(cols): vertices.append((row, col)) # vertices = [(r,c) for r in range(rows) for c in range(cols)] <-- versión del profesor # Crea un MFSet vacío, mfs, y añádele uno a uno los vértices de la lista vertices usando su método add. # Para crear un MFSet utiliza la clase MergeFindSet disponible en algoritmia.datastructures.mergefindsets. mfs = MergeFindSet() for vertice in vertices: mfs.add(vertice) # Crea una lista, edges, con todos los pares de vértices vecinos y barájala. Usa la función # shuffle del módulo random. edges = [] for row in range(rows): for col in range(cols): if col > 0: edges.append(((row, col), (row, col - 1))) if row > 0: edges.append(((row, col), (row - 1, col))) # edges = [((row, col), (row, col + 1)) for r in range(rows) for c in range(cols-1)] # edges.extend( # [((row, col), (row, col + 1)) for r in range(rows-1) for c in range(cols)] # ) random.shuffle(edges) # Crea una lista vacía, corridors. Aquí pondremos las aristas (pasillos) que tendrá al final # nuestro grafo (laberinto). corridors = [] # Recorre la lista edges y, para cada arista (u,v), encuentra la clase a la que pertenece # cada uno de los dos vértices usando find. Si son diferentes, fusiónalas en la misma clase con # merge y añade la arista (u,v) a la lista corridors. for u, v in edges: if mfs.find(u) != mfs.find(v): corridors.append((u, v)) mfs.merge(u, v) else: if n > 0: corridors.append((u, v)) #mfs.merge(u, v) n -= 1 # El laberinto es el grafo no dirigido que tiene a la lista corridors como conjunto de aristas: # return UndirectedGraph(E = corridors) # print("Corridors: ") # print(corridors) return UndirectedGraph(E=corridors)
def create_labyrinth(rows: int, cols: int, n: int = 0) -> UndirectedGraph: # Definition # Step 1 vertices = [(r, c) for r in range(rows) for c in range(cols)] # Step 2 mfs = MergeFindSet() for v in vertices: mfs.add(v) # Step 3 edges = [] for (r, c) in vertices: if r + 1 < rows: edges.append(((r, c), (r + 1, c))) if c + 1 < cols: edges.append(((r, c), (r, c + 1))) random.shuffle(edges) # Step 4 corridors = [] discarted_edges = [] #modificacion # Step 5 for (u, v) in edges: if mfs.find(u) != mfs.find(v): mfs.merge(u, v) corridors.append((u, v)) else: discarted_edges.append((u, v)) #modificacion corridors.extend(discarted_edges[:n]) #modificacion # Step 6 return UndirectedGraph(E=corridors)
def create_labyrinth(rows, cols, n=0): # for i in range(rows): # for j in range(cols): # vertices.append((i, j)) vertices = [(row, col) for row in range(rows) for col in range(cols)] print(vertices) mfs = MergeFindSet() for elem in vertices: mfs.add(elem) edges = [] for row, col in vertices: if row+1 < rows: edges.append(((row, col), (row+1, col))) if col+1 < cols: edges.append(((row, col),(row, col+1))) shuffle(edges) contador = 0 corridors = [] for u, v in edges: if mfs.find(u) != mfs.find(v): mfs.merge(u, v) corridors.append((u, v)) elif n > contador: corridors.append((u, v)) contador+=1 return UndirectedGraph(E=corridors)
class TestMFset(unittest.TestCase): def setUp(self): self.mf1 = MergeFindSet() self.mf2 = MergeFindSet( ((i, ) for i in range(10)), createMap=lambda nodes: IntKeyMap(capacity=max(nodes) + 1)) def test_mfsets(self): for i in range(10): self.mf1.add(i) for i in range(10): self.assertEqual(self.mf1.find(i), i) self.assertEqual(self.mf2.find(i), i) for i in range(0, 10, 2): self.mf1.merge(i, i + 1) self.mf2.merge(i, i + 1) for i in range(0, 10, 2): self.assertEqual(self.mf1.find(i), self.mf1.find(i + 1)) self.assertEqual(self.mf2.find(i), self.mf2.find(i + 1)) for i in range(0, 10 - 3, 4): self.mf1.merge(i, i + 3) self.mf2.merge(i, i + 3) for i in range(0, 10 - 4, 4): self.assertEqual(self.mf1.find(i), self.mf1.find(i + 1)) self.assertEqual(self.mf1.find(i), self.mf1.find(i + 2)) self.assertEqual(self.mf1.find(i), self.mf1.find(i + 3)) self.assertEqual(self.mf2.find(i), self.mf2.find(i + 1)) self.assertEqual(self.mf2.find(i), self.mf2.find(i + 2)) self.assertEqual(self.mf2.find(i), self.mf2.find(i + 3))