def test_is_empty(self): p = PriorityQueue() assert p.is_empty() is True p.enqueue('A', 1) assert p.is_empty() is False p.enqueue('B', 1) assert p.is_empty() is False p.dequeue() assert p.is_empty() is False p.dequeue() assert p.is_empty() is True
def minimum_spanning_tree(graph): min_heap = PriorityQueue(True) vertex_to_edge = {} result = [] for vertex in graph.all_vertex.values(): min_heap.add_task(sys.maxsize, vertex) start_vertex = next(iter((graph.all_vertex.values()))) min_heap.change_task_priority(0, start_vertex) while min_heap.is_empty() is False: current = min_heap.pop_task() if (current in vertex_to_edge): spanning_tree_edge = vertex_to_edge[current] result.append(spanning_tree_edge) for edge in current.edges: adjacent = get_other_vertex_for_edge(current, edge) if min_heap.contains_task( adjacent) is True and min_heap.get_task_priority( adjacent) > edge.weight: min_heap.change_task_priority(edge.weight, adjacent) vertex_to_edge[adjacent] = edge return result
def shortest_path(graph, sourceVertex): min_heap = PriorityQueue(True) distance = {} parent = {} for vertex in graph.all_vertex.values(): min_heap.add_task(sys.maxsize, vertex) min_heap.change_task_priority(0, sourceVertex) distance[sourceVertex] = 0 parent[sourceVertex] = None while min_heap.is_empty() is False: task = min_heap.peek_task() weight = min_heap.get_task_priority(task) current = min_heap.pop_task() distance[current] = weight for edge in current.edges: adjacent = get_other_vertex_for_edge(current, edge) if min_heap.contains_task(adjacent) is False: continue new_distance = distance[current] + edge.weight; if min_heap.get_task_priority(adjacent) > new_distance: min_heap.change_task_priority(new_distance, adjacent) parent[adjacent] = current return distance
def get_path(self, start, end, board, cost_estimate=get_distance): t0 = time.time() explored = set() previous = {} previous[start] = None moves = {} moves[start] = 0 frontier = PriorityQueue() frontier.insert(start, cost_estimate(start, end)) if VERBOSE_ASTAR: print 'get_path start, end:', start, end while not frontier.is_empty(): if (time.time() - t0 > PATHFINDER_TIMEOUT): print 'PATHFINDING TIMEOUT: Averting disconnect...' print ' get_path: Probably could not find a valid path from', start, 'to', end return [start, start] if VERBOSE_ASTAR: print 'get_path frontier:', frontier current = frontier.remove() explored.add(current) if VERBOSE_ASTAR: print 'get_path explored set', explored if VERBOSE_ASTAR: print 'get_path current pos:', current if (current == end): if VERBOSE_ASTAR: print 'Found end loc' break else: neighbors = get_neighboring_locs(current, board) if VERBOSE_ASTAR: print 'get_path neighbors:', neighbors for n in neighbors: if n not in explored and (board.passable(n) or n in (start, end)): moves[n] = moves[current] + MOVE_COST frontier.insert(n, cost_estimate(n, end) + moves[n]) previous[n] = current # found goal, now reconstruct path i = end path = [i] while i != start: if (i in previous): path.append(previous[i]) i = previous[i] else: print 'get_path error: probably could not find a valid path from', start, 'to', end return [start, start] # return something valid path.reverse() return path
def test_init_with_list(self): q = PriorityQueue() q.enqueue('B', 3) q.enqueue('C', 5) q.enqueue('A', 1) assert q.front() == 'A' assert q.length() == 3 assert q.is_empty() is False
def test_dequeue(self): pq = PriorityQueue([(1, 'A'), (2, 'B'), (3, 'C')]) assert pq.dequeue() == (1, 'A') assert pq.length() == 2 assert pq.dequeue() == (2, 'B') assert pq.length() == 1 assert pq.dequeue() == (3, 'C') assert pq.length() == 0 assert pq.is_empty() is True with self.assertRaises(ValueError): pq.dequeue()
def test_enqueue(self): q = PriorityQueue() q.enqueue('A', 3) assert q.front() == 'A' assert q.length() == 1 q.enqueue('B', 1) assert q.front() == 'B' assert q.length() == 2 q.enqueue('C', 4) assert q.front() == 'B' assert q.length() == 3 assert q.is_empty() is False
def test_enqueue(self): pq = PriorityQueue() pq.enqueue('B', 2) assert pq.front() == (2, 'B') assert pq.length() == 1 pq.enqueue('A', 1) assert pq.front() == (1, 'A') assert pq.length() == 2 pq.enqueue('C', 3) assert pq.front() == (1, 'A') assert pq.length() == 3 assert pq.is_empty() is False
def test_dequeue(self): q = PriorityQueue() q.enqueue('A', 1) q.enqueue('B', 2) q.enqueue('C', 3) assert q.dequeue() == 'A' assert q.length() == 2 assert q.dequeue() == 'B' assert q.length() == 1 assert q.dequeue() == 'C' assert q.length() == 0 assert q.is_empty() is True with self.assertRaises(ValueError): q.dequeue()
class TestPriorityQueue(unittest.TestCase): def setUp(self): self.pq = PriorityQueue(":memory:") def test_empty(self): result = self.pq.is_empty() self.assertTrue(result) def test_order(self): self.assertEqual("hello", self.pq.push(10, "hello")) self.pq.push(1, "foo") self.pq.push(30, "bar") self.pq.push(5, "baz") self.assertEqual("bar", self.pq.pop()) self.assertEqual("hello", self.pq.pop()) self.assertEqual("baz", self.pq.pop()) self.assertEqual("foo", self.pq.pop())
def prims_algorithm_mst(graph): """ Prim's algorithm, this algorithm has the same time complexity as Djikstra's single source shorted path algorithm. This particular algorithm is O((V ** 2) + (V * E)) but with a priority queue or vEB tree this can be reduced to O((V * log(V)) + (V * E)) a time complexity equivalent to Djikstra's """ if not isinstance(graph, Graph): raise TypeError('this function expects an instance of Graph') queue = PriorityQueue(graph) root = None nodes = {u: TreeNode(u) for u in graph.vertices} while not queue.is_empty(): u = queue.pop_min() if root is None: root = nodes[u] for v in graph.adj[u]: if queue.contains(v): queue.update(v, graph.weights[(u, v)]) nodes[v].parent = nodes[u] for n in nodes: node = nodes[n] if node.parent is not None: node.parent.children.append(node) return root
def Astar(puzzle8, came_from): frontier = PriorityQueue() cost_so_far = {} frontier.enqueue(puzzle8, 0) cost_so_far[puzzle8.ToString()] = puzzle8.cost came_from[puzzle8.ToString()] = None while not frontier.is_empty(): puzzle8 = frontier.dequeue() if puzzle8.isGoal(): return puzzle8 else: moves = puzzle8.getAllMoves() for move in moves: newpuzzle8 = puzzle8.clone() newpuzzle8.move(*move) new_cost = newpuzzle8.cost if cost_so_far.get(newpuzzle8.ToString()) == None or \ new_cost < cost_so_far[newpuzzle8.ToString()]: cost_so_far[newpuzzle8.ToString()] = new_cost priority = new_cost + newpuzzle8.heuristics frontier.enqueue(newpuzzle8, priority) came_from[newpuzzle8.ToString()] = puzzle8 return None
def test_init_with_list(self): pq = PriorityQueue([(1, 'A'), (2, 'B'), (3, 'C')]) assert pq.front() == (1, 'A') assert pq.length() == 3 assert pq.is_empty() is False
def test_init(self): q = PriorityQueue() assert q.front() is None assert q.length() == 0 assert q.is_empty() is True
def astar(grid, start, goal): '''Return a path found by A* alogirhm and the number of steps it takes to find it. arguments: grid - A nested list with datatype int. 0 represents free space while 1 is obstacle. e.g. a 3x3 2D map: [[0, 0, 0], [0, 1, 0], [0, 0, 0]] start - The start node in the map. e.g. [0, 0] goal - The goal node in the map. e.g. [2, 2] return: path - A nested list that represents coordinates of each step (including start and goal node), with data type int. e.g. [[0, 0], [0, 1], [0, 2], [1, 2], [2, 2]] steps - Number of steps it takes to find the final solution, i.e. the number of nodes visited before finding a path (including start and goal node) >>> from main import load_map >>> grid, start, goal = load_map('test_map.csv') >>> astar_path, astar_steps = astar(grid, start, goal) It takes 7 steps to find a path using A* >>> astar_path [[0, 0], [1, 0], [2, 0], [3, 0], [3, 1]] ''' debug_draw = False path = [] steps = 0 found = False map = map2d(grid) frontier = PriorityQueue() frontier.put(start, map.get_manhattan_distance(start, goal)) came_from = {} came_from[tuple(start)] = { 'from': None, 'cost': 0 } while not frontier.is_empty(): (curr_cost, current) = frontier.get() frontier.remove() if tuple(goal) in came_from.keys(): found = True break for neighbor in map.get_neighbors(current): if neighbor is None or map.get_value(neighbor) == 1: continue neighbor_cost = curr_cost - map.get_manhattan_distance(current, goal) + \ map.get_manhattan_distance(current, neighbor) + \ map.get_manhattan_distance(neighbor, goal) if tuple(neighbor) not in came_from or \ neighbor_cost < came_from.get(tuple(neighbor)).get('cost'): frontier.put(neighbor, neighbor_cost) came_from[tuple(neighbor)] = { 'from': current, 'cost': neighbor_cost } if debug_draw: map.draw_path(start = start, goal = goal, path = path, came_from = came_from) # found = True steps = len(came_from) - 1 curr_point = goal while curr_point != start: path.append(curr_point) curr_point = came_from.get(tuple(curr_point)).get('from') path.append(start) path.reverse() if found: print(f"It takes {steps} steps to find a path using A*") else: print("No path found") return path, steps