def __init__(self, g): self.mst = [] self.g = g self.heap = MinHeap() self.UF = UnionFind(g.V) self.populateHeap() self.populate_mst()
def test_random_additions(): for i in range(100): heap = MinHeap() for j in range(100): heap.add(j) assert heap.is_valid()
def heap_sort(int_array): minheap = MinHeap("value") for x in int_array: minheap.push(NodeForPrimitiveDataTypes(x)) return minheap.get_sorted_list()
class KruskalsMST: def __init__(self, g): self.mst = [] self.g = g self.heap = MinHeap() self.UF = UnionFind(g.V) self.populateHeap() self.populate_mst() def populateHeap(self): edges = set() for i in range(self.g.V): for edge in self.g.adj(i): edges.add(edge) for edge in edges: self.heap.add_item(edge) def populate_mst(self): while len(self.mst) < self.g.V - 1 and not self.heap.is_empty(): edge = self.heap.del_min() if not self.UF.find(edge.either(), edge.other(edge.either())): self.mst.append(edge) self.UF.union(edge.either(), edge.other(edge.either())) def get_mst(self): return self.mst
class KruskalsMST: def __init__(self, g): self.mst = [] self.g = g self.heap = MinHeap() self.done = [False]*self.g.V self.populate_mst() def travel_node(self, node): self.done[node] = True for each in self.g.adj(node): self.heap.add_item(each) def populate_mst(self): self.travel_node(0) while len(self.mst) < self.g.V-1 and not self.heap.is_empty(): edge = self.heap.del_min() if not self.done[edge.either()] and self.done[edge.other(edge.either())]: self.travel_node(edge.either()) self.mst.append(edge) elif self.done[edge.either()] and not self.done[edge.other(edge.either())]: self.travel_node(edge.other(edge.either())) self.mst.append(edge) def get_mst(self): return self.mst
def test_min_heap(): heap = MinHeap() heap.add(1) heap.add(2) value = heap.retrieve_min() assert value == 1
def dijkstra(G, s): d = {} nodes = [] # node with distances from source predecessor = {} # node predecessor on the shortest path #initing distances to INF for all but source. for v in G: if v == s: nodes.append((0, s)) d[s] = 0 else: nodes.append((float("inf"), v)) d[v] = float("inf") predecessor[s] = None Q = MinHeap( nodes ) # contains all nodes to find shortest paths to, intially everything. while (Q.arr): # until there is nothing left in Q u = Q.delete_min()[1] # get min distance node for v in G[u]: # relax all outgoing edges from it relax(u, v, d, predecessor, Q) print(d) print_paths(predecessor)
def test_has_child(): heap = MinHeap() heap.heap_list = [None, 3, 4] heap.size = 2 for_num_3 = heap.has_child(1) for_num_4 = heap.has_child(2) assert for_num_3 is True assert for_num_4 is False
def test_extract_min(): for _ in range(100): heap = MinHeap() values = [randrange(0, 1000) for _ in range(100)] heap.add_all(values) values.sort() k = 0 for val in values: assert values[k] == val k += 1
def solve_with_a_star(self): path = [] openList = MinHeap([]) entryFinder = {} initial_cost = self.heuristic[self.startingNode] openList.insert(initial_cost, [self.startingNode, []]) entryFinder[self.startingNode] = 0 closedList = [] memory_spend = 0 for i in range(1, MAX_ATTEMPTS): if openList.heap_size is 0: raise Exception("Not found a solution") else: if openList.heap_size > memory_spend: memory_spend = openList.heap_size p = openList.extract_min() cost_until_now = p[0] actual_city = p[1][0] if actual_city in entryFinder: entryFinder.pop(actual_city) if actual_city in self.objectives: finalPath = p[1][1] finalPath.append(actual_city) print(memory_spend) print(finalPath) print(cost_until_now) return adj_cities = self.graph[actual_city] closedList.append(actual_city) for adj_city in adj_cities: if adj_city not in closedList: gx = (cost_until_now - self.heuristic[actual_city] ) + adj_cities[adj_city]['distance'] cost = gx + self.heuristic[adj_city] if adj_city not in entryFinder: path = p[1][1] newPath = list(path) newPath.append(actual_city) openList.insert(cost, [adj_city, newPath]) entryFinder[adj_city] = cost else: if cost < entryFinder[adj_city]: path = p[1][1] newPath = list(path) newPath.append(actual_city) for i in range(1, openList.heap_size): if openList.heap[i][1][0] == adj_city: openList.heap[i][1][1] = newPath openList.decrease_priority(i, cost) entryFinder[adj_city] = cost break raise Exception("Max attempts reached")
def shortest_path(self, start: Vertice, destination: Vertice, time: float) -> tuple: for v in self.__v.values(): v.set_distance(-1) v.set_parrent(None) unexplored = MinHeap(len(self.__v)) for v in self.__v.values(): unexplored.insert(v) unexplored.update(start.v_id(), 0) self.__v[start.v_id()].set_distance(0) traffic = 0 for edge in self.__traffic.keys(): for t in self.__traffic[edge]: if time <= t: traffic += 1 v = self.__v[edge[0]] u = self.__v[edge[1]] self.set_e_weight(v, u, self.__weight(v, u, traffic)) traffic = 0 explored = [] while not destination.v_id() in explored: v = unexplored.pop_min() explored.append(v.v_id()) for edge in self.__adj[v.v_id()]: if v.distance() + edge[1] < self.__v[edge[0]].distance(): unexplored.update(edge[0], v.distance() + edge[1]) self.__v[edge[0]].set_distance(v.distance() + edge[1]) self.__v[edge[0]].set_parrent(v) finded_path = [] curr = destination travel_time = 0 while curr is not start: finded_path.append(curr.v_id()) travel_time += self.e_weight(curr, curr.parrent()) curr = curr.parrent() travel_time *= 120 finded_path.append(curr.v_id()) for i in range(len(finded_path) - 1): self.__traffic[(finded_path[i], finded_path[i + 1])].append(time + travel_time) self.__traffic[(finded_path[i + 1], finded_path[i])].append(time + travel_time) finded_path.append(travel_time) return tuple(reversed(finded_path))
def test_retrieve_min(capsys): heap = MinHeap() heap.heap_list = [None, 1, 2, 4, 3] heap.size = 4 minimum = heap.retrieve_min() assert heap.size == 3 assert minimum == 1 assert heap.heap_list == [None, 2, 3, 4] heap.retrieve_min() heap.retrieve_min() heap.retrieve_min() assert heap.retrieve_min() is None captured = capsys.readouterr() assert captured.out == "Error, heap is empty!\n"
def test_smaller_child(): heap = MinHeap() heap.heap_list = [None, 3, 4, 5] heap.size = 3 smaller_1 = heap.get_smaller_child(1) heap.heap_list = [None, 3, 5, 4] smaller_2 = heap.get_smaller_child(1) assert smaller_1 == 2 assert smaller_2 == 3 heap.heap_list = [None, 3, 4] heap.size = 2 smaller = heap.get_smaller_child(1) assert smaller == 2
def test_init_with_unsorted_iterable(l=[5, 2, 1, 4, 3]): from min_heap import MinHeap mh = MinHeap(l) assert mh._list[0] == 1 assert mh._list[1] == 3 assert mh._list[2] == 2 assert mh._list[3] == 5 assert mh._list[4] == 4
def prim(graph: UndirectedGraph): for node in graph.nodes: node.distance = None node.parent = None node.in_queue = True graph.nodes[0].distance = 0 q = MinHeap(graph.nodes, lambda n: n.distance, set_node_distance) while q.get_min(): u = q.pop_min() u.in_queue = False for v in graph.neighbours_of(u): uv_edge = graph.get_edge_between(u, v).weight if v.in_queue and uv_edge < v.distance: v.parent = u v.distance = uv_edge.weight
def test_init_with_sorted_iterable(l=[1, 2, 3, 4, 5]): from min_heap import MinHeap mh = MinHeap(l) assert mh._list[0] == 1 assert mh._list[1] == 2 assert mh._list[2] == 3 assert mh._list[3] == 4 assert mh._list[4] == 5
def shortest_path(self, v_start, v_end): # item structure: {'w': 11, 'path': ['va', 'vb', ...]} priority_queue = MinHeap(criterion='w') # structure: {..., 'v_name': {'w': 11, 'path': ['va', 'vb',...] }} best_tracks = {} curr_track = {'path': [v_start], 'w': 0, 'v': v_start} while True: for edge in self.vertex_edges[curr_track['v']]: new_track = { 'w': curr_track['w'] + edge['w'], 'path': curr_track['path'] + [edge['v2']] } priority_queue.insert(new_track) assert priority_queue.is_empty() == False min_track = priority_queue.getMin() while better_track_exists(min_track, best_tracks): min_track = priority_queue.getMin() if at_destination(min_track, v_end): return min_track best_tracks[min_track['path'][-1]] = min_track curr_track = min_track.copy() curr_track['v'] = min_track['path'][-1]
def MST_prim2(self): #최종적으로 만들어질 MST mst = Graph() mst.add_vertex(self.vertex_num) #TV={} : MST 정점의 집합, 시작 노드부터 하나씩 채워나간다 TV = set() #w_list : 각 정점의 w 값을 담아두기 위한 배열 w_list = [None for _ in range(self.vertex_num)] #min heap에 w와 from을 가진 정점을 담아둔다 #heap 초기화 : w->inf, from->None h = MinHeap() for i in range(1, self.vertex_num): w_list[i] = math.inf h.push(Element(i, math.inf, None)) #시작 노드인 0은 w->0, from->None w_list[0] = 0 h.push(Element(0, 0, None)) while not h.is_empty(): #가중치가 가장 작은 에지 (from, v) : w #정보를 가진 정점 Element v v = h.pop() #TV에 정점을 추가 TV.add(v.v) #TE에 에지 추가 if v._from != None: mst.insert_edge(v.v, v._from, v.w) #TV에 정점이 추가되면 인접 정점 중 #트리 밖에 있는 정점에 대해 업데이트 시도 #u는 새로 추가된 정점 v에 인접한 정점 노드 u = self.adjacency_list[v.v] while u: #u가 트리 밖의 정점이고 #기존 w 값보다 w(u, v)이 작다면 업데이트 if u.vertex not in TV and u.weight < w_list[u.vertex]: #w_list 업데이트 w_list[u.vertex] = u.weight h.decrease_weight(Element(u.vertex, u.weight, v.v)) u = u.link return mst
def minTimeEncoding(fileSizes: List[int]) -> int: # create a min heap and add all the sizes to it minHeap = MinHeap() for size in fileSizes: minHeap.add(size) while not minHeap.isEmpty(): # pull the least two sizes and add it to the heap until there # is only one size left in the heap size1 = minHeap.poll() if minHeap.isEmpty(): return size1 size2 = minHeap.poll() mergeTime = size1 + size2 minHeap.add(mergeTime) return 0
def dijkstra(self, start): seen = set() heap = MinHeap() heap.push(start, start.val) seen.add(start) while not heap.is_empty(): top, priority = heap.pop() for name, edge_dist in top.neighbors.items(): tmp_distance = edge_dist + priority neighbor = self.nodes[name] if tmp_distance < neighbor.val: neighbor.parent = top neighbor.val = tmp_distance if neighbor in seen: heap.update_priority(neighbor, neighbor.val) else: heap.push(neighbor, neighbor.val)
def test_heapify_down(): heap = MinHeap() heap.heap_list = [None, 4, 2, 3] heap.size = 3 heap.heapify_down() assert heap.heap_list == [None, 2, 4, 3]
def test_heapify_up(): heap = MinHeap() heap.heap_list = [None, 2, 3, 4, 1] heap.size = 4 heap.heapify_up() assert heap.heap_list == [None, 1, 2, 4, 3]
def update(self, query, count): self.lock.acquire_write() p = '' for i in range(len(query)): p += query[i] if p not in self.prefixes: self.prefixes[p] = MinHeap([(count, query)], self.top_k) else: if query in self.prefixes[p].arr_pos_map: self.prefixes[p].update_key(query, count) else: self.prefixes[p].pop_n_push((count, query)) self.lock.release_write()
class PriorityQueue(object): def __init__(self): self._heap = MinHeap() self._num_inserted = 0 def _gen_order(self): self._num_inserted += 1 return self._num_inserted def insert(self, prioritized_item): prioritized_item._order = self. _gen_order() self._heap.push(prioritized_item) def pop(self): return self._heap.pop() def peek(self): return self._heap.peek() def __str__(self): s = [] [s.append(str(item)) for item in self._heap._list] return "".join(s)
def algorithm(P: NPuzzleInstance, name='ASTAR'): begin = time.now() open_heap = MinHeap() open_heap.push( P.initial_state, P.initial_state.get_total_cost() if name == 'ASTAR' else P.initial_state.greedy_value) cost_so_far = {P.initial_state: 0} father_of = {P.initial_state: None} while not open_heap.is_empty(): # print('heap size -> ' + str(len(open_heap.elements)), end='\r', flush=True) P.current_state = open_heap.pop() if P.is_solved(): P.spent_time = time.now() - begin solution = [] curr = P.current_state while curr: solution.append(curr) curr = father_of[curr] P.build_solution(list(reversed(solution))) return P for neighbor in P.neighbors(): if neighbor not in cost_so_far.keys( ) or P.current_state.greedy_value < cost_so_far[neighbor]: cost_so_far[neighbor] = P.current_state.greedy_value open_heap.push( neighbor, neighbor.get_total_cost() if name == 'ASTAR' else neighbor.greedy_value) father_of[neighbor] = State( P.current_state.matrix, P.current_state.greedy_value, P.current_state.heuristic_value if name == 'ASTAR' else 0) return None
def dijkstra(source, graph): cnt = 1 distance = {} heap = MinHeap(len(graph.nodes)) for i in graph.nodes: distance[i] = float('inf') distance[source] = 0 heap.insert((0, source)) while cnt != 0: dist, node = heap.removeMin() cnt -= 1 for i in graph.adjList[node]: if distance[i[0]] > dist + i[1]: distance[i[0]] = dist + i[1] heap.insert((distance[i[0]], i[0])) cnt += 1 return distance
def test_add(): for _ in range(100): heap = MinHeap() check = set() for _ in range(100): rand = randrange(0, 1000) heap.add(rand) check.add(rand) for num in check: assert heap.contains(num) rand = randrange(0, 1000) if rand not in check: assert not heap.contains(rand)
def a_star_search(P: NPuzzleInstance, parents=[]): open_heap = MinHeap() open_heap.push(P.initial_state, P.initial_state.get_total_cost()) cost_so_far = { P.initial_state: 0 } father_of = { P.initial_state: None } while not open_heap.is_empty(): print('\theap size -> ' + str(len(open_heap.elements)), end='\r', flush=True) P.current_state = open_heap.pop() if P.is_solved(): solution = [] curr = P.current_state while father_of[curr]: solution.append(curr) curr = father_of[curr] solution.append(curr) return list(reversed(solution)) for neighbor in P.neighbors(): new_cost = P.current_state.greedy_value if neighbor not in cost_so_far.keys() or new_cost < cost_so_far[neighbor]: cost_so_far[neighbor] = new_cost open_heap.push(neighbor, neighbor.get_total_cost()) father_of[neighbor] = State( P.current_state.matrix, P.current_state.greedy_value, P.current_state.heuristic_value ) return None
def __init__(self, graph): self.__tree = [] self.__weight = 0 heap = MinHeap() for i in range(graph.get_node_nums()): adj = graph.iter_nodes(i) for edge in adj: if edge.orgin < edge.goal: heap.add(edge) union_find = UnionFind(graph.get_node_nums()) while not heap.is_empty() and len( self.__tree) < graph.get_node_nums() - 1: edge = heap.pop() if not union_find.is_connected(edge.orgin, edge.goal): self.__tree.append(edge) union_find.union(edge.orgin, edge.goal) for x in self.__tree: self.__weight += x.weight
# Declare left_child and right_child as variables and assign them to the appropriate elements from the internal list. # You can do this by using helper methods .left_child_idx() and .right_child_idx() to access elements in self.heap_list. # Make another conditional for the comparison between left_child and right_child. # If the left child is smaller, print a message saying so and return the index of the left child. # Else, do the same but for the right child. # Tab over to script.py and test out this new method by replacing None with the correct index value. # import random number generator from random import randrange # import heap class from min_heap import MinHeap # make an instance of MinHeap min_heap = MinHeap() # set internal list for testing purposes... min_heap.heap_list = [None, 10, 13, 21, 61, 22, 23, 99] min_heap.count = 7 print("The smaller child of index 1 is: ") smaller_child_of_idx_1 = min_heap.get_smaller_child_idx(1) smaller_child_element = min_heap.heap_list[smaller_child_of_idx_1] print(smaller_child_element) print("The smaller child of index 2 is: ") smaller_child_of_idx_2 = min_heap.get_smaller_child_idx(2) smaller_child_element = min_heap.heap_list[smaller_child_of_idx_2] print(smaller_child_element)
def test_swap(): from min_heap import MinHeap two_item_heap = MinHeap([1, 2]) two_item_heap._swap(0, 1) assert two_item_heap._list[0] == 2 assert two_item_heap._list[1] == 1
def __init__(self): self._heap = MinHeap() self._num_inserted = 0