2011-11-25 14 views
12

मैं उलझन में हूं कि कैसे ट्री कार्यान्वयन अंतरिक्ष बचाता है & अधिकांश कॉम्पैक्ट रूप में डेटा स्टोर करता है!ट्री अंतरिक्ष बचाता है, लेकिन कैसे?

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

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

enter image description here

+0

यदि कोई नोड 16 बाइट्स लेता है लेकिन 16 से अधिक तारों (जावा में 8) में पुन: उपयोग किया जाता है, तो यह स्थान बचाता है। फिर यह केवल एक सवाल है कि क्या आप बर्बाद कर रहे हैं उससे ज्यादा जगह बचाते हैं। यह मानते हुए कि आपके उदाहरण में नीली संख्या दोहराई गई गणना है, स्ट्रिंग्स की एक साधारण सरणी की तुलना में बचत बर्बाद जगह से बड़ी हो जाती है। हालांकि इस मामले में दोहराव की गणना के साथ पूर्ण तारों को स्टोर करना बेहतर होगा। – han

उत्तर

2

आप यह समझ सकते हैं कि यह स्थान एक आदर्श मशीन पर है जहां हर बाइट कुशलता से आवंटित किया जाता है। हालांकि वास्तविक मशीनें स्मृति के गठित ब्लॉक आवंटित करती हैं (जावा पर 8 बाइट्स और कुछ सी ++ पर 16 बाइट्स) और इसलिए यह किसी भी स्थान को सहेज नहीं सकता है।

जावा स्ट्रिंग्स और संग्रह अपेक्षाकृत अधिक मात्रा में सिर जोड़ते हैं ताकि प्रतिशत अंतर बहुत छोटा हो।

जब तक आपकी संरचना बहुत बड़ी न हो, तब तक आपके समय का मूल्य स्मृति की लागत को कम करता है जो संग्रह को बनाए रखने के लिए सबसे सरल, सबसे मानक और सबसे आसान उपयोग करना अधिक महत्वपूर्ण है। जैसे आपका समय 1000x या उससे अधिक मूल्यवान स्मृति के मूल्य के बराबर हो सकता है जिसे आप सहेजने का प्रयास कर रहे हैं।

उदा मान लें कि आपके पास 10000 नाम हैं जिन्हें आप एक तिहाई का उपयोग कर 16 बाइट्स बचा सकते हैं। (मान लीजिए कि अधिक समय लेने के बिना साबित किया जा सकता है) यह 16 केबी के बराबर है, जो आज की कीमतों पर 0.1 सेंट के बराबर है। यदि आपका समय आपकी कंपनी $ 30 प्रति घंटा खर्च करता है, तो परीक्षण कोड की एक पंक्ति लिखने की लागत $ 1 हो सकती है।

यदि आप इसके बारे में 16 KB को बचाने के लिए लंबे समय तक आंखों का झपकी सोचते हैं, तो यह पीसी के लिए इसके लायक होने की संभावना नहीं है। (मोबाइल उपकरणों के लिए एक अलग कहानी हैं, लेकिन एक ही तर्क IMHO लागू होता है)

संपादित करें: तुम मुझे एक अद्यतन जोड़ने के लिए http://vanillajava.blogspot.com/2011/11/ever-decreasing-cost-of-main-memory.html

+0

ट्राई तेज़ी से और अंतरिक्ष को बचाएगा। 15 के प्रविष्टियों के लिए यह आपको 0.2 सेंट स्मृति और सीपीयू बचा सकता है। यदि आपने देखा कि सड़क के दूसरी तरफ 0.2 सेंट क्या हो सकता है तो क्या आप इसे चुनने के लिए पार करेंगे? मैं केवल तभी ऐसा करूंगा जब आपके समय का दूसरा हिस्सा लगे। दिया गया ट्रीमैप आपके कोड का समर्थन करने वाले किसी भी व्यक्ति द्वारा निर्मित, अच्छी तरह से परीक्षण, दस्तावेज और समझ में आता है, यह आपको स्मृति में लागत के मुकाबले कहीं ज्यादा दूर तक बचाएगा (जब तक कि आप कई उपकरणों का उपयोग नहीं कर रहे हैं) –

+1

यदि आप हजारों या लाखों उपभोक्ताओं को तैनात पुस्तकालय लिख रहे हैं, तो 0.2 सेंट में एकाधिक हैं, और जब उपयोग द्वारा चार्ज करने वाले सर्वर पर तैनात किया जाता है, तो 0.2 सेंट के पास एक और एकाधिक होता है। "प्रदर्शन कोई फर्क नहीं पड़ता" समाधान नहीं है, यह एक विचारधारा है। – Ajax

