Mengapa DFS tidak dapat digunakan untuk menemukan jalur terpendek dalam grafik tidak tertimbang?

16

Saya mengerti bahwa menggunakan DFS "sebagaimana adanya" tidak akan menemukan jalur terpendek dalam grafik tidak tertimbang.

Tetapi mengapa mengutak-atik DFS untuk memungkinkannya menemukan jalur terpendek dalam grafik tak tertimbang sedemikian rupa sehingga menjadi harapan yang sia-sia? Semua teks pada subjek hanya menyatakan bahwa itu tidak dapat dilakukan. Saya tidak yakin (tanpa mencobanya sendiri).

Apakah Anda tahu modifikasi apa pun yang akan memungkinkan DFS menemukan jalur terpendek dalam grafik tidak tertimbang? Jika tidak, ada apa dengan algoritma yang membuatnya sangat sulit?

Kucing Unfun
sumber
1
Algoritma pathfinding paling umum pada grafik tidak tertimbang adalah A *, dengan sedikit modifikasi yang mengikat lebih dekat ke finish. Ini akan memberikan algoritma yang mirip dengan DFS, karena ia akan mencoba rute paling langsung terlebih dahulu, dan hanya gelembung keluar jika perlu.
BlueRaja - Danny Pflughoeft
1
Coba gunakan DFS pada beberapa grafik (dipilih dengan baik); jika itu benar-benar tidak berhasil, Anda harus menemui masalah. Btw, pertanyaan Anda berbunyi seolah-olah itu bekerja pada grafik tertimbang.
Raphael
ya kamu bisa melakukannya. Ini solusinya
Anmol Middha

Jawaban:

12

Satu-satunya elemen pencarian mendalam-pertama yang Anda ubah adalah urutan penyelidikan anak-anak. Versi normal berlangsung dalam urutan acak, yaitu dalam urutan anak-anak disimpan.

Satu-satunya alternatif yang layak (menuju jalur terpendek) yang bisa saya temukan adalah pendekatan serakah, yaitu melihat anak-anak dalam urutan jarak mereka dari simpul saat ini (dari kecil ke besar). Sangat mudah untuk membuat sampel tandingan untuk aturan ini:

contoh berlawanan untuk aturan serakah
[ sumber ]

Sekarang, itu bukan bukti bahwa tidak ada strategi untuk memilih anak berikutnya yang akan diselidiki yang akan membuat DFS menemukan jalur terpendek.

Namun, tidak peduli aturan¹ Anda dapat membuat grafik yang memiliki DFS berkomitmen untuk jalan memutar panjang pada simpul pertama, seperti yang saya lakukan untuk aturan serakah. Tetapkan tepi dan bobot sedemikian sehingga aturan memilih untuk mengunjungi pertama, dan menetapkan bobot yang lebih besar daripada yang . Oleh karena itu, masuk akal bahwa DFS tidak pernah dapat menemukan jalur terpendek (dalam grafik umum).( s , a ) a ( a , b ) ( s , t )(s,t)(s,a)a(a,b)(s,t)

Perhatikan bahwa karena Anda dapat mengekspresikan setiap grafik berbobot (bilangan positif-bilangan bulat) sebagai grafik tidak berbobot - cukup ganti tepi dengan biaya dengan rantai dengan simpul - contoh yang sama berhubungan dengan DFS pada grafik tanpa bobot. Di sini, situasinya bahkan lebih suram: tanpa beban, apa yang bisa digunakan DFS untuk menentukan anak berikutnya yang akan dikunjungi?c - 1cc1


  1. Selama aturannya deterministik. Jika tidak, itu jelas tidak selalu dapat menemukan jalur terpendek.
Raphael
sumber
Perbaiki saya jika saya salah, tetapi apakah ini berarti bahwa DFS dapat menemukan jalur terpendek dalam grafik apa pun, tetapi akan memakan waktu eksponensial saat melakukannya?
Anmol Singh Jaggi
@AnmolSinghJaggi No. DFS hanya pernah menemukan satu jalur.
Raphael
10

Breadth -first-search adalah algoritma yang akan menemukan jalur terpendek dalam grafik tidak tertimbang.

