Які алгоритми обчислюють напрямки від точки А до точки В на карті?


543

Як постачальники карт (наприклад, Google або Yahoo! Maps) пропонують вказівки?

Я маю на увазі, вони, мабуть, мають реальну інформацію в якійсь формі, звичайно, включаючи відстані, але також, можливо, такі речі, як швидкість руху, наявність тротуарів, розклад поїздів тощо. Але припустимо, дані були у більш простому форматі, скажімо, дуже великий спрямований графік з крайовими вагами, що відображають відстані. Я хочу мати можливість швидко обчислити напрямки від однієї довільної точки до іншої. Іноді ці точки будуть близько один від одного (в межах одного міста), а іноді вони будуть далеко один від одного (поперек).

Графічні алгоритми на зразок алгоритму Дейкстри не працюватимуть, оскільки графік величезний. На щастя, евристичні алгоритми на зразок A *, ймовірно, спрацюють. Однак наші дані дуже структуровані, і можливо, якийсь багаторівневий підхід може спрацювати? (Наприклад, зберігайте попередньо обчислені напрямки між певними "ключовими" точками далеко один від одного, а також деякими локальними напрямками. Тоді вказівки для двох віддалених точок включатимуть місцеві напрямки до ключових точок, глобальні напрямки до іншої ключової точки, а потім локальні вказівки знову.)

Які алгоритми реально використовуються на практиці?

PS. Це питання було мотивоване пошуку химерностей в напрямках онлайн-картографування. На відміну від нерівності трикутників, інколи Google Maps вважає, що XZ займає більше часу і довше, ніж використання проміжної точки, як у XYZ . Але, можливо, їх напрямки ходіння оптимізуються і для іншого параметра?

PPS. Ось ще одне порушення нерівності трикутників, що говорить (на мене) про те, що вони використовують якийсь багаторівневий підхід: XZ проти XYZ . Перший, здається, використовує видатний бульвар Севастополя, хоча він трохи не в дорозі.

Редагувати : Здається, жоден із цих прикладів більше не працює, але обидва вони робили під час первинної публікації.


3
BTW, алгоритм A * "- це узагальнення алгоритму Дейкстри, що зменшує розмір підграфа, який необхідно дослідити, якщо є додаткова інформація, яка забезпечує нижню межу на" відстані "до цілі"
Мітч Пшеничний

Re A *: так, справді. На щастя, у нашому випадку ця "додаткова інформація" доступна, наприклад, за допомогою прямолінійної відстані. Коли я кажу "Dijkstra" вище, я маю на увазі ванільну Dijkstra.
А. Рекс

Напрямки прогулянки? Не знаю ні про що, але тут (у Гемпширі, Великобританія) великий G не має пішохідних даних - він рухає мене по дорогах навколо пішохідних дільниць тощо. Єдине, що добре для цього - це зміни оцінки часу, витраченого на маршрут :)
jTresidder

Мені особливо не байдуже, чи напрямки для їзди чи пішки. Я просто хочу знати, як вони працюють! Причина, по якій я маю пішохідні зв’язки, полягає в тому, що я обчислював спосіб прогулятися по Парижу і побачити всі 66 фонтанів Уоллес. (Кінцевими точками цих карт повинні бути фонтани Уоллес.)
А. Рекс,

Завдання цього питання полягає у заохоченні більшої та кращої відповіді, особливо від людей, які працюють у одного з найбільших постачальників послуг. Коментарі щодо структур даних, алгоритмів, кількості попередніх обчислень тощо.
А. Рекс

Відповіді:


526

Виступаючи як хтось, хто 18 місяців працював у картографічній компанії, яка включала роботу над алгоритмом маршрутизації ... так, Dijkstra працює, з кількома модифікаціями:

  • Замість того, щоб робити один раз Дійкстра від джерела до місця, ви починаєте з кожного кінця і розгортаєте обидві сторони, поки вони не зустрінуться посередині. Це виключає приблизно половину роботи (2 * pi * (r / 2) ^ 2 vs pi * r ^ 2).
  • Щоб не досліджувати завулки кожного міста між вашим джерелом та пунктом призначення, ви можете мати кілька шарів даних карт: "Шосе", що містить лише шосе, "вторинний" шар, що містить лише вторинні вулиці тощо. Потім ви вивчаєте лише менші ділянки детальніших шарів, розширюючи за необхідності. Очевидно, цей опис залишає безліч деталей, але ви розумієте.

