简体   繁体   中英

A-star Numpy Gscore error “unhashable type: 'numpy.ndarray'”

Overall I am trying to create the best path from 2 to -1 on a grid. I am going to change the location of these numbers and I want the path to be able to calculate the shortest distance between the two points.

I am having problems, specifically, with this section so far

def astar(array, start, goal):
    neighbors = [(0,1),(0,-1),(1,0),(-1,0),(1,1),(1,-1),(-1,1),(-1,-1)]
    close_set = set()
    came_from = {}
    gscore = {start:0} 
    fscore = {start:heuristic(start, goal)}
    oheap = []
    heapq.heappush(oheap, (fscore[start], start)) 

my gscore gives me an error of

unhashable type: 'numpy.ndarray'

I have not figured out what to change to make it work.

The code works when the starting and ending points are coordinates. aka start = (0,0) , goal = (0,19)

Full code for reference

import numpy as np
import heapq
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure



##############################################################################
# plot grid
##############################################################################

grid=grid = np.array([
 [2, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
# start point and goal
##start = np.any(grid>=2)
##start = grid.argmax()
##print(start)
start = np.where(grid==2)
##goal = np.any(grid<=-1)
##goal = grid.argmin()
##print(goal)
goal = np.where(grid==-1)




##############################################################################
# heuristic function for path scoring
##############################################################################

def heuristic(a, b):
 return np.sqrt((b[0] - a[0]) ** 2 + (b[1] - a[1]) ** 2)

##############################################################################
# path finding function
##############################################################################

def astar(array, start, goal):
 neighbors = [(0,1),(0,-1),(1,0),(-1,0),(1,1),(1,-1),(-1,1),(-1,-1)]
 close_set = set()
 came_from = {}
 gscore = {start:0} ## start:0
 fscore = {start:heuristic(start, goal)}
 oheap = []
 heapq.heappush(oheap, (fscore[start], start)) 

 while oheap:
     current = heapq.heappop(oheap)[1]
     if current == goal:
         data = []
         while current in came_from:
             data.append(current)
             current = came_from[current]
         return data
     close_set.add(current)
     for i, j in neighbors:
         neighbor = current[0] + i, current[1] + j
         tentative_g_score = gscore[current] + heuristic(current, neighbor)
         if 0 <= neighbor[0] < array.shape[0]:
             if 0 <= neighbor[1] < array.shape[1]:                
                 if array[neighbor[0]][neighbor[1]] == 1:
                     continue
             else:
                 # array bound y walls
                 continue
         else:
             # array bound x walls
             continue

         if neighbor in close_set and tentative_g_score >= gscore.get(neighbor, 0):
             continue

         if  tentative_g_score < gscore.get(neighbor, 0) or neighbor not in [i[1]for i in oheap]:
             came_from[neighbor] = current
             gscore[neighbor] = tentative_g_score
             fscore[neighbor] = tentative_g_score + heuristic(neighbor, goal)
             heapq.heappush(oheap, (fscore[neighbor], neighbor))

 return False
route = astar(grid, start, goal)
route = route + [start]
route = route[::-1]
print(route)

##############################################################################
# plot the path
##############################################################################

#extract x and y coordinates from route list
x_coords = []
y_coords = []
for i in (range(0,len(route))):
 x = route[i][0]
 y = route[i][1]
 x_coords.append(x)
 y_coords.append(y)
# plot map and path
fig, ax = plt.subplots(figsize=(20,20))
ax.imshow(grid, cmap=plt.cm.Dark2)
ax.scatter(start[1],start[0], marker = "*", color = "yellow", s = 200)
ax.scatter(goal[1],goal[0], marker = "*", color = "red", s = 200)
ax.plot(y_coords,x_coords, color = "black")
plt.show()

The problem is that ndarray is mutable while dict keys must be immutables. See Immutable vs Mutable types . The problem is variable 'start'. I guess it is ndarray so it must be converted to immuable type to be used as a key. Convert it to tuple with command:

start=tuple(start.tolist())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM