Memoisasi tanpa array

14

Dalam Pengantar algoritma Cormen et al. , Bagian 15.3 Elemen pemrograman dinamis menjelaskan memoisasi sebagai berikut:

Algoritma rekursif memoized mempertahankan entri dalam tabel untuk solusi untuk setiap sub-masalah. Setiap entri tabel awalnya berisi nilai khusus untuk menunjukkan bahwa entri belum diisi. Ketika subproblem pertama kali ditemui ketika algoritma rekursif dibuka, solusinya dihitung dan kemudian disimpan dalam tabel. Setiap kali kita menghadapi subproblem ini, kita cukup mencari nilai yang disimpan dalam tabel dan mengembalikannya.

Dan itu menambahkan, sebagai catatan kaki:

Pendekatan ini mengandaikan bahwa kita mengetahui himpunan semua parameter subproblem yang mungkin dan bahwa kita telah menetapkan hubungan antara posisi tabel dan subproblem. Lain, lebih umum, pendekatan adalah untuk memoize dengan menggunakan hashing dengan parameter subproblem sebagai kunci.

Apakah ada masalah DP yang perlu diketahui (atau membuatnya lebih mudah) untuk menyimpan nilai memoized dalam kamus daripada dalam array (multi dimensi)?


Latar belakang: jika ini ada gunanya, alasan untuk pertanyaan ini adalah bahwa saya mencoba untuk memotivasi gagasan pohon pencarian biner (seimbang) kepada orang-orang yang baru saja melihat pemrograman dinamis.

Pece
sumber
Dalam perangkat lunak asli yang bekerja dengan saya, memoizing dapat menggunakan fakta bahwa fungsi yang relatif mahal (seperti exp , log , atau pow ) dapat dipanggil dari berbagai tempat dalam kode, dan sering disebut beberapa kali sesuai dengan nilai yang sama dari setiap lokasi kode tertentu. Dalam hal itu, "kamus" dapat berupa nilai tunggal yang disimpan dalam variabel spesifik lokasi kode.
Mike Dunlavey

Jawaban:

5

Mungkin ada contoh-contoh yang lebih baik, tetapi ini ada satu, di luar kepala saya:

Katakanlah Anda ingin memeriksa apakah jarak edit antara dua string adalah , dan jika ya, hitung jarak edit. Anda dapat menggunakan algoritme pemrograman dinamis standar untuk menghitung jarak edit, tetapi "pangkas" perhitungannya (hentikan rekursi) di tempat di mana jarak edit diketahui . Ini berarti Anda mungkin tidak perlu mengisi seluruh tabel; Anda hanya perlu mengisi beberapa entri. Dengan demikian, menggunakan kamus dapat memberikan peningkatan kinerja.S,Td>d

DW
sumber
3

Saya ingin memberikan 2 contoh.

0-1 Masalah ransel

Dalam hal masalah 0-1 Knapsack (di mana W adalah kapasitas dari knapsack dan N adalah jumlah item), kadang-kadang lebih baik menggunakan Pemrograman Dinamis top-down dengan memoisasi, daripada enumerasi bottom-up sistematis dari seluruh array 2D ukuran WxN (terutama dalam kasus ketika kapasitas ransel W besar, tetapi kardinalitas himpunan kombinasi bobot item yang diizinkan jauh lebih kecil daripada W ).

Dalam hal ini, demi penghematan memori, orang dapat memilih untuk menggunakan kamus untuk memoisasi daripada array 2D.

Algoritma parsing Earley

Algoritma parsing Earley dapat digunakan untuk parsing pernyataan, yang termasuk dalam tata bahasa bebas konteks. Berbeda dengan algoritma CYK (yang didasarkan pada pendekatan DP bottom-up, dan menggunakan tabel 2D untuk memoisasi) - Earley parser menggunakan pendekatan top-down dalam kombinasi dengan bagan parsing untuk memoisasi.

Parsing chart berisi produksi gramatikal yang diurai sebagian (misalnya: diberikan produksi X → AB , dan setelah pencocokan yang sukses dari bagian A dari produksi ini, kami menyimpan produksi yang sebagian cocok di dalam diagram penguraian: X → A • B , di mana titik poin ke bagian yang sudah cocok).

Jumlah kolom di dalam bagan parsing sama dengan jumlah token. Namun, dalam kasus umum mungkin sangat sulit, untuk memperkirakan jumlah produksi tata bahasa yang diurai sebagian per kolom (tergantung pada tata bahasa dan urutan token tertentu).

Oleh karena itu, lebih mudah untuk mengimplementasikan parsing chart berdasarkan pada struktur data kamus.

Dalam domain Natural Language Processing, biasanya Earley pareser adalah pilihan yang lebih nyaman, karena tidak memerlukan bentuk normal Chomsky untuk tata bahasa (dan CYK memang memiliki persyaratan seperti itu).

batang
sumber
0

Dalam pengalaman saya dari pemrograman kompetitif, menggunakan tabel hash (Python dictatau serupa) sering lebih nyaman daripada menggunakan array, karena semua tipe data hashable dapat digunakan sebagai kunci, seperti string, set ( frozensetdengan Python) atau tuple seperti (string, int)dll. Jika menggunakan array, Anda harus menerjemahkan secara manual semua kunci menjadi bilangan bulat (mulai dari 0), yang membutuhkan kerja ekstra dan, seperti yang dicatat oleh sumber Anda, mungkin tidak dapat dilakukan jika Anda tidak tahu ruang kunci sebelumnya. Jadi kamus lebih umum daripada array.

Tentu saja, jika Anda bisa menggunakan array, ini mungkin lebih cepat karena menghindari berulang kali menghitung hash (di sisi lain itu membutuhkan inisialisasi seluruh array terlebih dahulu, yang membutuhkan waktu dan memori), tetapi mungkin perlu waktu lebih lama untuk menulis kode karena Anda harus melakukan pekerjaan ekstra menerjemahkan semua kunci menjadi bilangan bulat.

Elias Riedel Gårding
sumber