Завдяки модифікаціям у цих напрямках ви можете здійснювати навіть маршрутизацію між країнами у дуже розумні часові рамки.


29
Хтось, хто працював над цим у реальному світі, приголомшливий! Чи маєте ви уявлення про те, наскільки це можливо попередньо обчислити, як у статті про Google, згаданій в іншому коментарі?
А. Рекс

10
Ми не проводили жодної попередньої обробки такої природи, але це, безумовно, здається цікавою оптимізацією.
Нік Джонсон

29
"гарантується лише рішення, не обов'язково найефективніше". Це неправда; доки допустимий використаний евристик, алгоритм A * виробляє шлях з найменшими витратами. Допустима означає, що вартість ніколи не завищується, але вона може бути занижена (але погані оцінки уповільнюватимуть алгоритм). Використання даних попередньої обробки, ймовірно, допоможе покращити допустиму евристику, а отже, прискорити роботу A *.
a1kmm

6
Насправді, при подальшому розгляді, ви цілком праві. Ви можете вдосконалити існуючий алгоритм, щоб скористатися цим, просто додавши велику відстань кола між цільовим вузлом та пунктом призначення до вартості краю, що оцінюється. Я насправді не впевнений, чи зробив це наш алгоритм - але це дуже розумна оптимізація.
Нік Джонсон

11
A *, в гіршому випадку (евристика, яка говорить про те, що всі шляхи рівнозначні), точно дорівнює Джикстрі.
Тордек

111

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

Арахнід описав використання двонаправленого пошуку та обрізки краю на основі ієрархічної інформації. Ці методи прискорення працюють досить добре, але останні алгоритми всіма засобами перевершують ці методи. За існуючих алгоритмів найкоротші шляхи можна обчислити за значно менший час, ніж одна мілісекунда в континентальній дорожній мережі. Швидка реалізація немодифікованого алгоритму Дейкстри потребує близько 10 секунд .

Стаття Алгоритми планування швидкого маршруту дає огляд прогресу досліджень у цій галузі. Для отримання додаткової інформації див. Посилання цього документу.

Найшвидші відомі алгоритми не використовують інформацію про ієрархічний стан дороги в даних, тобто якщо це шосе або місцева дорога. Натомість вони на етапі попередньої обробки обчислюють власну ієрархію, оптимізовану для прискорення планування маршруту. Цей попередній обчислення може бути використаний для обрізання пошуку. Далеко від початкових та цільових доріг дороги не слід розглядати під час Алгоритму Дійкстри. Переваги - це дуже хороші показники та гарантія коректності результату.

Перші оптимізовані алгоритми планування маршруту стосувалися лише статичних дорожніх мереж, що означає, що край у графіку має фіксовану вартість витрат. На практиці це не вірно, оскільки ми хочемо врахувати динамічну інформацію, таку як пробки або обмежені обмеження транспортних засобів. Останні алгоритми також можуть вирішувати подібні проблеми, але проблеми, які необхідно вирішити, тривають, і дослідження тривають.

Якщо вам потрібні найкоротші відстані шляху для обчислення рішення для TSP , то вас, мабуть, цікавлять матриці, які містять усі відстані між джерелами та пунктами призначення. Для цього ви можете розглянути обчислення багато-до-багатьох найкоротших шляхів за допомогою ієрархій шосе . Зауважимо, що це було покращено новішими підходами за останні 2 роки.


1
Дійсно, освічуюче. Які нові підходи ви згадуєте?
Томаш Пайонк

1
Зокрема, Ієрархії скорочень. Докладніше про це можна знайти тут: algo2.iti.kit.edu/routeplanning.php . Про це також розмовляють google tech: youtube.com/watch?v=-0ErpE8tQbw
SebastianK

19