Ada tweak sederhana untuk mendapatkan dari DFS ke sebuah algoritma yang akan menemukan jalur terpendek pada grafik tidak tertimbang. Pada dasarnya, Anda mengganti tumpukan yang digunakan oleh DFS dengan antrian. Namun, algoritma yang dihasilkan tidak lagi disebut DFS. Sebagai gantinya, Anda akan menerapkan pencarian luas pertama.

Paragraf di atas memberikan intuisi yang benar, tetapi terlalu menyederhanakan situasi sedikit. Sangat mudah untuk menulis kode yang swap sederhana tidak memberikan implementasi pencarian pertama yang luas, tetapi juga mudah untuk menulis kode yang pada awalnya terlihat seperti implementasi yang benar tetapi sebenarnya tidak. Anda dapat menemukan pertanyaan cs.SE terkait BFS vs DFS di sini . Anda dapat menemukan beberapa kode pseudo yang bagus di sini.

Joe
sumber
3

Kamu bisa!!!

Tandai node sebagai dikunjungi saat Anda pergi mendalam dan menghapus tanda saat Anda kembali, saat kembali ketika Anda menemukan cabang lain ulangi sama.

Hemat biaya / jalur untuk semua kemungkinan pencarian di mana Anda menemukan node target, bandingkan semua biaya / jalur tersebut dan pilih yang terpendek.

Masalah besar (dan saya maksudkan BESAR) dengan pendekatan ini adalah bahwa Anda akan mengunjungi simpul yang sama beberapa kali yang membuat dfs pilihan yang jelas buruk untuk algoritma jalur terpendek.

pengguna2407394
sumber
1
st
1
@ user2407394 Sudahkah Anda benar-benar menerapkan variasi DFS ini sekali dan menjalankannya dengan benar untuk grafik yang cukup besar? Saya akan ragu menyebut variasi ini sebagai DFS. Saya akan menyebutnya pencarian mendalam-pertama-melelahkan jalan.
John L.
Saya sudah menerapkan pendekatan semacam ini, kerjanya sangat lambat. Saya sedang berpikir tentang menambahkan mnemonisasi untuk meningkatkan kinerja.
Mic
@ user2407394 sepertinya berhasil, tetapi bagaimana Anda memeriksa kapan harus berhenti karena tidak akan ada daftar 'dikunjungi' jika Anda tidak menandai semuanya?
Joe Black
0

BFS memiliki properti yang bagus yang akan memeriksa semua tepi dari root dan menjaga jarak dari root ke node lain seminimal mungkin, tetapi dfs hanya melompat ke node yang berdekatan pertama dan berjalan dengan bijak. Anda BISA memodifikasi DFS untuk mendapatkan jalur terpendek, tetapi Anda hanya akan berakhir dalam algoritme yang memiliki kompleksitas waktu lebih tinggi atau pada akhirnya akan melakukan hal yang sama seperti yang dilakukan BFS

vikkyhacks
sumber
-3

TI dimungkinkan untuk menemukan jalur antara dua simpul dengan jumlah tepi minimum menggunakan DFS. kita bisa menerapkan pendekatan level

Abereham Wodajia
sumber
2
Tolong beri lebih detail. Saya tidak tahu algoritma apa yang Anda coba gambarkan dalam kalimat tunggal ini.
David Richerby
-3

Kamu bisa

cukup lintasi grafik dengan cara dfs dan periksa

if(distance[dest] > distance[source]+cost[source_to_destination]){
    distance[dest] = distance[source] + cost[source_to_destination]);
}

Inilah tautan untuk solusi lengkap

Anmol Middha
sumber
1
Jawaban yang diterima mengklaim ini tidak mungkin, yang bertentangan dengan klaim Anda. Bisakah Anda menjelaskan mengapa Anda berpikir bahwa pendekatan ini berhasil? (atau jelaskan mengapa pendekatan ini bekerja secara umum)
Kadal diskrit
Bukankah ini hanya mengulangi jawaban user2407394 ini , hanya dengan hard-to-memahami kode (Anda tidak didefinisikan apa pun dari variabel berarti, dan itu tidak jelas, bagi saya) bukan penjelasan?
David Richerby
Ya, ini adalah implementasi dari jawaban user2407394. Maaf atas ketidaknyamanan Saya telah menambahkan komentar dalam kode. Anda bisa memeriksanya sekarang.
Anmol Middha