Context: I am trying to write an A* search in an unknown environment. To do this, I am maintaining a representation of the environment in a 2-D or 3-D list (depending on the environment), and another n-D list that represents the agent's knowledge of the environment.
When the agent moves, I check the area around them with the actual environment. If there is a discrepancy, their map gets updated, and I run A* again.
Problem: What is the fastest method to check if there is a difference between the ranges of these two lists?
Naive Solution:
from itertools import product
from random import randint
width, height = 10, 10
known_environment = [[0 for x in range(width)] for y in range(height)]
actual_environment = [[0 for x in range(width)] for y in range(height)]
# Populate with obstacles
for i in xrange(10):
x = randint(0, len(actual_environment) - 1)
y = randint(0, len(actual_environment[x]) - 1)
actual_environment[x][y] += 1
# Run A* and get a path
path = [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4),
(5, 5), (6, 6), (7, 7), (8, 8), (9, 9)] # dummy path
# Traverse path, checking for "new" obstacles
for step in path:
x, y = step[0], step[1]
# check area around agent
for (i, j) in product([-1, 0, 1], [-1, 0, 1]):
# don't bother checking out-of-bounds
if not 0 <= x + i < width:
continue
if not 0 <= y + j < height:
continue
# internal map doesn't match real world, update
if not known_environment[x + i][ y + j] == actual_environment[x + i][ y + j]:
known_environment[x + i][ y + j] = actual_environment[x + i][ y + j]
# Re-run A*
This works, but it feels inefficient. I'm thinking I could replace the loop with something like set(known_environment).intersection(actual_environment)
to check if there is a discrepancy, and then update if needed; but this can probably be improved upon as well.
Thoughts?
Edit: I've switched over to numpy slicing, and use array_equal instead of sets.
# check area around agent
left = x - sight if x - sight >= 0 else 0
right = x + sight if x + sight < width else width - 1
top = y - sight if y - sight >= 0 else 0
bottom = y + sight if y + sight < height else height - 1
known_section = known_environment[left:right + 1, top:bottom + 1]
actual_section = actual_environment[left:right + 1, top:bottom + 1]
if not np.array_equal(known_section, actual_section):
known_environment[left:right + 1, top:bottom + 1] = actual_section