Поиск пути в 2D: комбинации точек маршрута для перехода от curLocation к targetLocation

Пожалуйста, найдите минутку, чтобы понять мою ситуацию. Если это не понятно, пожалуйста, сообщите мне в комментарии.

У меня есть ArrayList путевых точек. Эти путевые точки не в любом порядке. Путевая точка имеет следующие свойства:
{int type, float z, float y, float x, float rotation}

Это применимо к трехмерному миру, но поскольку мой поиск пути не должен заботиться о высоте (и, таким образом, рассматривать мир как двумерный), значение y игнорируется. Ротация не имеет значения для этого вопроса.

  • В этом двухмерном мире х представляет ось х, а z представляет ось у.
  • Если x увеличивается, объект в мире перемещается на восток. Если x уменьшается, объект в мире движется на запад.
  • Если z увеличивается, объект в мире перемещается на север. Если z уменьшается, объект в мире перемещается на юг.

Таким образом, эти «новые» путевые точки можно упростить до: waypoint = {float x, float y}.

Теперь эти путевые точки представляют расположение объекта по оси X (x) и по оси Y (z). Кроме того, есть текущее местоположение: curLocation = {float x, float y} и целевое местоположение: tarLocation = {float x, float y}.

Вот что я хочу получить:
Все комбинации путевых точек (иначе: пути или маршруты), которые ведут из curLocation в tarLocation при следующих строгих условиях:

  1. Расстояние между каждой путевой точкой не может превышать (float) maxInbetweenDistance. Сюда входит начальное расстояние от curLocation до первой путевой точки и расстояние от последней путевой точки до tarLocation. Если такая комбинация путевых точек невозможна, следует вернуть null.
  2. Если в пределах maxInbetweenDistance найдено несколько путевых точек от путевой точки, ведущих к целевой путевой точке, следует выбрать ближайшую путевую точку (еще лучше было бы, если альтернативная путевая точка, которая немного дальше, приведет к новому пути с более длинным расстоянием, который также вернулся).
  3. Порядок возвращаемых комбинаций путевых точек (путей) должен быть от кратчайшего маршрута (минимальное расстояние) до самого длинного маршрута (максимальное расстояние).

Наконец, обратите внимание на следующие моменты:

  1. Это единственное, что мне нужно для ИИ/поиска пути, поэтому я не хочу использовать полноценную систему поиска пути или ИИ. Я считаю, что одна функция должна быть в состоянии справиться с вышеизложенным.
  2. Если возврат всех возможных комбинаций путевых точек вызывает слишком много накладных расходов, также было бы хорошо, если бы можно было указать максимальное количество комбинаций (но все же в порядке от ближайшего к самому дальнему). Например. 5 ближайших путей.

Как бы я этого добился? Любая обратная связь приветствуется.


person Tom    schedule 04.03.2011    source источник


Ответы (3)


Я думаю, что ваше решение состоит в том, чтобы начать с алгоритма Дейкстры, чтобы найти кратчайший путь первый. Вы можете рассматривать свои путевые точки как связанный граф, в котором узлы соединены, если они достаточно близки в плоскости xy, а затем применить Дейкстру (в Интернете есть много примеров списков кода).

Теперь у вас есть кратчайший путь через ваш граф от начала до конца, который будет состоять из N ребер графа.

Затем вам нужно будет создать N новых графиков, каждый из которых будет точно таким же, как первый, но с одним несоединенным сегментом кратчайшего маршрута. Найдите кратчайшие маршруты от начала до конца на этих модифицированных графиках. Теперь у вас есть N+1 маршруты, которые вы можете отсортировать по длине.

Повторяйте это до тех пор, пока не найдете достаточно путей для своих нужд или не останется неранжированных путей.

Я не нашел названия для этой техники, но она описана как модификация Дейкстры здесь. .

person Matthew Gilliard    schedule 04.03.2011

Если ваши путевые точки имеют возможность подключения, вам следует взглянуть на алгоритм кратчайшего пути Дейкстры. В первой паре запросов Google даже указана реализация на Java. (Я не могу сказать, известна ли связь из поста, но он содержит тег «граф-алгоритм», поэтому я предполагаю, что да). Как следует из названия, этот метод дает вам кратчайший путь между двумя узлами.

