示例#1
0
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.
    """

    # Make the initial state a node
    sourceNode = Node(source)
    targetNode = Node(target)

    # Add initial state node to frontier (using QueueFrontier for BFS)
    frontier = QueueFrontier()
    frontier.add(sourceNode)
    state_frontier = [sourceNode.get_state()]

    # Keep track of explored state
    explored = []

    while True:

        # If the frontier is empty, return None
        if frontier.empty():
            return None

        # Check if the goal state is in the frontier
        if targetNode.get_state() in state_frontier:
            consideredNode = frontier.target_found(targetNode)
            explored.append(consideredNode.get_state())

            # List for the path
            path = []

            # Trace back the path
            while consideredNode.get_parent() is not None:
                temp = (consideredNode.get_action(),
                        consideredNode.get_state())
                path.append(temp)
                consideredNode = consideredNode.get_parent()

            # Reverse the path and return it
            path.reverse()
            return path

        # Move one node in frontier to explored node (this node will now be considered)
        consideredNode = frontier.removeNode()
        explored.append(consideredNode.get_state())

        # Find the neighbour of the considered node that hasn't been explored and add them to the frontier
        for movie, neighbour in neighbors_for_person(
                consideredNode.get_state()):
            if not frontier.contains_state(
                    neighbour) and neighbour not in explored:
                neighbourNode = Node(neighbour, consideredNode, movie)
                frontier.add(neighbourNode)
                state_frontier.append(neighbourNode.get_state())

                if neighbour == targetNode.get_state():
                    targetNode = neighbourNode
示例#2
0
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