def test_dijkstra_3(self): for g in self.graph_1s: self.assertEqual([ graph.Edge(graph.Node(1), graph.Node(2), 1), graph.Edge(graph.Node(2), graph.Node(4), 1), graph.Edge(graph.Node(4), graph.Node(5), 1) ], searches.dijkstra_search(g, graph.Node(1), graph.Node(5)))
def test_dijkstra_5(self): for g in self.graph_2s: self.assertEqual([ graph.Edge(graph.Node(0), graph.Node(6), 3), graph.Edge(graph.Node(6), graph.Node(4), 1), graph.Edge(graph.Node(4), graph.Node(5), 5) ], searches.dijkstra_search(g, graph.Node(0), graph.Node(5)))
def test_bfs_1(self): for g in self.graph_1s: self.assertEqual([ graph.Edge(graph.Node(1), graph.Node(3), 1), graph.Edge(graph.Node(3), graph.Node(10), 1), graph.Edge(graph.Node(10), graph.Node(8), 1) ], searches.bfs(g, graph.Node(1), graph.Node(8)))
def test_bfs_3(self): for g in self.graph_1s: self.assertEqual([ graph.Edge(graph.Node(1), graph.Node(2), 1), graph.Edge(graph.Node(2), graph.Node(4), 1), graph.Edge(graph.Node(4), graph.Node(5), 1) ], searches.bfs(g, graph.Node(1), graph.Node(5)))
def test_dfs_4(self): for g in self.graph_2s: self.assertEqual([ graph.Edge(graph.Node(0), graph.Node(1), 4), graph.Edge(graph.Node(1), graph.Node(2), 7), graph.Edge(graph.Node(2), graph.Node(5), 2) ], searches.dfs(g, graph.Node(0), graph.Node(5)))
def test_dijkstra_1(self): for g in self.graph_1s: self.assertEqual([ graph.Edge(graph.Node(1), graph.Node(3), 1), graph.Edge(graph.Node(3), graph.Node(10), 1), graph.Edge(graph.Node(10), graph.Node(8), 1) ], searches.dijkstra_search(g, graph.Node(1), graph.Node(8)))
def test_add_edge(self): self.assertEqual(False, self.graph_1.adjacent(graph.Node(1), graph.Node(4))) self.assertEqual(True, self.graph_1.add_edge(graph.Edge(graph.Node(1), graph.Node(4), 1))) self.assertEqual([graph.Node(2),graph.Node(3),graph.Node(4)], self.graph_1.neighbors(graph.Node(1))) self.assertEqual(True, self.graph_1.adjacent(graph.Node(1), graph.Node(4))) # When adding edge that already existed, should return false self.assertEqual(False, self.graph_1.add_edge(graph.Edge(graph.Node(1), graph.Node(2), 1)))
def test_bfs_5(self): for g in self.graph_2s: self.assertEqual( [ graph.Edge(graph.Node(0), graph.Node(1), 4), graph.Edge(graph.Node(1), graph.Node(2), 7) ], searches.bfs(g, graph.Node(0), graph.Node(2)) )
def test_bfs_4(self): for g in self.graph_2s: self.assertEqual( [ graph.Edge(graph.Node(0), graph.Node(3), 1), graph.Edge(graph.Node(3), graph.Node(5), 11) ], searches.bfs(g, graph.Node(0), graph.Node(5)) )
def test_remove_edge(self): # removing edges that doesn't exist should return false self.assertEqual( False, self.graph_1.remove_edge( graph.Edge(graph.Node(1), graph.Node(6), 1))) self.assertEqual( True, self.graph_1.remove_edge( graph.Edge(graph.Node(6), graph.Node(5), 1))) self.assertEqual(False, self.graph_1.adjacent(graph.Node(6), graph.Node(5)))
def queue_search(graph, initial_node, dest_node, visit_queue, dijkstra=False): distances = {} parents = {} path = [] path_trace_tile = None distances[initial_node] = 0 visit_queue.put((0, initial_node)) while not visit_queue.empty(): entry = visit_queue.get() current = entry[1] if entry[0] != distances[current]: continue for adjacent in graph.neighbors(current): possible_distance = distances[current] + graph.distance( current, adjacent) if adjacent not in distances or ( dijkstra and possible_distance < distances[adjacent]): distances[adjacent] = possible_distance parents[adjacent] = current if dest_node == adjacent: path_trace_tile = adjacent visit_queue.put((distances[adjacent], adjacent)) while path_trace_tile in parents: path.append( g.Edge(parents[path_trace_tile], path_trace_tile, graph.distance(parents[path_trace_tile], path_trace_tile))) path_trace_tile = parents[path_trace_tile] return list(reversed(path))
def bfs(initial_node, dest_node): """ Breadth First Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ queue = [] actions = [] queue.append([initial_node]) while queue: path = queue.pop(0) # last node in path node = path[-1] if node == dest_node: # convert nodes to edges for i in range(len(path) - 1): edge = g.Edge(path[i], path[i + 1], transition_state(path[i].data, path[i + 1].data)['event']['effect']) actions.append(edge) return actions for neighbor_room in get_state(node.data)['neighbors']: neighbor = g.Node(neighbor_room['id']) new_path = list(path) new_path.append(neighbor) queue.append(new_path)
def construct_graph_from_json(my_graph, list): neighbors = list['neighbors'] added_queue = set() added_queue.add(list['id']) queue = Queue(maxsize=0) queue.put(list['neighbors'][0]['id']) parent = list['id'] print("Constructing graph... ") while queue.qsize() > 0: for nnode in neighbors: added_queue.add(nnode['id']) weight = transition_state(parent, nnode['id']) if (nnode['id'] != '7f3dc077574c013d98b2de8f735058b4'): my_graph.add_edge( g.Edge(g.Node(parent), g.Node(nnode['id']), weight['event']['effect'])) if 'f1f131f647621a4be7c71292e79613f9' not in added_queue: queue.put(nnode['id']) print("Queue size is: " + str(queue.qsize())) parent = queue.get() room = get_state(parent) neighbors.clear() neighbors = room['neighbors'] print("Constructed Graph: " + str(my_graph)) return my_graph
def test_dfs_2(self): for g in self.graph_1s: self.assertEqual([ graph.Edge(graph.Node(1), graph.Node(2), 1), graph.Edge(graph.Node(2), graph.Node(4), 1), graph.Edge(graph.Node(4), graph.Node(5), 1), graph.Edge(graph.Node(5), graph.Node(0), 1), graph.Edge(graph.Node(0), graph.Node(7), 1), graph.Edge(graph.Node(7), graph.Node(10), 1) ], searches.dfs(g, graph.Node(1), graph.Node(10)))
def a_star_search(graph, initial_node, dest_node): """ A* Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ to_explore = queue.PriorityQueue() explored = {} parents = {} to_explore.put((0, initial_node)) g_score = {initial_node: 0} f_score = {initial_node: dist(initial_node, dest_node)} while not to_explore.empty(): current = to_explore.get()[1] if current in explored: continue if current == dest_node: path = [] current_node = dest_node while current_node != initial_node: next_node = parents[current_node] path = [ g.Edge(next_node, current_node, graph.distance(next_node, current_node)) ] + path current_node = next_node return path explored[current] = True for neighbor in graph.neighbors(current): if neighbor in explored: continue possible_score = graph.distance( current, neighbor ) + g_score[current] if current in g_score else sys.maxsize if neighbor in g_score and possible_score > g_score[neighbor]: continue parents[neighbor] = current g_score[neighbor] = possible_score f_score[neighbor] = g_score[neighbor] + dist(neighbor, dest_node) to_explore.put((f_score[neighbor], neighbor)) return []
def queue_search(initial_node, dest_node, visit_queue, dijkstra=False): distances = {} distance_paths = {} parents = {} path = [] path_trace_tile = None distances[initial_node] = 0 distance_paths[initial_node] = [initial_node] visit_queue.put((0, initial_node)) while not visit_queue.empty(): entry = visit_queue.get() current = entry[1] if entry[0] != distances[current]: continue current_state = get_state(current) for neighbor in current_state['neighbors']: adjacent = neighbor['id'] possible_distance = distances[current] + (-1 * transition_state( current, neighbor['id'])['event']['effect']) possible_distance_path = distance_paths[current] + [adjacent] if adjacent not in distances or ( dijkstra and possible_distance < distances[adjacent] and len(possible_distance_path) == len( set(possible_distance_path))): distances[adjacent] = possible_distance distance_paths[adjacent] = possible_distance_path parents[adjacent] = current if dest_node == adjacent: path_trace_tile = adjacent visit_queue.put((distances[adjacent], adjacent)) while path_trace_tile in parents: distance = transition_state(parents[path_trace_tile], path_trace_tile)['event']['effect'] path.append( graph.Edge(graph.Node(parents[path_trace_tile]), graph.Node(path_trace_tile), distance)) path_trace_tile = parents[path_trace_tile] return list(reversed(path))
def dfs(graph, initial_node, dest_node): """ Depth First Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ #probably use recursion to keep searching or use stack iterated = [] path = [] parents = {} stack = [] stack.append(initial_node) while stack: current = stack.pop() if current not in iterated: iterated.append(current) temp = [] for node in graph.neighbors(current): if (bool(parents) == False): parents[current] = None parents[node] = current if node not in iterated: parents[node] = current temp.append(node) temp = temp[::-1] for t in temp: if current in stack: stack.remove(current) stack.append(t) if dest_node in parents: #checks to see if the destination node is in parents, continue current = dest_node while parents[current]: for node in parents: if current == node: path.append( g.Edge(parents[node], current, graph.get_edge_weight(parents[node], current))) current = parents[node] path = path[::-1] return path
def bfs(graph, initial_node, dest_node): """ Breadth First Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ #use a queue for this one q = Queue() q.put(initial_node) iterated = [] path = [] parents = {} while q: if (q.empty()): break current = q.get(0) #get the first element if current not in iterated: #if its not in iterated, add it to iterated to keep track of all the items iterated through iterated.append(current) for node in graph.neighbors(current): if (bool(parents) == False): parents[current] = None parents[node] = current else: if node not in parents: parents[node] = current q.put(node) if dest_node in parents: #checks to see if the destination node is in parents, continue current = dest_node while parents[current]: for node in parents: if current == node: path.append( g.Edge(parents[node], current, graph.get_edge_weight(parents[node], current))) current = parents[node] path = path[::-1] return path
def getPathEdges(graph, came_from, initial_node, dest_node): # Create path current = dest_node path = [current] while current != initial_node: current = came_from[current] path.append(current) path.reverse() # Create edges from list 'path' edges = [] for i in range(len(path) - 1): distance = graph.distance(path[i], path[i + 1]) edge = g.Edge(path[i], path[i + 1], distance) edges.append(edge) return edges
def dijkstra_search(graph, initial_node, dest_node): """ Dijkstra Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ queue, _trace_nodes, cost, result = [], {}, {}, [] heapq.heappush(queue, PriorityNode(0, initial_node)) cost[initial_node] = 0 visited_set = set() while queue: current_node = heapq.heappop(queue).node visited_set.add(current_node) if current_node == dest_node: break for neighbors_node in graph.neighbors(current_node): if neighbors_node not in visited_set: total_cost = cost[current_node] + graph.distance( current_node, neighbors_node) if neighbors_node not in cost or total_cost > cost[ neighbors_node]: cost[neighbors_node] = total_cost heapq.heappush(queue, PriorityNode(-(total_cost), neighbors_node)) _trace_nodes[neighbors_node] = current_node if (dest_node in _trace_nodes): parent = _trace_nodes[dest_node] while parent is not None: #print("Parent of " + str(parent) + " is" + str(dest_node)) result.insert( 0, g.Edge(parent, dest_node, graph.distance(parent, dest_node))) dest_node = parent if dest_node in _trace_nodes: parent = _trace_nodes[dest_node] else: parent = None return result
def dijkstra_search(graph, initial_node, dest_node): """ Dijkstra Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ pq = PriorityQueue() pq.put((0, initial_node)) path = [] parent = {} cost = {} parent[initial_node] = None cost[initial_node] = 0 while not pq.empty(): current = pq.get() # print(graph.neighbors(current[1])) # break if current[1] == dest_node: break for node in graph.neighbors(current[1]): new_cost = cost[current[1]] + graph.get_edge_weight( current[1], node) if node not in cost or new_cost < cost[node]: cost[node] = new_cost pq.put((new_cost, node)) parent[node] = current[1] if dest_node in parent: current = dest_node while parent[current]: for node in parent: if current == node: path.append( g.Edge(parent[node], current, graph.get_edge_weight(parent[node], current))) current = parent[node] path = path[::-1] return path
def dijkstra_search(graph, initial_node, dest_node): """ Dijkstra Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ queue, _trace_nodes, cost, result = [], {}, {}, [] heapq.heappush(queue, PriorityNode(0, initial_node)) cost[initial_node] = 0 while queue: current_node = heapq.heappop(queue).node # print(current_node) if current_node == dest_node: break for neighbors_node in graph.neighbors(current_node): # print("Current node cost is: " +str(cost[current_node])) # print("Distance cost is: " + str(graph.distance(current_node, neighbors_node))) total_cost = cost[current_node] + graph.distance( current_node, neighbors_node) # print("Current distance is: " + str(total_cost)) if neighbors_node not in cost or total_cost < cost[neighbors_node]: cost[neighbors_node] = total_cost heapq.heappush(queue, PriorityNode(total_cost, neighbors_node)) _trace_nodes[neighbors_node] = current_node if (dest_node in _trace_nodes): parent = _trace_nodes[dest_node] while parent is not None: result.insert( 0, g.Edge(parent, dest_node, graph.distance(parent, dest_node))) dest_node = parent if dest_node in _trace_nodes: parent = _trace_nodes[dest_node] else: parent = None print(result) return result
def a_star_search(graph, initial_node, dest_node): """ A* Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ queue, _trace_nodes, cost, result = [], {}, {}, [] heapq.heappush(queue, PriorityNode(0, initial_node)) cost[initial_node] = 0 while queue: current_node = heapq.heappop(queue).node # print(current_node) if current_node == dest_node: break for neighbors_node in graph.neighbors(current_node): total_cost = cost[current_node] + graph.distance( current_node, neighbors_node) if neighbors_node not in cost or total_cost < cost[neighbors_node]: cost[neighbors_node] = total_cost priority = total_cost + heuristic(current_node.data, neighbors_node.data) heapq.heappush(queue, PriorityNode(priority, neighbors_node)) _trace_nodes[neighbors_node] = current_node if (dest_node in _trace_nodes): parent = _trace_nodes[dest_node] while parent is not None: result.insert( 0, g.Edge(parent, dest_node, graph.distance(parent, dest_node))) dest_node = parent if dest_node in _trace_nodes: parent = _trace_nodes[dest_node] else: parent = None return result
def dfs(graph, initial_node, dest_node): """ Depth First Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ parents = {} dfs_rec(graph, initial_node, {}, parents) path = [] current_node = dest_node while current_node != initial_node: next_node = parents[current_node] path = [ g.Edge(next_node, current_node, graph.distance(next_node, current_node)) ] + path current_node = next_node return path
def dijkstra_search(initial_node, dest_node): """ Dijkstra Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ dist = {} prev = {} queue = [] actions = [] visited = [] dist[initial_node] = 0 queue.append((0, initial_node)) while queue: node = queue.pop(0)[1] visited.append(node) current_room = get_state(node.data) for neighbor_room in current_room['neighbors']: neighbor = g.Node(neighbor_room['id']) alt = dist[node] - transition_state(node.data, neighbor.data)['event']['effect'] if neighbor not in dist or (alt < dist[neighbor] and neighbor not in visited): queue.append((alt, neighbor)) dist[neighbor] = alt prev[neighbor] = node # sort queue = sorted(queue, key=lambda priority: priority[0]) current = dest_node # convert nodes to edges while current != initial_node: parent = prev[current] actions = [g.Edge(parent, current, transition_state(parent.data, current.data)['event']['effect'])] + actions current = parent return actions
def bfs(graph, initial_node, dest_node): """ Breadth First Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ _visiting_queue = Queue(maxsize=0) _visiting_queue.put(initial_node) _trace_nodes, _visited_list, result = {}, set(), [] while _visiting_queue: current_node = _visiting_queue.get() _visited_list.add(current_node) if (current_node == dest_node): break for neighbors_node in (graph.neighbors(current_node)): if neighbors_node not in _trace_nodes: _trace_nodes[neighbors_node] = current_node if neighbors_node not in _visited_list: _visiting_queue.put(neighbors_node) if dest_node in _trace_nodes: parent = _trace_nodes[dest_node] while parent is not None: result.insert( 0, g.Edge(parent, dest_node, graph.distance(parent, dest_node))) dest_node = parent if dest_node in _trace_nodes: parent = _trace_nodes[dest_node] else: parent = None return result
def dfs(graph, initial_node, dest_node): """ Depth First Search uses graph to do search from the initial_node to dest_node returns a list of actions going from the initial node to dest_node """ _visited_list, stack = [], [initial_node] _trace_nodes = {} result = [] while stack: current_node = stack.pop() _visited_list.append(current_node) if (current_node == dest_node): break neighbors = graph.neighbors(current_node) for neighbors_node in neighbors[::-1]: if neighbors_node not in _visited_list: _trace_nodes[neighbors_node] = current_node stack.append(neighbors_node) if (dest_node in _trace_nodes): parent = _trace_nodes[dest_node] while parent is not None: result.insert( 0, g.Edge(parent, dest_node, graph.distance(parent, dest_node))) dest_node = parent if dest_node in _trace_nodes: parent = _trace_nodes[dest_node] else: parent = None return result
def test_edge_comparison(self): """Test edge comparison""" self.assertEqual(graph.Edge(graph.Node(1), graph.Node(2), 1), graph.Edge(graph.Node(1), graph.Node(2), 1))