गतिशील प्रोग्रामिंग किस बारे में है?


33

अग्रिम में खेद है अगर यह सवाल गूंगा लगता है ...

जहाँ तक मुझे पता है, डायनेमिक प्रोग्रामिंग का उपयोग करके एक एल्गोरिथ्म का निर्माण इस तरह से काम करता है:

  1. समस्या को पुनरावृत्ति संबंध के रूप में व्यक्त करें;
  2. पुनरावृत्ति संबंध को या तो संस्मरण के माध्यम से या नीचे के दृष्टिकोण के माध्यम से लागू करें।

जहां तक ​​मुझे पता है, मैंने गतिशील प्रोग्रामिंग के बारे में सब कुछ कहा है। मेरा मतलब है: गतिशील प्रोग्रामिंग पुनरावृत्ति संबंधों को व्यक्त करने के लिए उपकरण / नियम / तरीके / सिद्धांत नहीं देते हैं, न ही उन्हें कोड में बदलने के लिए।

तो, गतिशील प्रोग्रामिंग के बारे में क्या खास है? यह आपको एक निश्चित प्रकार की समस्याओं के लिए एक अस्पष्ट पद्धति के अलावा क्या देता है?


11
ऐतिहासिक फैक्टॉइड (यह टिप्पणी आपको मदद नहीं करेगी, लेकिन बेलमैन वास्तव में एक अच्छा नेतृत्व है यदि आप गतिशील प्रोग्रामिंग पर सिद्धांत को भारी करना चाहते हैं): जब बेलमैन को अब गतिशील प्रोग्रामिंग के रूप में जाना जाता है, तो उन्होंने विचार को "गतिशील प्रोग्रामिंग" कहा। "क्योंकि विशुद्ध रूप से सैद्धांतिक काम उस समय अपने नियोक्ता के साथ नहीं उड़ेंगे, इसलिए उन्हें कुछ अधिक गूढ़ता की आवश्यकता थी जो एक pejorative तरीके से उपयोग नहीं की जा सकती थी
जी। बाच।

3
जहां तक ​​मुझे पता है कि यह वास्तव में इन दो बिंदुओं का उल्लेख है। यह अति विशिष्ट हो जाता है क्योंकि यह अतिव्यापी उपप्रकारों के कारण घातीय विस्फोट से बचता है। बस इतना ही। आह, वैसे, मेरे प्रोफेसर "अस्पष्ट विधि" से अधिक "अस्पष्ट विधि" पसंद करते हैं।
हेंड्रिक जान

"डायनेमिक प्रोग्रामिंग" मुख्य रूप से एक buzzword प्रतीत होता है (क्योंकि यह अपनी buzz खो चुका है)। इसका मतलब यह नहीं है कि यह निश्चित रूप से उपयोगी नहीं है।
user253751

3
एक उत्तर के योग्य नहीं है, लेकिन मेरे लिए गतिशील प्रोग्रामिंग निश्चित रूप से है "वह चीज जिसका आप उपयोग करते हैं जब आप किसी समस्या को पुनरावर्ती रूप से हल करने का प्रयास करते हैं, लेकिन आप समय-समय पर एक ही उपप्रोब्लेम्स को फिर से जारी करने में समय बर्बाद करते हैं।"
hobbs

जवाबों:


27

डायनेमिक प्रोग्रामिंग आपको एल्गोरिथम डिज़ाइन के बारे में सोचने का एक तरीका देता है। यह अक्सर बहुत मददगार होता है।

संस्मरण संबंधों को कोड में बदलने के लिए संस्मरण और नीचे-ऊपर के तरीके आपको एक नियम / विधि प्रदान करते हैं। संस्मरण एक अपेक्षाकृत सरल विचार है, लेकिन सबसे अच्छे विचार अक्सर होते हैं!

