def uniform_cost_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    Uniform-cost search algorithm finds the optimal 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)). 

    See depth_first_search() for details.
    """
    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 = PriorityQueue(order="min", f=lambda v: v)
    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.put(start, 0)
    while open_set:
        children = []
        currentNode, v = open_set.pop()
        if currentNode == goal:  # reach the goal, start backtrace
            closed_set.add(
                currentNode
            )  # for the same outcome with the demo video provided
            p_row, p_col = goal
            while (p_row, p_col) != start:
                movement.append(actions[p_row][p_col])
                p_row, p_col = parent[p_row][p_col]
            movement.reverse()

            return movement, closed_set

        closed_set.add(currentNode)
        currentNode_row, currentNode_col = currentNode
        # get the children
        children = [((currentNode_row - 1, currentNode_col), v + costFn(
            (currentNode_row - 1, currentNode_col))),
                    ((currentNode_row, currentNode_col - 1), v + costFn(
                        (currentNode_row, currentNode_col - 1))),
                    ((currentNode_row + 1, currentNode_col), v + costFn(
                        (currentNode_row + 1, currentNode_col))),
                    ((currentNode_row, currentNode_col + 1), v + costFn(
                        (currentNode_row, currentNode_col + 1)))]

        #expand the children
        for child in children:
            node, cost = child
            child_row, child_col = node
            if (
                    child_row, child_col
            ) not in obstacles and child_row >= 0 and child_col >= 0 and child_row < n_rows and child_col < n_cols:
                if node not in closed_set and node not in open_set:
                    open_set.put(node, cost)
                    parent[child_row][child_col] = currentNode
                    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 need to update with a lower cost
                elif child in open_set and open_set.get(
                    (child_row, child_col)) > cost:
                    open_set.remove(child)
                    open_set.put(node, cost)
                    parent[child_row][child_col] = currentNode
                    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]
Ejemplo n.º 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
    # ----------------------------------------
    #############################################################################
    open_set.add(start)
    while open_set:
        node = open_set.pop()
        closed_set.add(node)
        for action in ACTIONS:
            child = (node[0] + action[0], node[1] + action[1])
            if child not in open_set and child not in closed_set and child not in obstacles and child[
                    0] >= 0 and child[0] < n_rows and child[1] >= 0 and child[
                        1] < n_cols:
                if child == goal:
                    movement.append(action)
                    while node is not start:
                        movement.insert(0, actions[node[0]][node[1]])
                        node = parent[node[0]][node[1]]
                    return movement, closed_set
                else:
                    open_set.add(child)
                    parent[(child)[0]][(child)[1]] = node
                    actions[(child)[0]][(child)[1]] = action


#############################################################################
    return movement, closed_set
Ejemplo n.º 3
0
def astar_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    A* search algorithm finds the optimal 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)).   

    See depth_first_search() for details.    
    """
    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 = PriorityQueue(order="min", f=lambda v: abs(v))
    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 to implement a Manhattan distance heuristic
    # ----------------------------------------
    def heuristic(row, col):
        #############################################################################
        return abs(row - goal[0]) + abs(col - goal[1])

    open_set.put(start, heuristic(start[0], start[1]))
    flag = 0
    dict = {}
    dict[start] = ([None], 0)
    while len(open_set) != 0:
        temp, value = open_set.pop()
        up = ((temp[0] - 1), temp[1])
        down = ((temp[0] + 1), temp[1])
        left = (temp[0], (temp[1] - 1))
        right = (temp[0], (temp[1] + 1))
        children = [left, up, right, down]
        closed_set.add(temp)
        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 closed_set:
                    if child == goal:
                        closed_set.add(child)
                        dict[child] = (temp, value)
                        flag = 1
                        break
                    else:
                        value = dict[temp][1] + costFn(child)
                        if (child not in open_set):
                            open_set.put(child,
                                         value + heuristic(child[0], child[1]))
                            dict[child] = (temp, value)
                        elif (value < dict[child][1]):
                            open_set.remove(child)
                            open_set.put(child,
                                         value + heuristic(child[0], child[1]))
                            dict[child] = (temp, value)

        if flag == 1:
            break

    if flag == 0:
        movement = []
    else:
        node = goal
        while node != start:
            cur = node
            node = (dict[node][0])
            action = (cur[0] - node[0], cur[1] - node[1])
            if (action in ACTIONS):
                movement.insert(0, action)


#############################################################################
    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