Ваши ограничения сложны, как и необходимость всех возможных комбинаций путей при этих ограничениях. Опять же, при условии, что связь существует, ваша матрица смежности узлов может обеспечить соблюдение вашего правила maxInbetweenDistance. Точно так же вы можете использовать эту матрицу для получения «следующих лучших» решений. Как только оптимальный путь известен, вы можете пометить этот путь (или его элементы) как недоступные, а затем повторно запустить алгоритм Дейкстры. Повторяя этот процесс, вы можете получить набор все более неоптимальных путей.

Условно: в большинстве задач вычислительной геометрии Z — это высота, а горизонтальная плоскость образована осями XY.

person Throwback1986    schedule 04.03.2011
comment
Спасибо, кто-то еще добавил тег графического алгоритма. Я не уверен, что именно вы имеете в виду под подключением, поэтому я полагаю, что его не существует (?). - person Tom; 04.03.2011
comment
Связность — это просто свойство, при котором одни узлы связаны с другими. Другими словами, есть некоторые узлы, до которых вы не можете добраться за один прыжок, а до некоторых можно. Ваше первое условие strict подразумевает, что у вас есть связный граф. - person Matthew Gilliard; 04.03.2011
comment
@ mjg123 mjg123, я думаю, что все узлы, которые находятся рядом друг с другом, должны быть подключены. Однако на данный момент ничего подобного не установлено. - person Tom; 04.03.2011
comment
Тем не менее, алгоритм Дейкстры покажет вам только кратчайший путь, он не даст вам список коротких путей в порядке длины. - person Matthew Gilliard; 04.03.2011
comment
@ mjg123 mjg123 все в порядке, так как я могу повторить процесс без предыдущего пути, если мне нужен другой вариант. Пока я нашел полную реализацию только в довольно большой библиотеке (JUNG). - person Tom; 04.03.2011
comment
Я предположил, что близость не подразумевает возможности соединения. Другими словами, два узла могут быть рядом, но между ними нет пути. Несмотря на это, Дийсктра может применяться. - person Throwback1986; 04.03.2011
comment
@ Throwback1986 Знаете ли вы об облегченной (но проверенной) реализации для Java алгоритма кратчайшего пути Дейкстры? - person Tom; 05.03.2011

Ну, проще всего реализовать, вероятно, создание ArrayList путей, который, в свою очередь, будет ArrayList путевых точек, который содержит ВСЕ возможные пути, а затем использовать рекурсивную функцию для возврата того, является ли каждый путь действительным или нет с учетом начальной и конечной точки. значения и максимальное расстояние, а если путь недействителен, удалите его из списка. Следующим шагом будет прохождение каждого из оставшихся путей и упорядочение их от кратчайшего общего расстояния к кратчайшему. Это был бы метод грубой силы для получения того, что вы хотите, поэтому наименее эффективный из возможных. Когда я вернусь домой сегодня вечером, я сделаю репост, если у кого-то еще нет более эффективного метода для этого в java.

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

person keepitreall89    schedule 04.03.2011
comment
Интересно, но я боюсь, что это действительно слишком много грубой силы, так как это создало бы безумное количество возможностей (представьте себе формирование комбинаций с 500 путевыми точками). Я с нетерпением жду вашего обновления, хотя (если применимо). Спасибо. - person Tom; 04.03.2011
comment
Если у вас 500 узлов то это сложная задача с любой техникой! Тем более, что вы, похоже, не исключили пути с петлями (возможно, я не уверен, что понимаю условие № 2) - person Matthew Gilliard; 04.03.2011
comment
@ mjg123 # 2 просто указывает, что он должен выбрать кратчайший маршрут. Я понимаю, что гораздо проще найти только самый береговой путь. Я считаю, что это тоже будет хорошо (потому что я могу повторить процесс без возвращаемого пути, чтобы найти, например, второй кратчайший путь). - person Tom; 05.03.2011
comment
Тогда у вас есть решение :) - person Matthew Gilliard; 05.03.2011
comment
@ mjg123, я не совсем уверен, понимаю ли я использование алгоритма. Я прочитаю об этом больше и приму ответ, если это действительно то, что мне нужно. - person Tom; 05.03.2011
comment
@ mjg123, добавил комментарий к вашему ответу. - person Tom; 05.03.2011