Pemrograman dinamis dapat mengurangi waktu yang dibutuhkan untuk melakukan algoritma rekursif. Saya tahu bahwa pemrograman dinamis dapat membantu mengurangi kompleksitas waktu dari algoritma. Apakah kondisi umum sedemikian rupa sehingga jika puas dengan algoritma rekursif akan menyiratkan bahwa menggunakan pemrograman dinamis akan mengurangi kompleksitas waktu dari algoritma? Kapan saya harus menggunakan pemrograman dinamis?
13
Jawaban:
Pemrograman dinamis bermanfaat adalah algoritma rekursif Anda menemukan dirinya mencapai situasi yang sama (parameter input) berkali-kali. Ada transformasi umum dari algoritma rekursif ke pemrograman dinamis yang dikenal sebagai memoisasi , di mana ada tabel yang menyimpan semua hasil yang pernah dihitung oleh prosedur rekursif Anda. Ketika prosedur rekursif dipanggil pada set input yang sudah digunakan, hasilnya baru diambil dari tabel. Ini mengurangi Fibonacci rekursif ke Fibonacci berulang.
Pemrograman dinamis dapat menjadi lebih pintar, menerapkan optimasi yang lebih spesifik. Misalnya, kadang-kadang tidak perlu menyimpan seluruh tabel dalam memori pada waktu tertentu.
sumber
Jika Anda hanya ingin mempercepat algoritme rekursif Anda, memoisasi mungkin cukup. Ini adalah teknik menyimpan hasil panggilan fungsi sehingga panggilan di masa depan dengan parameter yang sama bisa menggunakan kembali hasilnya. Ini berlaku jika (dan hanya jika) fungsi Anda
Ini akan menghemat waktu Anda jika (dan hanya jika) fungsi dipanggil dengan parameter yang sama berulang-ulang. Contoh-contoh populer termasuk definisi rekursif dari angka-angka Fibonacci, yaitu
Ketika dievaluasi secara naif, sering disebut secara eksponensial. Dengan memoisasi, selalu dihitung dengan , sehingga hanya sejumlah panggilan linear yang tersisa.f ( n ) f ( n + 1 )f f(n) f(n+1)
Perhatikan bahwa, sebaliknya, memoisasi hampir tidak berguna untuk algoritma seperti penggabungan: biasanya beberapa (jika ada) sebagian daftar identik, dan pemeriksaan kesetaraan mahal (pengurutan hanya sedikit lebih mahal!).
Dalam implementasi praktis, cara Anda menyimpan hasil sangat penting untuk kinerja. Menggunakan tabel hash mungkin merupakan pilihan yang jelas, tetapi mungkin merusak wilayah. Jika parameter Anda adalah bilangan bulat non-negatif, array adalah pilihan alami tetapi dapat menyebabkan overhead memori yang besar jika Anda hanya menggunakan beberapa entri. Oleh karena itu, memoisasi adalah pertukaran antara efek dan biaya; apakah itu terbayar tergantung pada skenario spesifik Anda.
Pemrograman dinamis adalah binatang yang sepenuhnya lain. Itu berlaku untuk masalah dengan properti itu
Ini biasanya (secara implisit) tersirat ketika orang-orang menggunakan Bellman Principle of Optimality .
Sekarang, ini hanya menggambarkan kelas masalah yang dapat diekspresikan oleh jenis rekursi tertentu. Evaluasi hal-hal itu (sering) efisien karena memoisasi dapat diterapkan dengan efek yang besar (lihat di atas); biasanya, subproblem yang lebih kecil terjadi sebagai bagian dari banyak masalah yang lebih besar. Contoh populer termasuk jarak edit dan algoritma Bellman-Ford .
sumber