क्या यह अपरिवर्तनीय राज्यों के साथ कुशलता से ऑब्जेक्ट-ग्राफ के उत्परिवर्तन का प्रतिनिधित्व करना संभव है?


12

मैं C ++ में अपरिवर्तनीय वस्तु का उपयोग करके अभ्यास कर रहा हूं। मेरा व्यक्तिगत लक्ष्य अपरिवर्तनीय रेखांकन के अनुक्रम के साथ सामान्य वस्तु ग्राफ (ढेर में) का प्रतिनिधित्व कर रहा है।

बहु-संस्करण ग्राफ का निर्माण करना उतना कठिन नहीं है। समस्या प्रदर्शन है। ब्रूट-फोर्स वर्जनिंग को ग्राफ की पूरी प्रतिलिपि की आवश्यकता होती है, और यह स्वीकार्य नहीं था।

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

जहां तक ​​मैं कल्पना कर सकता हूं, अपरिवर्तनीय राज्यों के साथ वस्तु ग्राफ के उत्परिवर्तन का प्रतिनिधित्व करने का कोई वास्तविक कुशल तरीका नहीं है। इसलिए मैं इस पर कुछ विचार करने के लिए कह रहा हूं।

क्या यह अपरिवर्तनीय स्थिति के साथ कुशलता से वस्तु ग्राफ के उत्परिवर्तन का प्रतिनिधित्व करना संभव है?


1
यह केवल मुश्किल है क्योंकि आप किनारों को नोड्स पर रख रहे हैं। यदि आपने किनारों को एक अपरिवर्तनीय संग्रह में संग्रहीत किया है, तो यह आसान होगा।
dan_waterworth

@dan_waterworth यदि मैं आसन्न सूची का उपयोग करता हूं, तो मुझे प्रत्येक बार प्रत्येक किनारे की खोज करनी होगी। इसलिए मुझे लगता है कि यह पढ़ने और लिखने के प्रदर्शन के बीच का व्यापार है।
Eonil

1
यह एक सूची नहीं है।
dan_waterworth

@dan_waterworth आप बी पेड़ की तरह कुछ मतलब है?
Eonil

2
B- पेड़ों की तरह व्यापक पेड़ों का उपयोग तब किया जाता है जब भंडारण माध्यम की विलंबता अधिक होती है। इस मामले में, आप कुछ संकरा होने से बेहतर हो सकते हैं, लेकिन हां, कुछ प्रकार के संतुलित खोज वृक्ष एक अच्छा विचार होगा।
dan_waterworth

जवाबों:


11

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

हालाँकि, कुछ अजीब कारणों के लिए, लगातार ग्राफ को नजरअंदाज किया जाता है। हमारे पास दर्जनों प्रकार के पेड़, सरणियाँ, प्राथमिकता कतारें, नक्शे हैं, लेकिन कोई रेखांकन नहीं है।

मुझे वास्तव में केवल एक पेपर मिला: पूरी तरह से लगातार ग्राफ़ - कौन सा चुनना है?


4

यदि आप अपने संस्करण संसाधन का हिस्सा होने के लिए वस्तुओं के बीच कनेक्शन पर विचार नहीं करते हैं (और आप कर सकते हैं - जिस स्थिति में निम्नलिखित संभवत: बहुत मदद नहीं करता है), तो आप अपनी वस्तुओं को ऐसे हिस्से में विभाजित करने पर विचार कर सकते हैं जो कनेक्टिविटी हिस्से का प्रतिनिधित्व करता है वस्तु और एक हिस्सा जो अपरिवर्तनीय स्थिति का प्रतिनिधित्व करता है।

तब आपके पास प्रत्येक कनेक्टिविटी उप-ऑब्जेक्ट में संस्करण वाले राज्यों का एक वेक्टर हो सकता है। इस तरह से आप उपयुक्त अपरिवर्तनीय स्थिति तक पहुंचने के लिए एक ग्राफ संस्करण संख्या के साथ काम कर सकते हैं।

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

यदि वस्तुओं के बीच कनेक्टिविटी आपके संस्करण की स्थिति का हिस्सा है, तो पूर्वगामी काम नहीं करता है। लेकिन शायद आप इसे इस प्रकार बढ़ा सकते हैं:

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

ऊपर वर्णित एक ही तर्क हैंडल के भीतर संस्करणों को अपडेट करने के लिए लागू होता है - जो आलसी, स्थानीयकृत अपडेट की अनुमति देता है।


3

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

विचार यह है कि प्रत्येक वस्तु, अपनी वर्तमान अपरिवर्तनीय स्थिति को संग्रहीत करने के अलावा, रिकॉर्डिंग परिवर्तनों के लिए स्थान रखती है। जब आप परिवर्तनों को लागू करके मौजूदा एक से एक नया अपरिवर्तनीय ग्राफ बनाना चाहते हैं, तो आपको दो मामलों पर विचार करना होगा:

  • जिस ऑब्जेक्ट को आप बदलना चाहते हैं उसमें अभी भी बदलाव के लिए जगह है। आप ऑब्जेक्ट में सीधे परिवर्तन स्टोर कर सकते हैं।

  • ऑब्जेक्ट में परिवर्तनों के लिए अधिक स्थान नहीं है। आप वर्तमान मूल्यों और खाली परिवर्तन रिकॉर्ड के आधार पर नए उदाहरण बनाते हैं। अब आपको नई वस्तु को संदर्भित करने के लिए पुरानी वस्तु को संदर्भित करने वाली सभी वस्तुओं को पुन: अद्यतन करने की आवश्यकता है।

    यदि संदर्भित ऑब्जेक्ट में स्वयं परिवर्तन के लिए अभी भी जगह है तो आप सीधे संदर्भ में परिवर्तन को संग्रहीत कर सकते हैं, अन्यथा यह पुनरावर्ती रूप से कैस्केड करता है।

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

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

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