Ini adalah pertanyaan yang sangat bagus. Saya tidak memiliki penjelasan yang sepenuhnya memuaskan, tetapi izinkan saya memberi Anda permulaan.
Pertama, penting untuk dipahami bahwa kami tidak dapat menyelesaikan masalah ini hanya dengan menghitung semua siklus dan memeriksa bobot masing-masing. Kenapa tidak? Karena mungkin ada (dan sering kali) banyak siklus secara eksponensial. Oleh karena itu, hanya penghitungan saja akan membutuhkan waktu yang eksponensial - terlalu lama untuk memungkinkan.
Jadi bagaimana cara kerja Bellman-Ford? Ini bekerja dengan beberapa trik pintar yang menghindari kebutuhan untuk secara individual memeriksa setiap siklus satu per satu. Alih-alih, itu membangun ringkasan yang merangkum sesuatu tentang efek dari semua jalur dan siklus panjang hinggan. Secara efektif, untuk setiap titikv, ini merangkum semua jalur yang dimulai v, akhiri pada v, dan ambil paling banyak nLangkah. Karena setiap siklus harus mengandung lintasan formulir ini, ringkasan entah bagaimana merangkum efek dari semua siklus yang mungkin.
Mengapa kita tidak bisa menggunakan ini untuk mendeteksi (katakanlah) apakah ada siklus berat ≥1? Itu karena ringkasan Bellman-Ford mencakup jalur yang berjalan mengelilingi siklus beberapa kali. Jika siklusnya panjangk, maka itu akan mencakup jalur panjang nyaitu jalur yang berjalan di sekitar siklus n/kwaktu. Misalnya, jika Anda memiliki siklus panjangn/3, lalu ringkasan menyertakan jalur yang berjalan di sekitar siklus tiga kali.
Apa efek berjalan mengelilingi siklus beberapa kali? Jika Anda ingin membedakan siklus positif-berat dari siklus yang beratnya tidak positif, berjalan mengelilingi siklus beberapa kali tidak ada salahnya. Jika siklus memiliki berat positif, maka Anda dapat berjalan di sekitarnya beberapa kali dan berat total akan tetap positif. Jika berat siklus tidak positif, maka Anda dapat berjalan di sekitarnya beberapa kali dan berat total akan tetap tidak positif. Jadi, jika yang kita pedulikan adalah perbedaan antara berat positif dan non-positif, berjalan di sekitar siklus beberapa kali tidak ada salahnya.
Tetapi sekarang pertimbangkan bagaimana hal-hal berubah jika apa yang kita pedulikan adalah perbedaan antara "berat ≥1"vs" berat <1"Jika kita memiliki siklus yang beratnya <1 dan kami berjalan mengitari siklus itu beberapa kali, total berat mungkin menjadi ≥1. Misalnya, jika bobot siklusnya adalah1/2 dan kami berjalan mengelilingi siklus itu tiga kali, maka bobot total dari jalur itu adalah 1.5, yang mana ≥1: kami mulai dengan siklus berat <1 dan berakhir dengan jalur berat ≥1.5. Fakta ini benar-benar mengacaukan Bellman-Ford dan membuatnya tidak berguna untuk memeriksa apakah ada siklus berat≥1. (Apakah Anda melihat perbedaannya?)
Saya menyadari ini bukan jawaban yang memuaskan 100%. Ini memberi tahu Anda mengapa Bellman-Ford tidak akan bekerja untuk menyelesaikan masalah Anda. Namun, itu tidak memberi Anda intuisi untuk menjelaskan mengapa ini sulit secara umum (misalnya, mengapa sulit untuk menemukan beberapa algoritma lain untuk menyelesaikannya). Saya tidak memiliki intuisi yang bagus untuk itu - mungkin orang lain akan memiliki penjelasan yang lebih baik untuk Anda. Sementara itu, mungkin ini memberi Anda awal untuk memahami mengapa masalah ini sulit.
Mari kita perhatikan versi sederhana dari masalah ini di mana edge tidak berbobot.
Diberikan grafikG , periksa apakah G memiliki siklus.
Diberikan grafikG dan angka k , periksa apakah G memiliki siklus panjang setidaknya k .
Yang pertama mudah dan bisa diselesaikan menggunakan DFS. Yang kedua adalah NP-hard.
Mari kita lihat masalah yang lebih sederhana:
Diberikan grafikG dan dua simpul s dan t , periksa apakah ada jalur sederhana dari s untuk t di G .
Diberikan grafikG dan dua simpul s dan t dan angka k , periksa apakah ada jalur sederhana dari s untuk t di G panjang setidaknya k .
Semua masalah ini memiliki cita rasa yang sama. Yang paling atas mudah sedangkan yang paling bawah NP-hard. Saya akan menjelaskan perbedaan untuk yang terakhir karena lebih sederhana tetapi penjelasan yang sama berlaku untuk pasangan lainnya.
Alasan mengapa yang paling atas itu mudah, sedangkan yang paling bawah bukan karena struktur jawaban untuk masalah-masalah ini.
Pertama-tama mari kita lihat masalah menemukan jalan yang sederhana dan mencoba menyelesaikannya secara rekursif. Jika kita hanya mencoba menyelesaikan masalah ini secara langsung, kita perlu melacak simpul yang telah kita gunakan sejauh ini:
Jika kita mencoba untuk menyelesaikan masalah dengan algoritma rekursif naif ini akan memakan waktu eksponensial: ada banyak kemungkinan secara eksponensial untuk set simpul yang tidak digunakan! Kita harus lebih pintar.
Mengapa kita mendapatkan banyak kemungkinan secara eksponensial? Karena kami berusaha menemukan jalan yang sederhana dan untuk menegakkan kondisi ini, kami perlu melacak simpul yang tidak digunakan.
OK, jadi mari kita jatuhkan kondisi itu dan lihat di mana kita bisa mendapatkan:
Pertimbangkan masalah menemukan jalan (tidak perlu sederhana) daris untuk t . Karena jalan tidak perlu sederhana, kita tidak perlu melacak simpul yang tidak digunakan. Dengan kata lain, grafik tidak berubah seiring waktu.
Tapi kita belum selesai. Masalahnya adalah kita tidak tahu jikaPathG(s,u)
adalah masalah yang lebih kecil dari PathG(s,t) . Jadi solusi rekursif ini mungkin berakhir dalam satu lingkaran dan tidak pernah berakhir.
Untuk menghindari ini, kita dapat menambahkan parameter tambahan yang memastikan masalah semakin kecil: jumlah tepi di jalur.
Sekarang perhatikan bahwa ada jalur sederhana daris untuk t jika ada jalan dari s untuk t dengan paling banyak n ujung-ujungnya. Dengan kata lain:
Poin-poin penting di sini adalah:
Setiap jalur sederhana (nontrivial) daris untuk t
terdiri dari jalur sederhana dari s untuk beberapa titik u dan keunggulan ut .
Kita bisa berasumsi itut tidak muncul di jalur sederhana dari s untuk u .
Kami tidak perlu secara eksplisit menyimpan daftar simpul yang tidak digunakan.
Properti ini memungkinkan kita untuk memiliki rekursi yang cerdas untuk keberadaan masalah jalur sederhana.
Sekarang ini tidak berlaku untuk masalah menemukan jalur panjang setidaknyak . Kami tidak tahu cara mengurangi masalah menemukan jalur panjang sederhana setidaknyak
ke subproblem yang lebih kecil tanpa menyimpan daftar simpul yang tidak digunakan. Properti itu memungkinkan kita untuk memecahkan masalah keberadaan jalur secara efisien.
Ketika grafik tidak memiliki siklus negatif, mereka memungkinkan kita untuk menyelesaikan keberadaan jalur panjang paling banyakk masalah dan masalah jalur sederhana terpendek efisien.
Namun mereka tidak memiliki keberadaan jalur panjang setidaknyak . Pertimbangkan grafik dengan3 sudut s,u,t .
w(su)=1000,w(st)=1000,w(ut)=10,w(tu)=10 . Jalur panjang setidaknya1001 dari s untuk t mengandung u dan jalur panjang setidaknya 1001 dari s untuk u mengandung t . Jadi kita tidak bisa mengurangi instance masalah menjadi instance yang lebih kecil dari masalah tanpa secara eksplisit memberikan daftar simpul yang tidak digunakan.
Dengan kata lain, kita tidak tahu rekursi yang cerdas untuk keberadaan jalur panjang sederhana setidaknyak masalah sementara kita tahu rekursi yang cerdas untuk keberadaan jalan yang sederhana.
Kembali ke bagian terakhir dari pertanyaan Anda, ada masalah dengan argumen Anda.
Memang demikian adanya siklus panjang>k
dapat diselesaikan dalam waktu polinomial untuk setiap perbaikan k (yaitu k bukan bagian dari input). (Mirip dengan bagaimana seseorang dapat memeriksa apakah grafik tidak tertimbang memiliki siklus panjangk
pada waktunya O(nk) .)
Namun kapank merupakan bagian dari input yang tidak dapat digunakan lagi karena waktu berjalan tergantung k dengan cara yang buruk.
sumber