डायनेमिक प्रोग्रामिंग आपको अपने एल्गोरिथ्म के चलने के समय के बारे में सोचने का एक संरचित तरीका देता है। चलने का समय मूल रूप से दो संख्याओं द्वारा निर्धारित किया जाता है: आपके द्वारा हल किए जाने वाले उपप्रोब्लेम्स की संख्या और प्रत्येक उपप्रोजेम को हल करने में लगने वाला समय। यह एल्गोरिदम डिजाइन समस्या के बारे में सोचने का एक आसान आसान तरीका प्रदान करता है। जब आपके पास एक उम्मीदवार पुनरावृत्ति संबंध होता है, तो आप इसे देख सकते हैं और बहुत जल्दी समझ सकते हैं कि दौड़ने का समय क्या हो सकता है (उदाहरण के लिए, आप अक्सर बहुत जल्दी बता सकते हैं कि कितने उपप्रकार होंगे, जो एक कम बाध्य है समय चल रहा है, अगर वहाँ तेजी से कई उपप्रकार आप को हल करने के लिए है, तो पुनरावृत्ति शायद एक अच्छा दृष्टिकोण नहीं होगा)। इससे आपको उम्मीदवार सबप्रॉब्लम डिकम्पोजिशन को नियंत्रित करने में भी मदद मिलती है। उदाहरण के लिए, यदि हमारे पास एक स्ट्रिंग है , उपसर्ग को परिभाषित करना उपसर्ग को परिभाषित करता है S [ 1 .. i ] या प्रत्ययया विकल्पउचित हो सकता है (की संख्यामें बहुपद है) , लेकिनकी एक अनुवर्ती द्वारा एक उपप्रकार को परिभाषितकरना एक अच्छा दृष्टिकोण होने की संभावना नहीं है (उपप्रकार की संख्यामें घातीय है)। यह आपको संभावित पुनरावृत्ति के "खोज स्थान" को चुभाने देता है।S[1..n]S[1..i]एस [ मैं j ] एन एस एनS[j..n]S[i..j]nSn

