def cria_arv_geradora_minima( self, valor_vertice_inicial) -> Dict[Vertice, Vertice]: pai = {} set_ja_explorado = set() peso = {} vertice_inicial = self.obtem_vertice(valor_vertice_inicial) if not vertice_inicial: return None fila_min_heap = MinHeap() for vertice in self.vertices.values(): pai[vertice] = None peso[vertice] = PesoVertice(vertice, float("inf")) peso[vertice_inicial].peso = 0 fila_min_heap.insere(peso[vertice_inicial]) #print(f"HEAP: {fila_min_heap}") #print(f"Vertice Origem: {vertice_inicial.valor}") #print(f"HEAP vertice origem: {fila_min_heap.retira_min().vertice_destino.valor}") while len(fila_min_heap.arr_heap) > 1: vertice = self.obtem_vertice( fila_min_heap.retira_min().vertice_destino.valor) set_ja_explorado.add(vertice) for adjacencia in vertice.adjacencias: distancia_aresta = vertice.adjacencias[adjacencia] if adjacencia not in set_ja_explorado and distancia_aresta < peso[ adjacencia].peso: pai[adjacencia] = vertice peso[adjacencia].peso = distancia_aresta fila_min_heap.insere(peso[adjacencia]) return pai
def dijkstra( self, valor_vertice_origem ) -> (Dict[Vertice, DistanciaVerticeOrigem], Dict[Vertice, Vertice]): distancia = {} pai = {} vertice_origem = self.obtem_vertice(valor_vertice_origem) if not vertice_origem: return None fila_min_heap = MinHeap() #inicialização for vertice in self.vertices.values(): distancia[vertice] = DistanciaVerticeOrigem(vertice, float("inf")) pai[vertice] = None fila_min_heap.insere(distancia[vertice]) #print(f"HEAP: {fila_min_heap}") #print(f"Vertice Origem: {vertice_origem.valor}") #escreva o código abaixo para preencher as veriaveis distancia e pai adequadamente distancia[vertice_origem].distancia = 0 while fila_min_heap.pos_ultimo_item > 0: vertice = self.obtem_vertice( fila_min_heap.retira_min().vertice.valor) for adjacencia in vertice.adjacencias: self.dijkstra_relax(fila_min_heap, vertice, adjacencia, distancia, pai) return distancia, pai
def test_insere(self): arr_test = [1, -8, -11, -14] arr_heap_esperado = [ [None, -12, -9, -6, -4, -3, -5, -2, -1, 1], [None, -12, -9, -6, -8, -3, -5, -2, -1, -4], [None, -12, -11, -6, -9, -3, -5, -2, -1, -4], [None, -14, -12, -6, -9, -3, -5, -2, -1, -4], ] #testa inserção no heap vazio for val_inserir in arr_test: objHeap = MinHeap() objHeap.insere(val_inserir) self.assertListEqual( [None, val_inserir], objHeap.arr_heap, f"Inserção incorreta ao inserir o valor {val_inserir} no heap {[None,12,9,6,4,3,5,2,1]}, esperado: {[None,val_inserir]} obtido: {objHeap.arr_heap}" ) for i, val_inserir in enumerate(arr_test): objHeap = MinHeap() objHeap.arr_heap = [None, -12, -9, -6, -4, -3, -5, -2, -1] objHeap.insere(val_inserir) self.assertListEqual( arr_heap_esperado[i], objHeap.arr_heap, f"Inserção incorreta ao inserir o valor {val_inserir} no heap {[None,12,9,6,4,3,5,2,1]}, esperado: {arr_heap_esperado[i]} obtido: {objHeap.arr_heap}" )
def dijkstra_relax(self, fila_min_heap: MinHeap, vertice_u: Vertice, vertice_v: Vertice, distancia: Dict[Vertice, DistanciaVerticeOrigem], pai: Dict[Vertice, Vertice]): distancia_aresta = vertice_u.adjacencias[vertice_v] if distancia[vertice_v].distancia > (distancia[vertice_u].distancia + distancia_aresta): distancia[vertice_v].distancia = distancia[ vertice_u].distancia + distancia_aresta pai[vertice_v] = vertice_u fila_min_heap.insere(distancia[vertice_v])
def dijkstra_relax(self, fila_min_heap: MinHeap, vertice_u: Vertice, vertice_v: Vertice, distancia: Dict[Vertice, DistanciaVerticeOrigem], pai: Dict[Vertice, Vertice]): dist = distancia[vertice_u].distancia vert = vertice_u.adjacencias dist = dist + vert[vertice_v] if distancia[vertice_v].distancia > dist: distancia[vertice_v].distancia = dist pai[vertice_v] = vertice_u fila_min_heap.insere(distancia[vertice_v])
def cria_arv_geradora_minima(self, valor_vertice_inicial) -> Dict[Vertice,Vertice]: pai = {} fila_min_heap = MinHeap() set_ja_explorado = set() peso = {} vertice_inicial = self.obtem_vertice(valor_vertice_inicial) if not vertice_inicial: return None #para cada u que pertence aos vertices do grafo faca: for vertice in self.vertices.values(): #pai[u] <- NULL pai[vertice] = None #menor_peso[u] <- infinito peso[vertice] = PesoVertice(vertice, float("inf")) #menor_peso[raiz] <- 0 peso[vertice_inicial].peso = 0 #INSERE(Q,raiz) fila_min_heap.insere(peso[vertice_inicial]) #enquanto a fila nao estiver vazia while len(fila_min_heap.arr_heap)>1: #u <- EXTRAI_MIN(Q) peso_vertice_u = fila_min_heap.retira_min() #acha o vertice correspondente ao peso extraido da fila for vertice, valor in peso.items(): if valor == peso_vertice_u: vertice_u = vertice #A <- A U {u} set_ja_explorado.add(vertice_u) #para cada vertice v adjacente ao vertice u faca: for vertice_v in vertice_u.adjacencias.keys(): peso_aresta_uv = vertice_u.adjacencias[vertice_v] #se o vertice v ainda nao foi visitado e se o peso da aresta uv for menor que o menor peso vinculado ao vertice v faca: if vertice_v not in set_ja_explorado and peso_aresta_uv < peso[vertice_v].peso: #pai[v] <- u pai[vertice_v] = vertice_u #menor_peso[v] <- w[u,v] peso[vertice_v].peso = peso_aresta_uv #INSERE(Q,v) fila_min_heap.insere(peso[vertice_v]) #retorna o caminho da arvore criada return pai
def dijkstra_relax(self, fila_min_heap: MinHeap, vertice_u: Vertice, vertice_v: Vertice, distancia: Dict[Vertice, DistanciaVerticeOrigem], pai: Dict[Vertice, Vertice]): ''' print(f"U: {vertice_u.obtem_valor()} | V: {vertice_v.obtem_valor()}") print(distancia) print(pai) print(fila_min_heap) ''' #"vertice_u.adjacencias[vertice_v]" -> peso da aresta (y,v). if distancia[vertice_v].distancia > (distancia[vertice_u].distancia + vertice_u.adjacencias[vertice_v]): distancia[vertice_v].distancia = (distancia[vertice_u].distancia + vertice_u.adjacencias[vertice_v]) pai[vertice_v] = vertice_u fila_min_heap.insere(distancia[vertice_v])