एक तकनीक है कि गतिशील प्रोग्रामिंग के लिए काफी उपयोगी है Memoization कहा जाता है। अधिक जानकारी के लिए, उदाहरण के लिए देखें blog post by Don Syme या introduction by Matthew Podwysocki।
विचार यह है कि आप (एक बेवकूफ) रिकर्सिव फ़ंक्शन लिखते हैं और फिर पिछले परिणामों को संग्रहीत करने वाले कैश को जोड़ते हैं। यह आपको फ़ंक्शन को सामान्य कार्यात्मक शैली में लिखने देता है, लेकिन गतिशील प्रोग्रामिंग का उपयोग करके कार्यान्वित एल्गोरिदम का प्रदर्शन प्राप्त करता है।
उदाहरण के लिए, फिबोनैकी संख्या की गणना के लिए एक अनुभवहीन (अक्षम) समारोह इस तरह दिखता है:
let rec fibs n =
if n < 1 then 1 else
(fibs (n - 1)) + (fibs (n - 2))
यह अक्षम है, क्योंकि जब आप fibs 3
कहते हैं, यह fibs 1
तीन बार (और कई और अधिक बार अगर कॉल करेंगे आप कॉल करते हैं, उदाहरण के लिए, fibs 6
)। ज्ञापन के पीछे विचार यह है कि हम एक कैश लिखते हैं जो fib 1
और fib 2
के परिणाम संग्रहीत करता है, और इसी तरह, इसलिए दोहराए गए कॉल केवल कैश से पूर्व-गणना मूल्य चुनेंगे।
एक सामान्य समारोह Memoization इस तरह लिखा जा सकता है करता है कि:
open System.Collections.Generic
let memoize(f) =
// Create (mutable) cache that is used for storing results of
// for function arguments that were already calculated.
let cache = new Dictionary<_, _>()
(fun x ->
// The returned function first performs a cache lookup
let succ, v = cache.TryGetValue(x)
if succ then v else
// If value was not found, calculate & cache it
let v = f(x)
cache.Add(x, v)
v)
अधिक कुशल फाइबोनैचि समारोह लिखने के लिए, हम अब memoize
फोन और यह समारोह है कि एक तर्क के रूप गणना करता है दे सकते हैं:
let rec fibs = memoize (fun n ->
if n < 1 then 1 else
(fibs (n - 1)) + (fibs (n - 2)))
ध्यान दें कि यह एक पुनरावर्ती मूल्य है - फ़ंक्शन का बॉडी ज्ञात fibs
फ़ंक्शन को याद करता है।
स्रोत
2011-11-02 18:53:08
गतिशील:
आप भी इस और सीधे (
Seq.unfold
का उपयोग किए बिना) कर सकता है: इसलिए आप कुछ इस तरह कर सकते हैं प्रोग्रामिंग समस्या बनाम एक प्रक्रियात्मक प्रोग्राम किया गया है, हालांकि प्रक्रियात्मक संस्करण के चलने का समय आसान हो सकता है। – gradbot