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