def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.

    After expanding a node, to retrieve the cost of a child node at location (x,y), 
    please call costFn((x,y)). 
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object composed of actions
        that should move the agent from the start to goal cell along the path
        as found by the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()
    closed_set = Stack()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    parent = [  # the immediate predecessor cell from which to reach a cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]

    movement = []
    # ----------------------------------------
    # finish the code below
    # ----------------------------------------
    #############################################################################
    open_set.add(start)
    while not len(open_set) == 0:
        node = open_set.pop()
        closed_set.add(node)

        temp = list(node)
        temp[0] += 1
        if n_rows > temp[0] >= 0:
            child = tuple(temp)

            if child not in open_set and child not in closed_set and child not in obstacles:
                actions[temp[0]][temp[1]] = (1, 0)
                parent[temp[0]][temp[1]] = node
                if child == goal:
                    movement = construct_movement(start_row, start_col,
                                                  goal_row, goal_col, actions,
                                                  parent)
                    return movement, closed_set
                else:
                    open_set.add(child)

        temp = list(node)
        temp[0] -= 1
        if n_rows > temp[0] >= 0:
            child = tuple(temp)

            if child not in open_set and child not in closed_set and child not in obstacles:
                actions[temp[0]][temp[1]] = (-1, 0)
                parent[temp[0]][temp[1]] = node
                if child == goal:
                    movement = construct_movement(start_row, start_col,
                                                  goal_row, goal_col, actions,
                                                  parent)
                    return movement, closed_set
                else:
                    open_set.add(child)

        temp = list(node)
        temp[1] += 1
        if n_cols > temp[1] >= 0:
            child = tuple(temp)

            if child not in open_set and child not in closed_set and child not in obstacles:
                actions[temp[0]][temp[1]] = (0, 1)
                parent[temp[0]][temp[1]] = node
                if child == goal:
                    movement = construct_movement(start_row, start_col,
                                                  goal_row, goal_col, actions,
                                                  parent)
                    return movement, closed_set
                else:
                    open_set.add(child)

        temp = list(node)
        temp[1] -= 1
        if n_cols > temp[1] >= 0:
            child = tuple(temp)

            if child not in open_set and child not in closed_set and child not in obstacles:
                actions[temp[0]][temp[1]] = (0, -1)
                parent[temp[0]][temp[1]] = node
                if child == goal:
                    movement = construct_movement(start_row, start_col,
                                                  goal_row, goal_col, actions,
                                                  parent)
                    return movement, closed_set
                else:
                    open_set.add(child)


#############################################################################
    return movement, closed_set
Exemple #2
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.

    After expanding a node, to retrieve the cost of a child node at location (x,y),
    please call costFn((x,y)).

    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action.
    logger: a logger to visualize the search process.
         Do not do anything to it.



    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object composed of actions
        that should move the agent from the start to goal cell along the path
        as found by the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.

    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()
    closed_set = OrderedSet()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    parent = [  # the immediate predecessor cell from which to reach a cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]

    movement = []
    # ----------------------------------------
    # finish the code below
    # ----------------------------------------
    #############################################################################
    flag = 0  #counter variable to check whether goal reached or not
    open_set.add(start)
    while (open_set and flag == 0):
        node = open_set.pop()
        closed_set.add(node)
        x = list(
            node
        )  #converting the parent node to list for ease in performing operations
        for action in ACTIONS:
            r1, c1 = action
            z1 = x[0] + r1  #row coordinate of child node
            z2 = x[1] + c1  #column coordinate of child node
            child = tuple((z1, z2))
            if child not in open_set and child not in closed_set and child not in obstacles and 0 <= z1 < n_rows and 0 <= z2 < n_cols:  #checking if child not in obstacles and lies in grid
                parent[z1][z2] = node  #storing parent of child
                actions[z1][
                    z2] = action  #storing action taken by parent to reach child
                if child == goal:
                    flag = 1  #goal reached
                else:
                    open_set.add(child)

    #generating path once goal has been reached
    if flag == 1:
        y = parent[goal_row][goal_col]
        movement.append(actions[goal_row][goal_col])
        while (y != start):
            p = list(y)
            movement.append(actions[p[0]][p[1]])
            y = parent[p[0]][p[1]]
        movement.reverse()


#############################################################################
    return movement, closed_set
Exemple #3
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. The default cost is 1, regardless of the
         action and the landing cell, i.e. every time the agent moves NSEW
         it costs one unit. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object who is composed of actions
        that should made moving from the start to goal cell along the path
        found the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()
    closed_set = Stack()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    movement = []

    # ----------------------------------------
    # finish the code below
    # ----------------------------------------
    #############################################################################

    def TransitionModel(node):
        current_row = node[0]
        current_col = node[1]
        direction_can_go = []

        TempRow = current_row
        TempCol = current_col + 1
        TempNode = (TempRow, TempCol)

        if TempNode not in obstacles and TempRow >= 0 and TempCol >= 0 and TempRow <= n_rows and TempCol <= n_cols:
            direction_can_go.append(TempNode)

        TempRow = current_row + 1
        TempCol = current_col
        TempNode = (TempRow, TempCol)

        if TempNode not in obstacles and TempRow >= 0 and TempCol >= 0 and TempRow <= n_rows and TempCol <= n_cols:
            direction_can_go.append(TempNode)

        TempRow = current_row - 1
        TempCol = current_col
        TempNode = (TempRow, TempCol)

        if TempNode not in obstacles and TempRow >= 0 and TempCol >= 0 and TempRow <= n_rows and TempCol <= n_cols:
            direction_can_go.append(TempNode)

        TempRow = current_row
        TempCol = current_col - 1
        TempNode = (TempRow, TempCol)

        if TempNode not in obstacles and TempRow >= 0 and TempCol >= 0 and TempRow <= n_rows and TempCol <= n_cols:
            direction_can_go.append(TempNode)
        #print("direction_can_go ::",direction_can_go)
        #print("node ::",node)
        return direction_can_go

    def ExpandNode():
        while len(open_set):
            i = 0
            node = open_set.pop()
            '''
            if i:
                prevnode=node   
                
                R= prevnode[0]-node[0]
                C =prevnode[1]-node[1]

                if(R == -1 and C == 0):
                    movement.append(ACTIONS[0])
                if(R == 0 and C == -1):
                    movement.append(ACTIONS[1])
                if(R == 1 and C == 0):
                    movement.append(ACTIONS[2])
                if(R == 0 and C == 1):
                    movement.append(ACTIONS[3])
            i=1
            '''
            closed_set.add(node)
            actions_posible = TransitionModel(node)

            for nextnode in actions_posible:
                #print("nextnode ::" ,nextnode)
                if nextnode not in closed_set and nextnode not in open_set:
                    if nextnode == goal:
                        closed_set.add(nextnode)
                        print("found it")
                        movement = backtrace(parent, start, goal)
                        movement = closed_set
                        return movement, closed_set
                    else:
                        open_set.add(nextnode)
                        #parent[nextnode] = node

                        R = node[0] - nextnode[0]
                        C = node[1] - nextnode[1]

                        if (R == -1 and C == 0):
                            movement.append(ACTIONS[0])
                        if (R == 0 and C == -1):
                            movement.append(ACTIONS[1])
                        if (R == 1 and C == 0):
                            movement.append(ACTIONS[2])
                        if (R == 0 and C == 1):
                            movement.append(ACTIONS[3])

    open_set.add(start)
    parent = {}

    ExpandNode()

    #############################################################################
    return movement, closed_set
Exemple #4
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.

    After expanding a node, to retrieve the cost of a child node at location (x,y), 
    please call costFn((x,y)). 
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object composed of actions
        that should move the agent from the start to goal cell along the path
        as found by the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()  #For DFS we required LIFO, so Stack set is selected
    closed_set = OrderedSet()

    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    parent = [  # the immediate predecessor cell from which to reach a cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]

    movement = []
    # ----------------------------------------
    # finish the code below
    # ----------------------------------------
    open_set.add(start)  #Adding start into open set
    path = []  #For finding the path

    while open_set:

        node = open_set.pop()
        if node == goal:  #If goal is achieved
            print("PATH FOUND")

            j = goal
            while j != start:  #For backtracking
                par_j = parent[j[0]][j[1]]
                path.append(par_j)
                j = par_j
                closed_set.add(node)
            break

        closed_set.add(node)

        for i in ACTIONS:  #Finding children of node
            child = (node[0] + i[0], node[1] + i[1])

            if child not in open_set and child not in closed_set:  #Checking the children in open set and closed set, if not then find children
                if child not in obstacles and 0 <= child[
                        0] < n_rows and 0 <= child[
                            1] < n_cols:  #Entering boundary condition and obstacle check for child
                    open_set.add(child)
                    parent[child[0]][child[1]] = (
                        node[0], node[1]
                    )  #Placing the parent of respective child
    path.reverse()  #Because of backtracing we have to reverse the path
    path.append(goal)

    for i in range(
            len(path) -
            1):  #Finding the movement, substracting the parent from child
        move = (path[i + 1][0] - path[i][0], path[i + 1][1] - path[i][1])
        movement.append(move)

    #############################################################################

    #############################################################################
    return movement, closed_set
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.

    After expanding a node, to retrieve the cost of a child node at location (x,y), 
    please call costFn((x,y)). 
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object composed of actions
        that should move the agent from the start to goal cell along the path
        as found by the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()
    closed_set = OrderedSet()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    parent = [  # the immediate predecessor cell from which to reach a cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]

    movement = []

    # ----------------------------------------
    # finish the code below
    # ----------------------------------------
    #############################################################################
    '''
    Based on the pseudo code from the slides
    '''
    open_set.add(start)
    while open_set:
        children = []
        currentNode = open_set.pop()
        closed_set.add(currentNode)
        currentNode_row, currentNode_col = currentNode
        # get the children
        children = [(currentNode_row - 1, currentNode_col),
                    (currentNode_row, currentNode_col - 1),
                    (currentNode_row + 1, currentNode_col),
                    (currentNode_row, currentNode_col + 1)]

        # expand the children
        for child in children:
            child_row, child_col = child
            if child not in obstacles and child_row >= 0 and child_col >= 0 and child_row < n_rows and child_col < n_cols:
                if child not in closed_set and child not in open_set:
                    action = (child_row - currentNode_row,
                              child_col - currentNode_col)
                    if action == (-1, 0):
                        actions[child_row][child_col] = ACTIONS[0]
                    if action == (0, -1):
                        actions[child_row][child_col] = ACTIONS[1]
                    if action == (1, 0):
                        actions[child_row][child_col] = ACTIONS[2]
                    if action == (0, 1):
                        actions[child_row][child_col] = ACTIONS[3]
                    if child == goal:  # child reaching the goal?
                        parent[child_row][child_col] = currentNode
                        p_row, p_col = child
                        while (p_row, p_col) != start:
                            #print(p_row)
                            movement.append(actions[p_row][p_col])
                            p_row, p_col = parent[p_row][p_col]

                        movement.reverse()
                        closed_set.add(
                            child
                        )  # for the same outcome with the demo video provided

                        return movement, closed_set
                    else:
                        open_set.add(child)
                        parent[child_row][child_col] = currentNode


#############################################################################
    return movement, closed_set
Exemple #6
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.

    After expanding a node, to retrieve the cost of a child node at location (x,y), 
    please call costFn((x,y)). 
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object composed of actions
        that should move the agent from the start to goal cell along the path
        as found by the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()
    closed_set = Queue()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    parent = [  # the immediate predecessor cell from which to reach a cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]

    movement = []
    path_storage = {}
    # ----------------------------------------
    # finish the code below
    # ----------------------------------------
    #############################################################################
    open_set.add(start)
    i = 0
    while open_set:
        child = []
        node_current = open_set.pop()
        closed_set.add(node_current)
        current_row, current_col = node_current
        child = [
            (current_row - 1, current_col), (current_row, current_col + 1),
            (current_row + 1, current_col), (current_row, current_col - 1)
        ]

        for child_node in child:
            child_row, child_col = child_node
            if child_node not in obstacles and child_row >= 0 and child_col >= 0 and child_row < n_rows and child_col < n_cols:
                print('Child node is', child_node)
                if child_node not in closed_set and child_node not in open_set:
                    if child_node == goal:
                        path_storage[child_node] = node_current
                        path_list = [goal]
                        print('The goal is', goal)
                        while path_list[-1] != start:
                            print('The parent node is',
                                  path_storage[path_list[-1]])
                            path_list.append(path_storage[path_list[-1]])
                        path_list.reverse()
                        iter = 0
                        for iter in range(len(path_list) - 1):
                            r, c = path_list[iter]
                            r2, c2 = path_list[iter + 1]
                            row = r2 - r
                            col = c2 - c
                            if (row == -1 and col == 0):
                                movement.append((-1, 0))
                            if (row == 0 and col == -1):
                                movement.append((0, -1))
                            if (row == 1 and col == 0):
                                movement.append((1, 0))
                            if (row == 0 and col == 1):
                                movement.append((0, 1))
                            iter += 1
                        return movement, closed_set
                    else:
                        open_set.add(child_node)
                        path_storage[child_node] = node_current
        i += 1


#############################################################################
    return movement, closed_set
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.

    After expanding a node, to retrieve the cost of a child node at location (x,y), 
    please call costFn((x,y)). 
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object composed of actions
        that should move the agent from the start to goal cell along the path
        as found by the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()
    closed_set = OrderedSet()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    parent = [  # the immediate predecessor cell from which to reach a cell
        [(-2, -2) for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [(-2, -2) for __ in range(n_cols)] for _ in range(n_rows)
    ]
    #   ACTIONS = (
    #  (-1,  0), # go up
    #( 0, -1), # go left
    # ( 1,  0), # go down
    #( 0,  1)  # go right
    #)
    movement = []
    # ----------------------------------------
    # finish the code below
    # ----------------------------------------
    #############################################################################
    open_set.add(start)

    while open_set:
        current = open_set.pop()
        closed_set.add(current)
        up = (current[0] - 1, current[1])
        left = (current[0], current[1] - 1)
        down = (current[0] + 1, current[1])
        right = (current[0], current[1] + 1)
        if (current == goal):
            break
        if (up[0] >= 0 and up not in closed_set and up not in obstacles
                and up not in open_set):
            open_set.add(up)
            parent[up[0]][up[1]] = current
            actions[up[0]][up[1]] = ACTIONS[0]
        if (left[1] >= 0 and left not in closed_set and left not in obstacles
                and left not in open_set):
            open_set.add(left)
            parent[left[0]][left[1]] = current
            actions[left[0]][left[1]] = ACTIONS[1]
        if (down[0] < grid_size[0] and down not in closed_set
                and down not in obstacles and down not in open_set):
            open_set.add(down)
            parent[down[0]][down[1]] = current
            actions[down[0]][down[1]] = ACTIONS[2]
        if (right[1] < grid_size[1] and right not in closed_set
                and right not in obstacles and right not in open_set):
            open_set.add(right)
            parent[right[0]][right[1]] = current
            actions[right[0]][right[1]] = ACTIONS[3]

    movement = find_path(parent, actions, start, goal)
    #############################################################################

    return movement, closed_set
Exemple #8
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.

    After expanding a node, to retrieve the cost of a child node at location (x,y), 
    please call costFn((x,y)). 
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object composed of actions
        that should move the agent from the start to goal cell along the path
        as found by the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    #open_set = OrderedSet()
    open_set = Stack()
    closed_set = OrderedSet()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    parent = [  # the immediate predecessor cell from which to reach a cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]

    movement = []
    # ----------------------------------------
    # finish the code below

    # open_set = Stack()

    open_set.add(start)
    flag = 0
    li = []
    while len(open_set) != 0:

        temp = open_set.pop()
        # for i in range(0,4):

        up = ((temp[0] - 1), temp[1])
        down = ((temp[0] + 1), temp[1])
        left = (temp[0], (temp[1] - 1))
        right = (temp[0], (temp[1] + 1))

        upCost = costFn(up)
        downCost = costFn(down)
        leftCost = costFn(left)
        rightCost = costFn(right)
        costs1 = [upCost, downCost, leftCost, rightCost]
        costs = {up: upCost, down: downCost, left: leftCost, right: rightCost}
        children = []
        closed_set.add(temp)
        li.append(temp)
        if len(set(costs1)) <= 1:
            children = [left, up, right, down]
        else:

            while costs:
                keyMax = max(costs, key=costs.get)
                if keyMax == up:
                    children.append(up)
                elif keyMax == down:
                    children.append(down)
                elif keyMax == left:
                    children.append(left)
                elif keyMax == right:
                    children.append(right)
                costs.pop(keyMax)
        for child in children:
            if child not in obstacles and child[0] >= 0 and child[
                    0] < n_rows and child[1] >= 0 and child[1] < n_cols:
                if child not in open_set and child not in closed_set:
                    if child == goal:
                        li.append(child)
                        closed_set.add(child)
                        flag = 1
                        break
                    else:
                        open_set.add(child)

        if flag == 1:
            break

    if flag == 0:
        movement = []
    else:
        last = len(li) - 1
        mov = li[last]
        for i in range(last, -1, -1):
            action = (mov[0] - li[i - 1][0], mov[1] - li[i - 1][1])
            if (action in ACTIONS):
                movement.insert(0, action)
                mov = li[i - 1]

    # ----------------------------------------


#############################################################################

#############################################################################
    return movement, closed_set
Exemple #9
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):

    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()  # Use Stack for openset
    closed_set = Queue()

    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set

    parents = [  # the immediate predecessor cell from which to reach a cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]

    movement = []

    # Define DFS
    open_set.add(start)
    while (open_set != []):
        parent = open_set.pop()
        closed_set.add(parent)

        # Search each direction of the parent
        for i in range(4):

            # Moving direction
            action_rows = action[i][0]
            action_cols = action[i][1]

            # Calculate child position
            parent_rows, parent_cols = parent
            child_rows, child_cols = parent_rows + action_rows, parent_cols + action_cols
            child = child_rows, child_cols

            # Restrict the node in the map
            if (child not in obstacles) and (child_rows < n_rows) and (
                    child_cols < n_cols) and (child_rows >= 0) and (child_cols
                                                                    >= 0):
                if (child not in open_set) and (child not in closed_set):

                    # Record parent and action for each step
                    parents[child_rows][child_cols] = parent
                    actions[child_rows][child_cols] = tuple(action[i])

                    if child == goal:

                        # Find Path
                        for j in range(n_cols * n_rows):

                            # find action for each step
                            act = actions[child_rows][child_cols]

                            # Save action in movement[]
                            movement.insert(0, act)

                            # find parent for each step
                            parent = parents[child_rows][child_cols]
                            child_rows, child_cols = parent

                            # Stop and return results
                            if parent == start:
                                return movement, closed_set
                    else:
                        open_set.add(child)
Exemple #10
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.

    After expanding a node, to retrieve the cost of a child node at location (x,y), 
    please call costFn((x,y)). 
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object composed of actions
        that should move the agent from the start to goal cell along the path
        as found by the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()
    closed_set = OrderedSet()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    parent = [  # the immediate predecessor cell from which to reach a cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]

    movement = []
    # ----------------------------------------
    # Student Code Below:
    # ----------------------------------------
    open_set.add((start_row, start_col))
    parent[start_row][start_col] = (start_row, start_col)
    flag = False
    while len(open_set) != 0 and flag == False:
        node = open_set.pop()
        closed_set.add(node)
        for action in ACTIONS:
            child = (node[0] + action[0], node[1] + action[1])
            if collision_check(child, obstacles) == False and out_of_bounds(
                    child, n_rows, n_cols) == False:
                if child not in open_set and child not in closed_set:
                    parent[child[0]][child[1]] = node
                    actions[child[0]][child[1]] = action
                    if child[0] == goal_row and child[1] == goal_col:
                        flag = True
                        break
                    else:
                        open_set.add(child)

    node = child
    while True:
        movement.append(actions[node[0]][node[1]])
        node = parent[node[0]][node[1]]
        if node[0] == start_row and node[1] == start_col: break
    movement.reverse()
    #############################################################################

    #############################################################################
    return movement, closed_set
Exemple #11
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.

    After expanding a node, to retrieve the cost of a child node at location (x,y), 
    please call costFn((x,y)). 
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Return
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object composed of actions
        that should move the agent from the start to goal cell along the path
        as found by the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    open_set = Stack()  # LIFO data structure
    closed_set = OrderedSet()  # orderset  data structure

    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set

    parents = [  # the immediate predecessor cell from which to reach a cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]
    actions = [  # the action that the parent took to reach the cell
        [None for __ in range(n_cols)] for _ in range(n_rows)
    ]

    open_set.add(start)  # initial state

    while len(open_set) > 0:

        node = open_set.pop()  # next expanded node

        closed_set.add(node)  # add expaned node to close_set

        x, y = node  # node location

        children = [(x - 1, y), (x, y - 1), (x + 1, y),
                    (x, y + 1)]  # possible children(up,left,down,right)

        boundary = [(x, y) for x in range(n_rows)
                    for y in range(n_cols)]  # boundary restriction

        for child in children:

            if child in boundary and child not in obstacles:

                if child not in open_set and child not in closed_set:

                    parents[child[0]][
                        child[1]] = node  # remark parent for current children

                    actions[child[0]][child[1]] = (child[0] - node[0],
                                                   child[1] - node[1]
                                                   )  # remark children action

                    if child == goal:

                        movement = path_backtrack(
                            start, child, parents,
                            actions)  # backtrack to find the path

                        return movement, closed_set

                    else:
                        open_set.add(child)
Exemple #12
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. The default cost is 1, regardless of the
         action and the landing cell, i.e. every time the agent moves NSEW
         it costs one unit. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object who is composed of actions
        that should made moving from the start to goal cell along the path
        found the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    # open_set = OrderedSet()
    # closed_set = OrderedSet()
    open_set = Stack()
    closed_set = Queue()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    movement = []
    pathTrace = {}

    def Backtrace():
        #############################################################################
        path = [goal]
        print('goal is', goal)
        while path[-1] != start:
            #if pathTrace[path[-1]] not in path:
            print('parent is', pathTrace[path[-1]])
            path.append(pathTrace[path[-1]])
        path.reverse()
        num = 0
        while num < len(path) - 1:
            row, col = path[num]
            parentRow, parentCol = path[num + 1]
            dRow = parentRow - row
            dCol = parentCol - col
            if (dRow == -1 and dCol == 0):
                movement.append((-1, 0))
            if (dRow == 0 and dCol == -1):
                movement.append((0, -1))
            if (dRow == 1 and dCol == 0):
                movement.append((1, 0))
            if (dRow == 0 and dCol == 1):
                movement.append((0, 1))
            num += 1
        return movement

    # ----------------------------------------
    # finish the code below
    # ----------------------------------------
#############################################################################
    open_set.add(start)
    i = 0
    while open_set:
        i = i + 1
        children = []
        currentNode = open_set.pop()
        closed_set.add(currentNode)
        currentNode_row, currentNode_col = currentNode

        children = [(currentNode_row - 1, currentNode_col),
                    (currentNode_row + 1, currentNode_col),
                    (currentNode_row, currentNode_col - 1),
                    (currentNode_row, currentNode_col + 1)]

        for childNode in children:
            node_row, node_col = childNode
            if childNode not in obstacles and node_row >= 0 and node_col >= 0 and node_row < n_rows and node_col < n_cols:
                if childNode not in closed_set and childNode not in open_set:
                    if childNode == goal:
                        pathTrace[childNode] = currentNode
                        movement = Backtrace()
                        return movement, closed_set
                    else:
                        open_set.add(childNode)
                        pathTrace[childNode] = currentNode


#############################################################################
    return movement, closed_set
Exemple #13
0
def depth_first_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    DFS algorithm finds the path from the start cell to the
    goal cell in the 2D grid world.
    
    Parameters
    ----------
    grid_size: tuple, (n_rows, n_cols)
        (number of rows of the grid, number of cols of the grid)
    start: tuple, (row, col)
        location of the start cell;
        row and col are counted from 0, i.e. the 1st row is 0
    goal: tuple, (row, col)
        location of the goal cell
    obstacles: tuple, ((row, col), (row, col), ...)
        locations of obstacles in the grid
        the cells where obstacles are located are not allowed to access 
    costFn: a function that returns the cost of landing to a cell (x,y)
         after taking an action. The default cost is 1, regardless of the
         action and the landing cell, i.e. every time the agent moves NSEW
         it costs one unit. 
    logger: a logger to visualize the search process.
         Do not do anything to it.

   

    Returns
    -------
    movement along the path from the start to goal cell: list of actions
        The first returned value is the movement list found by the search
        algorithm from the start cell to the end cell.
        The movement list should be a list object who is composed of actions
        that should made moving from the start to goal cell along the path
        found the algorithm.
        For example, if nodes in the path from the start to end cell are:
            (0, 0) (start) -> (0, 1) -> (1, 1) -> (1, 0) (goal)
        then, the returned movement list should be
            [(0,1), (1,0), (0, -1)]
        which means: move right, down, left.

        Return an EMPTY list if the search algorithm fails finding any
        available path.
        
    closed set: list of location tuple (row, col)
        The second returned value is the closed set, namely, the cells are expanded during search.
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = Stack()
    closed_set = OrderedSet()
    ##########################################

    ##########################################
    # Set up visualization logger hook
    # Please do not modify these four lines
    closed_set.logger = logger
    logger.closed_set = closed_set
    open_set.logger = logger
    logger.open_set = open_set
    ##########################################

    movement = []
    # ----------------------------------------
    # finish the code below
    # ----------------------------------------
    
    # dictionary to store neighbor and action 
    temp_movement={}
    movement_rev=[]
    
    #put start node into the open_set
    
    open_set.add((start_row, start_col))
    
    #looping until the open_set is empty 
   
    while len(open_set)!=0:
        node=open_set.pop()
        closed_set.add(node)
        current_row , current_col = node
    #call neighbor funcation to get child/neighbor and actions of current node 
        list_neg,list_mom=negh(current_row,current_col,n_rows,n_cols,obstacles)
        for x in range(len(list_neg)):
            if list_neg[x] not in closed_set and list_neg[x] not in open_set: 
                temp_movement.update({list_neg[x]:list_mom[list_neg[x]]}) 
                if list_neg[x]==goal:
                    temp=goal
    # code to traceback path form the goal to start
                    while temp!=start:
                        temp_row,temp_col=temp
                        temp1_row,temp1_col=temp_movement[temp]
                        temp_row=temp_row-(temp1_row)
                        temp_col=temp_col-(temp1_col)
                        movement_rev.append(temp_movement[temp])
                        temp=temp_row,temp_col
                        movement=Reverse(movement_rev)
                    return movement, closed_set
                else:
                    open_set.add(list_neg[x])
#######################################################################

#############################################################################
    return movement, closed_set