| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- # ----------
- # User Instructions:
- #
- # Create a function compute_value which returns
- # a grid of values. The value of a cell is the minimum
- # number of moves required to get from the cell to the goal.
- #
- # If a cell is a wall or it is impossible to reach the goal from a cell,
- # assign that cell a value of 99.
- # ----------
- import heapq
- from collections import deque
- import numpy as np
- from icecream import ic
- from first_search import check_navigable
- grid = [[0, 1, 0, 0, 0, 0],
- [0, 1, 0, 0, 0, 0],
- [0, 1, 0, 0, 0, 0],
- [0, 1, 0, 0, 0, 0],
- [0, 0, 0, 0, 1, 0]]
- grid = np.array([[0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
- [0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
- [0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0],
- [0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
- [0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0],
- [0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0],
- [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
- [0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
- [0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0],
- [0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0]])
- # init = [0,0]
- goal = [len(grid)-1, len(grid[0])-1]
- cost = 1 # the cost associated with moving from a cell to an adjacent one
- delta = [[-1, 0], # go up
- [0, -1], # go left
- [1, 0], # go down
- [0, 1]] # go right
- delta_name = ['^', '<', 'v', '>']
- def heuristic(*args):
- return 0
- def compute_value(grid, goal, cost):
- """Compute the reversed cost map. The goal point will have zero cost and
- each grid has a cost value representing the cost from here to the goal.
- Parameters
- ----------
- grid : np.ndarray
- Map of the env.
- goal : np.ndarray
- Goal position.
- cost : float
- Cost value for each step.
- Returns
- -------
- np.ndarray
- A reversed cost map.
- """
- grid = np.array(grid)
- goal = np.array(goal)
- open_list = []
- heapq.heappush(open_list, np.concatenate(
- ([heuristic(goal, goal), 0], goal)))
- closed_list = dict()
- closed_list[tuple(goal)] = 0
- cost_map = np.zeros([len(grid), len(grid[0])]) + float('inf')
- cost_map[goal[0], goal[1]] = 0
- expand_map = np.zeros([len(grid), len(grid[0])]) - float('inf')
- current_expand_num = 0
- expand_map[goal[0], goal[1]] = current_expand_num
- while open_list:
- current_center_grid = heapq.heappop(open_list)
- current_center_grid = current_center_grid[2:4] # type: list[int]
- if check_navigable(grid, current_center_grid):
- for move_num in range(len(delta)):
- next = np.array(current_center_grid)+delta[move_num]
- next = next.astype('int') # type: np.ndarray[int]
- if check_navigable(grid, next) and tuple(next) not in closed_list:
- current_expand_num += 1
- current_cost = closed_list[current_center_grid[0],
- current_center_grid[1]]+cost
- expand_grid = [heuristic(next, goal)+current_expand_num,
- current_expand_num] + list(next)
- heapq.heappush(open_list, expand_grid)
- closed_list[tuple(next)] = current_cost
- cost_map[next[0], next[1]] = current_cost
- expand_map[next[0], next[1]] = current_expand_num
- return cost_map
- def generate_policy(cost_map, goal):
- def check_navigable(cost_map, pos):
- goal = np.array(pos).astype(int)
- if all(goal >= np.array([0, 0])) and all(goal <= np.array([len(cost_map)-1, len(cost_map[0])-1])):
- if cost_map[goal[0], goal[1]] != float('inf'):
- return True
- return False
- delta = np.array([[-1, 0], # type: np.ndarray[int]
- [0, -1], # go left
- [1, 0], # go down
- [0, 1]]) # go right
- cost_map = np.array(cost_map)
- policy_map = np.array([['+' for _ in range(len(cost_map[0]))]
- for _ in range(len(cost_map))])
- policy_map[goal[0], goal[1]] = '*'
- open_list = deque()
- checked = set([tuple(goal)])
- neighbor_grids = np.array([goal for _ in range(4)]) + delta
- neighbor_grids = map(lambda pos: pos if check_navigable(
- cost_map, pos) else False, neighbor_grids)
- # print(list(neighbor_grids))
- for pos in neighbor_grids:
- if type(pos) == np.ndarray:
- open_list.append(pos)
- while open_list:
- current_grid = open_list.popleft()
- checked.add(tuple(current_grid))
- neighbor_grids = np.array([current_grid for _ in range(4)]) + delta
- neighbor_costs = list(map(lambda pos: cost_map[pos[0], pos[1]] if check_navigable(
- cost_map, pos) else float('inf'), neighbor_grids))
- # expand the open list
- for i in range(4):
- if neighbor_costs[i] != float('inf') and tuple(neighbor_grids[i]) not in checked:
- open_list.append(neighbor_grids[i])
- minimum_cost_grid_index = np.argmin(neighbor_costs)
- dlt_opst = ['^', '<', 'v', '>']
- policy_map[current_grid[0], current_grid[1]
- ] = dlt_opst[minimum_cost_grid_index]
- return policy_map
- cost_map = compute_value(grid, goal, cost)
- ic(generate_policy(cost_map, goal))
|