def kruskal(grafo): '''Algoritmo de Kruskal para hallar el árbol de expansión mínimo''' bosque = [] aristas = Heap(tamanio_grafo(grafo)**2) aux = grafo.inicio while aux is not None: bosque.append([aux.info]) adyac = aux.adyacentes.inicio while adyac is not None: arribo_heap(aristas, [aux.info, adyac.destino], adyac.info) adyac = adyac.sig aux = aux.sig while len(bosque) > 1 and not heap_vacio(aristas): dato = atencion_heap(aristas) origen = None for elemento in bosque: if dato[1][0] in elemento: origen = bosque.pop(bosque.index(elemento)) break destino = None for elemento in bosque: if dato[1][1] in elemento: destino = bosque.pop(bosque.index(elemento)) break if origen is not None and destino is not None: if len(origen) > 1 and len(destino) == 1: destino = [dato[1][0], dato[1][1]] elif len(destino) > 1 and len(origen) == 1: origen = [dato[1][0], dato[1][1]] elif len(destino) > 1 and len(origen) > 1: origen += [dato[1][0], dato[1][1]] bosque.append(origen + destino) else: bosque.append(origen) return bosque[0]
def dijkstra2(grafo, origen, destino): '''Camino mas corto entre dos nodos. Devuelve el camino y el peso total''' no_visitados = Heap(grafo.tamanio) camino = Pila() aux_vertices = grafo.inicio while aux_vertices is not None: if aux_vertices.info == origen: arribo_H(no_visitados, 0, [aux_vertices, None]) else: arribo_H(no_visitados, inf, [aux_vertices, None]) aux_vertices = aux_vertices.sig while not heap_vacio(no_visitados): dato = atencion_H(no_visitados) apilar(camino, dato) aux_adyacentes = dato[1][0].adyacentes.inicio while aux_adyacentes is not None: pos = buscar_H(no_visitados, aux_adyacentes.destino) distancia_acumulada = dato[0] + aux_adyacentes.info if (distancia_acumulada < no_visitados.vector[pos][0]): no_visitados.vector[pos][1][1] = dato[1][0].info cambiarPrioridad(no_visitados, pos, distancia_acumulada) aux_adyacentes = aux_adyacentes.sig largo_de_camino = resolverCaminoDijkstraPeso(camino, destino) camino_resuelto = resolverCaminoDijkstra(camino, destino) return camino_resuelto, largo_de_camino
def dijkstra(grafo, origen, destino): '''Camino mas corto entre dos nodos''' no_visitados = Heap(grafo.tamanio) camino = Pila() aux_vertices = grafo.inicio # Carga inicial de todos los vértices, con sus pesos temporales en infinito, excepto el de inicio while aux_vertices is not None: if aux_vertices.info == origen: arribo_H(no_visitados, 0, [aux_vertices, None]) else: arribo_H(no_visitados, inf, [aux_vertices, None]) aux_vertices = aux_vertices.sig while not heap_vacio(no_visitados): # Se extrae el vertice de menor peso que no haya sido visitado dato = atencion_H(no_visitados) apilar(camino, dato) # Se apunta a sus adyacentes para hacer un barrido aux_adyacentes = dato[1][0].adyacentes.inicio while aux_adyacentes is not None: # Se busca en el heap el adyacente, (en el heap están solo los que no fueron vvisitados) pos = buscar_H(no_visitados, aux_adyacentes.destino) # Se calcula la distancia acumulada que tomaría desde lo que lleva la arista analizada más el camino que tomaría llegar a la nueva arista distancia_acumulada = dato[0] + aux_adyacentes.info # Si el que está en heap tiene mayor peso que el acumulado anterior, se reemplazan los valores if (distancia_acumulada < no_visitados.vector[pos][0]): no_visitados.vector[pos][1][1] = dato[1][ 0].info # Cambia el valor "de donde viene" cambiarPrioridad( no_visitados, pos, distancia_acumulada) # Cambia el peso y flota o hunde aux_adyacentes = aux_adyacentes.sig return resolverCaminoDijkstra(camino, destino)
def punto2(): cola_prioridad = Heap(10) # a b y c trajes = [ 'Mark XLIV', 'Mark XV', 'Mark I', 'Mark V', 'Mark IV', 'Mark II', 'Mark VII' ] estado = ['Producir', 'Reparar'] pos = 0 for i in range(len(trajes)): arribo_heap(cola_prioridad, trajes[pos], randint(1, 3), choice(estado)) pos += 1 print() print('Se atiende los 3 primeros trajes') for i in range(3): print(atencion_heap(cola_prioridad)) print() print('Inserto 3 trajes nuevos(Mark XLV, XXL y III)') print() arribo_heap(cola_prioridad, 'Mark XLV', 3, 'Reparar') arribo_heap(cola_prioridad, 'Mark XXL', 2, 'Producir') arribo_heap(cola_prioridad, 'Mark III', 1, 'Reparar') while not heap_vacio(cola_prioridad): print(atencion_heap(cola_prioridad))
def kruskal(grafo): """Algoritmo de Kruskal para hallar el árbol de expansión mínimo.""" bosque = [] heap_aristas = Heap(grafo.tamanio**2) aux_vertices = grafo.inicio while aux_vertices is not None: # Se inserta en el bosque, el origen bosque.append([aux_vertices.info]) adyacentes = aux_vertices.adyacentes.inicio while adyacentes is not None: # Se inserta en el heap todas las aristas del vertice datos = [aux_vertices.info, adyacentes.destino] peso = adyacentes.info arribo_H(heap_aristas, peso, datos) adyacentes = adyacentes.sig aux_vertices = aux_vertices.sig # Una vez tenemos todas las aristas en el heap, comenzamos: while (len(bosque) > 1) and (not heap_vacio(heap_aristas)): datos_y_peso = atencion_H(heap_aristas) peso = datos_y_peso[0] datos = datos_y_peso[1] origen = datos[0] destino = datos[1] array_origen = None # Array que contendrá al origen array_destino = None # Array que contendré al destino # Se busca si el origen y destino son conexos for array_conexo in bosque: if origen in array_conexo: indice = bosque.index(array_conexo) array_origen = bosque.pop(indice) break for array_conexo in bosque: if destino in array_conexo: indice = bosque.index(array_conexo) array_destino = bosque.pop(indice) break # Si están en el mismo grupo(array), se descarta, si están en distintos grupo(array) el origen y el destino, se juntan estos if (array_origen is not None) and (array_destino is not None): # Si ambos no son none, es porque están en distinto array if (len(array_origen) > len(array_destino)) or ( len(array_origen) == len(array_destino)): bosque.append(array_origen + array_destino) else: bosque.append(array_destino + array_origen) else: bosque.append(array_origen) return bosque[0]
def prim(grafo): '''Algoritmo de Prim para hallar el árbol de expansión mínimo''' bosque = [] aristas = Heap(tamanio_grafo(grafo)**2) adyac = grafo.inicio.adyacentes.inicio while adyac is not None: arribo_heap(aristas, [grafo.inicio.info, adyac.destino], adyac.info) adyac = adyac.sig while len(bosque) // 2 < tamanio_grafo(grafo) and not heap_vacio(aristas): dato = atencion_heap(aristas) if len(bosque) == 0 or ((dato[1][0] not in bosque) ^ (dato[1][1] not in bosque)): bosque += dato[1] destino = buscar_vertice(grafo, dato[1][1]) adyac = destino.adyacentes.inicio while adyac is not None: arribo_heap(aristas, [destino.info, adyac.destino], adyac.info) adyac = adyac.sig return bosque
def prim(grafo): """Algoritmo de Prim para hallar el árbol de expansión mínimo.""" bosque = [] vertice_inicial = grafo.inicio heap_aristas = Heap(grafo.tamanio**2) aux_adyacentes = vertice_inicial.adyacentes.inicio if grafo: bosque += vertice_inicial.info while aux_adyacentes is not None: # Se arriban todas las aristas datos = [vertice_inicial.info, aux_adyacentes.destino] peso = aux_adyacentes.info arribo_H(heap_aristas, peso, datos) aux_adyacentes = aux_adyacentes.sig while (len(bosque) // 2 < grafo.tamanio) and not heap_vacio(heap_aristas): # Mientras heap no esté vació, se desencola una arista datos_y_prioridad = atencion_H(heap_aristas) datos = datos_y_prioridad[1] origen = datos[0] destino = datos[1] # print("Ingresado par {} > {} con peso {}".format(origen, destino, peso)) # Si alguno de los extremos no ha sido visitado. es decir que ya existe camino entre ellos: if (len(bosque) == 0 or ((origen not in bosque) or (destino not in bosque))): bosque += destino nodo_destino = buscarVertice(grafo, destino) aux_adyacentes = nodo_destino.adyacentes.inicio # Se busca el vertice y se agrega al heap todas las aristas de este while aux_adyacentes is not None: peso = aux_adyacentes.info datos = [nodo_destino.info, aux_adyacentes.destino] arribo_H(heap_aristas, peso, datos) aux_adyacentes = aux_adyacentes.sig return bosque
def dijkstra_red(grafo, origen, destino): '''Dijkstra para hallar el camino mas corto''' no_visitados = Heap(tamanio_grafo(grafo)) camino = Pila() aux = grafo.inicio while aux is not None: if aux.info.nombre == origen: arribo_heap(no_visitados, [aux, None], 0) else: arribo_heap(no_visitados, [aux, None], inf) aux = aux.sig while not heap_vacio(no_visitados): dato = atencion_heap(no_visitados) apilar(camino, dato) aux = dato[1][0].adyacentes.inicio while aux is not None: pos = busqueda_heap_red(no_visitados, aux.destino) if no_visitados.vector[pos][0] > dato[0] + aux.info: no_visitados.vector[pos][1][1] = dato[1][0].info.nombre cambiar_prioridad(no_visitados, pos, dato[0] + aux.info) aux = aux.sig return camino