Saya sangat akrab dengan Dijkstra dan saya memiliki pertanyaan spesifik tentang algoritme. Jika saya memiliki grafik yang sangat besar, misalnya 3,5 miliar node (semua data OpenStreetMap) maka saya jelas tidak akan dapat memiliki grafik dalam memori, sehingga grafik disimpan pada disk di dalam basis data.
Ada perpustakaan yang tersedia untuk menghitung jalur terpendek pada grafik tersebut. bagaimana mereka melakukan ini? Lebih khusus lagi, bagaimana mereka memuat bagian yang diperlukan dari grafik untuk menjalankan algoritma Dijkstra?
Mengambil daftar kedekatan dari setiap titik yang dikunjungi akan membutuhkan sekitar 1.500 permintaan basis data per 10.000 node menurut data statistik saya, sehingga jelas bukan bagaimana mereka melakukannya. Itu akan terlalu lambat.
Bagaimana mereka melakukannya? Saya mencoba menerapkannya sendiri.
sumber
Jawaban:
Anda dapat menggunakan DB, format file khusus untuk dibaca dari disk dan pengaturan di dalam memori.
Tetapi dari pengalaman saya menggunakan DB kira-kira 5 sampai 10 kali lebih lambat dan lebih banyak kehabisan memori daripada menulis format file Anda sendiri berdasarkan format daftar tertaut 'sederhana'.
Yang menyenangkan adalah ada beberapa kerangka kerja perangkat lunak menggunakan OSM yang bersifat open source sehingga Anda dapat melihat langsung ke dalam kode misalnya lihat di sini . Dalam mesin perutean open source GraphHopper , sangat mudah untuk beralih dari pengaturan yang dipetakan memori (berbasis disk) ke pengaturan di dalam memori - keduanya menggunakan format yang sama. Pengaturan "mmap" bahkan memungkinkan penggunaan pada perangkat seluler yang dibatasi memori dan yang terakhir kinerjanya jauh lebih cepat jika Anda memiliki RAM yang diperlukan misalnya pada server. Misalnya untuk grafik di seluruh dunia (> 100 juta node) Anda kemudian membutuhkan sekitar 8-10gb RAM, ditambah banyak lebih banyak RAM jika Anda ingin mempercepat semuanya lebih lanjut misalnya dengan Hirarki Kontraksi - kira-kira 5-8gb lebih untuk setiap kendaraan yang Anda inginkan.
Formatnya sangat sederhana dan pada dasarnya hanya menyimpan data yang Anda butuhkan dengan beberapa trik untuk membuatnya kompak. Baca lebih lanjut di sini . Penafian: Saya penulis GraphHopper.
Mengenai jawaban lain:
Dijkstra 'normal' dapat berkinerja sangat masuk akal (<1 untuk kueri di seluruh negara seperti contoh 3mio Anda) dan optimal dalam 'pengertian teori' tetapi perlu sedikit penyesuaian untuk mendapatkan skenario skenario produksi yang cepat. Dan teknik seperti Hierachies Kontraksi menggunakan modifikasi dua arah dan berkinerja sangat baik.
jaringan jalan bersifat hierarkis untuk mobil saja dan tidak planar (jembatan, terowongan, ...)
sumber
NodeID
simpul terdekat darilatitude/longitude
? Itu diperlukan untuk menghitung jalur terpendek A-> B. Dan kita juga perlu mengingat bahwa A dan B mungkin tidak ada sebagai simpul, karena tidak setiap meter persegi berisi sebuah simpul. Jadi kita perlu menemukan 2 NodeID terdekat dari A dan B.Anda tidak perlu meletakkan semua tepi yang berdekatan dalam antrian prioritas. "Berbohong" pada algoritme Dijkstra dan berikan hanya simpul terpendek, v, insiden pada simpul itu, katakanlah w, ditarik dari tumpukan. Kemudian, ketika v ditarik dari antrian Anda mengatakan "oops" Saya membuat kesalahan dan seharusnya memberi Anda simpul ini juga, yang merupakan terdekat terdekat dengan simpul w. Sangat mudah terlihat bahwa dengan cara ini Anda akan memiliki solusi yang benar dan ukuran antrian secara dramatis dikurangi menjadi satu titik kejadian saja, bukan banyak. Anda perlu melacak insiden untuk selalu memberikan titik terdekat berikutnya - bila diperlukan. Salah satu komentar mengklaim jaringan jalan adalah planar yang tidak benar. Faktanya, sebuah penelitian menunjukkan bahwa mereka sangat non-planar. Pikirkan semua jalan raya yang menyeberang melalui jembatan melalui kota yang memicu banyak ketidaklancaran.
sumber
Algoritma Dijkstras sementara berlaku dianggap tidak optimal untuk masalah ini meskipun varian yang lebih efisien dapat dianggap sebagai "serupa". ada berbagai penyederhanaan. jaringan jalan bersifat hierarkis dan planar . di sini adalah pendekatan dasar. daerah ini umumnya dikenal sebagai "perencanaan rute dalam jaringan jalan".
struktur grafik dapat "dikompilasi" dari data daftar adjacency. ini adalah pendekatan di perpustakaan yang Anda kutip , SpatiaLite. struktur grafik ini disimpan dalam format biner terkompresi di mana lokasi grafik diwakili oleh bilangan bulat yang disandikan biner, dll., sehingga representasi grafik dan manipulasi membutuhkan ruang yang jauh lebih sedikit daripada menyimpan semua nama jalan dll .; tampaknya algoritma SpatiaLite tidak "online" dan berjalan sepenuhnya dalam memori.
ada algoritma paralel / terdistribusi. lihat misalnya Traversal Grafik Grafik Scalable / Merrill, Garland, Grimshaw.
pertanyaannya menggunakan terminologi client-server yaitu "query". algoritma tidak berjalan dengan "meminta" database dalam arti client-server. bahasa permintaan tingkat yang lebih tinggi seperti SQL adalah antarmuka ke database dan dapat digunakan untuk mengirimkan permintaan untuk menghitung rute minimal tetapi tidak digunakan oleh algoritma secara internal. umumnya algoritma berjalan "di dalam database" yaitu seluruhnya "sisi server". jadi karenanya menulis algoritma jalur terpendek dalam permintaan basis data layak untuk jaringan kecil tetapi tidak untuk skala menengah / besar.
ada pendekatan lain di mana estimasi dalam persentase kecil dapat diterima. ide dasarnya adalah untuk menjaga indeks jarak antar node. lihat mis. Estimasi Cepat dan Akurat dari Jalur Terpendek dalam Grafik Besar / Gubichev, Bedathur, Seufert, Weikum
tesis Phd (235p!) ini sangat berlaku. Perencanaan Rute di Jaringan Jalan / Schultes
beberapa algoritma menggunakan banyak dari ide-ide ini dan yang lainnya, sangat disesuaikan dan berpemilik dan mendekati rahasia perdagangan yang kompetitif. misalnya Google. mungkin ada beberapa media yang menyesatkan tentang hal ini. eg Algoritma Sederhana, Elegan yang Membuat Google Maps Kemungkinan yang mengklaim / menyiratkan Google menggunakan algoritma Dijkstras tanpa kutipan.
sumber
Pada set data yang sangat besar seperti itu, untuk mendapatkan hasil yang begitu cepat, saya merasa lebih baik menggunakan struktur data union-find dengan kompresi jalur. Namun, jika Anda mencari untuk hanya menggunakan algoritma Djikstra dan mengoptimalkannya, itu tergantung pada informasi apa yang dimiliki masing-masing simpul dalam grafik. Kemungkinan besar Anda tidak perlu melakukan semua 1.500 kueri.
Sebagai contoh, perhatikan contoh berikut. Katakanlah saya mencoba untuk menemukan derajat pemisahan antara 2 aktor (nomor Bacon) dan saya ingin menemukan jalur yang paling tidak berbobot (jalur menggunakan film terbaru mungkin). Sekarang, katakanlah saya memiliki fungsi yang dipanggil
shortestPath(actor A, actor B);
. Pertimbangkan skenario berikut.Jika Aktor A telah berakting sejak tahun 1970 dan Aktor B telah berakting sejak tahun 2000, maka mengingat info itu, akan jauh lebih logis untuk menemukan jalur mulai dari film pertama dari Aktor B dan kemudian melintasi jalan Anda ke Aktor A. Sebagai menentang iterasi melalui setiap film yang diperankan oleh Aktor A.
Jadi, intinya adalah bahwa optimalisasi algoritma Djikstra benar-benar tergantung pada apa set data Anda. Anda perlu memberikan lebih banyak informasi tentang apa yang dibutuhkan set data Anda agar kami dapat membantu Anda mengoptimalkan algoritma Anda.
EDIT: Katakanlah Anda mencoba menemukan jalur terpendek antara 2 kota di negara yang sama dan jika negara ini lebih panjang daripada yang lebih luas, misalnya Argentina, maka Anda dapat melakukan kueri berdasarkan garis bujur dan garis lintang negara batas-batas. Kemudian Anda dapat mulai melintasi secara vertikal (menggunakan bujur) sebagai kebalikan dari horizontal. Ofc, perlu ada penanganan pengecualian, tetapi Anda mendapatkan ide umum.
sumber