Просто вирішення питань нерівності трикутника, сподіваємось, додатковий фактор, який вони оптимізують, - це здоровий глузд. Ви не обов'язково бажаєте найкоротшого або найшвидшого шляху, оскільки це може призвести до хаосу та руйнування . Якщо ви хочете, щоб ваші вказівки надавали перевагу головним маршрутам, зручним для вантажних автомобілів, і можуть впоратися з тим, щоб кожен водій, який перебуває у режимі Sat-Nav, відправлений на них, ви швидко відкинете нерівність трикутника [1].

Якщо Y - вузька житлова вулиця між X і Z, ви, ймовірно, хочете скористатися ярликом лише через Y, якщо користувач явно запитує XYZ. Якщо вони просять XZ, вони повинні дотримуватися головних доріг, навіть якщо це трохи далі і займе трохи більше часу. Це схоже на парадокс Брейса - якщо кожен намагається пройти найкоротший, найшвидший маршрут, то виникаючий затор означає, що це вже не найшвидший шлях для когось. Звідси ми відходимо від теорії графів до теорії ігор.

[1] Насправді будь-яка надія на те, що отримані відстані будуть функцією відстані в математичному сенсі, вмирає, коли ви дозволяєте одностороннім дорогам і втрачаєте вимогу симетрії. Втрата нерівності трикутника теж просто втирання солі в рану.


14

Ось найшвидші в світі алгоритми маршрутизації порівняні та перевірені на правильність:

http://algo2.iti.uka.de/schultes/hwy/schultes_diss.pdf

Ось технічна бесіда в Google про цю тему:

http://www.youtube.com/watch?v=-0ErpE8tQbw

Ось реалізація алгоритму ієрархії шосе, як обговорювали Шчултес (наразі лише в Берліні, я пишу інтерфейс, а також розробляється мобільна версія):

http://tom.mapsforge.org/


9

Я раніше не працював у Google, Microsoft чи Yahoo Maps, тому не можу сказати, як вони працюють.

Однак я створив власну систему оптимізації ланцюгів поставок для енергетичної компанії, яка включала в себе програму планування та маршрутизації для їхнього парку вантажівок. Однак наші критерії щодо маршрутизації були набагато більш специфічними для бізнесу, ніж там, де будівництво чи сповільнення руху або закриття смуги руху.

Ми застосовували техніку під назвою ACO (оптимізація колонії мурашок) для розкладу та маршрутних вантажівок. Ця методика є методом AI, який застосовувався до проблеми мандрівного продавця для вирішення проблем маршрутизації. Трюк з ACO полягає в тому, щоб побудувати розрахунок помилок на основі відомих фактів маршрутизації, щоб модель вирішення графіків знала, коли потрібно вийти (коли помилка досить мала).

Ви можете знайти Google ACO або TSP, щоб дізнатися більше про цю техніку. Я для цього не використовував жодного інструменту AI з відкритим кодом, тому не можу запропонувати його (хоча я чув, що SWARM був досить вичерпним).


4
маршрутизація! = ч. л. в tsp ви знаєте всі відстані і оптимізуєте порядок зупинки - це не сенс для вказівки algo.
Каруссел

8

Графічні алгоритми на зразок алгоритму Дейкстри не працюватимуть, оскільки графік величезний.

Цей аргумент не обов'язково має місце, оскільки Dijkstra зазвичай не розглядає повний графік, а лише дуже малий підмножина (чим краще взаємопов’язаний графік, тим менший цей підмножина).

Дійкстра насправді може спрацьовувати досить добре для добре сприйнятих графіків. З іншого боку, ретельна параметризація A * завжди буде настільки ж хорошою чи кращою. Ви вже пробували, як це буде працювати з вашими даними?

З цього приводу мені також дуже цікаво почути досвід інших людей. Звичайно, особливо цікаві такі видатні приклади, як пошук у Google Map. Я міг уявити щось на кшталт спрямованого найближчого евристичного сусіда.


2
Припустимо, ви намагаєтеся знайти напрямки від точки А до В, оптимальна відстань для якої - d. Алгоритм Дейкстри, як мінімум, вивчить усі точки на відстані не більше d від A. Якщо A - Сан-Франциско, а B - Бостон, це означає, що він вивчає більшу частину США. N'est-ce pas?
А. Рекс

