def test_pop(self): # pop selected item - return value pq = minpq(A=5, B=8, C=1) value = pq.pop('B') self.assertEqual(value, 8) pq.pop('A') pq.pop('C') self.assertRaises(KeyError, pq.pop, 'A') self.assertRaises(KeyError, pq.pop, 'does_not_exist') # no args and empty - throws self.assertRaises(KeyError, pq.pop) # pq is now empty # no args - return top key pq = minpq(A=5, B=8, C=1) self.assertEqual(pq.pop(), 'C')
def dijkstra(self, vi0, dist_func): """Calculate shortest path from |vi0| to all other verts. dist_func: callable that takes two adjacent vertex indices and returns a number indicating the distance between them. Returns a list of |DijkstraResult|. Adapted from: http://pqdict.readthedocs.io/en/latest/examples.html """ result = [] queue = minpq() for vi1 in range(len(self._verts)): queue[vi1] = float('inf') result.append(self.DijkstraResult()) queue[vi0] = 0 for vi2, min_dist in queue.popitems(): result[vi2].dist = min_dist for vi3 in self.adj_vert_vert(vi2): if vi3 in queue: new_score = result[vi2].dist + dist_func(vi2, vi3) if new_score < queue[vi3]: # pqdict update is O(log n) queue[vi3] = new_score result[vi3].prev = vi2 return result
def lcv_calculation(self, cell): row_num = cell.row col_num = cell.column block_num = self.get_block_num(row_num, col_num) cell.value_queue = minpq() for value in cell.domain: value_constraint = 0 for other_cell in self.rows[row_num].cells: if other_cell != cell: if value in other_cell.value_queue: value_constraint += 1 for other_cell in self.columns[col_num].cells: if other_cell != cell: if value in other_cell.value_queue: value_constraint += 1 for other_cell in self.blocks[block_num].cells: if other_cell != cell: if value in other_cell.value_queue: value_constraint += 1 if value in cell.value_queue: cell.value_queue.updateitem(value, (value_constraint, cell.get_order_val(value))) else: cell.value_queue.additem(value, (value_constraint, cell.get_order_val(value)))
def test_repair(self): mutable_value = [3] pq = minpq(A=[1], B=[2], C=mutable_value) self.assertEqual(pq[pq.top()], [1]) mutable_value[0] = 0 self.assertEqual(pq[pq.top()], [1]) pq.heapify('C') self.assertEqual(pq[pq.top()], [0])
def test_swap_priority(self): pq = minpq(A=5, B=8, C=1) pq.swap_priority('A', 'C') self._check_index(pq) self.assertEqual(pq['A'], 1) self.assertEqual(pq['C'], 5) self.assertEqual(pq.top(), 'A') self.assertRaises(KeyError, pq.swap_priority, 'A', 'Z')
def test_repair(): mutable_value = [3] pq = minpq(A=[1], B=[2], C=mutable_value) assert pq[pq.top()] == [1] mutable_value[0] = 0 assert pq[pq.top()] == [1] pq.heapify("C") assert pq[pq.top()] == [0]
def test_pop(): # pop selected item - return value pq = minpq(A=5, B=8, C=1) value = pq.pop("B") assert value == 8 pq.pop("A") pq.pop("C") with pytest.raises(KeyError): pq.pop("A") with pytest.raises(KeyError): pq.pop("does_not_exist") # no args and empty - throws with pytest.raises(KeyError): pq.pop() # pq is now empty # no args - return top key pq = minpq(A=5, B=8, C=1) assert pq.pop() == "C"
def test_swap_priority(): pq = minpq(A=5, B=8, C=1) pq.swap_priority("A", "C") _check_index(pq) assert pq["A"] == 1 assert pq["C"] == 5 assert pq.top() == "A" with pytest.raises(KeyError): pq.swap_priority("A", "Z")
def test_replace_key(self): pq = minpq(A=5, B=8, C=1) pq.replace_key('A', 'Alice') pq.replace_key('B', 'Bob') self._check_index(pq) self.assertEqual(pq['Alice'], 5) self.assertEqual(pq['Bob'], 8) self.assertRaises(KeyError, pq.__getitem__, 'A') self.assertRaises(KeyError, pq.__getitem__, 'B') self.assertRaises(KeyError, pq.replace_key, 'C', 'Bob')
def test_constructor(self): # sequence of pairs pq0 = pqdict([('A', 5), ('B', 8), ('C', 7), ('D', 3), ('E', 9), ('F', 12), ('G', 1)]) pq1 = pqdict( zip(['A', 'B', 'C', 'D', 'E', 'F', 'G'], [5, 8, 7, 3, 9, 12, 1])) # dictionary pq2 = pqdict({'A': 5, 'B': 8, 'C': 7, 'D': 3, 'E': 9, 'F': 12, 'G': 1}) # keyword arguments pq3 = minpq(A=5, B=8, C=7, D=3, E=9, F=12, G=1) self.assertTrue(pq0 == pq1 == pq2 == pq3)
def test_constructor(self): # sequence of pairs pq0 = pqdict( [('A',5), ('B',8), ('C',7), ('D',3), ('E',9), ('F',12), ('G',1)]) pq1 = pqdict( zip(['A', 'B', 'C', 'D', 'E', 'F', 'G'], [5, 8, 7, 3, 9, 12, 1])) # dictionary pq2 = pqdict({'A': 5, 'B': 8, 'C': 7, 'D': 3, 'E': 9, 'F': 12, 'G': 1}) # keyword arguments pq3 = minpq(A=5, B=8, C=7, D=3, E=9, F=12, G=1) self.assertTrue(pq0 == pq1 == pq2 == pq3)
def test_constructor(): # sequence of pairs pq0 = pqdict([("A", 5), ("B", 8), ("C", 7), ("D", 3), ("E", 9), ("F", 12), ("G", 1)]) pq1 = pqdict( zip(["A", "B", "C", "D", "E", "F", "G"], [5, 8, 7, 3, 9, 12, 1])) # dictionary pq2 = pqdict({"A": 5, "B": 8, "C": 7, "D": 3, "E": 9, "F": 12, "G": 1}) # keyword arguments pq3 = minpq(A=5, B=8, C=7, D=3, E=9, F=12, G=1) assert pq0 == pq1 == pq2 == pq3
def test_replace_key(): pq = minpq(A=5, B=8, C=1) pq.replace_key("A", "Alice") pq.replace_key("B", "Bob") _check_index(pq) assert pq["Alice"] == 5 assert pq["Bob"] == 8 with pytest.raises(KeyError): pq.__getitem__("A") with pytest.raises(KeyError): pq.__getitem__("B") with pytest.raises(KeyError): pq.replace_key("C", "Bob")
def AStarWithPQ(_board: BoardStateManager): start = Node(_board.initial_vehicles, None, None) visited = set() pq = minpq() # Initialize pqdict with start node # Assign it score of 0 (which is what start.f is initialized to) pq.additem(start, (0, start)) while pq: curr_node, score_tup = pq.popitem() score = score_tup[0] vehicles = curr_node.vehicles if goal_state_reached(vehicles[0], _board): return compute_path(curr_node) # So we never visit this node again visited.add(curr_node) valid_actions = _board.compute_valid_actions(vehicles) successor_nodes = curr_node.generate_successors(valid_actions) for successor in successor_nodes: # No need to re-process visited nodes if successor in visited: continue successor.g = curr_node.g + 1 h = 0 #h = compute_heuristic(successor.vehicles, _board) successor.f = successor.g + h # Update scores as needed # successor is a temporary Node state, not the same as # the one in the pq if successor in pq: if successor.f < pq[successor][0]: pq[successor][1].f = successor.f pq[successor][1].g = successor.g pq.updateitem(successor, (successor.f, pq[successor][1])) else: pq.additem(successor, (successor.f, successor)) return None
def __init__(self, domain, row, column, cell_number, input_tokens, value=0): self.value = value self.domain = [value] if value != 0 else domain self.set = True if value != 0 else False self.row = row self.column = column self.cell_number = cell_number self.degree = 0 self.input_tokens = input_tokens self.row_degree = 0 self.column_degree = 0 self.block_degree = 0 self.value_queue = minpq() self.value_dict = dict() self.values_removed = [] self.initialize_value_queue()
def solver(maze): r, c = maze.shape start, end = get_start_end(maze) directions = [ np.array([1, 0]), np.array([0, 1]), np.array([-1, 0]), np.array([0, -1]) ] path = [] path_pre = {start: None} cost = {start: 0} frontier_queue = pqdict.minpq({0: [start]}) while frontier_queue: priority = frontier_queue.top() frontier = frontier_queue[priority][0] del frontier_queue[priority][0] if not frontier_queue[priority]: del frontier_queue[priority] if frontier == end: break for dir_neighbor in directions: next_node = tuple(frontier + dir_neighbor) next_cost = cost[frontier] + 1 if maze[next_node] in [0, 3, 4] and (next_node not in cost or next_cost < cost[next_node]): cost[next_node] = next_cost path_pre[next_node] = frontier heuristic = next_cost + l1_distance(next_node, end) # print(next_node) if heuristic in frontier_queue: frontier_queue[heuristic].append(next_node) else: frontier_queue[heuristic] = [next_node] node = end while node is not None: path.insert(0, node) node = path_pre[node] return path
def dijkstra_walk(start_id, end_id): distTo = {} parent = {} pq = minpq() for node in nodeDict: distTo[node] = float("inf") parent[node] = None distTo[start_id] = 0 pq.additem(start_id, 0) while len(pq) > 0: curr_id, curr_dist = pq.popitem() curr_lat, curr_lng = nodeDict[curr_id]['lat'], nodeDict[curr_id]['lng'] if curr_dist == distTo[curr_id]: if curr_id == end_id: break for neigh in nodeDict[curr_id]['neighbours']: neigh_lat, neigh_lng = nodeDict[neigh]['lat'], nodeDict[neigh][ 'lng'] dist_apart = walk_time( haversine(curr_lat, curr_lng, neigh_lat, neigh_lng)) if distTo[neigh] > distTo[curr_id] + dist_apart: distTo[neigh] = distTo[curr_id] + dist_apart parent[neigh] = curr_id try: pq.additem(neigh, distTo[neigh]) except: pq.updateitem(neigh, distTo[neigh]) totalDur = distTo[end_id] path_id = [] path_id.append(end_id) curr_id = end_id while curr_id != start_id: curr_id = parent[curr_id] path_id.append(curr_id) path_id.reverse() return path_id, totalDur
def __init__(self, N, P, Q, board_values, input_tokens): self.n = N self.p = P self.q = Q self.rows = [] self.columns = [] self.blocks = [] self.board_values = board_values self.num_cells = self.n * self. n self.cells_solved = 0 self.solved = False self.start_time = None self.time_out_limit = None self.input_tokens = input_tokens self.nodes_created = 0 self.times_backtracked = 0 # self.cell_queue = que.PriorityQueue() self.test_queue = minpq() self.domain = self.get_domain() self.check_board_params() self.initialize_board()
def dijkstra(graph, source, target=None): dist = {} #lengths of the shortest paths to each node pred = {} #predecessor node in each shortest path pq = minpq() for node in graph: if node == source: pq[node] = 0 else: pq[node] = float('inf') for node, min_dist in pq.popitems(): dist[node] = min_dist if node == target: break for neighbor in graph[node]: if neighbor in pq: new_score = dist[node] + graph[node][neighbor] if new_score < pq[neighbor]: # Updating the score of a node is O(log n) using pqdict. pq[neighbor] = new_score pred[neighbor] = node return dist, pred
def dijkstra_bus(start_id, end_id): distTo = {} parent = {} pq = minpq() for stop in stopDict: distTo[stop] = float("inf") parent[stop] = None distTo[start_id] = 0 pq.additem(start_id, 0) while len(pq) > 0: curr_id, curr_dist = pq.popitem() if curr_dist == distTo[curr_id]: if curr_id == end_id: break for neigh in stopDict[curr_id]['neighbours']: if distTo[neigh] > distTo[curr_id] + routeDict[ (curr_id, neigh)]['dur']: distTo[neigh] = distTo[curr_id] + routeDict[(curr_id, neigh)]['dur'] parent[neigh] = curr_id try: pq.additem(neigh, distTo[neigh]) except: pq.updateitem(neigh, distTo[neigh]) path_id = [] path_id.append(end_id) curr_id = end_id while curr_id != start_id: curr_id = parent[curr_id] path_id.append(curr_id) path_id.reverse() bus_path = getBus(path_id, start_id, end_id) return path_id, bus_path
def distanceCalcul(self): length = {} end = '256176' pq = minpq() for node in nx.node_connected_component(self.graph.G, self.author): if node == self.author: pq[node] = 0 else: pq[node] = float('inf') for node, min_dist in pq.popitems(): length[node] = min_dist if node == end: break for neighbor in self.graph.G.neighbors(node): if neighbor in pq: new_length = length[node] + self.graph.G[node][neighbor][ 'weight'] if new_length < pq[neighbor]: pq[neighbor] = new_length return length[end]
from ways.tools import compute_distance import numpy as np from pqdict import minpq # Read files roads = load_map_from_csv(Consts.getDataFilePath("israel.csv")) prob = BusProblem.load(Consts.getDataFilePath("TLV_5.in")) # TODO - Fix the missing parts in the following code # Print details of a random order order = prob.orders[np.random.choice(np.arange(len(prob.orders)))] # your code goes here myHeap = minpq() myHeap[1] = 3 myHeap[4] = 2 print("{}".format((myHeap.popitem())[1])) print("{}".format((myHeap.popitem())[1])) print("One of the orders is from junction #{} at ({}, {}) to #{} at ({}, {})". format(order[0], roads[order[0]].lat, roads[order[0]].lon, order[1], roads[order[1]].lat, roads[order[1]].lon)) print( "A lower bound on the distance we need to drive for this order is: {:.2f}km" .format( compute_distance(roads[order[0]].coordinates, roads[order[1]].coordinates) / 1000))
def a_star(estado_inicial): front = minpq() return generic_search(estado_inicial, front, manhattan)
def test_popitem(self): pq = minpq(A=5, B=8, C=1) # pop top item key, value = pq.popitem() self.assertEqual(key,'C') self.assertEqual(value,1)
def test_pushpopitem(self): pq = minpq(A=5, B=8, C=1) self.assertEqual(pq.pushpopitem('D', 10), ('C', 1)) self.assertEqual(pq.pushpopitem('E', 5), ('E', 5)) self.assertRaises(KeyError, pq.pushpopitem, 'A', 99)
def test_popitem(self): pq = minpq(A=5, B=8, C=1) # pop top item key, value = pq.popitem() self.assertEqual(key, 'C') self.assertEqual(value, 1)
def getBus(path_id, start_id, end_id): bus_graph = {} for i in range(len(path_id) - 1): stop1_id, stop2_id = path_id[i], path_id[i + 1] for bus in routeDict[(stop1_id, stop2_id)]['svc']: bus_graph[stop1_id + ' ' + bus] = [stop2_id] for j in range(i + 1, len(path_id) - 1): if bus in routeDict[(path_id[j], path_id[j + 1])]['svc']: bus_graph[stop1_id + ' ' + bus].append(path_id[j + 1]) distTo = {} parent = {} pq = minpq() for value in bus_graph: if value.split()[0] == start_id: pq.additem(value, 0) for stop_id in path_id: distTo[stop_id] = (float("inf")) parent[stop_id] = [] distTo[start_id] = 0 while len(pq) > 0: curr, curr_dist = pq.popitem() if curr_dist == distTo[curr.split()[0]]: for neigh in bus_graph[curr]: if distTo[neigh] > distTo[curr.split()[0]] + 1: distTo[neigh] = distTo[curr.split()[0]] + 1 parent[neigh].append(curr) for value in bus_graph: if value.split()[0] == neigh: pq.additem(value, distTo[neigh]) elif distTo[neigh] == distTo[curr.split()[0]] + 1: parent[neigh].append(curr) bus_path = [] while end_id != start_id: curr_buses = [] for value in parent[end_id]: curr_id = value.split()[0] if value.split()[1] not in curr_buses: curr_buses.append(value.split()[1]) bus_path.append([end_id, curr_buses, []]) end_id = curr_id bus_path.reverse() i, j = 0, 0 while j < len(path_id) and i < len(bus_path): if path_id[j] != bus_path[i][0]: bus_path[i][2].append(path_id[j]) j += 1 else: bus_path[i][2].append(path_id[j]) i += 1 for i in range(len(bus_path)): dur = 240 for j in range(len(bus_path[i][2][:-1])): if j != 0: dur += stopDict[bus_path[i][2][j]]['dur'] dur += routeDict[(bus_path[i][2][j], bus_path[i][2][j + 1])]['dur'] bus_path[i] = [['bus', dur, len(bus_path[i][2]) - 1], bus_path[i][2], bus_path[i][1]] return bus_path
def get_path(self): print self.end r, c = self.layout.shape init_state = self.encode_state(self.sim.mario.state) # we use path to record states, and state_action_map to map state to action path = [] state_action_map = {init_state: None} # state dict for previous state path_pre = {init_state: None} # cost to get this state, in terms of time (moves) cost = {init_state: 0} frontier_queue = pqdict.minpq({init_state: 0}) # astar search closest_distance = 99999999 expansion = 0 node = None solved = False while frontier_queue: # get top raw_frontier = frontier_queue.pop() frontier = self.decode_state(raw_frontier) self.sim.mario.state = frontier expansion += 1 # expand frontier for i in [ "remains", "left_jump", "right_jump", "left_nojump", "right_nojump", "nolr_jump" ]: next_cost = cost[raw_frontier] prev_state = self.sim.mario.state self.sim.advance_frame(action=i) next_cost += l2_distance(prev_state[0:2, 0], self.sim.mario.state[0:2, 0]) # upsample runs for j in range(self.interval - 1): prev_state = self.sim.mario.state self.sim.advance_frame(action="remains") next_cost += l2_distance(prev_state[0:2, 0], self.sim.mario.state[0:2, 0]) next_state = self.sim.mario.state raw_next_state = self.encode_state(next_state) # if new state is legal if not np.array_equal( next_state, frontier ) and next_state[0][0] > 0 and next_state[1][0] > 0 and ( raw_next_state not in cost or next_cost < cost[raw_next_state]): cost[raw_next_state] = next_cost path_pre[raw_next_state] = raw_frontier state_action_map[raw_next_state] = i # task end test distance_to_end = l1_distance(self.end, next_state[0:2, 0]) closest_distance = min(closest_distance, distance_to_end) # print i, next_state[0:2, 0], next_cost, closest_distance if closest_distance < 0.5: node = raw_next_state solved = True break heuristic = next_cost + distance_to_end frontier_queue[raw_next_state] = heuristic self.sim.mario.state = frontier if closest_distance < 0.5: solved = True break action_path = [] if solved: while node: for i in range(self.interval - 1): action_path.insert(0, "remains") action_path.insert(0, state_action_map[node]) node = path_pre[node] for i in range(self.interval): action_path.pop(0) print expansion return action_path
def a_star(layout, simulation, init_pos, end_pos, actions, interval=5, config=None): """ A* search for path-finding :param layout: 2D numpy array layout :param simulation: Physics simulation object :param init_pos: 3D vector of the initial position :param end_pos: 3D vector of the target position for search :param actions: Possible actions :param interval: Frame interval between two actions :return: Action sequence list """ epsilon = 0.001 if config is None or "epsilon" not in config else config["epsilon"] empty_action = "remains" if config is None or "empty_action" not in config else config["empty_action"] bound = -1, -1, layout.shape[0] + 8, layout.shape[1] + 8 simulation.mario.state[0:3, 0] = init_pos init_state = encode_state(simulation) end_state = None state_pre = {init_state: None} state_preaction_map = {} cost = {init_state: 0} reversed_action_path = [] frontier_queue = pqdict.minpq({init_state: heuristic(get_state_pos(init_state), end_pos)}) expansion = 0 greatest_x = 0 max_q = l2_distance(init_pos, end_pos) * 20 pruned_num = 0 while frontier_queue and not end_state: frontier = frontier_queue.pop() expansion += 1 if frontier[0] > greatest_x: greatest_x = frontier[0] # print frontier[0], frontier[3], pruned_num # Expand frontier for act in actions: simulation = decode_state(frontier, simulation) simulation.advance_frame(act) next_cost = l2_distance(get_state_pos(frontier), get_state_pos(simulation)) + cost[frontier] + 1 * interval # Downsample actions for i in range(interval - 1): mid_state = encode_state(simulation) simulation.advance_frame(empty_action) next_cost += l2_distance(get_state_pos(mid_state), get_state_pos(simulation)) next_state = encode_state(simulation) if in_bound(next_state, bound) and (next_state not in cost or next_cost < cost[next_state]): cost[next_state] = next_cost state_pre[next_state] = frontier state_preaction_map[next_state] = act h = heuristic(get_state_pos(next_state), end_pos) + next_cost if h < max_q: frontier_queue[next_state] = h else: pruned_num += 1 # Reach the end and exit if l1_distance(get_state_pos(next_state), end_pos) <= 1: end_state = next_state break # No solution found if not end_state: return [] # Generate action sequences node = end_state while node in state_preaction_map: reversed_action_path.extend(itertools.repeat(empty_action, interval - 1)) reversed_action_path.append(state_preaction_map[node]) node = state_pre[node] return list(reversed(reversed_action_path))
def test_pushpopitem(): pq = minpq(A=5, B=8, C=1) assert pq.pushpopitem("D", 10) == ("C", 1) assert pq.pushpopitem("E", 5) == ("E", 5) with pytest.raises(KeyError): pq.pushpopitem("A", 99)
def test_popitem(): pq = minpq(A=5, B=8, C=1) # pop top item key, value = pq.popitem() assert key == "C" assert value == 1
def test_minpq(self): pq = minpq(A=5, B=8, C=7, D=3, E=9, F=12, G=1) self.assertEqual(list(pq.popvalues()), [1, 3, 5, 7, 8, 9, 12]) self.assertEqual(pq.precedes, operator.lt)
def dijkstra_combined(start_id, end_id): distTo = {} parent = {} pq = minpq() for node in nodeDict: distTo[node] = float("inf") parent[node] = None distTo[start_id] = 0 pq.additem(start_id, 0) while len(pq) > 0: curr_id, curr_dist = pq.popitem() curr_lat, curr_lng = nodeDict[curr_id]['lat'], nodeDict[curr_id]['lng'] if curr_dist == distTo[curr_id]: if curr_id == end_id: break for neigh in nodeDict[curr_id]['neighbours']: neigh_lat, neigh_lng = nodeDict[neigh]['lat'], nodeDict[neigh][ 'lng'] dist_apart = walk_time( haversine(curr_lat, curr_lng, neigh_lat, neigh_lng)) if distTo[neigh] > distTo[curr_id] + dist_apart: distTo[neigh] = distTo[curr_id] + dist_apart parent[neigh] = (curr_id, 'walk') try: pq.additem(neigh, distTo[neigh]) except: pq.updateitem(neigh, distTo[neigh]) if nodeDict[curr_id]['type'] == 'Bus Stop': for neigh in stopDict[curr_id]['neighbours']: if distTo[neigh] > distTo[curr_id] + routeDict[ (curr_id, neigh)]['dur']: distTo[neigh] = distTo[curr_id] + routeDict[ (curr_id, neigh)]['dur'] parent[neigh] = (curr_id, 'bus') try: pq.additem(neigh, distTo[neigh]) except: pq.updateitem(neigh, distTo[neigh]) path_id = [] curr_id = end_id temp = [] temp.append(curr_id) transport_type = parent[curr_id][1] while curr_id != start_id: curr_id = parent[curr_id][0] temp.append(curr_id) if parent[curr_id] != None and parent[curr_id][1] != transport_type: temp.reverse() path_id.append([transport_type, temp]) temp = [curr_id] transport_type = parent[curr_id][1] temp.reverse() path_id.append([transport_type, temp]) path_id.reverse() path = [] for segment in path_id: if segment[0] == 'bus': path.extend(getBus(segment[1], segment[1][0], segment[1][-1])) else: dur = 0 for i in range(len(segment[1]) - 1): dur += walk_time( haversine(nodeDict[segment[1][i]]['lat'], nodeDict[segment[1][i]]['lng'], nodeDict[segment[1][i + 1]]['lat'], nodeDict[segment[1][i + 1]]['lng'])) path.append([['walk', dur], segment[1]]) return path
def test_minpq(self): pq = minpq(A=5, B=8, C=7, D=3, E=9, F=12, G=1) self.assertEqual( list(pq.popvalues()), [1, 3, 5, 7, 8, 9, 12]) self.assertEqual(pq.precedes, operator.lt)
def test_minpq(): pq = minpq(A=5, B=8, C=7, D=3, E=9, F=12, G=1) assert list(pq.popvalues()) == [1, 3, 5, 7, 8, 9, 12] assert pq.precedes == operator.lt