I'm menulis kurir/logistik simulasi pada peta OpenStreetMap dan telah menyadari bahwa dasar algoritma A* seperti yang digambarkan di bawah ini tidak akan cukup cepat untuk peta besar (seperti Greater London).
Hijau node sesuai untuk orang-orang yang dimasukkan ke dalam open set/antrian prioritas dan karena jumlah besar (seluruh peta adalah sesuatu seperti 1-2 juta), butuh waktu 5 detik atau lebih untuk menemukan rute yang digambarkan. Sayangnya 100ms per rute adalah sekitar saya mutlak batas.
Saat ini, node yang disimpan di kedua adjacency list dan juga tata ruang 100x100 2D array.
I'm mencari metode di mana saya bisa trade off preprocessing waktu, ruang, dan jika diperlukan optimalitas dari rute, untuk kueri lebih cepat. Garis lurus Haversine formula untuk heuristik biaya yang paling mahal fungsi menurut profiler - saya telah dioptimalkan dasar saya A* sebanyak yang saya bisa.
Sebagai contoh, saya berpikir jika saya memilih sewenang-wenang node X dari masing-masing kuadran dari 2D array dan menjalankan antara masing-masing, saya dapat menyimpan rute ke disk untuk selanjutnya simulasi. Ketika query, saya dapat menjalankan pencarian hanya di kuadran, untuk mendapatkan antara precomputed rute dan X.
Apakah ada versi yang lebih halus dari apa yang saya've yang dijelaskan di atas atau mungkin metode yang berbeda saya harus mengejar. Banyak terima kasih!
Sebagai catatan, berikut ini adalah beberapa hasil benchmark untuk sewenang-wenang bobot heuristik biaya dan komputasi jalan antara 10 pasang secara acak memilih node:
Weight // AvgDist% // Time (ms)
1 1 1461.2
1.05 1 1327.2
1.1 1 900.7
1.2 1.019658848 196.4
1.3 1.027619169 53.6
1.4 1.044714394 33.6
1.5 1.063963413 25.5
1.6 1.071694171 24.1
1.7 1.084093229 24.3
1.8 1.092208509 22
1.9 1.109188175 22.5
2 1.122856792 18.2
2.2 1.131574742 16.9
2.4 1.139104895 15.4
2.6 1.140021962 16
2.8 1.14088128 15.5
3 1.156303676 16
4 1.20256964 13
5 1.19610861 12.9
Anehnya meningkatkan koefisien 1.1 hampir setengahnya waktu eksekusi sementara menjaga rute yang sama.
Anda harus mampu untuk membuatnya lebih cepat dengan perdagangan off optimalitas. Lihat Diterimanya dan optimalitas di wikipedia.
Idenya adalah untuk menggunakan sebuah epsilon
nilai yang akan menyebabkan solusi tidak lebih buruk dari 1 + epsilon
times jalur yang optimal, tetapi yang akan menyebabkan lebih sedikit node untuk dipertimbangkan oleh algoritma. Catatan bahwa ini tidak berarti bahwa kembali solusi akan selalu menjadi 1 + epsilon
times jalur yang optimal. Ini adalah kasus terburuk. Saya don't tahu persis bagaimana hal itu akan berperilaku dalam praktek untuk masalah anda, tapi saya pikir itu perlu ditelusuri.
Anda diberi sejumlah algoritma yang bergantung pada ide ini di wikipedia. Saya percaya ini adalah taruhan terbaik anda untuk meningkatkan algoritma dan bahwa ia memiliki potensi untuk berjalan dalam batas waktu anda sementara masih kembali baik jalan.
Karena algoritma anda tidak berurusan dengan jutaan node dalam 5 detik, saya asumsikan anda juga menggunakan biner tumpukan untuk pelaksanaan, benar? Jika anda menerapkan mereka secara manual, pastikan mereka diimplementasikan sebagai array sederhana dan bahwa mereka adalah biner tumpukan.
Ada spesialis algoritma untuk masalah ini yang banyak melakukan pra-komputasi. Dari memori, pra-komputasi menambahkan informasi ke dalam grafik yang A digunakan untuk menghasilkan yang jauh lebih akurat heuristik dari jarak garis lurus. Wikipedia memberikan nama-nama dari sejumlah metode di http://en.wikipedia.org/wiki/Shortest_path_problem#Road_networks dan mengatakan bahwa Hub Pelabelan adalah pemimpin. Sebuah pencarian cepat di ini muncul http://research.microsoft.com/pubs/142356/HL-TR.pdf. Salah satu yang lebih tua, menggunakan, di http://research.microsoft.com/pubs/64505/goldberg-sp-wea07.pdf.
Apakah anda benar-benar perlu menggunakan Haversine? Untuk menutupi London, saya akan berpikir anda bisa diasumsikan bumi yang datar dan digunakan Pythagoras, atau disimpan panjang setiap link dalam grafik.
Ada's benar-benar artikel yang bagus bahwa Microsoft Research menulis pada subjek:
http://research.microsoft.com/en-us/news/features/shortestpath-070709.aspx
Kertas asli-host di sini (PDF):
http://www.cc.gatech.edu/~thad/6601-gradAI-fall2012/02-pencarian-Gutman04siam.pdf
Pada dasarnya ada's beberapa hal yang dapat anda coba:
GraphHopper melakukan dua hal lebih untuk mendapatkan cepat, tidak ada-heuristik dan fleksibel routing (catatan: saya'm penulis dan anda dapat mencobanya secara online di sini)
Jadi, itu harus mungkin untuk mendapatkan anda cepat rute untuk greater London.
Selain itu default mode adalah mode kecepatan yang membuat segalanya urutan besaran lebih cepat (misalnya 30ms Eropa lebar rute) tetapi kurang fleksibel, karena membutuhkan preprocessing (Kontraksi Hierarki). Jika anda don't seperti ini, hanya menonaktifkan dan juga lebih fine tune termasuk jalan-jalan untuk mobil atau mungkin lebih baik untuk membuat profil baru untuk truk - misalnya mengecualikan layanan jalan-jalan dan trek yang harus memberikan 30% boost. Dan seperti halnya algoritma bidirectional anda bisa dengan mudah menerapkan paralel pencarian.
Saya pikir itu's layak untuk bekerja-out ide anda dengan "kuadran". Lebih ketat, saya'd menyebutnya resolusi rendah pencarian rute.
Anda dapat memilih X yang terhubung node yang cukup dekat, dan memperlakukan mereka sebagai satu resolusi rendah node. Membagi seluruh grafik ke dalam kelompok-kelompok tersebut, dan anda mendapatkan rendah resolusi grafik. Ini adalah tahap persiapan.
Dalam rangka untuk menghitung rute dari sumber ke target, terlebih dahulu mengidentifikasi rendah-res node yang mereka milik, dan menemukan resolusi rendah rute. Kemudian meningkatkan hasil anda dengan mencari rute pada resolusi tinggi grafik, namun membatasi algoritma hanya untuk node yang termasuk ke hte resolusi rendah node resolusi rendah rute (opsional anda juga dapat mempertimbangkan tetangga resolusi rendah node hingga beberapa kedalaman).
Ini juga dapat digeneralisasi untuk beberapa resolusi, bukan hanya tinggi/rendah.
Pada akhirnya anda harus mendapatkan rute yang cukup dekat dengan optimal. It's lokal yang optimal, tapi mungkin agak lebih buruk daripada yang optimal secara global dengan batas tertentu, yang tergantung pada resolusi melompat (yaitu perkiraan yang anda buat ketika sekelompok node didefinisikan sebagai node tunggal).
Ada puluhan A* variasi yang mungkin sesuai dengan tagihan di sini. Anda harus berpikir tentang penggunaan kasus-kasus, meskipun.
Ada's tidak ada cara bagi kita untuk mengetahui semua rincian yang anda dan majikan anda mengetahui rahasia untuk. Berhenti pertama anda sehingga harus CiteSeer atau Google Cendekia: mencari makalah yang mengobati pathfinding sama dengan set umum kendala-kendala seperti anda.
Kemudian downselect untuk tiga atau empat algoritma, apakah prototipe, menguji bagaimana mereka scale up dan finetune mereka. Anda harus menanggung dalam pikiran anda dapat menggabungkan berbagai algoritma yang sama grand pathfinding rutin berdasarkan jarak antara titik-titik, waktu yang tersisa, atau faktor-faktor lainnya.
Seperti yang telah dikatakan, berdasarkan skala kecil dari area target anda menjatuhkan Haversine mungkin adalah langkah pertama anda menghemat waktu berharga mahal trigonometri evaluasi. CATATAN: saya tidak merekomendasikan menggunakan Euclidean distance di lat, lon koordinat - mengubah proyeksi peta anda menjadi misalnya transverse Mercator dekat pusat dan menggunakan koordinat Cartesian dalam meter atau meter!
Precomputing adalah yang kedua, dan mengubah penyusun dapat menjadi jelas ide ketiga (beralih ke C atau C++ - lihat https://benchmarksgame.alioth.debian.org/ untuk rincian).
Tambahan langkah optimalisasi mungkin termasuk menyingkirkan alokasi memori dinamis, dan efisien menggunakan indeks untuk mencari di antara node-node (berpikir R-pohon dan turunannya/alternatif).
Saya bekerja di sebuah Navigasi utama perusahaan, sehingga saya dapat mengatakan dengan keyakinan bahwa 100 ms harus mendapatkan rute dari London ke Athena bahkan pada perangkat embedded. Greater London akan menjadi tes peta bagi kita, seperti's ketika kecil (mudah cocok di RAM - ini isn't benar-benar diperlukan)
Pertama, A* sepenuhnya usang. Manfaat utama adalah bahwa hal itu "teknis" tidak't membutuhkan preprocessing. Dalam prakteknya, anda perlu untuk pra-proses OSM peta pula sehingga's sia-sia manfaat.
Teknik utama untuk memberikan anda besar meningkatkan kecepatan adalah busur bendera. Jika anda membagi peta di katakan 5x6 bagian, anda dapat mengalokasikan 1 bit di posisi 32 bit integer untuk setiap bagian. Anda sekarang dapat menentukan untuk masing-masing tepi apakah itu's pernah berguna ketika bepergian to bagian {X,Y}
dari bagian lain. Cukup sering, jalan dua arah dan ini berarti hanya salah satu dari dua arah yang lebih berguna. Jadi salah satu dari dua arah yang sedikit membedakan, dan yang lainnya telah dibersihkan. Ini mungkin tidak muncul untuk menjadi manfaat nyata, tapi itu berarti bahwa pada banyak persimpangan anda mengurangi jumlah pilihan untuk mempertimbangkan dari 2 ke 1, dan ini memakan waktu hanya satu bit operasi.
Biasanya A* datang bersama dengan terlalu banyak konsumsi memori daripada waktu stuggles.
Namun saya pikir itu bisa berguna untuk yang pertama hanya menghitung dengan node yang merupakan bagian dari "jalan-jalan besar" anda akan memilih sebuah jalan raya di atas sebuah gang kecil biasanya.
Saya kira anda mungkin sudah menggunakan ini untuk berat badan anda fungsi tetapi anda dapat lebih cepat jika anda menggunakan beberapa Antrian prioritas untuk memutuskan mana node untuk uji berikutnya untuk perjalanan jauh.
Anda juga bisa mencoba mengurangi grafik untuk hanya node-node yang merupakan bagian dari biaya rendah tepi dan kemudian menemukan cara untuk memulai/mengakhiri terdekat dari node ini. Sehingga anda memiliki 2 jalur dari mulai "jalan besar" dan "jalan besar" end. Sekarang anda dapat menghitung jalur terbaik antara dua node yang merupakan bagian dari "jalan-jalan besar" di penurunan grafik.
Pertanyaan lama, tapi belum:
Cobalah untuk menggunakan berbagai tumpukan yang "binary heap". 'Terbaik asymptotic kompleksitas heap' ini pasti Fibonacci Heap dan's halaman wiki mendapat gambaran yang baik:
https://en.wikipedia.org/wiki/Fibonacci_heap#Summary_of_running_times
Perhatikan bahwa binary heap memiliki lebih sederhana dan kode it's dilaksanakan selama array dan traversal dari array dapat diprediksi, jadi modern CPU mengeksekusi binary heap operasi much lebih cepat.
Namun, mengingat data yang cukup besar, selain tumpukan akan menang atas binary heap, karena kompleksitas mereka...
Pertanyaan ini tampaknya seperti dataset yang cukup besar.