+0

यदि आप एक मिलियन मशीनों में 0.2 सेंट की बचत करते हैं जो कुल 2000 डॉलर है। यह कुछ दिनों या यहां तक ​​कि एक सप्ताह तक खर्च करने लायक है। यदि यह केवल 100 के मशीन है तो आप कुछ घंटों या एक दिन भी देख रहे हैं। अगर यह केवल 10 के मशीनों में है तो आप कुछ मिनट देख रहे हैं। यदि यह केवल एक हजार मशीन या उससे कम है तो आप इसके बारे में चिंता करने में अपना समय बर्बाद कर सकते हैं। स्केल मायने रखता है, और अधिकांश परियोजनाओं को पर्याप्त मशीनों पर तैनात नहीं किया जाता है जो संसाधनों की थोड़ी मात्रा के बारे में चिंता करते हैं, यह एक अच्छा विचार है। –

6

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

लेकिन यदि आप स्थान को सहेजना चाहते हैं तो बेहतर डेटा संरचना है। ट्री directed acyclic word graph (DAWG) जितना स्थान बचाता है, क्योंकि यह पूरे ढांचे में सामान्य नोड साझा करता है, जबकि ट्राई नोड्स साझा नहीं करता है। wiki entry इस बारे में विस्तार से बताता है, इसलिए इसे देखें।

यहाँ अंतर (रेखांकन) Trie और DAWG के बीच है:

enter image description here

तार "नल", "टैप करता", "शीर्ष", और एक Trie में संग्रहीत "शीर्ष" (बाएं) और एक डीएडब्ल्यूजी (दाएं), ईओओ एंड-ऑफ-वर्ड के लिए खड़ा है।

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

+0

यही वह है जिसे मैं समझ नहीं पा रहा हूं। प्रत्येक चरित्र के लिए हम बचाते हैं, हम एक सूचक की कीमत का भुगतान करते हैं .. तो क्या यह बदतर नहीं है? – Pacerier

+0

@Pacerier: आप सूचक के लिए कितनी बार भुगतान करते हैं? एक बार जब आप इसके लिए भुगतान कर लेंगे, तो आप जितनी चाहें चरित्र के समान पुनरावृत्ति के लिए उपयोग कर सकते हैं। – Nawaz

14

जब एक Trie का उपयोग कर स्थान बचाने के लिए, एक एक compressed trie है, जिसके लिए एक नोड का प्रतिनिधित्व कर सकते हैं (यह भी एक पेट्रीसिया trie या मूलांक पेड़ के रूप में जाना जाता है) कई पात्रों का उपयोग कर सकते हैं:

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

उदाहरण:

radix tree or patricia trie

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

+0

मैंने पेट्रीसिया ट्री कार्यान्वयन पर एक नज़र डाली थी, लेकिन क्या यह गुवा और अपाचे कॉमन्स जैसी किसी भी लोकप्रिय पुस्तकालयों का हिस्सा है क्योंकि वे अपने दावे के अनुसार हैं? मैं अमरूद/अपाचे कॉमन्स संग्रह –

+3

@Marcos में इसके लागू होने का अनुमान नहीं लगा सका, गुवा में कोई त्रिज्या कार्यान्वयन नहीं है, हालांकि एक जोड़ने के लिए एक लंबा चलने वाला मुद्दा है, इसलिए अंत में ऐसा हो सकता है। – ColinD

+0

कूल। स्पष्टीकरण के लिए धन्यवाद! –

5

यह स्मृति में सस्ती जगह के बारे में नहीं है, यह फ़ाइल में या संचार लिंक पर कीमती जगह के बारे में है। उस ट्राय को बनाने वाले एल्गोरिदम के साथ, हम तीन बिट्स, बाएं-दाएं-दाएं में 'दस' भेज सकते हैं। 24 बिट्स 'दस' की तुलना में असम्पीडित हो जाएगा, यह मूल्यवान डिस्क स्पेस या ट्रांसफर बैंडविड्थ की एक बड़ी बचत है।

+0

यह वास्तव में एक बड़ा फायदा है! –

+0

तो, केवल डेटा संरचनाओं की आवश्यकता के बिना मेमोरी संरचनाओं के लिए, लेकिन लगभग 10,000 नामों के टेलीफोन नाम निर्देशिका के लिए खोज सुझाव प्राप्त करने के लिए एक कलाकार और अंतरिक्ष कुशल समाधान के लिए, ट्री मैप पर ट्री का अनुशंसा किया जाएगा? –

1

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

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

संबंधित मुद्दे