示例#1
0
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
示例#2
0
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
示例#3
0
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
示例#4
0
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)
示例#5
0
    def __init__(self, g, window_size=(400, 400), vertexmode=X_Y):
        EasyCanvas.__init__(self)

        if not isinstance(g, UndirectedGraph) or \
                any([type(p) != type((1, 1)) or
                     len(p) != 2 or
                     type(p[0]) != type(p[1]) for p in g.V]) or \
                any([type(p[0]) != type(1) and type(p[0]) != type(1.0) for p in g.V]):
            raise TypeError(
                "The graph must be an UndirectedGraph. Vertices must be tuples of two integers or floats"
            )

        if vertexmode == Graph2dViewer.ROW_COL:
            if any([type(p[0]) != type(1) for p in g.V]):
                raise TypeError(
                    "In this mode, vertices must be tuples of two integers")
            g = UndirectedGraph(V=[(v[1], -v[0]) for v in g.V],
                                E=[((u[1], -u[0]), (v[1], -v[0]))
                                   for (u, v) in g.E])

        self.g = g
        self.max_y = max(p[1] for p in self.g.V)
        self.max_x = max(p[0] for p in self.g.V)
        self.min_y = min(p[1] for p in self.g.V)
        self.min_x = min(p[0] for p in self.g.V)
        self.window_size = window_size
示例#6
0
文件: entregable2.py 项目: Mi7ai/A
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: int, cols: int, corridors) -> UndirectedGraph:
    vertices = [(r, c) for r in range(rows) for c in range(cols)]
    mfs = MergeFindSet()
    for v in vertices:
        mfs.add(v)

    return UndirectedGraph(E=corridors)
示例#8
0
def load_labyrinth(file: str) -> UndirectedGraph:
    """
    @param file: Fichero que contiene un laberinto.
    @return: Devuelve un UndirectedGraph equivalente al laberinto del fichero.
    """
    f = open(file, "r")
    lines = f.readlines()
    f.close()

    corridors = []
    global cols
    global rows

    rows = len(lines)
    for r in range(rows):
        cells = lines[r].rstrip('\n').split(',')
        if r == 0:
            cols = len(cells)
        for c in range(cols):
            if 's' not in cells[c] and r + 1 < rows:
                corridors.append(((r, c), (r + 1, c)))
            if 'e' not in cells[c] and c + 1 < cols:
                corridors.append(((r, c), (r, c + 1)))

    return UndirectedGraph(E=corridors)
示例#9
0
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)
示例#10
0
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)
示例#11
0
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)
示例#12
0
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)
示例#13
0
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)
示例#14
0
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)
示例#15
0
def load_lab(fichero):
    fich = open(fichero)

    #Lee la primera linea
    #cols = len de la lista que devuelve split
    cols = len(fich.readline().split(","))

    #Lee el resto de filas
    #rows = num de filas + la leida antes
    rows = len(fich.readlines()) + 1

    fich.seek(0)
    edges = []
    for r in range(rows):
        #Vector que guarda cada linea
        row = fich.readline().split(",")
        for c in range(cols):
            column = row[c]
            #Si la celda no tiene pared al norte o al este se añaden los pasillos
            if "s" not in column:
                edges.append(((r, c), (r + 1, c)))
            if "e" not in column:
                edges.append(((r, c), (r, c + 1)))

    #Devolvemos el grafo construido, junto con sus dimensiones
    return UndirectedGraph(E=edges), rows, cols
示例#16
0
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
示例#17
0
def hourse_graph(rows, cols) -> UndirectedGraph:
    vertexes = [(fil, col) for fil in range(rows) for col in range(cols)]
    edges = []
    for fil, col in vertexes:
        for sr, sc in [(1, -2), (2, -1), (2, 1), (1, 2)]:
            if sr + fil < rows and 0 <= col + sc < cols:
                edges.append(((fil, col), (fil + sr, col + sc)))
    return UndirectedGraph(E=edges, V=vertexes)
示例#18
0
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
示例#19
0
def horse_graph(rows: int, cols: int) -> UndirectedGraph:
    vertices = [(u, v) for u in range(rows) for v in range(cols)]
    edges = []
    for (u, v) in vertices:
        for (ir, ic) in [(-2, 1), (-2, -1), (-1, 2), (-1, -2)]:
            if u + ir >= 0 and 0 <= v + ic < cols:
                edges.append(((u, v), (u + ir, v + ic)))
    g = UndirectedGraph(E=edges, V=vertices)
    return g
