क्या हर पुनरावृत्ति को पुनरावृति में परिवर्तित किया जा सकता है?


181

एक लाल धागा एक स्पष्ट रूप से दिलचस्प सवाल लाया:

टेल पुनरावर्ती कार्य तुच्छ रूप से पुनरावृत्त कार्यों में परिवर्तित हो सकते हैं। अन्य, एक स्पष्ट स्टैक का उपयोग करके परिवर्तित किया जा सकता है। क्या हर पुनरावृत्ति को पुनरावृति में बदला जा सकता है?

पोस्ट में (काउंटर?) उदाहरण युग्म है:

(define (num-ways x y)
  (case ((= x 0) 1)
        ((= y 0) 1)
        (num-ways2 x y) ))

(define (num-ways2 x y)
  (+ (num-ways (- x 1) y)
     (num-ways x (- y 1))

3
मैं नहीं देखता कि यह कैसे एक प्रति-उदाहरण है। स्टैक तकनीक काम करेगी। यह सुंदर नहीं होगा, और मैं इसे लिखने वाला नहीं हूं, लेकिन यह उल्लेखनीय है। ऐसा प्रतीत होता है कि आपके लिंक में akdas स्वीकार करता है।
मैथ्यू फ्लैशेन

आपका (संख्या-तरीके xy) सिर्फ (x + y) choosex = (x + y)! / (X-y!) है, जिसे पुनरावृत्ति की आवश्यकता नहीं है।
श्रीवत्सआर


मैं कहूंगा कि पुनरावृत्ति केवल एक सुविधा है।
e2-e4

जवाबों:


181

क्या आप हमेशा पुनरावर्ती कार्य को पुनरावृति में बदल सकते हैं? हां, बिल्कुल, और चर्च-ट्यूरिंग थीसिस यह साबित करती है कि अगर स्मृति कार्य करती है। लेट शब्दों में, यह बताता है कि पुनरावर्ती कार्यों द्वारा गणना योग्य क्या पुनरावृत्त मॉडल (जैसे ट्यूरिंग मशीन) और इसके विपरीत द्वारा गणना योग्य है। थीसिस आपको ठीक से नहीं बताती है कि रूपांतरण कैसे किया जाए, लेकिन यह कहता है कि यह निश्चित रूप से संभव है।

कई मामलों में, एक पुनरावर्ती फ़ंक्शन को परिवर्तित करना आसान है। नूथ "द आर्ट ऑफ़ कंप्यूटर प्रोग्रामिंग" में कई तकनीकें प्रदान करता है। और अक्सर, पुनरावर्ती रूप से गणना की गई चीज की गणना कम समय और स्थान में पूरी तरह से अलग दृष्टिकोण से की जा सकती है। इसका क्लासिक उदाहरण फाइबोनैचि संख्या या उसके क्रम हैं। आप निश्चित रूप से अपनी डिग्री योजना में इस समस्या से मिले हैं।

इस सिक्के के फ्लिप पक्ष पर, हम निश्चित रूप से एक प्रोग्रामिंग सिस्टम की कल्पना कर सकते हैं, जो पहले परिणाम को याद करने के लिए एक निमंत्रण के रूप में एक सूत्र की पुनरावर्ती परिभाषा का इलाज करने के लिए उन्नत है, इस प्रकार कंप्यूटर को बताए जाने की परेशानी के बिना गति लाभ की पेशकश करने के लिए कौन से कदम एक पुनरावर्ती परिभाषा के साथ सूत्र की गणना में पालन करें। दीजकस्ट्रा ने निश्चित रूप से ऐसी प्रणाली की कल्पना की थी। उन्होंने एक प्रोग्रामिंग भाषा के शब्दार्थ से कार्यान्वयन को अलग करने की कोशिश में एक लंबा समय बिताया। फिर, उनकी गैर-नियतात्मक और बहुप्रचारित प्रोग्रामिंग भाषा पेशेवर प्रोग्रामर के अभ्यास से ऊपर एक लीग में हैं।

अंतिम विश्लेषण में, कई कार्यों को पुनरावर्ती रूप में समझना, पढ़ना और लिखना आसान है। जब तक कोई सम्मोहक कारण न हो, आप शायद इन कार्यों को स्पष्ट रूप से पुनरावृत्त एल्गोरिथ्म में परिवर्तित न करें। आपका कंप्यूटर उस काम को सही ढंग से संभाल लेगा।

मैं एक सम्मोहक कारण देख सकता हूं। मान लीजिए कि आप सुपर-हाई लेवल लैंग्वेज में एक प्रोटोटाइप सिस्टम है जैसे [ डोनिंग एस्बेस्टस अंडरवियर ] स्कीम, लिस्प, हास्केल, ओकेमेल, पर्ल या पास्कल। मान लीजिए कि स्थितियां ऐसी हैं जिन्हें आपको C या Java में लागू करने की आवश्यकता है। (शायद यह राजनीति है।) तो आप निश्चित रूप से कुछ कार्यों को पुनरावर्ती लिखा जा सकता है, लेकिन जो शाब्दिक अनुवाद किया गया है, आपके रनटाइम सिस्टम को विस्फोट करेगा। उदाहरण के लिए, स्कीम में अनंत पूंछ पुनरावृत्ति संभव है, लेकिन वही मुहावरा मौजूदा सी वातावरण के लिए एक समस्या का कारण बनता है। एक अन्य उदाहरण लेक्सिकली नेस्टेड फ़ंक्शंस और स्टेटिक स्कोप का उपयोग है, जो पास्कल समर्थन करता है लेकिन सी नहीं करता है।

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


10
क्या चर्च-ट्यूरिंग अभी तक सिद्ध नहीं हुआ है?
लीरान ओरवी

15
@ वेलिडेलेसनेस: यदि आप ए को बी में लागू कर सकते हैं, तो इसका मतलब है कि बी में ए के रूप में कम से कम बिजली है। यदि आप ए-कार्यान्वयन-ए-बी में ए के कुछ बयान को निष्पादित नहीं कर सकते हैं, तो यह कार्यान्वयन नहीं है। यदि A को B और B में लागू किया जा सकता है तो A, पावर (A)> पावर (B), और पावर (B)> = पावर (A) में लागू किया जा सकता है। एकमात्र समाधान शक्ति (ए) == शक्ति (बी) है।
टोरेक

6
पुन: पहला पैराग्राफ: आप कंप्‍यूटेशन के मॉडल के बारे में बोल रहे हैं, चर्च-ट्यूरिंग थीसिस के बारे में नहीं। तुलसी चर्च और / या ट्यूरिंग द्वारा साबित की गई थी, लेकिन यह थीसिस नहीं है। थीसिस एक प्रायोगिक तथ्य है कि सब कुछ सहज ज्ञान युक्त कम्प्यूटेशनल सख्त गणितीय अर्थ (ट्यूरिंग मशीन / पुनरावर्ती कार्य आदि) से गणना योग्य है। यह नापसंद हो सकता है अगर भौतिकी के नियमों का उपयोग करते हुए हम कुछ गैर-कम्प्यूटेशनल कंप्यूटरों का निर्माण कर सकते हैं जो कि कुछ ट्यूरिंग मशीनों को कंप्यूटिंग कर सकते हैं (जैसे समस्या को हल करना)। जबकि समानता एक गणितीय प्रमेय है, और यह अव्यवस्थित नहीं होगा।
sdcvvc

7
इस जवाब को किस तरह से कोई सकारात्मक वोट मिला? पहले यह चर्च-ट्यूरिंग थीसिस के साथ ट्यूरिंग पूर्णता को मिलाता है, फिर यह गलत तरीके से हाथ से करने का एक गुच्छा बनाता है, "उन्नत" प्रणालियों का उल्लेख करता है और आलसी अनंत पूंछ पुनरावृत्ति (जिसे आप सी या किसी भी पूर्ण भाषा के रूप में कर सकते हैं) को छोड़ देते हैं क्योंकि .. उह। क्या किसी को पता है कि ट्यूरिंग का पूरा मतलब क्या है?)। फिर एक उम्मीद के साथ हाथ पकड़ने का निष्कर्ष, जैसे कि ओपरा पर यह सवाल था और आपको सकारात्मक और उत्थान की आवश्यकता है? भयावह जवाब!
ex0du5

8
और शब्दार्थ के बारे में बी एस ??? वास्तव में? यह वाक्यात्मक परिवर्तनों पर एक सवाल है, और किसी तरह यह ड्रॉपकजस्ट्रा नाम देने का एक शानदार तरीका बन गया है और इसका मतलब है कि आप पाई-पथरी के बारे में कुछ जानते हैं? मुझे यह स्पष्ट करने दें: क्या कोई भाषा के शब्दार्थ को देखता है या किसी अन्य मॉडल को इस प्रश्न के उत्तर पर कोई असर नहीं पड़ेगा। चाहे भाषा असेंबली हो या जेनेरिक डोमेन मॉडलिंग भाषा का मतलब कुछ भी नहीं है। इसकी केवल ट्यूरिंग पूर्णता और "स्टैक चर" को "वैरिएबल के एक स्टैक" में बदलना है।
ex0du5

43

क्या हर पुनरावर्ती फ़ंक्शन के लिए गैर-पुनरावर्ती फ़ॉर्म लिखना हमेशा संभव है?

हाँ। एक साधारण औपचारिक प्रमाण यह दिखाना है कि and पुनरावृत्ति और गैर-पुनरावर्ती कलन जैसे कि GOTO दोनों पूर्ण हो रहे हैं। चूँकि सभी ट्यूरिंग पूर्ण पथरी अपनी अभिव्यंजक शक्ति में कड़ाई से समतुल्य हैं, सभी पुनरावर्ती कार्यों को गैर-पुनरावर्ती ट्यूरिंग-पूर्ण पथरी द्वारा कार्यान्वित किया जा सकता है।

दुर्भाग्य से, मैं यहाँ GOTO ऑनलाइन की एक अच्छी, औपचारिक परिभाषा नहीं पा रहा हूँ:

एक GOTO प्रोग्राम एक अनुक्रम मशीन पर निष्पादित पी के आदेशों का एक अनुक्रम है जैसे कि पी निम्नलिखित में से एक है:

  • HALT, जो निष्पादन को रोक देता है
  • r = r + 1rकोई रजिस्टर कहाँ है
  • r = r – 1rकोई रजिस्टर कहाँ है
  • GOTO xxलेबल कहां है
  • IF r ≠ 0 GOTO xजहां rकोई भी रजिस्टर है और xएक लेबल है
  • एक लेबल, इसके बाद के संस्करण के किसी भी आदेश।

हालांकि, पुनरावर्ती और गैर-पुनरावर्ती कार्यों के बीच रूपांतरण हमेशा तुच्छ नहीं होता है (कॉल स्टैक के माइंडलेस मैनुअल पुन: कार्यान्वयन को छोड़कर)।

अधिक जानकारी के लिए यह उत्तर देखें ।


बहुत बढ़िया जवाब! हालांकि व्यवहार में मुझे पुनरावृत्ति वाले अल्गों को पुनरावृत्त करने में बहुत कठिनाई होती है। उदाहरण के लिए मैं अब तक असमर्थ यहां प्रस्तुत monomorphic टाइपकर्ता चालू करने के लिए था community.topcoder.com/... एक सतत एल्गोरिथ्म में
निल्स

31

पुनरावृत्ति को वास्तविक दुभाषियों या संकलक में ढेर या समान निर्माण के रूप में लागू किया जाता है। तो आप निश्चित रूप से एक पुनरावर्ती कार्य को पुनरावृत्त समकक्ष में बदल सकते हैं, क्योंकि यह हमेशा ऐसा होता है (यदि स्वचालित रूप से) । तुम बस एक अदना सा और शायद एक बहुत ही बदसूरत और अक्षम तरीके से कंपाइलर के काम की नकल कर रहे हो।


13

मूल रूप से हां, संक्षेप में आप जो करते हैं वह विधि कॉल (जो स्टैक पर निहित रूप से धक्का स्थिति है) को बदलने के लिए स्पष्ट स्टैक में यह याद रखने के लिए कि 'पिछली कॉल' कहां तक ​​पहुंच गई थी, और फिर 'कॉल विधि' निष्पादित करें। बजाय।

मुझे लगता है कि एक लूप, एक स्टैक और एक स्टेट-मशीन का संयोजन मूल रूप से विधि कॉल का अनुकरण करके सभी परिदृश्यों के लिए इस्तेमाल किया जा सकता है। यह 'बेहतर' होने जा रहा है या नहीं (या तो तेज, या कुछ अर्थों में अधिक कुशल) सामान्य रूप से कहना संभव नहीं है।


9
  • पुनरावर्ती कार्य निष्पादन प्रवाह को एक पेड़ के रूप में दर्शाया जा सकता है।

  • एक ही तर्क एक लूप द्वारा किया जा सकता है, जो उस पेड़ को पार करने के लिए एक डेटा-संरचना का उपयोग करता है।

  • एक स्टैक का उपयोग करके गहराई-पहला ट्रैवर्सल किया जा सकता है, एक कतार का उपयोग करके चौड़ाई-पहला ट्रैवर्सल किया जा सकता है।

तो उत्तर हां है। क्यों: https://stackoverflow.com/a/531721/2128327

क्या एक ही पाश में कोई पुनरावृत्ति हो सकती है? हाँ क्योकि

ट्यूरिंग मशीन एक लूप निष्पादित करके वह सब कुछ करती है:

  1. एक निर्देश प्राप्त करें,
  2. इसका मूल्यांकन करें,
  3. गोटो १।

7

हां, स्पष्ट रूप से एक स्टैक का उपयोग करना (लेकिन पुनरावृत्ति पढ़ने में अधिक सुखद है, IMHO)।


17
मैं यह नहीं कहूंगा कि यह हमेशा पढ़ने के लिए अधिक सुखद है। पुनरावृत्ति और पुनरावृत्ति दोनों का अपना स्थान है।
मैथ्यू फ्लैशेन

6

हां, गैर-पुनरावर्ती संस्करण लिखना हमेशा संभव होता है। तुच्छ समाधान एक स्टैक डेटा संरचना का उपयोग करना और पुनरावर्ती निष्पादन का अनुकरण करना है।


यदि आपका स्टैक डेटा संरचना स्टैक पर आबंटित है, या यह ढेर पर आवंटित होने पर अधिक समय लेता है तो उद्देश्य को पराजित करता है, नहीं? यह मेरे लिए तुच्छ लेकिन अकुशल लगता है।
conradkleinespel

1
@conradk कुछ मामलों में, यदि आप कॉल स्टैक को समाप्त करने के लिए पर्याप्त रूप से बड़ी समस्या पर कुछ ट्री-पुनरावर्ती ऑपरेशन करना चाहिए, तो यह व्यावहारिक बात है; हीप मेमोरी आमतौर पर बहुत अधिक बहुतायत से होती है।
jamesdlin

4

सिद्धांत रूप में यह हमेशा पुनरावृत्ति को हटाने और इसे भाषा में पुनरावृत्ति के साथ बदलने के लिए संभव है, जिसमें डेटा संरचनाओं के लिए और कॉल स्टैक दोनों के लिए अनंत स्थिति है। यह चर्च-ट्यूरिंग थीसिस का एक मूल परिणाम है।

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


2

सभी कम्प्यूटिंग कार्यों की गणना ट्यूरिंग मशीन द्वारा की जा सकती है और इसलिए पुनरावर्ती प्रणालियां और ट्यूरिंग मशीन (पुनरावृत्त प्रणाली) बराबर हैं।


1

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

यह अब एक समस्या से कम है, क्योंकि फैशन अन्य प्रौद्योगिकियों की ओर स्थानांतरित हो गया है।



0

स्पष्ट स्टैक से पुनरावृत्ति, पुनरावृत्ति को पुनरावृत्ति में परिवर्तित करने के लिए एक और पैटर्न एक ट्रैंपोलिन के उपयोग के साथ है।

यहाँ, फ़ंक्शंस या तो अंतिम परिणाम लौटाते हैं, या फ़ंक्शन कॉल को बंद कर देते हैं जो यह अन्यथा प्रदर्शन करेगा। फिर, आरंभ (trampolining) फ़ंक्शन अंतिम परिणाम तक पहुंचने तक लौटाए गए क्लोजर को आमंत्रित करता रहता है।

यह दृष्टिकोण पारस्परिक रूप से पुनरावर्ती कार्यों के लिए काम करता है, लेकिन मुझे डर है कि यह केवल पूंछ-कॉल के लिए काम करता है।

http://en.wikipedia.org/wiki/Trampoline_(computers)


0

मैं कहूँगा हाँ - एक फंक्शन कॉल कुछ नहीं बल्कि एक गोटो और एक स्टैक ऑपरेशन (मोटे तौर पर बोलने वाला) है। आपको केवल फ़ंक्शन को लागू करते समय बनाए गए स्टैक की नकल करना है और एक गोटो के समान कुछ करना है (आप उन भाषाओं के साथ गोटो की नकल कर सकते हैं जिनके पास स्पष्ट रूप से यह कीवर्ड नहीं है)।


1
मुझे लगता है कि ओपी एक प्रमाण या कुछ और की तलाश में है
टिम

0

विकिपीडिया पर निम्नलिखित प्रविष्टियों पर एक नज़र डालें, आप अपने प्रश्न का पूरा उत्तर खोजने के लिए उन्हें शुरुआती बिंदु के रूप में उपयोग कर सकते हैं।

एक पैराग्राफ का अनुसरण करता है जो आपको कुछ संकेत दे सकता है कि कहां से शुरू करें:

पुनरावृत्ति संबंध को हल करने का अर्थ है एक बंद-रूप समाधान प्राप्त करना : एन का एक गैर-पुनरावर्ती कार्य।

इस प्रविष्टि के अंतिम पैराग्राफ पर भी एक नज़र डालें ।


0

किसी भी पुनरावर्ती एल्गोरिदम को गैर-पुनरावर्ती एक में परिवर्तित करना संभव है, लेकिन अक्सर तर्क बहुत अधिक जटिल होता है और ऐसा करने के लिए एक स्टैक के उपयोग की आवश्यकता होती है। वास्तव में, पुनरावर्तन स्वयं एक स्टैक का उपयोग करता है: फ़ंक्शन स्टैक।

अधिक विवरण: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Funions


-1

tazzego, recursion का मतलब है कि एक फ़ंक्शन खुद को कॉल करेगा कि आप इसे पसंद करते हैं या नहीं। जब लोग इस बारे में बात कर रहे हैं कि पुनरावृत्ति के बिना चीजें हो सकती हैं या नहीं, तो उनका मतलब यह है और आप यह नहीं कह सकते हैं कि "नहीं, यह सच नहीं है, क्योंकि मैं एक वैध बयान के रूप में पुनरावृत्ति की परिभाषा से सहमत नहीं हूं"।

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

वैसे, ट्यूरिंग-पूर्ण भाषाएं मौजूद हैं जो केवल लूपिंग के साधन के रूप में पुनरावृत्ति (जैसे एसएमएल) को लागू करती हैं। ट्यूरिंग-पूर्ण भाषाएं भी मौजूद हैं जो केवल लूपिंग (जैसे फोरट्रान IV) के साधन के रूप में पुनरावृत्ति को लागू करती हैं। चर्च-ट्यूरिंग थीसिस साबित करती है कि एक पुनरावृत्ति-केवल भाषाओं में कुछ भी संभव हो सकता है एक गैर-पुनरावर्ती भाषा और वीका-वर्सा में इस तथ्य से किया जा सकता है कि उनके पास ट्यूरिंग-पूर्णता की संपत्ति है।


-3

यहाँ एक पुनरावृत्त एल्गोरिथ्म है:

def howmany(x,y)
  a = {}
  for n in (0..x+y)
    for m in (0..n)
      a[[m,n-m]] = if m==0 or n-m==0 then 1 else a[[m-1,n-m]] + a[[m,n-m-1]] end
    end
  end
  return a[[x,y]]
end
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.