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