Каков наилучший способ представления и решения лабиринта с учетом изображения?
Учитывая изображение в формате JPEG (как показано выше), какой лучший способ его прочитать, проанализировать его в некоторой структуре данных и решить лабиринт? Мой первый инстинкт - прочитать изображение в пикселях по пикселям и сохранить его в списке (массиве) логических значений: True
для белого пикселя и False
для небелого пикселя (цвета могут быть отброшены), Проблема с этим методом заключается в том, что изображение не может быть "идеальным пикселем". Под этим я просто подразумеваю, что если есть белый пиксель где-то на стене, он может создать непреднамеренный путь.
Еще один способ (который пришел ко мне после некоторого раздумья) - преобразовать изображение в SVG файл - это список путей, нарисованных на холсте. Таким образом, пути могут быть прочитаны в один и тот же список (логические значения), где True
указывает путь или стену, False
, указывающий пространство, способное путешествовать. Проблема с этим методом возникает, если преобразование не является на 100% точным и не полностью соединяет все стены, создавая пробелы.
Также проблема с преобразованием в SVG заключается в том, что строки не "идеально" прямые. Это приводит к тому, что пути являются кубическими кривыми безье. С помощью списка (массива) логических значений, индексированных целыми числами, кривые не будут переноситься легко, и все точки, которые строятся на кривой, должны быть вычислены, но не будут точно соответствовать индексам списка.
Я предполагаю, что хотя один из этих методов может работать (хотя, вероятно, и нет), что они очень неэффективны при таком большом изображении и что существует лучший способ. Как это лучше (наиболее эффективно и/или с наименьшей сложностью)? Есть ли лучший способ?
Затем приходит решение лабиринта. Если я использую один из первых двух методов, я, по сути, получаю матрицу. Согласно этому ответу, хорошим способом представления лабиринта является использование дерева, и хорошим способом его решения является использование алгоритм A *. Как создать дерево из изображения? Любые идеи?
TL; DR
Лучший способ разобрать? В какую структуру данных? Как бы упомянутая структура помогла/препятствовала решению?
UPDATE
Я попробовал свои силы при реализации того, что @Mikhail написал на Python, используя numpy
, как рекомендовал @Thomas. Я чувствую, что алгоритм правильный, но он не работает, как надеялся. (Код ниже.) Библиотека PNG PyPNG.
import png, numpy, Queue, operator, itertools
def is_white(coord, image):
""" Returns whether (x, y) is approx. a white pixel."""
a = True
for i in xrange(3):
if not a: break
a = image[coord[1]][coord[0] * 3 + i] > 240
return a
def bfs(s, e, i, visited):
""" Perform a breadth-first search. """
frontier = Queue.Queue()
while s != e:
for d in [(-1, 0), (0, -1), (1, 0), (0, 1)]:
np = tuple(map(operator.add, s, d))
if is_white(np, i) and np not in visited:
frontier.put(np)
visited.append(s)
s = frontier.get()
return visited
def main():
r = png.Reader(filename = "thescope-134.png")
rows, cols, pixels, meta = r.asDirect()
assert meta['planes'] == 3 # ensure the file is RGB
image2d = numpy.vstack(itertools.imap(numpy.uint8, pixels))
start, end = (402, 985), (398, 27)
print bfs(start, end, image2d, [])