Ejemplo n.º 5
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
Ejemplo n.º 6
0
def uniform_cost_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    Uniform-cost search algorithm finds the optimal 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)). In all of the grid maps, the cost is always 1.

    See depth_first_search() for details.
    """
    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 = PriorityQueue()
    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.put((start_row, start_col),0)
    
    #looping until open_set is empty 
   
    while(len(open_set))!=0:
        node=open_set.pop()
        noderc , node_val = node
        current_row,current_col=noderc
        if noderc==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
        closed_set.add(noderc)
    
    #call neighbor function 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)):
            child_row, child_col=list_neg[x]
            if list_neg[x] not in open_set and list_neg[x] not in closed_set: 
                open_set.put(list_neg[x],costFn(list_neg[x]))
                temp_movement.update({list_neg[x]:list_mom[list_neg[x]]}) 
            elif list_neg[x] in open_set and costFn((child_row,child_col))>node_val:
                noderc=list_neg[x]
                   
#############################################################################

#############################################################################
    return movement, closed_set
Ejemplo n.º 7
0
def astar_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 = PriorityQueue(order="min", f=lambda v: v)
    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

    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 = []

    def heuristic(row, col):
        h = abs(goal_row - row) + abs(goal_col - col)
        #print(h)
        return h
        pass

    # Variable Initialization
    g = 0  # g(n)
    h = heuristic(start_row, start_col)  # h(n)
    f = g + h  # f(n) Path cost

    # Add start point to openset
    open_set.put(start, f)

    # Define A*
    while (open_set != []):

        # Take out (x,y)(parent) and path v(cost) from openset
        temp_parent = open_set.pop()
        parent, v = temp_parent
        parent_rows, parent_cols = parent

        # Update h
        h = heuristic(parent_rows, parent_cols)

        # Determine whether the agent reach to goal
        if parent == goal:

            # Search path
            for j in range(n_cols * n_rows):
                parent_rows, parent_cols = parent

                # Stop and return
                if parent == start:
                    return movement, closed_set

                # record action and put it in to movement()
                act = actions[parent_rows][parent_cols]
                movement.insert(0, act)

                # Update parent
                parent = parents[parent_rows][parent_cols]

        # Add parent to closedset
        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
            child_rows, child_cols = parent_rows + action_rows, parent_cols + action_cols
            child = child_rows, child_cols

            # Update g, h and f value
            g = (v - h) + costFn((parent_rows, parent_cols))
            h_child = heuristic(child_rows, child_cols)
            f = g + h_child

            # 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):

                    # Add into openset
                    open_set.put(child, f)

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

                elif (child in open_set) and (f < open_set.get(child)):

                    # Add into openset
                    open_set.put(child, f)

                    # Record parent and action for each step
                    parents[child_rows][child_cols] = parent
                    actions[child_rows][child_cols] = tuple(action[i])
Ejemplo n.º 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 = 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
Ejemplo n.º 9
0
def astar_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    A* search algorithm finds the optimal 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)).   

    See depth_first_search() for details.    
    """

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

    open_set = PriorityQueue(order="min",
                             f=lambda v: v)  # priority data structure
    closed_set = OrderedSet()  # OrderedSet 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)
    ]

    # Manhanttan distance
    def heuristic(row, col):
        Manhanttan_dis = abs(goal_row - row) + abs(goal_col - col)
        return Manhanttan_dis

    g_start = 0  # initial path-cost
    h_start = heuristic(start_row, start_col)  # initial heuristic
    f_start = g_start + h_start  # initial total cost

    open_set.put(start, f_start)  # initial state

    while len(open_set) > 0:

        out = open_set.pop()  # next expanded node

        node, f = out

        x, y = node  # node location

        if node == goal:  # when expanded node is goal, stop

            closed_set.add(node)

            movement = path_backtrack(start, node, parents, actions)

            return movement, closed_set

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

        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:

            # child cost
            h_parent = heuristic(node[0], node[1])
            g_parent = f - h_parent
            f_child = heuristic(child[0], child[1]) + g_parent + costFn(
                (child[0], child[1]))

            if child in boundary and child not in obstacles:

                if child not in open_set and child not in closed_set:

                    open_set.put(child, f_child)

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

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

                elif child in open_set and child not in closed_set:

                    if f_child < open_set.get(
                            child
                    ):  # update parent, action,cost of child existed in open_set
                        open_set.put(child, f_child)
                        parents[child[0]][child[1]] = node
                        actions[child[0]][child[1]] = (child[0] - node[0],
                                                       child[1] - node[1])
