def setUp(self): self.fh = FibonacciHeap() # # 17 24 23 7 21 3 # | /\ / | \ # 30 26 46 18 52 41 # | | | # 35 39 44 # self.elems = { v: HeapNode(v) for v in (30, 7, 35, 26, 46, 24, 23, 17, 21, 39, 18, 52, 44, 41, 3) } self.snd_min_elem = sorted(self.elems.values())[1] self.elems[41].link(self.elems[44]) self.elems[18].link(self.elems[39]) self.elems[3].link(self.elems[41]) self.elems[3].link(self.elems[52]) self.elems[3].link(self.elems[18]) self.fh.add_tree(self.elems[3]) self.fh.add_tree(self.elems[21]) self.fh.add_tree(self.elems[7]) self.fh.add_tree(self.elems[23]) self.elems[26].link(self.elems[35]) self.elems[24].link(self.elems[46]) self.elems[24].link(self.elems[26]) self.fh.add_tree(self.elems[24]) self.elems[17].link(self.elems[30]) self.fh.add_tree(self.elems[17]) # Remove `3` self.fh.extract_min() self.exp_num_trees = 3
def setUp(self): self.fh = FibonacciHeap() self.num_elems = 30 self.elems = [ HeapNode(random.randint(1, 100)) for i in range(self.num_elems) ] self.min_elem = min(self.elems) for elem in self.elems: self.fh.add_tree(elem)
def dijkstra(self, source): """ Computes Dijkstra's algorithm (shortest path from a source vertex to all other verticies). Assumption(s): - "source" is in the graph. - The graph has no negative edge-weights. - The graph has no negative cycles. :param source: The vertex to perform Dijkstra's on. :return Two dictionaries: -A dictionary containing the cost to traverse from "source" to each reachable vertex in the graph. -A dictionary encoding the shortest path from "source" to each reachable vertex in the graph. """ V = self.get_vertices() dist, prev = {}, {} assert source in V pq = FibonacciHeap() for v in V: dist[v] = INFINITY if v != source else 0 prev[v] = None pq.push(v, dist[v]) while not pq.empty(): u = pq.pop() neighbors = self.get_neighbors(u) for neighbor in neighbors: alt = dist[u] + self.get_edge_value(u, neighbor) if alt >= dist[neighbor]: continue dist[neighbor] = alt prev[neighbor] = u if neighbor not in pq: pq.push(neighbor, alt) else: pq.decrease_key(neighbor, alt) return dist, prev
def setUp(self): self.fh = FibonacciHeap() # # 7 18 38 # / | \ /\ | # 24 17 23 21 39 41 # / \ | | # 26 46 30 52 # / \ | # 35 88 72 # self.elems = { v: HeapNode(v) for v in (41, 38, 39, 52, 21, 18, 23, 30, 17, 72, 46, 88, 35, 26, 24, 7) } self.elems[38].link(self.elems[41]) self.fh.add_tree(self.elems[38]) self.elems[21].link(self.elems[52]) self.elems[18].link(self.elems[39]) self.elems[18].link(self.elems[21]) self.fh.add_tree(self.elems[18]) self.elems[17].link(self.elems[30]) self.elems[46].link(self.elems[72]) self.elems[26].link(self.elems[88]) self.elems[26].link(self.elems[35]) self.elems[24].link(self.elems[46]) self.elems[24].link(self.elems[26]) self.elems[7].link(self.elems[23]) self.elems[7].link(self.elems[17]) self.elems[7].link(self.elems[24]) self.fh.add_tree(self.elems[7]) self.elems[29] = self.fh.dec_key(self.elems[46], 29) del self.elems[46] self.elems[15] = self.fh.dec_key(self.elems[29], 15) del self.elems[29] self.elems[35].parent.mark() self.elems[35].parent.parent.mark() self.elems[5] = self.fh.dec_key(self.elems[35], 5) self.exp_num_trees = 7 self.min_elem = min(self.elems.values())
def dijkstra(vertice_list, src, num_ver): parent = [] #marca todos os vertices como nao visitados for i in range(num_ver): parent.append(-1) #vertice inicial tem distancia 0. Na 1 iteracao todos os demais estao setados com 'infinidade' vertice_list[src].dist = 0 from fibheap import FibonacciHeap f = FibonacciHeap() f.insert(vertice_list[src].dist, src) #print("Nodes:",f.total_nodes) #pelo numero de vertices, escolha o vertice de menor distancia atualmente no grafo. #Na primeira iteracao sera o source. i = 0 while (f.total_nodes != 0): #while(i<10): i += 1 #print(i) v_min_node = f.extract_min() # 1.1 #print('key:',v_min_node.key) #print("Nodes:",f.total_nodes) v_min = vertice_list[v_min_node.value] if (v_min == None): continue v_min.visited = 1 #marque vertice minimo como ja visitado. Desse modo o 1.2 sera feito, pois nao sera mais contado #para cada vertice adjacente ao vertice minimo for key in v_min.adjs: # 1.3 adj_ver = vertice_list[ v_min.adjs[key].id] #pega o vertice adjacente #Se a distancia atual do vertice minimo, mais o seu peso, for menor que a distancia do vert adjacente if (adj_ver.visited == 0 and v_min.dist + v_min.weights[key] < adj_ver.dist): adj_ver.dist = v_min.dist + v_min.weights[ key] #a distancia do vertice adjacente tera esse novo valor parent[ adj_ver. id] = v_min.id # a pos que era do vertice adjacente, sera do menor v agora f.insert(adj_ver.dist, adj_ver.id)
def mst(self): """ Computes the minimum spanning tree of the graph using Prim's algorithm. :return: The minimum spanning tree (in a list of connecting edges). """ V = self.get_vertices() heap = FibonacciHeap() cost, prev = {}, {} for u in V: cost[u] = INFINITY prev[u] = None v = random.choice(V) cost[v] = 0 for u in V: heap.push(u, cost[u]) while not heap.empty(): u = heap.pop() neighbors = self.get_neighbors(u) for v in neighbors: edge_weight = self.get_edge_value(u, v) if v in heap and cost[v] > edge_weight: cost[v] = edge_weight prev[v] = u heap.decrease_key(v, cost[v]) mst = set() for v in V: if prev[v] is None: continue edge = (prev[v], v) if prev[v] < v else (v, prev[v]) mst.add(edge) return mst
def setUp(self): self.fh = FibonacciHeap() self.elem = HeapNode(random.randint(1, 100)) self.fh.add_tree(self.elem)
def setUp(self): self.fh = FibonacciHeap()