विशुद्ध रूप से कार्यात्मक प्रोग्रामिंग की क्षमता


397

क्या किसी को पता है कि सबसे खराब संभव स्पर्शोन्मुख मंदी है जो तब हो सकती है जब विशुद्ध रूप से कार्यात्मक रूप से प्रोग्रामिंग अनिवार्य रूप से विरोध किया जाता है (अर्थात साइड-इफेक्ट की अनुमति देता है)?

Itowlson द्वारा टिप्पणी से स्पष्टीकरण : क्या कोई समस्या है जिसके लिए सबसे अच्छा ज्ञात गैर-विनाशकारी एल्गोरिथ्म सबसे प्रसिद्ध ज्ञात विनाशकारी एल्गोरिदम की तुलना में विषम है, और यदि ऐसा है तो कितना?


6
समान रूप से प्रोग्रामिंग करते समय, जो कुछ भी है।
आर। मार्टिनो फर्नांडीस 3

3
@jldupont: पाठ्यक्रम की गणना के परिणाम को वापस करने के लिए। कई साइड इफेक्ट फ्री प्रोग्राम मौजूद हैं। वे सिर्फ अपने इनपुट पर गणना के अलावा बहुत कुछ नहीं कर सकते। लेकिन यह अभी भी उपयोगी है।
जलेफ़

24
मैं अपने कार्यात्मक कोड को बुरी तरह से लिखकर, इसे जितना चाहें उतना बुरा बना सकता हूं! * मुस्कराहट * मुझे लगता है कि आप जो पूछ रहे हैं, "क्या कोई समस्या है जिसके लिए सबसे अच्छा ज्ञात गैर-विनाशकारी एल्गोरिथ्म सबसे प्रसिद्ध ज्ञात विनाशकारी एल्गोरिदम की तुलना में विषम है, और यदि ऐसा है तो कितना?" ... क्या यह सही है? ?
itowlson

2
क्या आप उस मंदी के प्रकार का उदाहरण दे सकते हैं जिसमें आप रुचि रखते हैं। आपका प्रश्न थोड़ा अस्पष्ट है।
पीटर रेकोर

5
एक उपयोगकर्ता ने अपना उत्तर हटा दिया, लेकिन उसने दावा किया कि 8-क्वीन समस्या का कार्यात्मक संस्करण n = 13. के लिए एक मिनट से अधिक समय तक चला। उसने स्वीकार किया कि यह "बहुत अच्छी तरह से लिखा नहीं गया था", इसलिए मैंने अपना स्वयं का संस्करण लिखने का फैसला किया। F # में 8 रानियाँ: pastebin.com/ffa8d4c4 । कहने की जरूरत नहीं है, मेरा विशुद्ध रूप से कार्य कार्यक्रम केवल एक सेकंड में n = 20 की गणना करता है।
जूलियट

जवाबों:


531

पिप्पेनगर के अनुसार [१ ९९ ६] , जब एक लिस्प प्रणाली की तुलना की जाती है जो विशुद्ध रूप से कार्यात्मक होती है (और इसका सख्त मूल्यांकन शब्दार्थ है, आलसी नहीं है) जो कि डेटा को म्यूट कर सकती है, अशुद्ध लिस्प के लिए लिखे गए एल्गोरिथ्म जो O ( n ) में चलता है, का अनुवाद किया जा सकता है। शुद्ध लिस्प में एक एल्गोरिथ्म जो ओ ( एन लॉग एन ) समय में चलता है ( केवल बिंदुओं का उपयोग करके यादृच्छिक अभिगम स्मृति के अनुकरण के बारे में बेन-अम्राम और गैलिल [1992] के आधार पर )। पिप्पेंगर यह भी स्थापित करता है कि एल्गोरिदम हैं जिनके लिए आप सबसे अच्छा कर सकते हैं; शुद्ध प्रणाली में there ( n log n ) जो अशुद्ध प्रणाली में O ( n ) हैं समस्याएं हैं ।

इस पेपर के बारे में कुछ बातें बताई जानी हैं। सबसे महत्वपूर्ण यह है कि यह आलसी कार्यात्मक भाषाओं जैसे हास्केल को संबोधित नहीं करता है। बर्ड, जोन्स और डी मूर [१ ९९ demonstrate ] प्रदर्शित करते हैं कि पिप्पेंजर द्वारा निर्मित समस्या को ओ ( एन ) समय में एक आलसी कार्यात्मक भाषा में हल किया जा सकता है , लेकिन वे स्थापित नहीं करते हैं (और जहां तक ​​मुझे पता है, किसी के पास नहीं है) या एक आलसी कार्यात्मक भाषा एक ही विषम समय में सभी समस्याओं को एक भाषा के रूप में म्यूटेशन के साथ हल नहीं कर सकती है।

