어떤 알고리즘이지도에서 지점 A에서 지점 B까지의 방향을 계산합니까?
지도 제공 업체 (예 : Google 또는 Yahoo!지도)는 길 찾기를 어떻게 제안합니까?
내 말은, 아마도 거리를 포함하여 어떤 형태로든 실제 데이터를 가지고있을 것입니다. 물론 주행 속도, 보도의 존재 여부, 기차 시간표 등과 같은 것들도 있지만 데이터가 더 간단한 형식이라고 가정하십시오. 거리를 반영하는 가장자리 가중치 임의의 한 지점에서 다른 지점으로 방향을 신속하게 계산할 수 있기를 원합니다. 때때로이 지점들은 (한 도시 내에서) 서로 가까이있는 반면 때로는 멀리 떨어져 있습니다 (국가 간).
그래프가 엄청 나서 Dijkstra의 알고리즘과 같은 그래프 알고리즘은 작동하지 않습니다. 운 좋게도 A *와 같은 휴리스틱 알고리즘이 작동 할 것입니다. 그러나 우리의 데이터는 매우 체계적으로 구성되어 있으며 어떤 종류의 계층 적 접근 방식이 효과가있을 수 있습니까? 예를 들어, 특정 "키"지점 사이의 미리 계산 된 방향과 일부 로컬 방향을 저장합니다. 그러면 두 개의 원거리 지점에 대한 방향에는 주요 지점에 대한 로컬 방향, 다른 주요 지점에 대한 전역 방향 및 로컬이 포함됩니다. 다시 지시하십시오.)
실제로 어떤 알고리즘이 사용됩니까?
추신. 이 질문은 온라인 매핑 방향에서 기발한 부분을 찾아 동기를 부여했습니다. 삼각형 부등식과 달리 Google지도는 XZ 가 XYZ 에서와 같이 중간 지점을 사용하는 것보다 시간이 오래 걸리고 더 먼 것으로 생각합니다 . 그러나 도보 방향이 다른 매개 변수에 맞게 최적화 될 수 있습니까?
PPS. 삼각형 불균형에 대한 또 다른 위반은 다음과 같습니다. XZ 대 XYZ . 전자는 눈에 띄지 않는 Boulevard de Sebastopol을 사용하는 것 같습니다.
편집 :이 예제 중 어느 것도 더 이상 작동하지 않는 것 같지만 원래 게시물 당시에는 두 가지 모두 작동했습니다.
라우팅 알고리즘에 대한 작업을 포함하여 18 개월 동안지도 회사에서 근무한 사람으로 말하면 Dijkstra 는 몇 가지 수정 작업을 수행합니다.
- 소스에서 대상까지 Dijkstra를 한 번 수행하는 대신 각 끝에서 시작하여 중간에서 만날 때까지 양쪽을 확장하십시오. 이것은 작업의 대략 절반을 제거합니다 (2 * pi * (r / 2) ^ 2 vs pi * r ^ 2).
- 출발지와 목적지 사이의 모든 도시의 뒷골목을 탐색하지 않으려면 몇 가지 맵 데이터 계층을 가질 수 있습니다. 고속도로 만 포함하는 '고속도로'레이어, 2 차 거리 만 포함하는 '보조'레이어 등. 그런 다음 더 세부적인 레이어의 작은 섹션 만 탐색하고 필요에 따라 확장합니다. 분명히이 설명은 많은 세부 사항을 생략하지만 아이디어를 얻습니다.
이러한 라인을 따라 수정하면 매우 합리적인 시간 내에 국가 간 라우팅을 수행 할 수도 있습니다.
이 질문은 지난 몇 년간 활발한 연구 분야였습니다. 주요 아이디어는 그래프 에서 사전 처리 를 한 번 수행 하여 모든 후속 쿼리 속도 를 높이는 것 입니다. 이 추가 정보를 사용하면 여정을 매우 빠르게 계산할 수 있습니다. 그럼에도 불구하고 Dijkstra의 알고리즘 은 모든 최적화의 기초입니다.
Arachnid 는 계층 적 정보를 기반으로 양방향 검색 및 엣지 프 루닝의 사용법을 설명했습니다. 이러한 속도 향상 기법은 꽤 잘 작동하지만 최신 알고리즘은 이러한 기법보다 훨씬 뛰어납니다. 현재 알고리즘을 사용하면 대륙 도로 네트워크 에서 최단 경로를 1 밀리 초 보다 훨씬 짧은 시간에 계산할 수 있습니다 . Dijkstra의 수정되지 않은 알고리즘의 빠른 구현에는 약 10 초가 필요합니다 .
공학 빠른 경로 계획 알고리즘 기사 는 해당 분야의 연구 진행 상황에 대한 개요를 제공합니다. 자세한 내용은 해당 논문의 참조를 참조하십시오.
가장 빠른 알려진 알고리즘은 데이터에서 도로의 계층 상태 (예 : 고속도로 또는 지방 도로)에 대한 정보를 사용하지 않습니다. 대신, 전처리 단계에서 경로 계획을 가속화하도록 최적화 된 자체 계층 구조를 계산합니다. 그런 다음이 사전 계산을 사용하여 검색을 정리할 수 있습니다. Dijkstra의 알고리즘 중에 출발지와 목적지에서 멀리 떨어진 느린 도로는 고려할 필요가 없습니다. 이점은 매우 우수한 성능 과 결과에 대한 정확성 보장입니다.
첫 번째로 최적화 된 경로 계획 알고리즘은 정적 도로 네트워크 만 처리했습니다. 즉, 그래프의 모서리에 고정 비용 값이 있음을 의미합니다. 교통 체증이나 차량 의존 제한과 같은 동적 정보를 고려하기 때문에 실제로는 그렇지 않습니다. 최신 알고리즘도 이러한 문제를 해결할 수 있지만 여전히 해결해야 할 문제가 있으며 연구가 진행 중입니다.
TSP 솔루션을 계산하기 위해 가장 짧은 경로 거리가 필요한 경우 소스와 대상 사이의 모든 거리를 포함하는 행렬에 관심이있을 것입니다. 이를 위해 고속도로 계층을 사용하여 다 대다 최단 경로 계산을 고려할 수 있습니다. 지난 2 년 동안 새로운 접근 방식으로 개선되었습니다.
삼각형 불평등 위반을 해결하는 것만으로도 그들이 최적화하는 추가 요소는 상식적입니다. 혼돈 과 파괴로 이어질 수 있으므로 반드시 최단 또는 가장 빠른 경로를 원하지는 않습니다 . 트럭 친화적 인 모든 주요 항로를 따라가는 모든 경로를 따라가는 운전자가 경로를 선호하는 방향을 원한다면 삼각형의 부등식을 빨리 버립니다 [1].
Y가 X와 Z 사이의 좁은 주거 거리 인 경우 사용자가 XYZ를 명시 적으로 요청하는 경우 Y를 통해 바로 가기 만 사용하려고 할 수 있습니다. 그들이 XZ를 요구한다면, 조금 더 길고 더 오래 걸리더라도 주요 도로를 고수해야합니다. Braess의 역설 과 비슷 합니다. 모든 사람이 가장 짧고 빠른 경로를 사용하려고하면 혼잡은 더 이상 가장 빠른 경로가 아님을 의미합니다. 여기에서 그래프 이론에서 게임 이론으로 넘어갑니다.
[1] 실제로, 일방 통행 도로를 허용하고 대칭 요구 사항을 잃으면 생성 된 거리가 수학적 의미에서 거리 함수가 될 것이라는 희망은 사라집니다. 삼각형의 불평등을 잃는 것도 상처에 소금을 문지르는 것입니다.
정확성을 위해 비교되고 입증 된 세계에서 가장 빠른 라우팅 알고리즘은 다음과 같습니다.
http://algo2.iti.uka.de/schultes/hwy/schultes_diss.pdf
주제에 대한 Google 기술 강연은 다음과 같습니다.
http://www.youtube.com/watch?v=-0ErpE8tQbw
다음은 schultes가 논의한 고속도로 계층 구조 알고리즘의 구현입니다 (현재 베를린에서만 인터페이스를 작성 중이며 모바일 버전도 개발 중입니다).
이전에 Google, Microsoft 또는 Yahoo Maps에서 작업 한 적이 없으므로 작동 방식을 말할 수 없습니다.
그러나 에너지 회사를위한 맞춤형 공급망 최적화 시스템을 설계했는데, 여기에는 트럭에 대한 일정 및 라우팅 응용 프로그램이 포함되어 있습니다. 그러나 라우팅에 대한 우리의 기준은 건설 또는 교통 속도 저하 또는 차선 폐쇄 위치보다 훨씬 비즈니스별로 다릅니다.
우리는 트럭을 예약하고 경로를 정하기 위해 ACO (Ant Colony Optimization)라는 기술을 사용했습니다. 이 기술은 이동 판매원 문제에 적용되어 라우팅 문제를 해결 한 AI 기술입니다. ACO의 트릭은 알려진 라우팅 사실을 기반으로 오류 계산을 작성하여 그래프 해결 모델이 종료시기를 알 수 있도록하는 것입니다 (오류가 충분히 작은 경우).
이 기술에 대해 자세히 알아 보려면 Google ACO 또는 TSP를 사용할 수 있습니다. 나는 이것을 위해 오픈 소스 AI 도구를 사용하지 않았으므로 제안 할 수는 없습니다 (SWARM이 꽤 포괄적이라고 들었지만).
그래프가 엄청 나서 Dijkstra의 알고리즘과 같은 그래프 알고리즘은 작동하지 않습니다.
Dijkstra는 일반적으로 완전한 그래프를 보는 것이 아니라 매우 작은 부분 집합 (그래프를 더 잘 상호 연결할수록이 부분 집합이 더 작음)을 볼 것이기 때문에이 주장이 반드시 필요한 것은 아닙니다.
Dijkstra는 실제로 잘 작동하는 그래프에서 다소 성능이 좋을 수 있습니다. 반면에 신중하게 매개 변수를 지정하면 A *는 항상 좋은 결과를 얻을 수 있습니다. 데이터에서 어떻게 수행되는지 이미 시도 했습니까?
즉, 나는 또한 다른 사람들의 경험에 대해 듣고 싶어합니다. 물론 Google지도 검색과 같은 두드러진 예가 특히 흥미 롭습니다. 가장 가까운 이웃 휴리스틱과 같은 것을 상상할 수 있습니다.
정적 도로 네트워크에 대한 쿼리 시간의 관점에서 현재의 최신 상태는 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 로 게시되었습니다 .
짧은 버전은 ...
허브 레이블링 알고리즘은 정적 도로 네트워크에 가장 빠른 쿼리를 제공하지만 실행하는 데 많은 양의 램 (18GiB)이 필요합니다.
전송 노드 라우팅은 약간 느리지 만 약 2GiB의 메모리 만 필요하며 전처리 시간이 더 빠릅니다.
수축 계층은 빠른 사전 처리 시간, 낮은 공간 요구 사항 (0.4 GiB) 및 빠른 쿼리 시간간에 훌륭한 균형을 유지합니다.
어느 알고리즘도 완전히 지배하지는 않습니다 ...
Peter Sanders의 Google 기술 강연은 흥미로울 것입니다
https://www.youtube.com/watch?v=-0ErpE8tQbw
앤드류 골드버그의 이야기
https://www.youtube.com/watch?v=WPrkc78XLhw
수축 계층 구조의 오픈 소스 구현은 KIT의 Peter Sanders 리서치 그룹 웹 사이트에서 제공됩니다. http://algo2.iti.kit.edu/english/routeplanning.php
또한 쉽게 접근 할 수있는 블로그 게시물은 CRP 알고리즘 ...의이 사용에 마이크로 소프트에 의해 작성 http://blogs.bing.com/maps/2012/01/05/bing-maps-new-routing-engine/
Floyd Warshall의 알고리즘이 여기에 언급 되지 않은 것은 조금 놀랍 습니다. 이 알고리즘은 Dijkstra와 매우 유사합니다. 또한 중간 정점을 계속 허용하려는 한 계산할 수있는 매우 멋진 기능이 있습니다. 따라서 고속도로 나 고속도로를 사용하는 노선을 자연스럽게 찾을 수 있습니다.
실제로 여러 가지 방법을 시도해 보았습니다. 지도의 크기 (지리적)에 따라, 허세 인 함수를 휴리스틱으로 사용하는 것이 좋습니다.
내가 만든 최고의 솔루션은 휴리스틱 함수로 직선 거리의 A *를 사용하는 것입니다. 그러나 맵의 각 점 (교차점 또는 정점)에 대해 일종의 좌표가 필요합니다. 휴리스틱 함수에 대해 다른 가중치를 시도 할 수도 있습니다. 즉
f(n) = k*h(n) + g(n)
여기서 k는 0보다 큰 상수입니다.
아마도 주요 위치와 계층화 된 맵 사이의 사전 계산 된 경로에 대한 답변과 비슷하지만 게임에서 A * 속도를 높이려면 매크로 탐색에 매우 거친 맵과 세밀한 맵이 있습니다. 매크로 방향의 경계로 이동합니다. 따라서 계산할 두 개의 작은 경로가 있으므로 대상에 대한 단일 경로를 수행하는 것보다 검색 공간이 훨씬 작습니다. 그리고 당신이 이것을 많이하는 사업에 있다면, 당신은 그 데이터를 미리 계산할 것입니다. 그래서 최소한 검색의 일부는 경로를 찾는 것이 아니라 미리 계산 된 데이터를 찾는 것입니다.
이것은 내 생각에 순수한 추측이지만 검색 도메인을 좁히기 위해 지시 된 맵을 오버레이하는 영향 맵 데이터 구조를 사용할 수 있다고 가정합니다. 이것은 원하는 여행이 길 때 검색 알고리즘이 주요 경로로 경로를 지시 할 수있게한다.
이것이 Google 앱이라는 점을 감안할 때 광범위한 캐싱을 통해 많은 마법이 수행된다고 가정하는 것도 합리적입니다. :) 가장 일반적인 Google지도 경로 요청 상위 5 %를 캐싱하면 간단한 검색으로 많은 청크 (20 % ~ 50 %?) 요청에 응답 할 수 있다는 사실에 놀라지 않을 것입니다.
나는 이것에 대해 더 많은 생각을했다.
1)지도는 실제 조직을 나타냅니다. 모든 교차점의 위도 / 경도를 저장하십시오. 목표 방향에있는 지점을 넘어서는 점검을 할 필요가 없습니다. 자신이 차단 된 경우에만이를 넘어서야합니다. 우수한 연결의 오버레이를 저장하면 훨씬 더 제한 할 수 있습니다. 일반적으로 최종 대상에서 벗어나는 방식으로는 그 중 하나를 거치지 않습니다.
2) 제한된 연결로 정의 된 전체 영역으로 세계를 나누고, 영역 사이의 모든 연결 지점을 정의하십시오. 사용자의 위치에서 각 연결 지점으로의 시작 및 끝 영역 경로에 대해 소스와 대상이있는 영역을 찾아서 단순히 연결 지점 사이의 영역을 매핑하십시오. (나는 많은 후자가 이미 미리 계산되어 있다고 생각합니다.)
구역은 대도시 지역보다 작을 수 있습니다. 지형을 나누는 지형 기능이있는 도시 (예 : 강)는 여러 영역이됩니다.
나는 잠시 후 우리가 산타 로사 근처의 같은 출발지에서 요세미티 국립 공원의 두 개의 다른 야영장으로가는 길을 찾았을 때 사용 된 휴리스틱에 대해 매우 궁금했습니다. 이 두 목적지는 마지막 100 마일 (CA-120을 따라)까지 수렴하여 마지막에 몇 마일 씩 다시 분기한다는 사실에도 불구하고 I-580 또는 CA-12를 통해 상당히 다른 노선을 생성했습니다. 이것은 매우 반복적이었습니다. 두 경로는 약 100 마일 동안 최대 50 마일 떨어져 있었지만, 예상대로 거리 / 시간은 서로 매우 가깝습니다.
아아 나는 그것을 재현 할 수 없다-알고리즘이 바뀌었을 것이다. 그러나 알고리즘에 대해 궁금했습니다. 내가 추측 할 수있는 것은 멀리서 볼 때 목적지 간의 작은 각도 차이에 정교하게 민감한 방향성 가지 치기가 있었거나 최종 목적지 선택에 의해 선택된 다른 사전 계산 된 세그먼트가 있다는 것입니다.
OpenStreetMap을 기반으로 한 빠른 오픈 소스 경로 플래너 인 GraphHopper에 대해 이야기하면서 약간의 문헌을 읽고 몇 가지 방법을 구현했습니다. 가장 간단한 솔루션은 Dijkstra이고 간단한 개선은 노드의 절반 만 탐색하는 양방향 Dijkstra입니다. 우연한 Dijkstra를 사용하면 독일 전체를 통과하는 경로는 이미 1 초가 걸립니다 (자동차 모드의 경우) .C에서는 아마도 0.5 초 정도입니다.)
나는 양방향 데이 크 스트라와 실제 경로 검색의 애니메이션 GIF 만든 여기를 . 또한 "목표 지향적 인 Dijkstra"인 A *를 수행하는 것과 같이 Dijkstra를 더 빠르게 만드는 아이디어가 더 있습니다. 또한 GIF 애니메이션 을 만들었 습니다.
그러나 어떻게 (많은) 더 빨리합니까?
문제는 경로 검색을 위해 위치 사이의 모든 노드를 탐색해야하며 독일에는 이미 수백만 개의 노드가 있으므로 실제로 비용이 많이 든다는 것입니다. 그러나 Dijkstra 등의 또 다른 어려움은 그러한 검색이 많은 RAM을 사용한다는 것입니다.
휴리스틱 솔루션이 있지만 계층 적 계층으로 그래프 (로드 네트워크)를 구성하는 정확한 솔루션이 있으며, 장점과 단점이 있으며 주로 속도와 RAM 문제를 해결합니다. 이 답변 에 그중 일부를 나열했습니다 .
GraphHopper의 경우 구현하기가 상대적으로 쉽고 그래프 준비에 시간이 걸리지 않기 때문에 수축 계층 구조 를 사용하기로 결정했습니다 . 온라인 인스턴스 GraphHopper Maps 에서 테스트 할 수있는 것처럼 응답 시간이 매우 빠릅니다 . 예 를 들어 남아프리카에서 중국 동부까지 23000km의 거리와 거의 14 일의 자동차 운전 시간이 발생했으며 서버에서 ~ 0.1 초 밖에 걸리지 않았습니다.
고객의 요구에 따라 최근 활동이 급증하면서 몇 년 동안 라우팅 작업을 해왔으며 A *가 충분히 빠르다는 것을 알았습니다. 최적화 나 더 복잡한 알고리즘을 찾을 필요가 없습니다. 막대한 그래프를 라우팅하는 것은 문제가되지 않습니다.
그러나 속도는 전체 라우팅 네트워크를 갖는 것에 달려 있습니다. 즉, 메모리에서 경로 세그먼트와 접합을 각각 나타내는 아크와 노드의 방향 그래프를 의미합니다. 주요 시간 오버 헤드는이 네트워크를 만드는 데 걸리는 시간입니다. Windows를 실행하는 일반 랩톱 및 스페인 전체에 라우팅하는 대략적인 수치 : 네트워크를 만드는 데 걸리는 시간 : 10-15 초; 경로를 계산하는 데 걸린 시간 : 측정하기에는 너무 짧습니다.
다른 중요한 것은 원하는만큼 많은 라우팅 계산을 위해 네트워크를 재사용 할 수 있다는 것입니다. 알고리즘이 A *에서와 같이 최상의 경로 (현재 노드에 대한 총 비용 및 최상의 아크)를 기록하는 방식으로 노드를 표시 한 경우이 이전 정보를 재설정하거나 지워야합니다. 수십만 개의 노드를 거치지 않고 세대 번호 시스템을 사용하는 것이 더 쉽습니다. 각 노드에 해당 데이터의 생성 번호를 표시하십시오. 새 경로를 계산할 때 생성 번호를 늘리십시오. 이전 세대 번호를 가진 모든 노드는 유효하지 않으며 해당 정보를 무시할 수 있습니다.
OP의지도에 어떤 문제가 있는지 확인합니다.
중간 지점이 지정된 경로를 확인하십시오. 직선이 아닌 도로로 인해 경로가 약간 뒤로 이동합니다.
알고리즘이 역 추적하지 않으면 더 짧은 경로를 볼 수 없습니다.
모든 쌍 최단 경로 알고리즘은 그래프의 모든 정점 사이의 최단 경로를 계산합니다. 이렇게하면 누군가 소스와 대상 사이의 최단 경로를 찾을 때마다 경로를 계산할 필요없이 경로를 미리 계산할 수 있습니다. Floyd-Warshall 알고리즘은 모든 쌍 최단 경로 알고리즘입니다.
지도는 전체지도를 고려하지 않습니다. 내 추측은 :-1. 당신의 위치에 따라, 그들은 장소와 그 장소에 랜드 마크를로드합니다. 2. 목적지를 검색 할 때지도의 다른 부분을로드하고 두 곳에서 그래프를 만든 다음 최단 경로 알고리즘을 적용합니다.
또한 가장 짧은 경로를 계산하는 데 사용되는 중요한 프로그래밍 동적 프로그래밍이 있습니다. 당신도 그것을 참조 할 수 있습니다.
'development' 카테고리의 다른 글
인터넷에서 소프트웨어가 깨진 다운로드로 발견되었습니다. 어떻게해야합니까? (0) | 2020.02.10 |
---|---|
Java에서 목록을 반복하는 방법 (0) | 2020.02.10 |
Node.js (package.json) 용“devDependencies”NPM 모듈 설치를 어떻게 방지합니까? (0) | 2020.02.10 |
wget을 사용하여 임의의 파일이있는 디렉토리를 재귀 적으로 가져 오기 (0) | 2020.02.10 |
.gitignore에 추가 한 후 원격 저장소에서 디렉토리를 제거하십시오. (0) | 2020.02.10 |