def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ frontier = QueueFrontier() node = Node(source, None, None) frontier.add(node) nodes_explored = [] edges = dict() print("Calculating...") while True: if frontier.empty(): graph = Graph(edges, []) graph.draw_graph("my_graph.png") return None node = frontier.remove() node_person_name = people[node.get_person_id()]["name"] if node.get_person_id() == target: path = [] path_name_labels = [people[source]["name"]] while node.get_parent() is not None: path.append([node.get_movie_id(), node.get_person_id()]) path_name_labels.append(people[node.get_person_id()]["name"]) node = node.get_parent() path.reverse() graph = Graph(edges, path_name_labels) graph.draw_graph("output_graph.png") return path else: nodes_explored.append(node.get_person_id()) for movie_id, person_id in neighbors_for_person(node.get_person_id()): child = Node(person_id, node, movie_id) child_person_name = people[child.get_person_id()]["name"] movie_name = movies[child.get_movie_id()]["title"] if(node_person_name != child_person_name): edges[(node_person_name, child_person_name)] = movie_name if not frontier.contains_state(person_id) and person_id not in nodes_explored: frontier.add(child)
def shortest_path(source, target): """ Returns the shortest list of (movie_id, person_id) pairs that connect the source to the target. If no possible path, returns None. """ global num_explored # Initialize starting node and frontier start = Node(state=source, parent=None, action=None) frontier = QueueFrontier() frontier.add(start) # initialize set for explored nodes explored = set() # Loop until solution found while True: # If nothing left in frontier, then there is no connection if frontier.empty(): return None # Take the node from the frontier node = frontier.remove() num_explored += 1 # Mark node as explored explored.add(node.get_state()) # Add neighbors to the frontier for action, state in neighbors_for_person(node.get_state()): if not frontier.contains_state(state) and state not in explored: child = Node(state, node, action) frontier.add(child) # If the node is the target, then there is connection if child.get_state() == target: connections = [] while child.get_parent() is not None: connections.append((child.get_action(), child.get_state())) child = child.get_parent() connections.reverse() return connections