Pippenger द्वारा निर्मित समस्या के लिए Ω ( n log n ) की आवश्यकता होती है, विशेष रूप से इस परिणाम को प्राप्त करने के लिए निर्मित किया जाता है, और यह जरूरी नहीं कि व्यावहारिक, वास्तविक दुनिया की समस्याओं का प्रतिनिधि हो। समस्या पर कुछ प्रतिबंध हैं जो कुछ अप्रत्याशित हैं, लेकिन काम करने के लिए सबूत के लिए आवश्यक हैं; विशेष रूप से, समस्या की आवश्यकता है कि परिणाम भविष्य के इनपुट तक पहुंचने में सक्षम होने के बिना, ऑन-लाइन गणना किए जाते हैं, और यह कि इनपुट में एक निश्चित आकार के सेट के बजाय संभावित परमाणुओं के अनबाउंड सेट से परमाणुओं का एक क्रम होता है। और कागज केवल रैखिक चल समय के एक अशुद्ध एल्गोरिथ्म के लिए (कम बाध्य) परिणाम स्थापित करता है; उन समस्याओं के लिए जिन्हें अधिक चलने वाले समय की आवश्यकता होती है, यह संभव है कि अतिरिक्त ओ (लॉग एन) रैखिक समस्या में देखा जाने वाला कारक अधिक चालू समय के साथ एल्गोरिदम के लिए आवश्यक अतिरिक्त संचालन की प्रक्रिया में "अवशोषित" हो सकता है। इन स्पष्टीकरणों और खुले प्रश्नों को बेन-अराम [1996] द्वारा संक्षिप्त रूप से खोजा गया है ।

व्यवहार में, कई एल्गोरिदम को एक ही दक्षता पर शुद्ध कार्यात्मक भाषा में लागू किया जा सकता है जैसा कि उत्परिवर्तनीय डेटा संरचनाओं वाली भाषा में होता है। विशुद्ध रूप से कार्यात्मक डेटा संरचनाओं को कुशलतापूर्वक लागू करने के लिए उपयोग की जाने वाली तकनीकों के अच्छे संदर्भ के लिए, क्रिस ओकासाकी की "विशुद्ध रूप से कार्यात्मक डेटा संरचनाएं" [ओकासाकी 1998] (जो उनकी थीसिस [ओकासाकी 1996] का विस्तारित संस्करण है ) देखें।

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

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

संदर्भ


50
इस सवाल पर पिपलिंगर निर्विवाद प्राधिकरण हैं। लेकिन हमें इस बात पर जोर देना चाहिए कि उसके परिणाम सैद्धांतिक हैं , व्यावहारिक नहीं। जब कार्यात्मक डेटा संरचनाओं को व्यावहारिक और कुशल बनाने की बात आती है, तो आप ओकासाकी से बेहतर नहीं कर सकते।
नॉर्मन रैमसे

6
itowlson: मुझे यह स्वीकार करना चाहिए कि मैंने आपके प्रश्न का उत्तर देने के लिए पिप्पेंगर को पर्याप्त नहीं पढ़ा; यह ओकासाकी द्वारा उद्धृत एक सहकर्मी की समीक्षा की गई पत्रिका में प्रकाशित हुआ था, और मैंने यह निर्धारित करने के लिए पर्याप्त पढ़ा कि उनके दावे इस प्रश्न के लिए प्रासंगिक हैं, लेकिन सबूत को समझने के लिए पर्याप्त नहीं हैं। वास्तविक दुनिया के परिणामों के लिए मुझे जो तात्कालिक रास्ता मिलता है, वह यह है कि एक संतुलित बाइनरी ट्री का उपयोग करके परिवर्तनीय स्मृति का अनुकरण करके, एक O ( n ) n एल्गोरिथ्म को O ( n log n ) शुद्ध एक में परिवर्तित करना तुच्छ है । ऐसी समस्याएं हैं जो इससे बेहतर नहीं कर सकती हैं; मुझे नहीं पता कि वे विशुद्ध रूप से सैद्धांतिक हैं।
ब्रायन कैंपबेल

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