2
Так. Що я хотів досягти, це те, що A * можна використовувати замість цього і що він завжди знаходить оптимальне рішення (навіть якщо він використовує евристичний)!
Конрад Рудольф

Так, звісно. Після того, як я написав свій оригінальний пост, я подумав про слово "евристичний", яке я вжив. Тут трохи неточно, тому що він знаходить оптимальне рішення.
А. Рекс

2
Ну, справа в тому , що A * використовує евристичний (на відміну від того один) , щоб визначити наступний крок. Це одне рішення справді може бути неоптимальним. Але це впливає лише на час виконання, а не на результат, оскільки він лише визначає, наскільки краще, ніж Дійстра, здогадується.
Конрад Рудольф

8

Сучасний стан техніки з точки зору часу запитів для статичних дорожніх мереж - це алгоритм маркування Hub, запропонований Abraham et al. http://link.springer.com/chapter/10.1007/978-3-642-20662-7_20 . Нещодавно охарактеризований опис цього поля був нещодавно опублікований як технічний звіт Microsoft http://research.microsoft.com/pubs/207102/MSR-TR-2014-4.pdf .

Коротка версія ...

Алгоритм маркування Hub забезпечує найшвидші запити для статичних дорожніх мереж, але для запуску потрібна велика кількість таран (18 Гб).

Маршрутизація транзитного вузла є дещо повільнішою, хоча для цього потрібно лише близько 2 Гб пам'яті та швидший час попередньої обробки.

Ієрархії скорочень забезпечують приємну угоду між швидкими часом попередньої обробки, низькими вимогами до місця (0,4 ГБ) та швидкими часом запитів.

Жоден алгоритм не домінує повністю ...

Ця технологічна розмова від Google Пітера Сандерса може зацікавити

https://www.youtube.com/watch?v=-0ErpE8tQbw

Також це розмова Ендрю Голдберга

https://www.youtube.com/watch?v=WPrkc78XLhw

Реалізація ієрархій скорочень із відкритим кодом доступна на веб-сайті дослідницької групи Пітера Сандерса в KIT. http://algo2.iti.kit.edu/english/routeplanning.php

Також легкодоступна публікація в блозі, написана Microsoft про використання алгоритму CRP ... http://blogs.bing.com/maps/2012/01/05/bing-maps-new-routing-engine/


7

Я трохи здивований, що не бачу згаданого тут алгоритму Флойда Варшалла . Цей алгоритм роботи дуже схожий на Діккстра. Він також має одну дуже приємну особливість, яка дозволяє вам здійснювати обчислення до тих пір, як ви хочете продовжувати, дозволяючи отримати більше проміжних вершин. Таким чином, він, природно, знайде маршрути, які доволі швидко використовують міжміські шляхи або автошляхи.


6

Я робив це досить багато разів, власне, пробуючи кілька різних методів. Залежно від розміру (географічної) карти, ви можете розглянути можливість використання функції гаверсина як евристичну.

Найкращим рішенням я було використання A * з прямою відстані як евристична функція. Але тоді вам потрібні якісь координати для кожної точки (перетину чи вершини) на карті. Можна також спробувати різні ваги для евристичної функції, тобто

f(n) = k*h(n) + g(n)

де k - деяка константа, більша за 0.


4

Можливо, подібний до відповіді на попередньо обчислені маршрути між основними локаціями та шаруватими картами, але я розумію, що в іграх, щоб пришвидшити A *, ви маєте карту, яка є дуже грубою для макро-навігації, і дрібнозернисту карту для навігація до межі макронапрямків. Отже, у вас є дві невеликі стежки для обчислення, а значить, і пошуковий простір набагато набагато менший, ніж просто проходження одного шляху до пункту призначення. І якщо ви займаєтеся цим великим завданням, у вас буде багато цих даних, попередньо обчислених, тому принаймні частина пошуку - це пошук попередньо обчислених даних, а не пошук шляху.


3

З мого боку це суто міркування, але я припускаю, що вони можуть використовувати структуру даних карти впливу, що накладає спрямовану карту, щоб звузити область пошуку. Це дозволило б алгоритму пошуку направляти шлях до основних маршрутів, коли бажана поїздка тривала.