Ejemplo n.º 10
0
def astar_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    A* search algorithm finds the optimal 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)).   

    See depth_first_search() for details.    
    """
    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 = PriorityQueue(order="min", f=lambda v: abs(v))
    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:
    # ----------------------------------------
    def heuristic(q):
        return (abs(goal_row - q[0]) + abs(goal_col - q[1]))

    open_set.put((start_row, start_col), 0 + heuristic((start_row, start_col)))
    parent[start_row][start_col] = (start_row, start_col)

    while len(open_set) != 0:
        node, f_node = open_set.pop()
        g_node = f_node - heuristic(node)
        if node[0] == goal_row and node[1] == goal_col:
            break
        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:
                f = (g_node + costFn(child)) + heuristic(child)

                if child not in open_set and child not in closed_set:
                    parent[child[0]][child[1]] = node
                    actions[child[0]][child[1]] = action
                    open_set.put(child, f)

                elif child in open_set and child not in closed_set and f < open_set.get(
                        child):
                    open_set.remove(child)
                    open_set.put(child, f)
                    parent[child[0]][child[1]] = node
                    actions[child[0]][child[1]] = action

    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
Ejemplo n.º 11
0
def uniform_cost_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    Uniform-cost search algorithm finds the optimal 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)). 

    See depth_first_search() for details.
    """

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

    open_set = PriorityQueue(order="min", f=lambda v: v)  # Priority sequence
    closed_set = OrderedSet()  # Orderedset 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)
    ]

    g_n = 0  # initial path_cost

    open_set.put(start, g_n)  # initial state

    while len(open_set) > 0:

        node, g = open_set.pop()  # next expanded node

        x, y = node  # next expand node location

        if node == goal:  # when expended node is goal that return path (optimal)

            closed_set.add(node)

            movement = path_backtrack(start, node, parents, actions)

            return movement, closed_set

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

        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:

            g_child = g + costFn((child[0], child[1]))  # child cost

            if child in boundary and child not in obstacles:

                if child not in open_set and child not in closed_set:

                    open_set.put(child, g_child)

                    parents[child[0]][child[1]] = node  # parent remark

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

                elif child in open_set and child not in closed_set:  # update that OPEN_node

                    if g_child < open_set.get(
                            child
                    ):  # update the cost and parent,action of child existed in open_set

                        open_set.put(child, g_child)
                        parents[child[0]][child[1]] = node
                        actions[child[0]][child[1]] = (child[0] - node[0],
                                                       child[1] - node[1])
Ejemplo n.º 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.

    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)
