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() explored = [] source_node = Node(source, None, None) frontier.add(source_node) while not frontier.empty(): node = frontier.remove() if node.person == target: return find_path(node) else: explored.append(node.person) for movie, person in neighbors_for_person(node.person): if not frontier.contains_person(person) and person not in explored: child = Node(person, node, movie) frontier.add(child) return None
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() start = Node(source, None, None) explored = set() frontier.add(start) while True: if frontier.empty(): return None # Frontier empty; no solution possible nextNode = frontier.remove() # Fetch the next node to search through explored.add( nextNode) # Add the node to the already explored nodes set neighbors = neighbors_for_person(nextNode.person) for movie, person in neighbors: if person == target: movies, people = [], [] while nextNode.parent is not None: movies.append(nextNode.movie) people.append(nextNode.person) nextNode = nextNode.parent # Going up a level in node parent list movies.reverse( ) # Reversing movies list because append() appends new item at the end of the list, and we are going from end back to the starting. people.reverse( ) # So, we basically need the new elements to be appended at the stating. This is a clever way to get the correct result. solution = ( movies, people ) # Need to assign it to a variable so the data type becomes a tuple return solution elif frontier.contains_person(person) and person not in explored: newNode = Node(person, nextNode, movie) frontier.add(newNode)