Реализация A * на треугольной / гексагональной сетке с отрицательными координатами - PullRequest
1 голос
/ 09 мая 2011

Следуя очевидной традиции использования этого вопроса в качестве основы для новых вопросов, у меня тоже есть проблема, которую я хочу решить как можно более элегантно:

Я реализовал гексагональную карту как таковую:

(хотел вставить изображение здесь .. но мне не разрешено из-за того, что я новичок ... Пожалуйста, смотрите ссылку выше)

Но теперь мне интересно, как (элегантно) реализовать A * для этого типа карты с этими типами координат. У меня есть опыт использования A * на типичных сетках в квадрате (я думаю, что это декартовы сетки), и способ его обработки там несовместим с этой системой координат.

Обычно я генерирую двумерный массив байтов. Индексы массива будут соответствовать координатной сетке, а значение в указанном индексе даст «вес» этого узла. (0 - невозможность, и более высокие числа «весят» больше, чем более низкие).

Пример: sbyte[,] pathGrid = new sbyte[5, 5] { {0,0,1,0,0}, {9,5,1,3,0}, {9,5,1,3,0}, {9,5,1,3,0}, {0,0,1,0,0} };

Там, где 0 были бы непроходимы, 1 легко пересекаются, а более высокие числа «обходятся» дороже. (извините за форматирование .. Я переполнение стека newb: P) Этот массив будет сгенерирован на основе композиции моей карты и затем передан в мой алгоритм поиска пути, который, в свою очередь, выдаст список узлов (путь) или вернет ноль, если путь не найден.

Однако, используя этот тип сетки, это невозможно (по крайней мере, на первый взгляд) из-за отрицательных координат (которые явно не работают в массиве) и того факта, что сетка не следует тем же правилам как «типичная» сетка.

Есть способы решить эту проблему, используя мой метод A *, я думаю, но все они довольно небрежны (преобразование координат сетки и использование пустых узлов), и мне было интересно, если кто-нибудь задумывался о способе сделать это элегантно.

Спасибо за чтение в любом случае :) (Кстати, я делаю это в C # /. Net за то, что это стоит)

Ответы [ 2 ]

2 голосов
/ 09 мая 2011

Даже если индексы массива начинаются с 0, вашей программе не нужно концептуально обрабатывать массивы таким образом.Например, если вы всегда добавляете, например, 3 к своим индексам, прежде чем использовать их для поиска в массиве, у вас фактически есть массив, где индексы начинаются с 3. Чтобы упростить работу с массивами таким образом, вы можете создать класснапример, ArbitraryBaseArray, который упаковывает массив и число, указывающее требуемый базовый индекс.

Затем вы можете создать класс HexGrid, который содержит массив ArbitraryBaseArray, каждый из которых имеет собственный базовый индекс.(в зависимости от того, как выглядит левый край вашей шестнадцатеричной области).Класс может иметь индексатор, который позволяет вам искать конкретный элемент на основе двух шестнадцатеричных координат.Он также может иметь статический метод, который, учитывая координату в шестнадцатеричной сетке, возвращает массив с шестью соседними координатами;этот метод может быть использован A *.(Обратите внимание, что хотя иллюстрация в вопросе, с которым вы связались, использует три координаты для каждой шестнадцатеричной плитки, достаточно двух координат.)

0 голосов
/ 09 мая 2011

Вы можете сохранить свои координаты в словаре:

var nodes = new Dictionary<Point, Vector[]>;

Таким образом, вы не ограничены положительными координатами, а также не ограничены количеством путей из каждого узла

...