गतिशील प्रोग्रामिंग आपको उम्मीदवार पुनरावृत्ति संबंधों की तलाश के लिए एक संरचित दृष्टिकोण प्रदान करता है। व्यावहारिक रूप से, यह दृष्टिकोण अक्सर प्रभावी होता है। विशेष रूप से, ऐसे कुछ आंकड़े / सामान्य प्रतिमान हैं जिन्हें आप इनपुट के प्रकार के आधार पर उप-प्रकारों को परिभाषित करने के सामान्य तरीकों के लिए पहचान सकते हैं। उदाहरण के लिए:

  • इनपुट एक है सकारात्मक पूर्णांक , एक उम्मीदवार रास्ता एक subproblem परिभाषित करने के लिए की जगह है n एक छोटे पूर्णांक के साथ n ' (सेंट 0 n 'n )।nnn0nn

  • यदि इनपुट एक स्ट्रिंग , तो उपप्रोब्लेम को परिभाषित करने के लिए कुछ उम्मीदवार तरीके शामिल हैं: S [ 1 .. n ] को उपसर्ग S [ 1 .. i ] से बदलें ; एक प्रत्यय S [ j के साथ S [ 1 .. n ] को बदलें एन ] ; की जगह एस [ 1 .. n ] सबस्ट्रिंग साथ एस [ मैं जे ]S[1..n]S[1..n]S[1..i]S[1..n]S[j..n]S[1..n]S[i..j]। (यहाँ उपप्रकार की पसंद से निर्धारित होता है ।)i,j

  • यदि इनपुट एक सूची है , तो वही करें जो आप स्ट्रिंग के लिए करेंगे।

  • इनपुट एक है पेड़ , एक उम्मीदवार रास्ता एक subproblem परिभाषित करने के लिए बदलने के लिए है टी के किसी भी सबट्री साथ टी (यानी, एक नोड लेने एक्स और की जगह टी सबट्री में निहित के साथ एक्स ; subproblem की पसंद से निर्धारित होता है एक्स )।TTTxTxx

  • यदि इनपुट एक युग्म , तो प्रत्येक के लिए एक उपप्रकार चुनने के तरीके की पहचान करने के लिए पुन: X के प्रकार और y के प्रकार को पुन: देखें । दूसरे शब्दों में, एक उम्मीदवार रास्ता एक subproblem परिभाषित करने के लिए बदलने के लिए है ( एक्स , वाई ) द्वारा ( एक्स ' , y ' ) जहां एक्स ' के लिए एक subproblem है एक्स और वाई ' के लिए एक subproblem है y । (आप फॉर्म ( x , y) के सबप्रोब्लेम्स पर भी विचार कर सकते हैं(x,y)xy(x,y)(x,y)xxyy या ( एक्स ' , y ) ।)(x,y)(x,y)

और इसी तरह। यह आपको एक बहुत उपयोगी उत्तराधिकार देता है: सिर्फ विधि के प्रकार पर हस्ताक्षर करके, आप उप-प्रकारों को परिभाषित करने के लिए उम्मीदवार तरीकों की एक सूची के साथ आ सकते हैं। दूसरे शब्दों में, सिर्फ समस्या कथन को देखते हुए - केवल इनपुट के प्रकारों को देखते हुए - आप एक उप-उम्मीदवार को परिभाषित करने के लिए मुट्ठी भर उम्मीदवार तरीकों के साथ आ सकते हैं।

यह अक्सर बहुत मददगार होता है। यह आपको नहीं बताता है कि पुनरावृत्ति संबंध क्या है, लेकिन जब आपके पास उपप्रकार को परिभाषित करने के लिए एक विशेष विकल्प है, तो अक्सर एक संबंधित पुनरावृत्ति संबंध को काम करना बहुत मुश्किल नहीं है। इसलिए, यह अक्सर एक गतिशील प्रोग्रामिंग एल्गोरिथ्म के डिजाइन को एक संरचित अनुभव में बदल देता है। आप स्क्रैप पेपर पर उपप्रोब्लेम्स को परिभाषित करने के लिए उम्मीदवार तरीकों की एक सूची लिखते हैं (ऊपर दिए गए अनुमान का उपयोग करके)। फिर, प्रत्येक उम्मीदवार के लिए, आप एक पुनरावृत्ति संबंध को लिखने की कोशिश करते हैं, और उप-प्रकारों की संख्या और प्रति उप-समय बिताए गए समय की गणना करके इसके चलने के समय का मूल्यांकन करते हैं। प्रत्येक उम्मीदवार की कोशिश करने के बाद, आप उस सर्वोत्तम को बनाए रखते हैं जिसे आप ढूंढने में सक्षम थे। एल्गोरिथ्म डिजाइन प्रक्रिया में कुछ संरचना प्रदान करना एक बड़ी मदद है, अन्यथा एल्गोरिथ्म डिजाइन को डराना हो सकता है (वहाँ)


तो आप पुष्टि करते हैं कि गतिशील प्रोग्रामिंग का पालन करने के लिए ठोस "प्रक्रियाओं" के साथ प्रदान नहीं करता है। जैसा कि आपने कहा, यह "सोचने का एक तरीका" है। ध्यान दें कि मैं यह तर्क नहीं दे रहा हूं कि डीपी बेकार है (इसके विपरीत!), मैं बस यह समझने की कोशिश कर रहा हूं कि क्या कुछ ऐसा है जो मुझे याद आ रहा है या अगर मुझे अभी और अभ्यास करना चाहिए।
अरे हे

@ इहे, अच्छा, हां ... और नहीं। अधिक विस्तार के लिए मेरा संशोधित उत्तर देखें। यह एक चांदी की गोली नहीं है, लेकिन यह कुछ अर्ध-ठोस प्रक्रियाएं प्रदान करता है जो अक्सर सहायक होते हैं (काम करने की गारंटी नहीं है, लेकिन अक्सर सहायक साबित होते हैं)।
डीडब्ल्यू

बहुत धन्यवाद! अभ्यास करके मैं उन "अर्ध-ठोस प्रक्रियाओं" में से कुछ से परिचित हो रहा हूं, जिनका आप वर्णन कर रहे हैं।
अरे हे

"अगर वहाँ तेजी से कई उपप्रकार आप को हल करने के लिए है, तो पुनरावृत्ति शायद एक अच्छा दृष्टिकोण नहीं होगा"। कई समस्याओं के लिए कोई ज्ञात बहुपद समय एल्गोरिथ्म नहीं है। डीपी का उपयोग करने के लिए यह एक मानदंड क्यों होना चाहिए?
चील दस ब्रिंक

@Chiel, यह डीपी का उपयोग करने के लिए एक मानदंड नहीं है। यदि आपके पास एक समस्या है जहां आप एक घातांक-समय के एल्गोरिदम से खुश होंगे, तो आप उस विशेष अभिभावकीय टिप्पणी को अनदेखा कर सकते हैं। यह केवल एक उदाहरण है जो मैं बना रहा था कि सामान्य बिंदु को स्पष्ट करने की कोशिश करो - ऐसा कुछ नहीं जिसे आपको बहुत गंभीरता से लेना चाहिए या एक कठिन-और-तेज नियम के रूप में व्याख्या करना चाहिए।
डीडब्ल्यू

9

डायनामिक प्रोग्रामिंग की आपकी समझ सही है ( afaik ), और आपका प्रश्न उचित है।

मुझे लगता है कि हम जिस तरह की पुनरावृत्ति से प्राप्त अतिरिक्त डिजाइन स्पेस को "डायनेमिक प्रोग्रामिंग" कहते हैं, उसे पुनरावर्ती दृष्टिकोणों के अन्य स्कीमाटा की तुलना में सबसे अच्छा देखा जा सकता है।

आइए दिखाते हैं कि हमारे इनपुट एअर्ज़ हैं कॉन्सेप्ट्स को उजागर करने के लिए।A[1..n]

  1. आगमनात्मक दृष्टिकोण

    यहां यह विचार है कि अपनी समस्या को छोटा करें, छोटे संस्करण को हल करें और मूल के लिए एक समाधान प्राप्त करें। रेखाचित्र के रूप में,

    f(A)=g(f(A[1..nc]),A)

    के साथ फ़ंक्शन / एल्गोरिथ्म जो समाधान का अनुवाद करता है।g

    उदाहरण: रैखिक समय में सुपरस्टार खोजना

  2. फूट डालो और जीतो

    इनपुट को कई छोटे भागों में विभाजित करें, प्रत्येक के लिए समस्या को हल करें और गठबंधन करें। योजनाबद्ध रूप से (दो भागों के लिए),

    f(A)=g(f(A[1..c]),f(A[c+1..n]),A)

    उदाहरण: मर्ज- / क्विकॉर्ट, विमान में सबसे छोटी जोड़ीदार दूरी

  3. गतिशील प्रोग्रामिंग

    समस्या को छोटी समस्याओं में विभाजित करने के सभी तरीकों पर विचार करें और सर्वोत्तम चुनें। योजनाबद्ध रूप से (दो भागों के लिए),

    f(A)=best{g(f(A[1..c]),f(A[c+1..n]))|1cn1}

    उदाहरण: एडिट डिस्टेंस, चेंज-मेकिंग प्रॉब्लम

    महत्वपूर्ण पक्ष ध्यान दें: गतिशील प्रोग्रामिंग जानवर बल नहीं है ! के आवेदन हर कदम में काफी खोज अंतरिक्ष कम कर देता है।best

एक अर्थ में, आप जानते हैं कि कम से कम सांख्यिकीय रूप से ऊपर से नीचे की ओर जा रहे हैं, और गतिशील रूप से अधिक से अधिक निर्णय लेने होंगे।

गतिशील प्रोग्रामिंग के बारे में सीखने से सबक यह है कि सभी संभव विभाजन की कोशिश करना ठीक है (ठीक है, यह शुद्धता के लिए आवश्यक है) क्योंकि यह अभी भी संस्मरण का उपयोग करके कुशल हो सकता है।


"प्रूनड डायनामिक प्रोग्रामिंग" (जब यह लागू होता है) साबित होता है कि शुद्धता के लिए सभी संभावनाओं की कोशिश करना आवश्यक नहीं है।
बेन Voigt

@BenVoigt बेशक। मैं जानबूझकर अस्पष्ट था कि "विभाजन के सभी तरीके" क्या हैं; आप जितना संभव हो उतना बाहर शासन करना चाहते हैं, बिल्कुल! (हालांकि, भले ही आप की कोशिश सभी विभाजन के बाद से आप केवल कभी के संयोजन की जांच आप जानवर बल नहीं मिलता है के तरीके इष्टतम , subproblems के समाधान जबकि जानवर बल के सभी संयोजनों की जांच करेगा सभी समाधान।)
राफेल


5

डायनेमिक प्रोग्रामिंग आपको गणना समय के लिए मेमोरी का व्यापार करने की अनुमति देता है। क्लासिक उदाहरण, फिबोनाची पर विचार करें।

फाइबोनैचि को पुनरावृत्ति द्वारा परिभाषित किया गया है । यदि आप इस पुनरावृत्ति का उपयोग करके हल करते हैं, तो आप अंत में O ( 2 n ) कॉल को F i b ( ) करते हैं , क्योंकि रिकर्सन ट्री ऊंचाई n वाला एक द्विआधारी वृक्ष है ।Fib(n)=Fib(n1)+Fib(n2)O(2n)Fib()n

इसके बजाय, आप गणना करना चाहते हैं , फिर F i b ( 3 ) को खोजने के लिए इसका उपयोग करते हैं, F i b ( 4 ) आदि को खोजने के लिए इसका उपयोग करते हैं । इसमें केवल O ( n ) समय लगता है।Fib(2)Fib(3)Fib(4)O(n)

डी पी भी एक नीचे से ऊपर समाधान में एक आवर्ती संबंध के अनुवाद के लिए बुनियादी तकनीकों के साथ प्रदान करता है, लेकिन इन अपेक्षाकृत (एक का उपयोग शामिल सीधा और आम तौर पर कर रहे हैं आयामी मैट्रिक्स, या इस तरह के एक मैट्रिक्स, की एक सीमा जहां मीटर में मानकों की संख्या है पुनरावृत्ति संबंध)। ये डीपी के बारे में किसी भी पाठ में अच्छी तरह से समझाया गया है।mm


1
आप केवल संस्मरण भाग के बारे में बात करते हैं, जो प्रश्न के बिंदु को याद करता है।
राफेल

1
"डायनेमिक प्रोग्रामिंग आपको गणना समय के लिए मेमोरी का व्यापार करने की अनुमति देता है" कुछ ऐसा नहीं है जो मैंने अंडरग्राउंड करते समय सुना है, और यह इस विषय को देखने का एक शानदार तरीका है। यह एक सहज उदाहरण के साथ एक सहज जवाब है।
trueshot

@ ट्रेसहॉट: सिवाय इसके कि कभी-कभी डायनेमिक प्रोग्रामिंग (और विशेष रूप से, "प्रूनड डायनामिक प्रोग्रामिंग") समय और स्थान दोनों आवश्यकताओं को कम करने में सक्षम है।
बेन Voigt

@ मैंने यह नहीं कहा कि यह एक-से-एक व्यापार था। आप एक पुनरावृत्ति पेड़ के रूप में अच्छी तरह से prune कर सकते हैं। मैं मानता हूं कि मैंने उस सवाल का जवाब दिया, जो था, "डीपी हमें क्या मिलता है?" यह समय के लिए ट्रेडिंग स्पेस द्वारा हमें तेजी से एल्गोरिदम प्राप्त करता है। मैं सहमत हूं कि स्वीकृत उत्तर अधिक गहन है, लेकिन यह मान्य भी है।
किट्सटिल

2

यहाँ एक और थोड़ा अलग तरीका है जो आपको गतिशील प्रोग्रामिंग देता है। डायनेमिक प्रोग्रामिंग समतुल्य वर्गों की बहुपद संख्या में प्रत्याशी समाधानों की एक घातांक संख्या को ढहा देती है, जैसे कि प्रत्येक कक्षा में अभ्यर्थी समाधान कुछ अर्थों में अप्रभेद्य होते हैं।

kAn2nO(n2) equivalence classes. This partitioning preserves enough information so that we can define a recurrence relation for the sizes of the classes. If f(i,) gives the number of subsequences which end in index i and have length , then we have:

f(i,)=j<i such thatA[j]<A[i]f(j,1)
f(i,1)=1 for all i=1n

This recurrence solves the problem in time O(n2k).

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.