def test_3_pq_peek(self): print("\n") pq = pqueue.pqueue(10) pq.print_pqueue() pq.insert(10) pq.print_pqueue() pq.insert(24) pq.print_pqueue() pq.insert(3) pq.print_pqueue() pq.insert(57) pq.print_pqueue() pq.insert(4) pq.print_pqueue() pq.insert(67) pq.print_pqueue() pq.insert(37) pq.print_pqueue() pq.insert(87) pq.print_pqueue() pq.insert(7) pq.print_pqueue() print("the first element of the queue is: ", pq.peek()) self.assertEqual(pq.peek(), 87) print("\n")
def dijkstra(graph, src, dst): min_dist = dict( ) # stores shortest path from src, ie min_dist[u] = w denotes, weight of shortest path (src->u) = w prev_vertex = dict( ) # prev_vertex[u], stores the previous node on the shortest path from src to u pq = pqueue.pqueue() pq.push((0, src)) min_dist[src] = 0 # distance to source is 0. prev_vertex[src] = None # no previous node for src while not pq.empty(): (dist, u) = pq.pop() for (v, w) in graph[u]: #v is adjacent to u, edge weight is w if v not in min_dist or w + min_dist[u] < min_dist[ v]: # shortest path to v is greater than going through u then v? min_dist[v] = w + min_dist[u] # make it the new path prev_vertex[v] = u pq.push((min_dist[v], v)) if dst not in min_dist: #no path from src to dst return None, None else: path = [] node = dst while node: path.append(node) node = prev_vertex[node] path.reverse() return min_dist[dst], path #return cost, path
def test_3_pq_insert(self): print("\n") pq = pqueue.pqueue(10) pq.print_pqueue() pq.insert(10) pq.print_pqueue() pq.insert(24) pq.print_pqueue() pq.insert(3) pq.print_pqueue() pq.insert(57) pq.print_pqueue() pq.insert(4) pq.print_pqueue() pq.insert(67) pq.print_pqueue() pq.insert(37) pq.print_pqueue() pq.insert(87) pq.print_pqueue() pq.insert(7) pq.print_pqueue() pq_list = [element for element in pq] print("pq_list is: ", pq_list) self.assertEqual(pq_list, [87, 67, 57, 24, 4, 3, 37, 10, 7]) print("\n")
def dijkstra(graph, src, dst): min_dist = dict() # stores shortest path from src, ie min_dist[u] = w denotes, weight of shortest path (src->u) = w prev_vertex = dict() # prev_vertex[u], stores the previous node on the shortest path from src to u pq = pqueue.pqueue() pq.push((0, src)) min_dist[src] = 0 # distance to source is 0. prev_vertex[src] = None # no previous node for src while not pq.empty(): (dist, u) = pq.pop() for (v, w) in graph[u]: # v is adjacent to u, edge weight is w if ( v not in min_dist or w + min_dist[u] < min_dist[v] ): # shortest path to v is greater than going through u then v? min_dist[v] = w + min_dist[u] # make it the new path prev_vertex[v] = u pq.push((min_dist[v], v)) if dst not in min_dist: # no path from src to dst return None, None else: path = [] node = dst while node: path.append(node) node = prev_vertex[node] path.reverse() return min_dist[dst], path # return cost, path
def test_3_pq_extract_max(self): print("inserting and extracting from a priority queue of 20 elements") print("\n") pq = pqueue.pqueue(20) pq.insert(85) pq.insert(34) pq.insert(35) pq.extract_max() pq.insert(17) pq.insert(33) pq.extract_max() pq.insert(31) pq.insert(14) pq.insert(42) pq.extract_max() pq.insert(41) pq.insert(19) pq.extract_max() pq.insert(77) pq.insert(23) pq.insert(78) pq.extract_max() pq.insert(60) pq.insert(13) pq.insert(71) pq.insert(2) pq.insert(43) pq.insert(57) pq.insert(4) pq_list = [element for element in pq] # print(pq_list) self.assertEqual( pq_list, [77, 71, 57, 33, 60, 34, 43, 23, 31, 13, 14, 2, 17, 19, 4]) print("\n")
def test_2_pq_overflow(self): print("extracting when the queue is empty") print("\n") pq = pqueue.pqueue(5) with self.assertRaises(KeyError): pq.extract_max() print("\n")
def test_1_pq_insert(self): print("inserting 20 elements") print("\n") pq = pqueue.pqueue(20) pq.insert(85) pq.insert(34) pq.insert(35) pq.insert(17) pq.insert(33) pq.insert(31) pq.insert(14) pq.insert(42) pq.insert(41) pq.insert(19) pq.insert(77) pq.insert(23) pq.insert(78) pq.insert(60) pq.insert(13) pq.insert(71) pq.insert(2) pq.insert(43) pq.insert(57) pq.insert(4) pq_list = [element for element in pq] self.assertEqual(pq_list, [ 85, 77, 78, 71, 42, 35, 60, 41, 57, 19, 33, 23, 31, 14, 13, 17, 2, 34, 43, 4 ]) print("\n")
def test_1_pq_extract_max(self): print("extract and return the maximum element of the queue") print("\n") pq = pqueue.pqueue(5) pq.insert(1) pq.insert(2) pq.insert(3) self.assertEqual(pq.extract_max(), 3) print("\n")
def test_1_pq_peek(self): print("Just return the first element of the queue.") print("\n") pq = pqueue.pqueue(5) pq.insert(1) pq.insert(2) pq.insert(3) self.assertEqual(pq.peek(), 3) print("\n")
def test_1_pq_insert(self): print("\n") print("insert into the priority queue") pq = pqueue.pqueue(5) pq.insert(1) pq.insert(2) pq.insert(3) pq_list = [element for element in pq] self.assertEqual(pq_list, [3, 1, 2]) print("\n")
def _resetSolution(): global solution global queue global walked global solvedPath global newWalked solution = [] solvedPath = False queue = pqueue() walked = [] newWalked = []
def test_2_pq_insert(self): print("\n") pq = pqueue.pqueue(5) pq.insert(1) pq.insert(2) pq.insert(3) pq.insert(4) pq.insert(5) pq_list = [element for element in pq] self.assertEqual(pq_list, [5, 4, 2, 1, 3]) print("\n")
def test_2_pq_extract_max(self): print("\n") pq = pqueue.pqueue(5) pq.insert(1) pq.insert(2) pq.insert(3) pq.extract_max() pq.insert(4) pq.insert(5) self.assertEqual(pq.extract_max(), 5) self.assertEqual(pq.extract_max(), 4) print("\n")
def test_1_pq_overflow(self): print("inserting when the queue is full") print("\n") pq = pqueue.pqueue(5) pq.insert(1) pq.insert(2) pq.insert(3) pq.insert(4) pq.insert(5) with self.assertRaises(IndexError): pq.insert(6) print("\n")
def test_3_pq_peek(self): print("\n") pq = pqueue.pqueue(10) pq.insert(10) pq.insert(24) pq.insert(3) pq.insert(57) pq.insert(4) pq.insert(67) pq.insert(37) pq.insert(87) pq.insert(7) self.assertEqual(pq.peek(), 87) print("\n")
def astar(neighbors, start, goal, hcost, dist): """ neighbors: a function that returns an iterator over neighbors. start: the index of the start node. goal: the index of the goal node. hcost: heuristic cost function. """ start_score = hcost(start, goal) openset = pqueue() closedset = set() openset.push(start_score, start) closedset = set() partialmap = {} gscore = {} fscore = {} fscore[start] = hcost(start, goal) while len(openset) > 0: # current lowest estimated cost node current = openset.pop() if current == goal: # finished - so build a map return reconstruct(partialmap, goal) closedset.add(current) for neighbor in neighbors(current): if neighbor in closedset: continue tenative_gscore = gscore.get(current, 0) + dist(current, neighbor) if not neighbor in openset or tenative_gscore < gscore.get( neighbor, 0): partialmap[neighbor] = current gscore[neighbor] = tenative_gscore fscore[neighbor] = gscore[neighbor] + hcost(neighbor, goal) openset.push(fscore[neighbor], neighbor) return False # bad result - no path found
def astar(neighbors, start, goal, hcost, dist): """ neighbors: a function that returns an iterator over neighbors. start: the index of the start node. goal: the index of the goal node. hcost: heuristic cost function. """ start_score = hcost(start,goal) openset = pqueue() closedset = set() openset.push(start_score, start) closedset = set() partialmap = {} gscore = {} fscore = {} fscore[start] = hcost(start,goal) while len(openset) > 0: # current lowest estimated cost node current = openset.pop() if current == goal: # finished - so build a map return reconstruct(partialmap, goal) closedset.add(current) for neighbor in neighbors(current): if neighbor in closedset: continue tenative_gscore = gscore.get(current, 0) + dist(current,neighbor) if not neighbor in openset or tenative_gscore < gscore.get(neighbor,0): partialmap[neighbor] = current gscore[neighbor] = tenative_gscore fscore[neighbor] = gscore[neighbor] + hcost(neighbor, goal) openset.push(fscore[neighbor], neighbor) return False # bad result - no path found
def shortest_path_prev(source, verts): # Initialisation. q = pqueue() dist = {v: math.inf for v in verts} prev = {v: None for v in verts} dist[source] = 0 for v in verts: q.add(v, dist[v]) # Work out dist and prev for each vertex. while len(q) > 0: u = q.pop() for v in adjacencies(u): if v in q: alt = dist[u] + 1 if alt < dist[v]: dist[v] = alt prev[v] = u q.add(v, alt) return prev
def test_3_pq_extract_max(self): print("\n") pq = pqueue.pqueue(10) pq.insert(10) pq.insert(24) pq.insert(3) pq.insert(57) pq.insert(4) pq.insert(67) pq.insert(37) pq.insert(87) pq.insert(7) pq_list = [element for element in pq] self.assertEqual(pq_list, [87, 67, 57, 24, 4, 3, 37, 10, 7]) pq.extract_max() pq.extract_max() pq.extract_max() pq.extract_max() pq.extract_max() pq.extract_max() pq_list = [element for element in pq] self.assertEqual(pq_list, [7, 4, 3]) print("\n")
def shortest_path(cave): # A* search algorithm. start = (0, 0, TORCH) sink = (*cave.target, TORCH) closed = set() open = pqueue() open.add(start, estimate_cost(start, sink)) came_from = {} g_score = defaultdict(lambda: math.inf) g_score[start] = 0 while len(open) > 0: current = open.pop() if current == sink: return reconstruct_path(came_from, current, cave) closed.add(current) for neighbor in neighbors(*current, cave): if neighbor in closed: continue tentative_g = g_score[current] + dist_between(current, neighbor) if neighbor in open and tentative_g >= g_score[neighbor]: continue came_from[neighbor] = current g_score[neighbor] = tentative_g open.add(neighbor, tentative_g + estimate_cost(neighbor, sink))
startEnd.append((x, y)) def solveReady(): return len(startEnd) > 1 def hasSolved(): if solvedPath is False: return False return len(solvedPath.previous) == 0 solution = [] queue = pqueue() walked = [] newWalked = [] def _resetSolution(): global solution global queue global walked global solvedPath global newWalked solution = [] solvedPath = False queue = pqueue() walked = [] newWalked = []
tenative_gscore = gscore.get(current, 0) + dist(current, neighbor) if not neighbor in openset or tenative_gscore < gscore.get( neighbor, 0): partialmap[neighbor] = current gscore[neighbor] = tenative_gscore fscore[neighbor] = gscore[neighbor] + hcost(neighbor, goal) openset.push(fscore[neighbor], neighbor) return False # bad result - no path found if __name__ == '__main__': if True: pq = pqueue(policy='LIFO') pq.push(15, 'a') pq.push(15, 'b') pq.push(15, 'c') pq.push(14, 'd') pq.push(16, 'e') pq.push(200, 'a') print "LIFO" print pq.pop() #d print pq.pop() #c print pq.pop() #b print pq.pop() #a print pq.pop() #e print "FIFO" pq = pqueue(policy='FIFO')
continue tenative_gscore = gscore.get(current, 0) + dist(current,neighbor) if not neighbor in openset or tenative_gscore < gscore.get(neighbor,0): partialmap[neighbor] = current gscore[neighbor] = tenative_gscore fscore[neighbor] = gscore[neighbor] + hcost(neighbor, goal) openset.push(fscore[neighbor], neighbor) return False # bad result - no path found if __name__ == '__main__': if True: pq = pqueue(policy = 'LIFO') pq.push(15,'a') pq.push(15,'b') pq.push(15,'c') pq.push(14,'d') pq.push(16,'e') pq.push(200,'a') print "LIFO" print pq.pop() #d print pq.pop() #c print pq.pop() #b print pq.pop() #a print pq.pop() #e print "FIFO" pq = pqueue(policy = 'FIFO')
def bidirectional_dijkstra(g, src, dst, undirected): rg = g if undirected else reverse_graph( g) #if graph is directed, prepare reverse graph for BI #data structures for FI pq_fi = pqueue.pqueue() prev_fi = dict() min_dist_fi = dict() #data structures for BI pq_bi = pqueue.pqueue() prev_bi = dict() min_dist_bi = dict() #initialize FI processed_fi = set() prev_fi[src] = None min_dist_fi[src] = 0 pq_fi.push((min_dist_fi[src], src)) #initialize BI processed_bi = set() prev_bi[dst] = None min_dist_bi[dst] = 0 pq_bi.push((min_dist_bi[dst], dst)) while not pq_fi.empty() and not pq_bi.empty(): d, u = pq_fi.pop() processed_fi.add(u) if u in processed_bi: break for v, w in g[u]: if v not in min_dist_fi or w + min_dist_fi[u] < min_dist_fi[v]: t = min_dist_fi[v] = w + min_dist_fi[u] prev_fi[v] = u pq_fi.push((t, v)) d, u = pq_bi.pop() processed_bi.add(u) if u in processed_fi: break for v, w in rg[u]: if v not in min_dist_bi or w + min_dist_bi[u] < min_dist_bi[v]: t = min_dist_bi[v] = w + min_dist_bi[u] prev_bi[v] = u pq_bi.push((t, v)) #find intermediate node k = None path_cost = None for k_ in min_dist_fi: if k_ in min_dist_bi: cost = min_dist_fi[k_] + min_dist_bi[k_] if path_cost == None or path_cost > cost: path_cost = cost k = k_ #no shortest path if k == None: return None, None path = [] #build path from k to source node = k while node != None: path.append(node) node = prev_fi[node] path.reverse() #reverse it so it's source->k node = prev_bi[k] # skip k, we already inserted it #build path from k to dst while node != None: path.append(node) node = prev_bi[node] return path_cost, path
def bidirectional_dijkstra(g, src, dst, undirected): rg = g if undirected else reverse_graph(g) # if graph is directed, prepare reverse graph for BI # data structures for FI pq_fi = pqueue.pqueue() prev_fi = dict() min_dist_fi = dict() # data structures for BI pq_bi = pqueue.pqueue() prev_bi = dict() min_dist_bi = dict() # initialize FI processed_fi = set() prev_fi[src] = None min_dist_fi[src] = 0 pq_fi.push((min_dist_fi[src], src)) # initialize BI processed_bi = set() prev_bi[dst] = None min_dist_bi[dst] = 0 pq_bi.push((min_dist_bi[dst], dst)) while not pq_fi.empty() and not pq_bi.empty(): d, u = pq_fi.pop() processed_fi.add(u) if u in processed_bi: break for v, w in g[u]: if v not in min_dist_fi or w + min_dist_fi[u] < min_dist_fi[v]: t = min_dist_fi[v] = w + min_dist_fi[u] prev_fi[v] = u pq_fi.push((t, v)) d, u = pq_bi.pop() processed_bi.add(u) if u in processed_fi: break for v, w in rg[u]: if v not in min_dist_bi or w + min_dist_bi[u] < min_dist_bi[v]: t = min_dist_bi[v] = w + min_dist_bi[u] prev_bi[v] = u pq_bi.push((t, v)) # find intermediate node k = None path_cost = None for k_ in min_dist_fi: if k_ in min_dist_bi: cost = min_dist_fi[k_] + min_dist_bi[k_] if path_cost == None or path_cost > cost: path_cost = cost k = k_ # no shortest path if k == None: return None, None path = [] # build path from k to source node = k while node != None: path.append(node) node = prev_fi[node] path.reverse() # reverse it so it's source->k node = prev_bi[k] # skip k, we already inserted it # build path from k to dst while node != None: path.append(node) node = prev_bi[node] return path_cost, path