Cukup mirip dengan pertanyaan saya yang diposting sebelumnya . Namun kali ini, grafik tidak diarahkan.
Diberikan
- Sebuah diarahkan grafik tanpa multiple-tepi atau loop,
- Sumber simpul ,
- Target titik ,
- Panjang jalur maksimal ,
Saya mencari - Subgraf yang berisi simpul dan tepi (dan hanya itu), yang merupakan bagian dari setidaknya satu jalur sederhana dari ke dengan panjang .
Catatan:
- Saya tidak perlu menyebutkan jalan.
- Saya mencari algoritma yang efisien (baik waktu dan memori), karena saya perlu menjalankannya pada grafik yang sangat besar (10 ^ 8 vertex, 10 ^ 9 edge).
ds.algorithms
graph-algorithms
shortest-path
Lior Kogan
sumber
sumber
Jawaban:
Nah, masalahnya ada di setelah semua. Aku akan menjaga jawaban sebelumnya karena juga bekerja untuk kasus diarahkan (yang NPC, seperti menjawab pada pertanyaan lain), dan menunjukkan itu adalah F P T sehubungan dengan l .P FPT l
Dalam kasus yang tidak diarahkan, ini dapat dipecahkan, secara deterministik melalui aliran biaya minimum (ini mungkin tidak bekerja pada skala yang Anda maksudkan dalam pertanyaan, tetapi lebih baik daripada algoritma eksponensial.
Prosedur berikut akan memutuskan apakah beberapa sisi harus menjadi bagian dari grafik output. Untuk menjawab masalah awal, lakukan perulangan di semua sisi.e=(u,v)∈E
Untuk membuat jaringan aliran, lakukan hal berikut:
Langkah 1: Perluas untuk memiliki simpul x e dan ganti e dengan tepian ( u , x e ) , ( x e , u ) , ( v , x e ) , ( x e , v ) (mereka diarahkan sebagai bagian dari jaringan aliran), tetapkan biaya ke 0.e xe e (u,xe), (xe,u),(v,xe),(xe,v)
Langkah 2: ganti setiap simpul , kecuali untuk x e oleh dua simpul t - dan t + , dan tambahkan tepi ( t - , t + ) . Atur biaya tepi ini ke 1.t xe t− t+ (t−,t+)
Langkah 3: Ganti setiap tepi dengan tepi ( a + , b - ) , ( b + , a - ) . Setel biaya tepi ini ke 0.{a,b}∈E (a+,b−),(b+,a−)
Langkah 4: Menambahkan baru vertex dan menambahkan tepi ( s , y e ) , ( t , y e ) dengan biaya 0.ye (s,ye),(t,ye)
Langkah 5: atur semua kapasitas ke 1.
Sekarang jalankan algoritma aliran biaya min, mencari aliran nilai 2 dari ke y e .xe ye
Analisis:
sumber
Berikut adalah jawaban yang salah : ini menghasilkan beberapa simpul yang merupakan bagian dari jalur non-sederhana dari ke dan yang bukan bagian dari jalur sederhana dari ke dari panjang . Jawabannya mungkin masih relevan dengan aplikasi penanya, jadi saya meninggalkannya di sini.t s t ≤ ℓs t s t ≤ℓ
Berikut ini adalah algoritma yang berjalan dalam waktu (dan sebenarnya lebih cepat dari ini ketika kecil).ℓO(|V|+|E|) ℓ
Algoritma menjalankan pencarian BFS dari yang berakhir pada kedalaman . BFS ini memberikan satu set dari semua simpul dicapai dari dengan jalan panjang paling , dan juga menghitung jarak untuk setiap . Lalu saya akan melakukan hal yang sama dari dan mendapatkan himpunan dan jarak dari . Akhirnya, simpul yang Anda cari persis . Tepi-tepi itu persis tepi-tepi itu dalam (s ℓ Vs s ℓ dist(s,v) v∈Vs t Vt t Vsolution={v:v∈Vs∩Vt,dist(s,v)+dist(t,v)≤ℓ} E[Vsolution] =(v,u)∈E:u,v∈Vsolution ).
Waktu berjalan dari algoritma ini pastinya adalah karena hanya melakukan dua BFSs. Tetapi waktu sebenarnya adalah yang akan jauh lebih kecil dari ukuran grafik ketika lingkungan -radius dari dan kecil.O ( | V s | + | V t | + | E [ V s ] | + | E [ V t ] | ) ℓ s tO(|V|+|E|) O(|Vs|+|Vt|+|E[Vs]|+|E[Vt]|) ℓ s t
Sunting: mungkin ada algoritma yang agak lebih cepat dalam praktiknya yang melakukan BFS dari dan hanya kedalaman daripada . Ini menemukan semua jalur, dan kemudian dengan sedikit pembukuan Anda dapat menemukan semua simpul. Ini memotong waktu berjalan dengan akar kuadrat untuk kasus grafik tampak acak besar ketika kecil.t ℓ / 2 ℓ ℓs t ℓ/2 ℓ ℓ
sumber
Ini dimaksudkan sebagai komentar, tetapi terlalu lama untuk memposting sebagai komentar.
Jika ini terdengar bermanfaat, saya dapat mencoba dan menggali konstruksi yang relevan untuk Anda.
sumber