def run_dijkstra(graph, source, target): """Dijkstra's shortest path algorithm""" queue = PriorityQueue() dist = {source: 0} prev = {} for vertex in graph: if vertex != source: dist[vertex] = float("inf") queue.insert(vertex, dist[vertex]) while not queue.is_empty(): u_dist, u = queue.pop() u_node = graph[u] if u == target: break for v in u_node['linkTo']: if queue.is_node_in_queue(v): alt = dist[u] + \ calc_distance(int(u_node['x']), int(u_node['y']), int(graph[v]['x']), int(graph[v]['y'])) if alt < dist[v]: dist[v] = alt prev[v] = u queue.insert(v, alt) path = [] curr = target while curr in prev: path.append(curr) curr = prev[curr] path.append(source) return path[::-1]
def prim(graph, start): # heap to have the vertex that are not added # key is the cheapest edge edge = set() overall_cost = 0 prev = {} prev[start] = start costs = {} costs[start] = 0 pq = PriorityQueue() visited = set() for node in graph.nodes(): pq.insert(float('inf'), node) pq.insert(0, start) while not pq.is_empty(): cost, ele = pq.delete_min() edge.add((prev[ele], ele)) overall_cost += cost visited.add(ele) for successor, edge_cost in graph.get_successors(ele): new_cost = edge_cost if successor not in visited and (successor not in costs or new_cost < costs[successor]): costs[successor] = new_cost prev[successor] = ele pq.update(new_cost, successor) return edge, overall_cost
def dijkstra(graph, start): prev = {} costs = {} costs[start] = 0 visited = set() pq = PriorityQueue() for node in graph.nodes(): if node != -1: pq.insert(float('inf'), node) pq.insert(0, start) while not pq.is_empty(): cost, ele = pq.delete_min() visited.add(ele) for successor in graph.get_successors(ele): new_cost = cost + graph.get_cost(ele, successor) if successor not in visited and (successor not in costs or new_cost < costs[successor]): costs[successor] = new_cost prev[successor] = ele pq.update(new_cost, successor) res = {} for key in costs: res[(start, key)] = costs[key] return res
def pq_sort(self, test_array): pq = PriorityQueue() for x in test_array: pq.insert(x) pq_size = pq.size() return [pq.extract_min() for x in range(pq_size)]
def test_size_remove(self): pq = PriorityQueue() for i in range(100): pq.insert(i) for i in range(100): pq.extract_min() self.assertEqual(pq.size(), 0)
def insert(self, item, priority): ''' Overrides the insert method in the 'PriorityQueue' class so that if a duplicate item is added, it changes the priority rather than inserting a copy. This will solve the problem that the given implementation can lose track of an item in the itemmap if it is inserted twice. ''' if item in self._itemmap: self.changepriority(item, priority) else: PriorityQueue.insert(self, item, priority)
def Dijkstra(G, src): #initialization dist = {} # prev = {} Q = PriorityQueue() # print(g["home"].keys()) #출발노드 s는 자신까지의 거리가 0이고 자신의 predecessor dist[src] = 0 # prev[s] = None #다른 노드들은 모두 거리를 infinity로 설정하고 predecessor는 일단 None으로 설정하고 '''for n in g: dist[n[0]] = float('inf') prev[n[0]] = None dist[n[1]] = float('inf') prev[n[1]] = None ''' #그러면서 PQ에다가 노드들을 넣어줍니다. for node in G.keys(): if node != src: dist[node] = float('inf') #prev[n] = None ''' if n in g[s].keys(): dist[n] = float('inf') prev[n] = None ''' Q.insert(dist[node], node) # n이 우선순위 dist가 value #PQ가 빌때까지 계속 루프를 돌면서, while Q.size() > 0: p, u = Q.pop() #현재까지 가장 짧은 거리를 갖고 있는 노드를 pop #꺼낸 노드의 각 이웃들까지의 거리를 현재 자신까지의 minimum cost와 더한 후 #이웃들이 가지고 있는 거리보다 작으면 이것으로 업데이트 시키고 다시 PQ에 넣거나 update합니다 #pd insert 기능에 포함되어 있다고 한다. '''for v in g[u].keys(): # alt = dist[u] + g[u][v].get('weight',1) alt = dist[u] + g[u][v] if alt < dist[v]: dist[v] = alt prev[v] = u Q.insert(dist[v],v) #for v in g.neighbors(u): ''' for v in G[u].keys(): #alt = dist[u] + g[u][v].get('weight',1) alt = dist[u] + G[u][v] if alt < dist[v]: dist[v] = alt Q.insert(dist[v], v) return dist
def get_huffman_tree(frequency_lst): frequency_lst = Counter(s) pq = PriorityQueue() for char, freq in frequency_lst: pq.insert(freq, TreeNode(char)) while pq.size() > 1: freq1, node1 = pq.delete_min() freq2, node2 = pq.delete_min() internal_node = TreeNode(node1.val + node2.val, node1, node2) pq.insert(freq1 + freq2, internal_node) _, root = pq.delete_min() return get_code(root)
class MaxHeap(object): def __init__(self, lst=[]): lst = [(-prio, ele) for (prio, ele) in lst] self.maxHeap = PriorityQueue(lst) def insert(self, priority, ele): self.maxHeap.insert(-priority, ele) def delete_max(self): prio, ele = self.maxHeap.delete_min() return -prio, ele def get_max(self): prio, ele = self.maxHeap.get_min() return -prio, ele def size(self): return self.maxHeap.size()
def dijkstra(graph, start): prev = {} costs = {} costs[start] = 0 pq = PriorityQueue() for node in graph.nodes(): pq.insert(float('inf'), node) pq.insert(0, start) while not pq.is_empty(): cost, ele = pq.delete_min() for successor, edge_cost in graph.get_successors(ele): new_cost = cost + edge_cost if successor not in costs or new_cost < costs[successor]: costs[successor] = new_cost prev[successor] = ele pq.update(new_cost, successor) return prev, costs
class Median(object): def __init__(self, lst=[]): self.minHeap = PriorityQueue() self.maxHeap = MaxHeap() self.size = len(lst) if lst: lst = sorted(lst) mid = len(lst) // 2 self.minHeap = PriorityQueue(lst[mid:]) self.maxHeap = MaxHeap(lst[0:mid]) def get_median(self): if self.size == 0: raise IndexError("empty heap") if self.size == 1 or self.size % 2 != 0: return self.minHeap.get_min()[0] else: return self.maxHeap.get_max()[0] def insert(self, prio, ele): if self.size == 0: self.minHeap.insert(prio, ele) elif self.size == 1: self.minHeap.insert(prio, ele) prio, ele = self.minHeap.delete_min() self.maxHeap.insert(prio, ele) else: min_in_minHeap = self.minHeap.get_min()[0] max_in_maxHeap = self.maxHeap.get_max()[1] if prio >= min_in_minHeap: self.minHeap.insert(prio, ele) else: self.maxHeap.insert(prio, ele) if not self.is_balanced(): self.balance() self.size += 1 def is_balanced(self): return self.minHeap.size() <= self.maxHeap.size() + 1 and \ self.minHeap.size() >= self.maxHeap.size() def balance(self): while not self.is_balanced(): if self.minHeap.size() >= self.maxHeap.size() + 1: prio, ele = self.minHeap.delete_min() self.maxHeap.insert(prio, ele) else: prio, ele = self.maxHeap.delete_max() self.minHeap.insert(prio, ele)
def test_size_insert(self): pq = PriorityQueue() for i in range(100): self.assertEqual(pq.size(), i) pq.insert(i)