Ejemplo n.º 13
0
def astar_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    A* search algorithm finds the optimal 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)). In all of the grid maps, the cost is always 1.  

    See depth_first_search() for details.    
    """
    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 = PriorityQueue()
    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
    ##########################################

  
    # ----------------------------------------
    # finish the code below to implement a Manhattan distance heuristic
    # ----------------------------------------
    def heuristic(row, col):
        return abs(row - goal_row) + abs(col - goal_col)

    
   
    movement = []
    temp_movement={}
    movement_rev=[]

    #put start node into the open_set with fval 0
    open_set.put((start_row,start_col),0)
    
    #looping until open_set is empty 
    while len(open_set) != 0:
        node = open_set.pop()

        curr_node, node_fval = node

        curr_row, curr_col = curr_node

        if curr_node == 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
        
        closed_set.add(curr_node)

        neighbors,my_move = negh(curr_row, curr_col, n_rows, n_cols, obstacles)

        
        for next_node in range(len(neighbors)):
            total_cost = 0
            child_row, child_col = neighbors[next_node]

            #to calculate the F-value: for A* F(node) = g(node) + h(node)
            #cost_g is the sum of path cost between current node and child_node + path_cost of current node
            #and h(node) is heuristics value between child_node and goal node
            
            cost_g = costFn((child_row, child_col))+ (node_fval - heuristic(curr_row, curr_col))
            cost_h = heuristic(child_row, child_col)
            total_cost = cost_g + cost_h

            if neighbors[next_node] not in open_set and neighbors[next_node] not in closed_set:
                #insert child_node and f_value into openset
                open_set.put(neighbors[next_node], total_cost)
                temp_movement.update({neighbors[next_node]:my_move[neighbors[next_node]]})
                
            elif neighbors[next_node] in open_set and total_cost < node_fval+heuristic(curr_row,curr_col):
                curr_node = neighbors[next_node]
                
    return movement, closed_set
Ejemplo n.º 14
0
def uniform_cost_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    Uniform-cost search algorithm finds the optimal 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)). 

    See depth_first_search() for details.
    """

    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 = PriorityQueue(order="min", f=lambda v: abs(v))
    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
    # ----------------------------------------
    """
    Unique operations of PriorityQueue:
    PriorityQueue(order="min", f=lambda v: v): build up a priority queue
        using the function f to compute the priority based on the value
        of an element
    s.put(x, v): add the element x with value v to the queue
                    update the value of x if x is already in the queue
    s.get(x): get the value of the element x
                raise KeyError if x is not in s
    s.pop(): return and remove the element with highest priority in s;
                raise IndexError if s is empty
                if order is "min", the element with minimum f(v) will be popped;
                if order is "max", the element with maximum f(v) will be popped.
    Example:
    s = PriorityQueue(order="max", f=lambda v: abs(v))
    s.put((1,1), -1)
    s.put((2,2), -20)
    s.put((3,3), 10)
    x, v = s.pop()  # the element with maximum value of abs(v) will be popped
    assert(x == (2,2) and v == -20)
    assert(x not in s)
    assert(x.get((1,1)) == -1)
    assert(x.get((3,3)) == 10)
    """
    #############################################################################
    open_set.put(start, 0)
    while open_set:
        node = open_set.pop()
        if node[0] == goal:
            node = node[0]
            while node is not start:
                movement.insert(0, actions[node[0]][node[1]])
                node = parent[node[0]][node[1]]
            return movement, closed_set
        closed_set.add(node[0])
        for action in ACTIONS:
            child = (node[0][0] + action[0], node[0][1] + action[1])
            cost = costFn(child)
            if child not in open_set and child not in closed_set and child not in obstacles and child[
                    0] >= 0 and child[0] < n_rows and child[1] >= 0 and child[
                        1] < n_cols:
                open_set.put(child, node[1] + cost)
                parent[(child)[0]][(child)[1]] = node[0]
                actions[(child)[0]][(child)[1]] = action
            elif child in open_set and open_set.get(child) > node[1] + cost:
                open_set.put(child, node[1] + cost)
                parent[(child)[0]][(child)[1]] = node[0]
                actions[(child)[0]][(child)[1]] = action


#############################################################################
    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
Ejemplo n.º 16
0
def astar_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    A* search algorithm finds the optimal 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)).   

    See depth_first_search() for details.    
    """
    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 = PriorityQueue(order="min", f=lambda v: abs(v))
    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 to implement a Manhattan distance heuristic
    # ----------------------------------------
    def heuristic(row, col):
        #############################################################################
        return abs(row - goal_row) + abs(col - goal_col)

    open_set.put(start, (0 + heuristic(start_row, start_col)))
    while open_set:
        node = open_set.pop()
        if node[0] == goal:
            node = node[0]
            while node is not start:
                movement.insert(0, actions[node[0]][node[1]])
                node = parent[node[0]][node[1]]
            return movement, closed_set
        closed_set.add(node[0])

        for action in ACTIONS:
            child = (node[0][0] + action[0], node[0][1] + action[1])
            cost = costFn(child)
            heur = heuristic(child[0], child[1])
            old_heur = heuristic(node[0][0], node[0][1])

            if child not in open_set and child not in closed_set and child not in obstacles and child[
                    0] >= 0 and child[0] < n_rows and child[1] >= 0 and child[
                        1] < n_cols:
                open_set.put(child, node[1] + cost + heur - old_heur)
                parent[(child)[0]][(child)[1]] = node[0]
                actions[(child)[0]][(child)[1]] = action

            elif child in open_set and open_set.get(
                    child) > node[1] + cost + heur:
                open_set.put(child, node[1] + cost + heur - old_heur)
                parent[(child)[0]][(child)[1]] = node[0]
                actions[(child)[0]][(child)[1]] = action


#############################################################################
    return movement, closed_set
def astar_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    A* search algorithm finds the optimal 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)).   

    See depth_first_search() for details.    
    """
    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 = PriorityQueue()
    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)
    ]

    movement = []

    # ----------------------------------------
    # finish the code below to implement a Manhattan distance heuristic
    # ----------------------------------------
    def heuristic(row, col):
        #############################################################################
        distance = abs(row - goal[0]) + abs(col - goal[1])
        return distance


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

    open_set.put(start, heuristic(start[0], start[1]))

    while open_set:
        current, current_cost = open_set.pop()
        current_cost = current_cost - heuristic(current[0], current[1])
        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):
            cost = current_cost + costFn(up) + heuristic(up[0], up[1])
            open_set.put(up, cost)
            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):
            cost = current_cost + costFn(left) + heuristic(left[0], left[1])
            open_set.put(left, cost)
            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):
            cost = current_cost + costFn(down) + heuristic(down[0], down[1])
            open_set.put(down, cost)
            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):
            cost = current_cost + costFn(right) + heuristic(right[0], right[1])
            open_set.put(right, cost)
            parent[right[0]][right[1]] = current
            actions[right[0]][right[1]] = ACTIONS[3]

    movement = find_path(parent, actions, start, goal)
    return movement, closed_set
