Saya baru saja memulai Python dan saya tidak tahu apa itu memoisasi dan bagaimana menggunakannya. Juga, bolehkah saya memiliki contoh sederhana?
python
memoization
blur959
sumber
sumber
Jawaban:
Memoisasi secara efektif mengacu pada mengingat ("memoisasi" → "memorandum" → untuk diingat) hasil pemanggilan metode berdasarkan input metode dan kemudian mengembalikan hasil yang diingat daripada menghitung hasilnya lagi. Anda dapat menganggapnya sebagai cache untuk hasil metode. Untuk perincian lebih lanjut, lihat halaman 387 untuk definisi dalam Pengantar Algoritma (3e), Cormen et al.
Contoh sederhana untuk menghitung faktorial menggunakan memoisasi dengan Python akan menjadi seperti ini:
Anda bisa menjadi lebih rumit dan merangkum proses memoisasi ke dalam kelas:
Kemudian:
Fitur yang dikenal sebagai " dekorator " telah ditambahkan dalam Python 2.4 yang memungkinkan Anda untuk sekarang cukup menulis yang berikut untuk mencapai hal yang sama:
The Python dekorator Perpustakaan memiliki dekorator serupa yang disebut
memoized
yang sedikit lebih kuat dariMemoize
kelas yang ditampilkan di sini.sumber
factorial_memo
, karena bagianfactorial
dalamdef factorial
masih menyebut yang lama tidak dapat diemofactorial
.if k not in factorial_memo:
, yang lebih baik daripada membacaif not k in factorial_memo:
.args
tuple.def some_function(*args)
membuat args tuple.Baru untuk Python 3.2 adalah
functools.lru_cache
. Secara default, hanya cache panggilan 128 yang terakhir digunakan, tapi Anda dapat mengaturmaxsize
untukNone
untuk menunjukkan bahwa cache tidak harus berakhir:Fungsi ini dengan sendirinya sangat lambat, coba
fib(36)
dan Anda harus menunggu sekitar sepuluh detik.Menambahkan
lru_cache
anotasi memastikan bahwa jika fungsi baru-baru ini dipanggil untuk nilai tertentu, itu tidak akan menghitung ulang nilai itu, tetapi menggunakan hasil sebelumnya yang di-cache. Dalam hal ini, ini mengarah pada peningkatan kecepatan yang luar biasa, sementara kode tidak berantakan dengan detail caching.sumber
fib
dipanggil, harus berulang ke kasing dasar sebelum memoisasi dapat terjadi. Jadi, perilaku Anda sudah sesuai harapan.Jawaban lainnya mencakup apa yang cukup baik. Saya tidak mengulanginya. Hanya beberapa poin yang mungkin bermanfaat bagi Anda.
Biasanya, memoisasi adalah operasi yang dapat Anda terapkan pada fungsi apa pun yang menghitung sesuatu (mahal) dan mengembalikan nilai. Karena itu, ini sering diterapkan sebagai dekorator . Implementasinya sangat mudah dan akan seperti ini
atau diekspresikan sebagai dekorator
sumber
Memoisasi adalah menjaga hasil perhitungan yang mahal dan mengembalikan hasil yang di-cache daripada terus-menerus menghitung ulang.
Ini sebuah contoh:
Deskripsi yang lebih lengkap dapat ditemukan di entri wikipedia tentang memoisasi .
sumber
if input not in self.cache
danself.cache[input]
(has_key
sudah usang sejak ... di awal seri 2.x, jika tidak 2.0. Tidakself.cache(index)
pernah benar. IIRC)Jangan lupa
hasattr
fungsi bawaan, untuk mereka yang ingin kerajinan tangan. Dengan begitu Anda dapat menyimpan cache mem di dalam definisi fungsi (sebagai lawan global).sumber
Saya menemukan ini sangat berguna
sumber
functools.wraps
.memo
sehingga memori dibebaskan?Memoisasi pada dasarnya menyimpan hasil operasi masa lalu yang dilakukan dengan algoritma rekursif untuk mengurangi kebutuhan untuk melintasi pohon rekursi jika perhitungan yang sama diperlukan pada tahap selanjutnya.
lihat http://scriptbucket.wordpress.com/2012/12/11/introduction-to-memoization/
Contoh Memoisasi Fibonacci dengan Python:
sumber
Memoisasi adalah konversi fungsi menjadi struktur data. Biasanya orang ingin konversi terjadi secara bertahap dan malas (berdasarkan permintaan elemen domain tertentu - atau "kunci"). Dalam bahasa fungsional malas, konversi malas ini dapat terjadi secara otomatis, dan dengan demikian memoisasi dapat diimplementasikan tanpa efek samping (eksplisit).
sumber
Baiklah saya harus jawab bagian pertama dulu: apa itu memoisasi?
Itu hanya metode untuk menukar memori untuk waktu. Pikirkan Tabel Multiplikasi .
Menggunakan objek yang dapat diubah sebagai nilai default dalam Python biasanya dianggap buruk. Tetapi jika menggunakannya dengan bijak, itu sebenarnya bisa berguna untuk mengimplementasikan
memoization
.Berikut ini contoh yang diadaptasi dari http://docs.python.org/2/faq/design.html#why-are-default-values-share-between-objects
Menggunakan bisa berubah
dict
dalam definisi fungsi, hasil yang dihitung menengah dapat di-cache (misalnya ketika menghitungfactorial(10)
setelah menghitungfactorial(9)
, kami dapat menggunakan kembali semua hasil menengah)sumber
Berikut ini adalah solusi yang akan bekerja dengan daftar atau jenis argumen tanpa merengek:
Perhatikan bahwa pendekatan ini dapat diperluas secara alami ke objek apa pun dengan menerapkan fungsi hash Anda sendiri sebagai kasus khusus di handle_item. Misalnya, untuk membuat pendekatan ini berfungsi untuk fungsi yang mengambil set sebagai argumen input, Anda bisa menambahkan ke handle_item:
sumber
list
argumen[1, 2, 3]
salah dapat dianggap sama denganset
argumen berbeda dengan nilai{1, 2, 3}
. Selain itu, set tidak teratur seperti kamus, jadi mereka juga perlusorted()
. Perhatikan juga bahwa argumen struktur data rekursif akan menyebabkan infinite loop.list
danset
"tupleized" menjadi hal yang sama dan karenanya tidak dapat dibedakan satu sama lain. Contoh kode untuk menambahkan dukungan untuk yangsets
dijelaskan dalam pembaruan terbaru Anda tidak menghindarkan saya dari ketakutan. Ini dapat dengan mudah dilihat dengan melewati secara terpisah[1,2,3]
dan{1,2,3}
sebagai argumen untuk fungsi tes "memoize" dan melihat apakah itu dipanggil dua kali, sebagaimana mestinya, atau tidak.list
s dandict
s karena mungkin untuklist
memiliki hal yang persis sama di dalamnya yang dihasilkan dari memanggilmake_tuple(sorted(x.items()))
kamus. Solusi sederhana untuk kedua kasus adalah dengan memasukkantype()
nilai dalam tuple yang dihasilkan. Saya bisa memikirkan cara yang lebih sederhana khusus untuk menanganiset
s, tetapi tidak menyamaratakan.Solusi yang berfungsi dengan argumen posisi dan kata kunci secara terpisah dari urutan penetapan arg kata kunci (menggunakan inspect.getargspec ):
Pertanyaan serupa: Mengidentifikasi panggilan fungsi varargs setara untuk memoisasi dengan Python
sumber
sumber
if n not in cache
sebagai gantinya. menggunakancache.keys
akan membangun daftar yang tidak perlu dalam python 2Hanya ingin menambah jawaban yang sudah disediakan, pustaka dekorator Python memiliki beberapa implementasi sederhana namun bermanfaat yang juga dapat memo "tipe yang tidak dapat dihancurkan", tidak seperti
functools.lru_cache
.sumber