2
बहुत अच्छा जवाब; मैं जोड़ना चाहूंगा कि विशुद्ध रूप से कार्यात्मक भाषाओं के लिए कंप्यूटिंग जटिलता के लिए मॉडल पर सार्वभौमिक रूप से सहमत नहीं है, जबकि अशुद्ध दुनिया में यूनिट-कॉस्ट रैम मशीन अपेक्षाकृत मानक है (इसलिए यह चीजों की तुलना करना अधिक कठिन बनाता है)। यह भी ध्यान दें कि शुद्ध / अशुद्ध में एक Lg (N) के अंतर की ऊपरी सीमा को एक शुद्ध भाषा में सरणियों के कार्यान्वयन को देखते हुए बहुत आसानी से समझाया जा सकता है (इसकी लागत lg (n) प्रति ऑपरेशन है (और आपको इतिहास मिलता है)) ।
user51568

4
महत्वपूर्ण बिंदु: विशुद्ध रूप से कार्यात्मक विनिर्देश को एक अधिक जटिल कुशल विशुद्ध रूप से कार्यात्मक कार्यान्वयन में अनुवाद करना, यदि आपको अंततः या तो स्वचालित रूप से या हाथ से अनुवाद किया जा रहा है, तो इसका बहुत कम लाभ होता है। अशुद्धता इतनी बड़ी बात नहीं है यदि आप इसे एक पिंजरे में रख सकते हैं, जैसे कि इसे बाहरी रूप से साइड-इफेक्ट-फ्री फ़ंक्शन में लॉक करके।
रॉबिन ग्रीन

44

वास्तव में कई एल्गोरिदम और डेटा संरचनाएं हैं, जिनके लिए कोई भी अलौकिक रूप से कुशल विशुद्ध रूप से कार्यात्मक समाधान नहीं है (शुद्ध लैम्ब्डा कैलकुलस में एक कार्यान्वयन योग्य), यहां तक ​​कि आलस्य के साथ भी जाना जाता है।

  • उपर्युक्त मिलन-खोज
  • हैश टेबल
  • Arrays
  • कुछ ग्राफ एल्गोरिदम
  • ...

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

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


3
यदि डेटासेट मेमोरी में फिट बैठता है, तो उस तक पहुंच ओ (1) है, जिसमें किसी भी आइटम को पढ़ने के लिए समय की मात्रा पर एक पूर्ण ऊपरी बाध्य ढूंढना संभव है। यदि डेटासेट नहीं है, तो आप I / O के बारे में बात कर रहे हैं और यह अब तक का प्रमुख कारक होगा, हालांकि कार्यक्रम लिखा है।
डोनल फैलो

ठीक है, निश्चित रूप से मैं हे (लॉग एन) बाहरी मेमोरी तक पहुंच के संचालन के बारे में बात कर रहा हूं। हालाँकि, किसी भी मामले में मैं bs से बात कर रहा था: बाहरी मेमोरी भी O (1) हो सकती है
-अच्छी

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

यहां तक ​​कि सूचक मॉडल (O (लॉग एन) मेमोरी एक्सेस, शिथिल रूप से बोलना) बहुत बड़े पैमाने पर शारीरिक रूप से यथार्थवादी नहीं है। प्रकाश की गति की सीमा कितनी जल्दी कंप्यूटिंग उपकरण के विभिन्न टुकड़े एक-दूसरे के साथ संवाद कर सकते हैं, जबकि वर्तमान में यह माना जाता है कि किसी दिए गए क्षेत्र में होने वाली अधिकतम जानकारी उसके सतह क्षेत्र से बंधी है।
dfeuer

36

यह लेख दावा करता है कि संघ के ज्ञात शुद्ध रूप से कार्यात्मक कार्यान्वयन -एल्गोरिदम सभी में उनके द्वारा प्रकाशित की तुलना में बदतर स्पर्शोन्मुख जटिलता है, जिसमें विशुद्ध रूप से कार्यात्मक इंटरफ़ेस है लेकिन आंतरिक रूप से परिवर्तनशील डेटा का उपयोग करता है।

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

संपादित करें:

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

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

यदि किसी फ़ंक्शन की सख्त भाषा में O (f (n)) जटिलता है, तो एक आलसी भाषा में भी जटिलता O (f (n)) है। चिंता क्यों? :)


4

स्मृति उपयोग पर एक निश्चित ऊपरी सीमा के साथ, कोई अंतर नहीं होना चाहिए।

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


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

@ ब्रायन कैंपबेल: यह सच है। मैं सिर्फ यह सुझाव दे रहा हूं कि यदि आप चाहते थे, तो आप व्यवहार में कई मामलों में निरंतर कारक के अंतर को अनदेखा कर सकते हैं। स्मृति और समय के बीच समझौता करते समय किसी को अभी भी अंतर से सावधान रहने की आवश्यकता होगी, यह सुनिश्चित करने के लिए कि अधिक बार मेमोरी का उपयोग करने से लॉग (m) के कम से कम कारक द्वारा आपके रनटाइम में कमी आती है।
ब्रायन

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