Ejemplo n.º 18
0
def astar_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    A* search algorithm finds the optimal 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)).   

    See depth_first_search() for details.    
    """
    n_rows, n_cols = grid_size
    start_row, start_col = start
    goal_row, goal_col = goal

    def heuristic(row, col):
        #############################################################################
        h = abs(goal_row - row) + abs(goal_col - col)
        return h

    ##########################################
    # Choose a proper container yourself from
    # OrderedSet, Stack, Queue, PriorityQueue
    # for the open set and closed set.
    open_set = PriorityQueue()
    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 = []
    h_start = heuristic(start_row, start_col)
    g_start = costFn(start)
    f_start = g_start + h_start
    open_set.put(start, f_start)
    path = []

    while open_set:

        node, cost = open_set.pop()

        if node == goal:
            print("PATH FOUND")
            j = goal
            while j != start:
                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:
            child = (node[0] + i[0], node[1] + i[1])
            h_cost = heuristic(child[0], child[1])
            g_node = cost - heuristic(node[0], node[1])
            f_cost = g_node + h_cost + costFn(child)

            if child not in open_set and child not in closed_set:
                if child not in obstacles and 0 <= child[
                        0] < n_rows and 0 <= child[1] < n_cols:
                    open_set.put(child, f_cost)
                    parent[child[0]][child[1]] = (node[0], node[1])
            elif child in open_set:
                if f_cost < open_set.get(child):
                    open_set.put(child, f_cost)
                    parent[child[0]][child[1]] = (node[0], node[1])

    path.reverse()
    path.append(goal)

    for i in range(len(path) - 1):
        move = (path[i + 1][0] - path[i][0], path[i + 1][1] - path[i][1])
        movement.append(move)

    # ----------------------------------------
    # finish the code below to implement a Manhattan distance heuristic
    # ----------------------------------------

    #############################################################################
    return movement, closed_set
Ejemplo n.º 19
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
Ejemplo n.º 20
0
def astar_search(grid_size, start, goal, obstacles, costFn, logger):
    """
    A* search algorithm finds the optimal 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)).

    See depth_first_search() for details.
    """
    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 = PriorityQueue(order="min")
    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 to implement a Manhattan distance heuristic
    # ----------------------------------------
    def heuristic(row, col):
        value = abs(row - goal_row) + abs(
            col - goal_col)  #calculating manhattan distance from goal
        return value
#############################################################################

    flag = 0  #counter variable to check whether goal reached or not
    g = 0  #initialising g value of start node
    h = heuristic(start_row, start_col)  #calculating h value of start node
    open_set.put(start, g + h)
    while (open_set and flag == 0):
        node, f_parent = open_set.pop()
        if node == goal:
            flag = 1  #goal reached
        else:
            closed_set.add(node)
            x = list(
                node
            )  #converting the parent node to list for ease in performing operations
            h_parent = heuristic(x[0], x[1])
            g_parent = f_parent - h_parent
            for action in ACTIONS:
                r1, c1 = action  #converting the action to list for ease in performing operations
                z1 = x[0] + r1  #row coordinate of child node
                z2 = x[1] + c1  #column coordinate of child node
                child = tuple((z1, z2))
                h_child = heuristic(z1, z2)  #calulating h value of child
                g_child = g_parent + costFn(
                    child)  #calculating g value of child
                f_child = g_child + h_child
                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
                    open_set.put(child, f_child)
                elif child in open_set:
                    f_child_prev = open_set.get(child)
                    if f_child_prev > f_child:  #updating child with lower g value to open list
                        parent[z1][z2] = node  #updating new parent
                        actions[z1][
                            z2] = action  #updating action taken by new parent to reach child
                        open_set.put(child, f_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
Ejemplo n.º 21
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