Зважаючи на те, що це додаток Google, також розумно припустити, що велика кількість магії робиться за допомогою широкого кешування. :) Я не був би здивований, якщо кешування найпоширеніших запитів маршрутів на Картах Google дозволяється на великий фрагмент (20%? 50%?) Запитів, щоб відповісти простим пошуком.


Чи є у вас гарне посилання на "структуру даних карти впливу"? Дякую!
А. Рекс

3

У мене було ще кілька думок з цього приводу:

1) Пам'ятайте, що карти являють собою фізичну організацію. Зберігайте широту / довготу кожного перехрестя. Вам не потрібно перевіряти набагато більше точок, які лежать у напрямку до вашої цілі. Тільки якщо ви опинитесь заблокованими, вам потрібно вийти за рамки цього. Якщо ви зберігаєте накладку вищих підключень, ви можете обмежити її ще більше - зазвичай ви ніколи не переходите через один із них таким чином, що відходить від вашого кінцевого пункту призначення.

2) Розділіть світ на цілу купу зон, визначених обмеженою сполучністю, визначте всі точки зв’язку між зонами. Знайдіть, в яких зонах знаходиться ваше джерело та ціль, для маршруту початку та кінця зони від вашого місцезнаходження до кожної точки з'єднання, для зон між простою картографією між точками з'єднання. (Я підозрюю, що багато останнього вже попередньо розраховано.)

Зауважте, що зони можуть бути меншими за мегаполіс. Будь-яке місто, яке має особливості рельєфу місцевості (скажімо, річку), було б декількома зонами.


3

Мені було дуже цікаво використана евристика, коли деякий час назад ми отримали маршрути від того самого початкового місця поблизу Санта-Рози, до двох різних таборів у національному парку Йосеміті. Ці різні напрямки виробляли досить різні маршрути (через I-580 або CA-12), незважаючи на те, що обидва маршрути сходилися протягом останніх 100 миль (уздовж CA-120), перш ніж знову розходитися на кілька миль в кінці. Це було цілком повторюваним. Два маршрути були відстані до 50 миль на відстані близько 100 миль, але відстані / часи були досить близькими один до одного, як можна було очікувати.

На жаль, я не можу це відтворити - алгоритми повинні бути змінені. Але мене цікавить алгоритм. Я можу тільки припустити, що відбулася деяка спрямована обрізка, яка, як виявилося, надзвичайно чутлива до крихітної кутової різниці між напрямками, як видно здалеку, або були різні попередньо обчислені сегменти, обрані вибором кінцевого пункту призначення.


3

Говорячи про GraphHopper , швидкому планувальнику маршрутів з відкритим кодом, заснованому на OpenStreetMap, я прочитав трохи літератури та застосував деякі методи. Найпростішим рішенням є Dijkstra, а просте вдосконалення - двонаправлений Dijkstra, який досліджує приблизно лише половину вузлів. З двонаправленим Dijkstra маршрут по всій Німеччині займає вже 1 сек (для автомобільного режиму), в C це було б, мабуть, лише 0,5s або близько того;)

Я створив анімовані GIF реального пошуку шляху з двонаправленими Дейкстрой тут . Також є ще кілька ідей зробити Dijkstra швидше, як робити A *, що є "орієнтованим на ціль Dijkstra". Також я створив для нього gif-анімацію .

Але як це зробити (набагато) швидше?

Проблема полягає в тому, що для пошуку шляху слід вивчити всі вузли між локаціями, і це дійсно дорого, оскільки вже в Німеччині їх є кілька мільйонів. Але додатковою больовою точкою Dijkstra тощо є те, що для таких пошуків використовується багато оперативної пам’яті.

Існують евристичні рішення, але також точні рішення, які організують графік (дорожню мережу) в ієрархічних шарах, мають і плюси, і в основному вирішують проблему швидкості та оперативної пам'яті. Я перерахував деякі з них у цій відповіді .

Для GraphHopper я вирішив використати ієрархії скорочень, оскільки це відносно "легко" для реалізації та не займає віків для підготовки графіка. Це все ще призводить до дуже швидких моментів реакції, як ви можете протестувати в нашому інтернет-екземплярі GraphHopper Maps . Наприклад, з південної Африки до східного Китаю, що призводить до відстані 23000 км і майже 14 днів часу для автомобіля, а сервер займає лише 0,1 секунди.


