Карта маршрутизации, а-ля Google Maps? - PullRequest
19 голосов
/ 06 августа 2008

Я всегда был заинтригован маршрутизацией карты, но я никогда не нашел хороших учебников начального (или даже продвинутого!) Уровня. У кого-нибудь есть какие-либо указатели, подсказки и т. Д.?

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

Ответы [ 9 ]

14 голосов
/ 06 августа 2008

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

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

4 голосов
/ 25 сентября 2008

A * на самом деле гораздо ближе к производственным картографическим алгоритмам. Требуется немного меньше исследований по сравнению с оригинальным алгоритмом Диджикстры.

4 голосов
/ 17 сентября 2008

Барри Брумитт (Barry Brumitt), один из инженеров функции поиска маршрутов карт Google, написал сообщение на эту тему, которое может представлять интерес:

Путь к лучшему поиску пути 06.11.2007 03:47:00

4 голосов
/ 15 августа 2008

Под Map Routing вы имеете в виду поиск кратчайшего пути по уличной сети?

Алгоритм кратчайшего пути Дейкстры является самым известным. В Википедии неплохое вступление: http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

Здесь есть Java-апплет, где вы можете увидеть его в действии: http://www.dgp.toronto.edu/people/JamesStewart/270/9798s/Laffra/DijkstraApplet.html и Google вы приведете вас к исходному коду практически на любом языке.

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

2 голосов
/ 26 сентября 2008

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

Конечно, алгоритм должен искать некоторую пропорцию из n ^ 2 путей по мере увеличения расстояния n. Вы бы заняли исходную позицию и проверили все доступные пути с этой точки. Затем рекурсивно вызывайте точки в конце этих путей и т. Д.

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

Альтернативным способом является использование подхода с феромонами муравьев, когда муравьи ползут случайным образом из начальной точки и оставляют след, который накапливает больше муравьев, пересекающих данный путь. Если вы отправите (достаточно) муравьев как из начальной, так и из конечной точек, то в конечном итоге путь с самым сильным запахом будет самым коротким. Это связано с тем, что самый короткий путь будет посещаться больше раз за определенный период времени, учитывая, что муравьи ходят с одинаковой скоростью.

РЕДАКТИРОВАТЬ @ Spikie

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

Вам нужно будет сохранить карту как сеть. Это просто набор nodes и edges между ними. Набор nodes составляет route. Край соединяет два узла (возможно, оба и тот же узел) и имеет связанный cost, такой как distance или time, для прохождения края. Край может быть либо двунаправленным, либо однонаправленным. Вероятно, проще всего иметь однонаправленные и удвоить для двухстороннего перемещения между узлами (то есть один край от А до В и другой для В от А).

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

Отметьте узлы, начиная снизу слева, слева направо и вверх, как A, B, C, D, E, F (F вверху).

Предположим, что края могут проходить в любом направлении. Каждый край имеет стоимость 1 км.

Хорошо, поэтому мы хотим проложить маршрут от левого нижнего A к верхней станции F. Есть много возможных маршрутов, в том числе те, которые удваиваются назад, например, ABCEBDEF.

У нас есть рутина, скажем, NextNode, которая принимает node и cost и вызывает себя для каждого узла, к которому она может перейти.

Очевидно, что если мы позволим этой подпрограмме выполняться, она в конечном итоге обнаружит все маршруты, включая потенциально бесконечные по длине (например, ABABABAB и т. Д.). Мы не допустим этого, сверяясь с cost. Всякий раз, когда мы посещаем узел, который ранее не посещался, мы сравниваем стоимость и узел, с которого пришли, с этим узлом. Если узел был посещен до того, как мы проверим его по существующей стоимости, и если мы дешевле, мы обновим узел и продолжим (рекурсивный). Если мы дороже, тогда мы пропускаем узел. Если все узлы пропущены, мы выходим из процедуры.

Если мы дойдем до нашего целевого узла, то также выйдем из подпрограммы.

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

Чтобы получить маршрут, мы работаем в обратном направлении от нашего целевого узла. Так как мы сохранили узел, из которого мы пришли, вместе со стоимостью, мы просто прыгнули назад, создавая маршрут. Для нашего примера мы получим что-то вроде:

Узел A - (Всего) Стоимость 0 - От Узла Нет
Узел B - Стоимость 1 - От Узла A
Узел C - Стоимость 2 - От Узла B
Узел D - Стоимость 1 - От Узла A
Узел E - Стоимость 2 - От Узла D / Стоимость 2 - От Узла B (это исключение, поскольку существует равная стоимость)
Узел F - Стоимость 2 - От Узла D

Итак, самый короткий маршрут - АПД.

2 голосов
/ 17 сентября 2008

Мне еще не удалось найти хорошее руководство по маршрутизации, но есть много кода для чтения:

Существуют приложения маршрутизации GPL, которые используют данные Openstreetmap, например, Gosmore , который работает в Windows (+ mobile) и Linux. Существует ряд интересных [приложений, использующих одни и те же данные, но у gosmore есть несколько интересных применений например. интерфейс с сайтами .

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

2 голосов
/ 06 августа 2008

Вместо изучения API для каждого поставщика картографических услуг (например, Gmaps, Ymaps api) полезно изучать Mapstraction

"Mapstraction - это библиотека, предоставляющая общий API для различных API отображения javascript"

Я бы посоветовал вам перейти по URL и изучить общий API. Существует также много How-Tos.

1 голос
/ 16 июля 2012

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

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

Сам алгоритм A * хорошо документирован в Википедии . Ключевым местом для оптимизации является выбор лучшего узла из открытого списка, для которого вам нужна высокопроизводительная очередь с приоритетами. Если вы используете C ++, вы можете использовать адаптер STL priority_queue.

Настройка алгоритма для маршрутизации через различные части сети (например, пешеход, автомобиль, общественный транспорт и т. Д.) С учетом скорости, расстояния или других критериев довольно проста. Вы делаете это путем написания фильтров, чтобы контролировать, какие сегменты маршрута доступны, при построении сети и какой вес назначен каждому.

1 голос
/ 19 сентября 2011

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

Пример: В соответствии с GoogleMaps, я могу (где я живу) пойти тремя путями, чтобы добраться из пункта А в пункт B. Подразделения Garmin предлагают каждый из этих 3 путей в расчете маршрута Quickest. После многократного прохождения каждого из этих маршрутов и усреднения (очевидно, будут ошибки в зависимости от времени суток, количества кофеина и т. Д.), Я считаю, что алгоритмы могут учитывать количество поворотов на дороге для обеспечения высокого уровня точности , Например, Прямая дорога длиной в 1 милю будет быстрее, чем дорога в 1 милю с острыми поворотами . Не практическое предложение, но, конечно, я использую его для улучшения набора результатов моих ежедневных поездок.

...