示例#20
0
def horse_graph(rows, cols):
    edges = []
    saltos = [(1, -2), (2, -1), (2, 1), (1, 2)]
    for r in range(rows):
        for c in range(cols):
            for (ri, ci) in saltos:
                if r + ri < rows and 0 <= c + ci < cols:
                    edges.append(((r, c), (r + ri, c + ci)))

    return UndirectedGraph(E=edges)
示例#21
0
def horse_graph(rows: int, cols: int) -> UndirectedGraph:
    vertices = [(r, c) for r in range(rows) for c in range(cols)]

    edges = []
    jumps = [(1, 2), (1, -2), (2, -1), (2, 1)]
    for r, c in vertices:
        for ir, ic in jumps:
            if r + ir < rows and 0 <= c + ic < cols:
                edges.append(((r, c), (r + ir, c + ic)))

    return UndirectedGraph(V=vertices, E=edges)
示例#22
0
def load_graph(filename: str):
    def string_to_tuple(linea: str) -> Tuple:
        linea = linea.split()
        return (int(linea[0]), int(linea[1])), (int(linea[2]), int(linea[3]))

    with open(filename, "r") as f:
        edges = []
        for line in f:
            edges.append(string_to_tuple(line))
    graph = UndirectedGraph(E=edges)
    return graph
示例#23
0
 def setUp(self):
     self.G = UndirectedGraph(
         E={
             0: [1, 2],
             1: [2],
             2: [],
             3: [4],
             4: [],
             5: [6, 7, 8],
             6: [7, 8],
             7: [8],
             8: []
         })
     self.chain = UndirectedGraph(E=[(0, 1), (1, 2), (2, 3), (3, 4), (4,
                                                                      5)])
     self.loop = UndirectedGraph(E=[(0, 1), (1, 2), (2, 3), (3,
                                                             4), (4,
                                                                  5), (5,
                                                                       0)])
     self.islands = UndirectedGraph(E=[(0, 1), (1, 2), (2, 0), (3, 4), (4,
                                                                        3)])
 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))
示例#25
0
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)
示例#26
0
def knight_graph(num_rows: int, num_cols: int) -> UndirectedGraph:
    vertices: List[Tuple] = []
    for r in range(num_rows):
        for c in range(num_cols):
            vertices.append((r, c))

    edges: List[Edge] = []
    for r, c in vertices:
        for (ir, ic) in [(-2, -1), (-1, -2), (-2, 1), (-1, 2)]:
            if 0 <= r + ir < num_rows and 0 <= c + ic < num_cols:
                edges.append(((r, c), (r + ir, c + ic)))

    return UndirectedGraph(V=vertices, E=edges)
示例#27
0
 def setUp(self):
     self.edges = [(0,1), (1,2), (2,3), (3,4), (4,5),(5,0), (0,3), (3,0), (0,2), (0,4), (0,7)]
     self.undirected_edges = set()
     for (u,v) in self.edges: 
         self.undirected_edges.add((u,v))
         self.undirected_edges.add((v,u))
     self.g1 = UndirectedGraph(V=range(8), E=self.edges)
     self.g1bis = UndirectedGraph(E=self.edges)
     self.g1bis.V.add(6)
     self.g2 = AdjacencyDigraph(V=range(8), E=self.edges, directed=False, 
                              createMap=lambda V: IntKeyMap(capacity=max(V)+1), 
                              createSet=lambda V: IntSet(capacity=max(V)+1))
     self.g3 = LinkedListSetAdjacencyDigraph(V=range(8), E=self.edges, directed=False, 
                              createMap=lambda V: IntKeyMap(capacity=max(V)+1))
     self.g4 = ListSetAdjacencyDigraph(V=range(8), E=self.edges, directed=False, 
                              createMap=lambda V: IntKeyMap(capacity=max(V)+1))
     self.g5 = SetAdjacencyDigraph(V=range(8), E=self.edges, directed=False, 
                              createMap=lambda V: IntKeyMap(capacity=max(V)+1))
     self.g6 = AdjacencyMatrixDigraph(V=range(8), E=self.edges, directed=False)
     self.g7 = InvAdjacencyDigraph(V=range(8), E=self.edges, directed=False, 
                              createMap=lambda V: IntKeyMap(capacity=max(V)+1), 
                              createSet=lambda V: IntSet(capacity=max(V)+1))
示例#28
0
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)
示例#29
0
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
示例#30
0
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