Двонаправлений Дійкстра, який використовує Орієнтири для здійснення цільового пошуку, є більш ефективним, ніж Двонаправлений Дийкстра. Див. Www14.informatik.tu-muenchen.de/lehre/2010SS/sarntal/… Однак цей документ недостатньо деталізований для обчислення потенційної функції, яка є трохи хитрою, або вибору орієнтирів.
Пол Черноч

2

Я працював над маршрутизацією протягом декількох років, коли нещодавній сплеск діяльності викликав потреби моїх клієнтів, і я виявив, що A * досить швидко; насправді не потрібно шукати оптимізації чи складніших алгоритмів. Маршрут на величезному графіку не є проблемою.

Але швидкість залежить від наявності всієї мережі маршрутизації, під якою я маю на увазі спрямований графік дуг і вузлів, що представляють відповідно сегменти маршруту та з'єднання відповідно. Основний накладний час - це час, необхідний для створення цієї мережі. Деякі приблизні цифри, засновані на звичайному ноутбуці під керуванням Windows та маршрутизації по всій Іспанії: час, необхідний для створення мережі: 10-15 секунд; час, необхідний для обчислення маршруту: занадто короткий для вимірювання.

Інша важлива річ - це можливість повторно використовувати мережу для стількох розрахунків маршрутизації, скільки вам подобається. Якщо ваш алгоритм позначав вузли якимось чином для запису найкращого маршруту (загальна вартість поточного вузла та найкраща дуга до нього) - як це має бути в A * - вам доведеться скинути або очистити цю стару інформацію. Замість того, щоб пройти сотні тисяч вузлів, простіше використовувати систему числення поколінь. Позначте кожен вузол номером генерації його даних; збільшити номер генерації під час обчислення нового маршруту; будь-який вузол із номером старшого покоління є несвіжим, його інформацію можна ігнорувати.


1

Я бачу, що відбувається з картами в ОП:

Подивіться на маршрут із вказаною проміжною точкою: Маршрут йде трохи назад, тому що дорога не пряма.

Якщо їх алгоритм не відхилиться, він не побачить коротший маршрут.


Цікава ідея. Я додав ще одне порушення в моєму PPS до ОП. Будь ласка, подивіться і побачите, чи можете ви побачити там пояснення.
А. Рекс

Збільшити ШЛЯХ вниз на точку А - одним клацанням від макс. Зверніть увагу, як триточковий маршрут йде на захід, південь, схід. Я думаю, що ми дивимось на алгоритм, який не любить відслідковувати, якщо тільки не потрібно було проходити точку руху.
Лорен Печтел

У моєму прикладі PPS змініть вихідну адресу на "10 Avenue de Flandre, 75019 Paris". Це видаляє маленький зворотний твір, про який ви говорите, але проблема все ще існує. Я думаю, що головне питання полягає в тому, що він дійсно хоче залишитися на головному бульварі ...
А. Рекс

1
Я думаю, що я виявив це в цьому випадку: чи мають це на автомобілі і терміни мають сенс. Він, мабуть, бачить велику дорогу як швидшу, і пішохідний маршрут не заважає.
Лорен Печтел

1
PS: Початкова проблема також має сенс у цьому стандарті, можливо, це не зворотний трек, який її спричинив.
Лорен Печтел

0

Алгоритм найкоротшого шляху для всіх пар обчислює найкоротші шляхи між усіма вершинами в графі. Це дозволить попередньо обчислити шляхи, а не вимагати обчислення шляху кожного разу, коли хтось захоче знайти найкоротший шлях між джерелом та пунктом призначення. Алгоритм Флойда-Варшалла - алгоритм найкоротшого шляху з усіма парами.


-4

Карти ніколи не враховують всю карту. Я здогадуюсь: - 1. Відповідно до вашого місцезнаходження, вони завантажують місце та орієнтири на цьому місці. 2. Під час пошуку місця призначення, коли вони завантажують іншу частину карти і складають графік з двох місць, а потім застосовують алгоритми найкоротшого шляху.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.