Comment les fournisseurs de cartes (tels que Google ou Yahoo! Maps) suggèrent-ils des itinéraires?
Je veux dire, ils ont probablement des données réelles sous une forme quelconque, incluant certainement les distances mais aussi des choses comme la vitesse de conduite, la présence de trottoirs, les horaires de train, etc. Mais supposons que les données soient dans un format plus simple, disons un très grand graphe dirigé avec des poids de bord reflétant des distances. Je veux être capable de calculer rapidement les directions d'un point à un autre. Parfois, ces points seront proches les uns des autres (dans une même ville), parfois ils seront éloignés l'un de l'autre (cross-country).
Les algorithmes graphiques tels que celui de Dijkstra ne fonctionneront pas car le graphique est énorme. Heureusement, des algorithmes heuristiques comme A * fonctionneront probablement. Cependant, nos données sont très structurées et peut-être une approche à plusieurs niveaux pourrait-elle fonctionner? (Par exemple, stockez les directions précalculées entre certains points "clés" éloignés les uns des autres, ainsi que certaines directions locales. Ensuite, les directions relatives à deux points éloignés impliqueront des directions locales vers un point clé, des directions globales vers un autre point clé, puis des informations locales. directions à nouveau.)
Quels algorithmes sont réellement utilisés dans la pratique?
PS Cette question a été motivée par la recherche de bizarreries dans les directions cartographiques en ligne. Contrairement à l'inégalité triangulaire, Google Maps pense parfois que X-Z prend plus de temps et est plus loin que d'utiliser un point intermédiaire comme dans X-Y-Z . Mais peut-être que leurs directions de marche optimisent aussi pour un autre paramètre?
PPS. Voici une autre violation de l'inégalité triangulaire qui suggère (selon moi) qu'ils utilisent une sorte d'approche à plusieurs niveaux: X-Z versus X-Y-Z . Le premier semble utiliser le boulevard de Sébastopol bien qu’il soit légèrement à l’écart.
Edit : Aucun de ces exemples ne semble plus fonctionner, mais les deux le faisaient au moment de la publication d'origine.
Parlant en tant que personne ayant travaillé pendant 18 mois dans une société de cartographie, ce qui comprenait le travail sur l'algorithme de routage ... oui, Dijkstra fonctionne, avec quelques modifications:
Avec des modifications allant dans ce sens, vous pouvez même effectuer un routage entre pays dans des délais très raisonnables.
Cette question a été un domaine de recherche actif ces dernières années. L’idée principale est de faire un prétraitement sur le graphique une fois , puis accélérer toutes les requêtes suivantes . Avec cette information supplémentaire, les itinéraires peuvent être calculés très rapidement. Néanmoins, l'algorithme de Dijkstra est la base de toutes les optimisations.
Arachnid a décrit l'utilisation de la recherche bidirectionnelle et de l'élagage Edge en fonction d'informations hiérarchiques. Ces techniques d'accélération fonctionnent assez bien, mais les algorithmes les plus récents surpassent ces techniques par tous les moyens. Avec les algorithmes actuels, un plus court chemin peut être calculé en moins de temps que une milliseconde sur un réseau routier continental. Une implémentation rapide de l'algorithme non modifié de Dijkstra nécessite environ 10 secondes .
L'article Algorithmes de planification rapide de l'ingénierie donne un aperçu des progrès de la recherche dans ce domaine. Voir les références de cet article pour plus d'informations.
Les algorithmes les plus rapides connus n’utilisent pas d’informations sur l’état hiérarchique de la route dans les données, c’est-à-dire s’il s’agit d’une route ou d’une route locale. Au lieu de cela, ils calculent dans une étape de prétraitement une propre hiérarchie optimisée pour accélérer la planification des itinéraires. Ce pré-calcul peut ensuite être utilisé pour élaguer la recherche: Les routes lentes éloignées du début et de la destination ne doivent pas être prises en compte lors de l'algorithme de Dijkstra. Les avantages sont très bons , performances et garantie de correction du résultat.
Les premiers algorithmes de planification d'itinéraire optimisés ne concernaient que les réseaux routiers statiques, ce qui signifie qu'un bord dans le graphique a une valeur de coût fixe. Ce n'est pas vrai en pratique, car nous voulons prendre en compte des informations dynamiques telles que les embouteillages ou les restrictions liées aux véhicules. Les algorithmes les plus récents peuvent également traiter de tels problèmes, mais il reste des problèmes à résoudre et les recherches se poursuivent.
Si vous avez besoin des distances de chemin les plus courtes pour calculer une solution pour le TSP, alors vous êtes probablement intéressé par les matrices contenant toutes les distances entre vos sources et vos sources. destinations. Pour cela, vous pouvez envisager: Calculer plusieurs chemins parmi les plus courts à l'aide de hiérarchies routières . Notez que cela a été amélioré par de nouvelles approches au cours des 2 dernières années.
En ce qui concerne les violations de l’inégalité des triangles, nous espérons que le facteur supplémentaire qu’elles optimisent est du bon sens. Vous ne voulez pas nécessairement l'itinéraire le plus court ou le plus rapide, car il peut conduire à chaosetdestruction . Si vous souhaitez que votre itinéraire privilégie les itinéraires principaux adaptés aux camionnettes et qu’il soit possible d’envoyer chaque conducteur suivant son repérage par satellite, vous devez rapidement supprimer l’inégalité du triangle [1].
Si Y est une rue résidentielle étroite entre X et Z, vous ne souhaiterez probablement utiliser le raccourci via Y que si l'utilisateur demande explicitement X-Y-Z. S'ils demandent X-Z, ils devraient rester sur les routes principales même si c'est un peu plus loin et prend un peu plus longtemps. Cela ressemble à paradoxe de Braess - si tout le monde essaie de prendre l'itinéraire le plus court et le plus rapide, la congestion qui en résulte signifie que ce n'est plus l'itinéraire le plus rapide pour personne. De là, nous passons de la théorie des graphes à la théorie des jeux.
[1] En fait, tout espoir que les distances générées soient une fonction de distance au sens mathématique s'éteigne lorsque vous autorisez les routes à sens unique et que vous perdez l'exigence de symétrie. Perdre l'inégalité triangulaire, c'est aussi simplement salir la plaie.
Voici les algorithmes de routage les plus rapides au monde comparés et éprouvés en matière de correction:
http://algo2.iti.uka.de/schultes/hwy/schultes_diss.pdf
Voici un exposé technique de Google sur le sujet:
http://www.youtube.com/watch?v=-0ErpE8tQbw
Voici une implémentation de l'algorithme autoroute-hiérarchies, comme discuté par schultes (je n'écris actuellement que l'interface berlin, et une version mobile est en cours de développement):
Je n'avais jamais travaillé sur Google, Microsoft ou Yahoo Maps, je ne peux donc pas vous dire comment ils fonctionnent.
Cependant, j’ai conçu un système d’optimisation de la chaîne logistique sur mesure pour une entreprise du secteur de l’énergie, qui comprenait une application de planification et d’acheminement de la flotte de camions. Cependant, nos critères d’acheminement étaient bien plus spécifiques aux entreprises qu’à la construction, aux ralentissements de la circulation ou aux fermetures de voies.
Nous avons utilisé une technique appelée ACO (optimisation des colonies de fourmis) pour planifier et acheminer les camions. Cette technique est une technique d'intelligence artificielle qui a été appliquée au problème du voyageur de commerce pour résoudre les problèmes de routage. Le truc avec ACO est de construire un calcul d’erreur basé sur des faits connus du routage afin que le modèle de résolution de graphe sache quand il faut quitter (quand l’erreur est-elle suffisamment petite).
Vous pouvez google ACO ou TSP pour en savoir plus sur cette technique. Je n'ai toutefois utilisé aucun des outils d'IA open-source pour cela, donc je ne peux pas en suggérer un (bien que j'ai entendu dire que SWARM était assez complet).
L'état actuel des connaissances en termes de temps d'interrogation pour les réseaux routiers statiques est l'algorithme d'étiquetage Hub proposé par Abraham et al. http://link.springer.com/chapter/10.1007/978-3-642-20662-7_2 . Une enquête approfondie et parfaitement écrite sur le terrain a récemment été publiée sous forme de rapport technique Microsoft http://research.Microsoft.com/pubs/207102/MSR-TR-2014-4.pdf .
La version courte est ...
L'algorithme d'étiquetage du concentrateur fournit les requêtes les plus rapides pour les réseaux routiers statiques, mais nécessite une grande quantité de mémoire RAM pour s'exécuter (18 Go).
Le routage des noeuds de transit est légèrement plus lent, bien qu'il ne nécessite qu'environ 2 GiB de mémoire et ait un temps de prétraitement plus rapide.
Les hiérarchies de contraction offrent un bon compromis entre temps de prétraitement rapide, faible encombrement (0,4 Go) et temps de requête rapide.
Aucun algorithme n'est complètement dominé ...
Cette conférence technique de Peter Sanders sur Google pourrait être intéressante
https://www.youtube.com/watch?v=-0ErpE8tQbw
Aussi cette conférence par Andrew Goldberg
https://www.youtube.com/watch?v=WPrkc78XLhw
Une implémentation open source des hiérarchies de contraction est disponible sur le site Web du groupe de recherche Peter Sanders à KIT. http://algo2.iti.kit.edu/english/routeplanning.php
Également un article de blog facilement accessible écrit par Microsoft sur leur utilisation de l'algorithme CRP ... http://blogs.bing.com/maps/2012/01/05/bing-maps-new-routing-engine /
Les algorithmes graphiques tels que celui de Dijkstra ne fonctionneront pas car le graphique est énorme.
Cet argument ne tient pas nécessairement, car Dijkstra ne regarde généralement pas le graphique complet, mais plutôt un très petit sous-ensemble (plus le graphique est interconnecté, plus ce sous-ensemble est petit).
Dijkstra peut en fait assez bien fonctionner pour des graphes bien comportés. Par contre, avec une paramétrisation soignée, A * fonctionnera toujours aussi bien, voire mieux. Avez-vous déjà essayé comment cela fonctionnerait sur vos données?
Cela dit, je serais également très intéressé par les expériences des autres. Bien entendu, des exemples notables tels que la recherche dans Google Map sont particulièrement intéressants. Je pourrais imaginer quelque chose comme une heuristique dirigée proche voisin.
Je suis un peu surpris de ne pas voir algorithme de Floyd Warshall mentionné ici. Ce travail d'algorithme est très semblable à celui de Dijkstra. Il possède également une fonctionnalité très agréable, à savoir qu’il vous permet de calculer aussi longtemps que vous le souhaitez afin de permettre davantage de sommets intermédiaires. Il trouvera donc naturellement les itinéraires qui empruntent les autoroutes ou les autoroutes assez rapidement.
En fait, j'ai souvent essayé plusieurs méthodes différentes. En fonction de la taille (géographique) de la carte, vous pouvez envisager d'utiliser la fonction haversine comme une heuristique.
La meilleure solution que j'ai faite consistait à utiliser A * avec une distance en ligne droite comme fonction heuristique. Mais vous avez besoin d'une sorte de coordonnées pour chaque point (intersection ou sommet) de la carte. Vous pouvez également essayer différentes pondérations pour la fonction heuristique, c.-à-d.
f(n) = k*h(n) + g(n)
où k est une constante supérieure à 0.
Probablement similaire à la réponse sur les itinéraires pré-calculés entre les principaux sites et les cartes superposées, mais si je comprends bien, pour accélérer les jeux A *, vous disposez d’une carte très grossière pour la navigation dans les macros, et d’une carte à grain fin pour navigation à la limite des macro directions. Donc, vous avez deux petits chemins à calculer, et votre espace de recherche est donc beaucoup plus petit que de simplement faire un seul chemin vers la destination. Et si vous faites beaucoup de choses là-dessus, vous aurez une grande partie de ces données pré-calculées, de sorte qu'au moins une partie de la recherche est une recherche de données pré-calculées, plutôt qu'une recherche de chemin.
En parlant de GraphHopper , un planificateur d'itinéraire rapide Open Source basé sur OpenStreetMap, j'ai lu un peu de littérature et mis en œuvre des méthodes. La solution la plus simple est un Dijkstra et une amélioration simple est un Dijkstra bidirectionnel qui explore en gros seulement la moitié des nœuds. Avec bidirctional Dijkstra, un itinéraire à travers toute l’Allemagne prend déjà 1 seconde (en mode voiture), en C il ne serait probablement que de 0,5 seconde environ;)
J'ai créé un gif animé d'une recherche de chemin réel avec Dijkstra bidirectionnel ici . Il y a aussi quelques idées supplémentaires pour accélérer Dijkstra comme faire A *, qui est une "Dijkstra orientée objectif". J'ai aussi créé un gif-animation pour cela.
Mais comment faire (beaucoup) plus rapidement?
Le problème est que pour une recherche de chemin, tous les nœuds situés entre les sites doivent être explorés, ce qui est très coûteux, car il en existe déjà plusieurs millions en Allemagne. Mais un autre inconvénient de Dijkstra, etc., est que de telles recherches utilisent beaucoup de RAM.
Il y a des solutions heuristiques mais aussi des solutions exactes qui organisent le graphe (réseau routier) en couches hiérarchiques, les deux ont des avantages et des inconvénients et résolvent principalement le problème de la vitesse et de la RAM. J'ai énuméré certains d'entre eux dans cette réponse .
Pour GraphHopper, j'ai décidé d'utiliser hiérarchies de contraction car il est relativement "facile" à mettre en œuvre et ne prend pas beaucoup de temps pour la préparation du graphique. Il en résulte toujours des temps de réponse très rapides comme vous pouvez le tester sur notre instance en ligne GraphHopper Maps . Par exemple. de l'Afrique du Sud à l'est de la Chine , ce qui représente une distance de 23 000 km et près de 14 jours de conduite pour une voiture. Le serveur n'a pris que 0,1 s environ.
C’est une pure spéculation de ma part, mais je suppose qu’ils peuvent utiliser une structure de données de carte d’influence superposée à la carte dirigée afin de restreindre le domaine de recherche. Cela permettrait à l'algorithme de recherche d'orienter le chemin vers les routes principales lorsque le trajet souhaité est long.
Étant donné qu'il s'agit d'une application Google, il est également raisonnable de supposer qu'une grande partie de la magie est réalisée via une mise en cache étendue. :) Je ne serais pas surpris si la mise en cache des 5% de demandes d'itinéraire de carte les plus courantes de Google Map permettait de traiter un grand nombre de demandes (20%? 50%?) Par simple recherche.
J'étais très curieux des heuristiques utilisées quand, il y a quelque temps, nous avions des itinéraires depuis le même lieu de départ, près de Santa Rosa, vers deux campings différents dans le parc national de Yosemite. Ces différentes destinations ont produit des itinéraires assez différents (via l'I-580 ou le CA-12) malgré le fait que les deux itinéraires ont convergé sur les 100 derniers milles (le long du CA-120) avant de diverger à nouveau de quelques kilomètres à la fin. C'était assez répétable. Les deux itinéraires étaient distants de 100 km, mais les distances et les temps étaient assez proches l'un de l'autre, comme on pouvait s'y attendre.
Hélas, je ne peux pas reproduire cela - les algorithmes doivent avoir changé. Mais il m'a curieux de connaître l'algorithme. Tout ce que je peux supposer, c'est qu'il existe une taille directionnelle extrêmement sensible à la différence minuscule angular entre les destinations vues de loin ou qu'il existe différents segments précalculés sélectionnés en fonction du choix de la destination finale. .
J'ai eu d'autres réflexions à ce sujet:
1) N'oubliez pas que les cartes représentent une organisation physique. Stocker la latitude/longitude de chaque intersection. Vous n'avez pas besoin de vérifier beaucoup au-delà des points situés dans la direction de votre cible. Si vous êtes bloqué, vous devez aller au-delà. Si vous stockez une superposition de connexions supérieures, vous pouvez la limiter encore plus - vous ne rencontrerez normalement jamais l'une de ces connexions d'une manière qui s'éloigne de votre destination finale.
2) Divisez le monde en un tas de zones définies par une connectivité limitée, définissez tous les points de connectivité entre les zones. Recherchez les zones dans lesquelles se trouvent votre source et votre cible, pour l'itinéraire des zones de début et de fin, de votre emplacement à chaque point de connexion, pour les zones situées simplement entre les points de connexion. (Je soupçonne que beaucoup de ces derniers sont déjà pré-calculés.)
Notez que les zones peuvent être plus petites qu'une zone métropolitaine. Toute ville dont les caractéristiques de terrain la diviseraient (par exemple une rivière) constituerait plusieurs zones.
Je travaille sur le routage depuis quelques années, avec un regain d'activité récent impulsé par les besoins de mes clients, et j'ai constaté qu'A * est assez rapide; il n'est vraiment pas nécessaire de rechercher des optimisations ou des algorithmes plus complexes. Le routage sur un graphique énorme n'est pas un problème.
Mais la vitesse dépend de la présence de l’ensemble du réseau de routage, c’est-à-dire du graphe orienté des arcs et des nœuds représentant respectivement les segments et les jonctions de la route, en mémoire. La surcharge de temps principale est le temps pris pour créer ce réseau. Quelques chiffres approximatifs basés sur un ordinateur portable ordinaire fonctionnant sous Windows et routant sur l’ensemble de l’Espagne: temps nécessaire pour créer le réseau: 10 à 15 secondes; temps pris pour calculer un itinéraire: trop court pour être mesuré.
L'autre chose importante est de pouvoir réutiliser le réseau pour autant de calculs de routage que vous le souhaitez. Si votre algorithme a marqué les nœuds de manière à enregistrer le meilleur itinéraire (coût total pour le nœud actuel et meilleur arc de cercle), comme il doit le faire sous A *, vous devez réinitialiser ou effacer ces anciennes informations. Plutôt que de passer par des centaines de milliers de nœuds, il est plus facile d'utiliser un système à numéro de génération. Marquez chaque noeud avec le numéro de génération de ses données; incrémenter le numéro de génération lorsque vous calculez un nouvel itinéraire; tout nœud avec un numéro de génération plus ancien est périmé et ses informations peuvent être ignorées.
Je vois ce qui se passe avec les cartes du PO:
Regardez la route avec le point intermédiaire spécifié: La route va légèrement en arrière à cause de cette route qui n'est pas rectiligne.
Si leur algorithme ne revient pas en arrière, il ne verra pas la route la plus courte.
Un algorithme de chemin le plus court pour toutes les paires calculera les chemins les plus courts entre tous les sommets d'un graphique. Cela permettra aux chemins d'être pré-calculés au lieu de demander qu'un chemin soit calculé chaque fois que quelqu'un veut trouver le chemin le plus court entre une source et une destination. L'algorithme de Floyd-Warshall est un algorithme de chemin le plus court pour toutes les paires.