Який найкращий спосіб зобразити та розв’язати лабіринт із заданим зображенням?
З огляду на зображення JPEG (як показано вище), який найкращий спосіб прочитати його, розібрати його в якусь структуру даних та вирішити лабіринт? Перший мій інстинкт - прочитати зображення в пікселі за пікселем і зберігати його у списку (масиві) булевих значень: True
для білого пікселя та False
для небілого пікселя (кольори можна відкинути). Проблема цього методу полягає в тому, що зображення може бути не "ідеальним для пікселів". Під цим я просто маю на увазі, що якщо є білий піксель десь на стіні, він може створити ненавмисний шлях.
Інший метод (який прийшов до мене після трохи роздумів) - це перетворити зображення у файл SVG - це список контурів, намальованих на полотні. Таким чином, шляхи можна прочитати в одному списку (булеві значення), де True
вказується шлях або стіна, що False
вказує простір , який може подорожувати. Проблема з цим методом виникає, якщо перетворення не є на 100% точним і не повністю з'єднує всі стіни, створюючи прогалини.
Також проблема при перетворенні на SVG полягає в тому, що лінії не є "ідеально" прямими. Це призводить до того, що шляхи становлять кубічні криві Безьє. Зі списком (масивом) булевих значень, індексованим цілими числами, криві не перенесуться легко, і всі точки, що знаходяться на кривій, повинні бути обчислені, але точно не збігаються з індексами списку.
Я припускаю, що хоча один із цих методів може працювати (хоча, мабуть, ні), вони дуже неефективні, враховуючи таке велике зображення, і існує кращий спосіб. Як це найкраще (найефективніше та / або з найменшою складністю) зробити? Чи існує навіть найкращий спосіб?
Потім настає розв’язання лабіринту. Якщо я використовую будь-який з перших двох методів, я, по суті, закінчую матрицею. Відповідно до цієї відповіді , хорошим способом представити лабіринт є використання дерева, а хороший спосіб вирішити це - за допомогою алгоритму A * . Як можна створити дерево із зображення? Будь-які ідеї?
TL; DR
Найкращий спосіб розбору? У яку структуру даних? Як сказана структура допоможе / перешкодить вирішенню?
ОНОВЛЕННЯ
Я намагався реалізувати те, що @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, [])
visited.append(s)
під a for.if
і замінити його visited.append(np)
. Вершина відвідується після її додавання до черги. Насправді цей масив повинен бути названий "в черзі". Ви також можете припинити BFS, як тільки доїдете до фінішу.