def orden_topologico(grafo): res = [] orden = {} visitados = set() for v in grafo.obt_vertices(): orden[v] = 0 for v in grafo.obt_vertices(): for w in grafo.obtener_vecinos(v): orden[w] += 1 cola = Cola() for v, grado in orden.items(): if grado == 0: cola.encolar(v) while (not cola.esta_vacia()): v = cola.desencolar() if v in visitados: continue res.append(v) visitados.add(v) for w in grafo.obtener_vecinos(v): orden[w] -= 1 for v, grado in orden.items(): if grado == 0: cola.encolar(v) return res
def contar_personas(personas)): if personas.esta_vacia(): return 0 i = 1 cola_aux = Cola() while not personas.esta_vacia(): cola_aux.encolar(personas.desencolar()) i +=1 while not cola_aux.esta_vacia(): personas.encolar(cola_aux.desencolar()) return i
def contar_archivos(self, equipo): if equipo.cola_de_impresion.esta_vacia(): return 0 i = 1 cola_aux = Cola() while not equipo.cola_de_impresion.esta_vacia(): cola_aux.encolar(equipo.cola_de_impresion.desencolar()) i +=1 while not cola_aux.esta_vacia(): equipo.cola_de_impresion.encolar(cola_aux.desencolar()) return i
def topologico_grados(grafo): g_ent = grados_entrada(grafo) q = Cola() for v in grafo: if g_ent[v] == 0: q.encolar(v) resultado = [] while not q.esta_vacia(): v = q.desencolar() resultado.append(v) for w in grafo.adyacentes(v): g_ent[w] -= 1 if g_ent[w] == 0: q.encolar(w) return resultado
def distancias_ady(grafo, origen, visitados, orden, dicc_dist): q = Cola() q.encolar(origen) visitados[origen] = True while not q.esta_vacia(): v = q.desencolar() ady = list(grafo.adyacentes(v)) for w in ady: if w not in visitados: visitados[w] = True orden[w] = orden[v] + 1 if not orden[w] in dicc_dist: dicc_dist[orden[w]] = 1 else: dicc_dist[orden[w]] += 1 q.encolar(w)
def camino_minimo(grafo, origen): visitados = set() distancia = {} padre = {} padre[origen] = None distancia[origen] = 0 q = Cola() q.encolar(origen) visitados.add(origen) while not q.esta_vacia(): v = q.desencolar() for w in grafo.adyacentes(v): if not w in visitados: padre[w] = v distancia[w] = distancia[v] + 1 visitados.add(w) q.encolar(w) return distancia, padre
def bfs(grafo, origen): visitados = set() padres = {} orden = {} padres[origen] = None orden[origen] = 0 visitados.add(origen) q = Cola() # usar deque de collections, NO QUEUE!! q.encolar(origen) while not q.esta_vacia(): v = q.desencolar() for w in grafo.adyacentes(v): # E1 + E2 + E3 + ... + Ev = k E if w not in visitados: padres[w] = v orden[w] = orden[v] + 1 visitados.add(w) q.encolar(w) # O(V + E) return padres, orden
def bfs(grafo, inicio): if not grafo.vertice_esta(inicio): return None cola = Cola() visitados = set() padres = {} padres[inicio] = None visitados.add(inicio) cola.encolar(inicio) while (not cola.esta_vacia()): vertice = cola.desencolar() for v in grafo.obtener_vecinos(vertice): if v in visitados: continue visitados.add(v) padres[v] = vertice cola.encolar(v) return padres
def orden_topologico(grafo): """Solo funciona para grafo dirigido""" resultado = [] cola = Cola() orden = {} for v in grafo.obtener_todos_vertices(): orden[v] = 0 for v in grafo.obtener_todos_vertices(): for w in grafo.adyacentes_vertice(v): orden[w] += 1 for v in grafo.obtener_todos_vertices(): if (orden[v] == 0): cola.encolar(v) while not cola.esta_vacia(): v = cola.desencolar() resultado.append(v) for w in grafo.adyacentes_vertice(v): orden[w] -= 1 if orden[w] == 0: cola.encolar(w) return resultado
def divulgar(grafo, args): origen = args[0] n = int(args[1]) resultado = [] visitados = set() orden = {} orden[origen] = 0 q = Cola() q.encolar(origen) visitados.add(origen) while not q.esta_vacia(): v = q.desencolar() for w in grafo.adyacentes(v): if not w in visitados: orden[w] = orden[v] + 1 if orden[w] > n: print(*resultado, sep=", ") return resultado.append(w) visitados.add(w) q.encolar(w)
def bfs(self, visitar=visitar_nulo, extra=None, inicio=None): '''Realiza un recorrido BFS dentro del grafo, aplicando la funcion pasada por parametro en cada vertice visitado. Parametros: - visitar: una funcion cuya firma sea del tipo: visitar(v, padre, orden, extra) -> Boolean Donde 'v' es el identificador del vertice actual, 'padre' el diccionario de padres actualizado hasta el momento, 'orden' el diccionario de ordenes del recorrido actualizado hasta el momento, y 'extra' un parametro extra que puede utilizar la funcion (cualquier elemento adicional que pueda servirle a la funcion a aplicar). La funcion aplicar devuelve True si se quiere continuar iterando, False en caso contrario. - extra: el parametro extra que se le pasara a la funcion 'visitar' - inicio: identificador del vertice que se usa como inicio. Si se indica un vertice, el recorrido se comenzara en dicho vertice, y solo se seguira hasta donde se pueda (no se seguira con los vertices que falten visitar) Salida: Tupla (padre, orden), donde : - 'padre' es un diccionario que indica para un identificador, cual es el identificador del vertice padre en el recorrido BFS (None si es el inicio) - 'orden' es un diccionario que indica para un identificador, cual es su orden en el recorrido BFS ''' if not inicio in self.vertices: raise KeyError (visitados, padre, orden) = crear_diccionarios(self.nombre_vertices) cola = Cola() cola.encolar(inicio) orden[inicio] = 0 while not cola.esta_vacia(): analizar = cola.desencolar() if not visitar(analizar, padre, orden, extra): return (padre, orden) dist = orden[analizar] if not visitados[analizar]: visitados[analizar] = True for adyacente in self.adyacentes(analizar): if orden[adyacente] == -1: orden[adyacente] = dist + 1 padre[adyacente] = analizar cola.encolar(adyacente) return (padre, orden)
def bfs(self, visitar = visitar_nulo, extra = None, inicio=None): '''Realiza un recorrido BFS dentro del grafo, aplicando la funcion pasada por parametro en cada vertice visitado. Parametros: - visitar: una funcion cuya firma sea del tipo: visitar(v, padre, orden, extra) -> Boolean Donde 'v' es el identificador del vertice actual, 'padre' el diccionario de padres actualizado hasta el momento, 'orden' el diccionario de ordenes del recorrido actualizado hasta el momento, y 'extra' un parametro extra que puede utilizar la funcion (cualquier elemento adicional que pueda servirle a la funcion a aplicar). La funcion aplicar devuelve True si se quiere continuar iterando, False en caso contrario. - extra: el parametro extra que se le pasara a la funcion 'visitar' - inicio: identificador del vertice que se usa como inicio. Si se indica un vertice, el recorrido se comenzara en dicho vertice, y solo se seguira hasta donde se pueda (no se seguira con los vertices que falten visitar) Salida: Tupla (padre, orden), donde : - 'padre' es un diccionario que indica para un identificador, cual es el identificador del vertice padre en el recorrido BFS (None si es el inicio) - 'orden' es un diccionario que indica para un identificador, cual es su orden en el recorrido BFS ''' if not inicio in self.vertices: raise KeyError (visitados, padre, orden) = crear_diccionarios(self.nombre_vertices) cola = Cola() cola.encolar(inicio) orden[inicio] = 0 while not cola.esta_vacia(): analizar = cola.desencolar() if not visitar(analizar,padre,orden,extra): return (padre,orden) dist = orden[analizar] if not visitados[analizar]: visitados[analizar] = True for adyacente in self.adyacentes(analizar): if orden[adyacente] == -1: orden[adyacente] = dist + 1 padre[adyacente] = analizar cola.encolar(adyacente) return (padre,orden)