अनलेबेड पेड़ों के कुशल संपीड़न


20

बिना लेबल वाले, जड़ वाले बाइनरी पेड़ों पर विचार करें। हम कर सकते हैं सेक जैसे पेड़: जब भी उपतरू के संकेत दिए गए हैं और के साथ (व्याख्या संरचनात्मक समानता के रूप में), हम स्टोर (wlog) और करने के लिए सभी संकेत की जगह की ओर इशारा के साथ । उदाहरण के लिए उली का उत्तर देखें ।टी टी = टी = टी टी टीTTT=T=TTT

एक एल्गोरिथ्म दें जो इनपुट के रूप में उपरोक्त अर्थ में एक पेड़ लेता है और संपीड़न के बाद रहने वाले नोड्स की न्यूनतम (न्यूनतम) संख्या की गणना करता है। एल्गोरिथ्म समय में चलाना चाहिए के साथ (वर्दी लागत मॉडल में) इनपुट में नोड्स की संख्या।एनO(nlogn)n

यह एक परीक्षा का प्रश्न है और मैं एक अच्छा समाधान नहीं दे पाया हूं, न ही मैंने एक देखा है।


और क्या "लागत", "समय", यहाँ प्राथमिक ऑपरेशन है? कितने नोड्स का दौरा किया? किनारों की संख्या का पता लगाया? और इनपुट का आकार कैसे निर्दिष्ट किया गया है?
औली

यह पेड़ संपीड़न हैश सहमति का एक उदाहरण है । यकीन नहीं है कि अगर एक सामान्य गिनती विधि की ओर जाता है।
गिल्स एसओ- बुराई को रोकना '

@ औली ने स्पष्ट किया कि क्या है। मुझे लगता है कि "समय" पर्याप्त विशिष्ट है, हालांकि। गैर-समवर्ती सेटिंग्स में, यह गिनती के संचालन के बराबर है जो सबसे अधिक बार होने वाले प्राथमिक ऑपरेशन की गिनती के लिए लैंडौ शर्तों में है। n
राफेल

@ राफेल निश्चित रूप से मैं अनुमान लगा सकता हूं कि इच्छित प्राथमिक ऑपरेशन क्या होना चाहिए और शायद बाकी सभी लोगों के समान होगा। लेकिन, और मुझे पता है कि मैं यहां पंडित हूं, जब भी "समय सीमा" दी जाती है, यह बताना महत्वपूर्ण है कि क्या गिना जा रहा है। क्या यह स्वैप, तुलना, परिवर्धन, मेमोरी एक्सेस, निरीक्षण नोड्स, ट्रैवर्स किए गए किनारों, आप इसे नाम देते हैं। यह भौतिकी में माप की इकाई को छोड़ने जैसा है। क्या यह या ? और मुझे लगता है कि मेमोरी एक्सेस लगभग हमेशा सबसे लगातार ऑपरेशन है। १०10kg10ms
औली

@ मूल विवरण ये हैं कि "समान लागत मॉडल" को व्यक्त करना है। यह ठीक से परिभाषित करने के लिए दर्दनाक है कि क्या ऑपरेशन प्राथमिक हैं, लेकिन 99.99% मामलों में (इसमें एक सहित) कोई अस्पष्टता नहीं है। कॉम्प्लेक्सिटी कक्षाओं में मूल रूप से इकाइयां नहीं होती हैं, वे उस समय को मापते नहीं हैं जो एक उदाहरण के रूप में लेता है लेकिन इस बार इनपुट भिन्न होने के तरीके में भिन्नता है।
गिल्स एसओ- बुराई को रोकना '

जवाबों:


10

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

सबसे पहले, हम 'संरचनात्मक समानता' को सक्रिय रूप से चिह्नित करते हैं। बता दें कि और दो (उप) पेड़ हैं। यदि और दोनों अशक्त वृक्ष हैं (बिल्कुल कोई कोने नहीं हैं), तो वे संरचनात्मक रूप से समतुल्य हैं। यदि और दोनों शून्य वृक्ष नहीं हैं, तो वे संरचनात्मक रूप से समान हैं यदि उनके बाएं बच्चे संरचनात्मक रूप से समतुल्य हैं और उनके दाएं बच्चे संरचनात्मक रूप से समतुल्य हैं। The संरचनात्मक समतुल्यता ’इन परिभाषाओं पर न्यूनतम निश्चित बिंदु है।टी ' टी टी ' टी टी 'TTTTTT

उदाहरण के लिए, किसी भी दो पत्ती के नोड्स संरचनात्मक रूप से समतुल्य होते हैं, क्योंकि दोनों में उनके दोनों बच्चों के रूप में अशक्त पेड़ होते हैं, जो संरचनात्मक रूप से समान होते हैं।

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

उपरोक्त परिभाषा हमें तुरंत एक संकेत देती है कि संपीड़न कैसे किया जाए: यदि हम जानते हैं कि अधिकतम पर गहराई के साथ सभी उपप्रकारों की संरचनात्मक तुल्यता है , तो हम आसानी से गहराई साथ उपप्रकार के संरचनात्मक तुल्यता की गणना कर सकते हैं । हमें इस गणना को स्मार्ट तरीके से रनिंग टाइम से बचने के लिए करना है ।d + 1 O ( n 2 )dd+1O(n2)

एल्गोरिदम अपने निष्पादन के दौरान हर शीर्ष पर पहचानकर्ताओं को असाइन करेगा। एक पहचानकर्ता सेट में एक संख्या है । पहचानकर्ता अद्वितीय हैं और कभी नहीं बदलते हैं: इसलिए हम मान लेते हैं कि हम एल्गोरिथम की शुरुआत में कुछ (वैश्विक) चर को 1 पर सेट करते हैं, और हर बार जब हम कुछ शीर्ष पर पहचानकर्ता को असाइन करते हैं, तो हम उस चर के वर्तमान मूल्य को शीर्ष और वृद्धि के लिए असाइन करते हैं उस चर का मान।{1,2,3,,n}

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

हम पहले सभी पत्तियों को संपीड़ित करते हैं (हम इन पत्तियों को गहराई में 0 के कोने के साथ सूची में पा सकते हैं) एक ही शीर्ष में। हम इस शीर्ष को एक पहचानकर्ता निर्दिष्ट करते हैं। इसके बजाय दूसरे वर्टेक्स को इंगित करने के लिए या तो शीर्ष के माता-पिता को पुनर्निर्देशित करके दो कोने का संपीड़न किया जाता है।

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

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

उपरोक्त टिप्पणियों से साबित होता है कि यह दृष्टिकोण काम करता है और संपीड़ित पेड़ में परिणाम होता है। कुल चलने का समय और साथ ही हमारे द्वारा बनाई गई सूचियों को क्रमबद्ध करने के लिए आवश्यक समय है। जैसा कि पूर्णांक जोड़े की कुल संख्या , यह हमें देता है कि कुल चलने का समय , आवश्यकतानुसार। प्रक्रिया के अंत में हमने कितने नोड्स छोड़े हैं, यह गिनती करना तुच्छ है (बस यह देखें कि हमने कितने पहचानकर्ता सौंपे हैं)।n O ( n लॉग एन )O(n)nO(nlogn)


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

@ एलेक्स "कड़ाई से छोटे degree" डिग्री के बच्चे शायद होने चाहिए depth? और सीएस-पेड़ों के नीचे की ओर बढ़ने के बावजूद मुझे "एक पेड़ की गहराई" से कम भ्रामक "पेड़ की ऊंचाई" लगती है।
औली

अच्छा उत्तर। मुझे ऐसा लग रहा है कि छँटाई करने का कोई तरीका होना चाहिए। @ जवाब पर मेरी दूसरी टिप्पणी यहाँ भी मान्य है।
राफेल

@ुली: हाँ, आप सही कह रहे हैं, मैंने इसे ठीक कर दिया है (मुझे यकीन नहीं है कि मैंने उन दो शब्दों को क्यों भ्रमित किया है)। ऊँचाई और गहराई दो अलग-अलग अवधारणाएँ हैं, और मुझे बाद की ज़रूरत है :) मुझे लगा कि मैं पारंपरिक 'गहराई' के बजाय सभी को स्वैप करके भ्रमित करना चाहता हूं।
एलेक्स दस ब्रिंक

4

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

nO(nlg(n))

मैं पेड़ों को निम्नलिखित संरचना (हास्केल सिंटैक्स में यहां लिखा गया) के रूप में मानूंगा:

data Tree = Leaf
          | Node Tree Tree

nodes:T×TNएन टी = एन { } TNT=N{}

हम nodesइस तरह के एक संतुलित द्विआधारी खोज पेड़ के लिए एक लघुगणकीय-समय डेटा संरचना का उपयोग कर सकते हैं । नीचे मैं lookup nodesउस ऑपरेशन को कॉल करूंगा जो nodesडेटा संरचना में एक कुंजी दिखता है , और insert nodesवह ऑपरेशन जो एक ताज़ा कुंजी के तहत एक मूल्य जोड़ता है और उस कुंजी को वापस करता है।

अब हम पेड़ को पार करते हैं और नोड्स को जोड़ते हैं जैसे हम साथ चलते हैं। हालाँकि मैं हास्केल-जैसे स्यूडकोड में लिख रहा हूं, मैं nodesएक वैश्विक परिवर्तनशील चर के रूप में व्यवहार करूंगा ; हम केवल इसे कभी भी जोड़ सकते हैं, लेकिन आवेषण को थ्रेडेड करने की आवश्यकता है। addसमारोह एक पेड़ पर recurses करने के लिए अपने subtrees जोड़ने, nodes, नक्शे और जड़ के पहचानकर्ता देता है।

insert (p1,p2) =
add Leaf = $\ell$
add (Node t1 t2) =
    let p1 = add t1
    let p2 = add t2
    case lookup nodes (p1,p2) of
      Nothing -> insert nodes (p1,p2)
      Just p -> p

insertकॉल की संख्या , जो nodesडेटा संरचना का अंतिम आकार भी है , अधिकतम संपीड़न के बाद नोड्स की संख्या है। (यदि आवश्यक हो तो खाली पेड़ के लिए एक जोड़ें।)


क्या आप " ऑपरेशंस में हमेशा आकार की डेटा संरचना को हश कर सकते हैं ?" ध्यान दें कि वांछित रनटाइम प्राप्त करने के लिए आपको संतुलित पेड़ों की आवश्यकता होगी । O ( n l g ( n ) )nO(nlg(n))nodes
राफेल

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

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

1
@Raphael हैशिंग संरचनाओं, के रूप में उन्हें मनमाना क्रमांक देने का विरोध किया, थोड़ा कुशल है। एकसमान लागत मॉडल में, आप किसी भी चीज़ को एक बड़े पूर्णांक में सांकेतिक शब्दों में बदलना कर सकते हैं और उस पर निरंतर समय संचालन कर सकते हैं, जो यथार्थवादी नहीं है। वास्तविक दुनिया में, आप क्रिप्टोग्राफिक हैश का उपयोग कर सकते हैं, जिसमें वास्तविक सेट से लेकर पूर्णांक की एक सीमित सीमा तक एक वास्तविक मानचित्रण हो सकता है, लेकिन वे धीमे हैं। यदि आप हैश के रूप में एक गैर-क्रिप्टो चेकसम का उपयोग करते हैं, तो आपको टकरावों के बारे में सोचने की आवश्यकता है।
गाइल्स का SO- दुष्ट होना बंद करें '

3

यहाँ एक और विचार है जिसका उद्देश्य (इंजेक्शन से) पेड़ों की संरचना को संख्याओं में बदलना है, न कि केवल उन्हें मनमाने ढंग से लेबल करने के बजाय। उसके लिए, हम उपयोग करते हैं कि किसी भी संख्या का मुख्य गुणनखंड अद्वितीय है।

एन ( एल , आर ) एलEN(l,r)lrN(E,E)

f(E)=0f(N(l,r))=2f(l)3f(r)

का उपयोग करते हुए , हम ट्री-अप में निहित सभी उपप्रकारों के सेट की गणना कर सकते हैं; हर नोड में, हम बच्चों से प्राप्त एन्कोडिंग के सेट को मर्ज करते हैं और एक नया नंबर जोड़ते हैं (जिसे बच्चों के एनकोडिंग से निरंतर समय में गणना की जा सकती है)।f

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

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


1

जैसा कि टिप्पणियों में चित्रों की अनुमति नहीं है:

यहाँ छवि विवरण दर्ज करें

शीर्ष बाएँ: एक इनपुट ट्री

शीर्ष दाएं: नोड्स 5 और 7 में निहित सबटाइम्स आइसोमोर्फिक भी हैं।

निचले बाएँ और दाएँ: संपीड़ित पेड़ विशिष्ट रूप से परिभाषित नहीं हैं।

7+5|T|6+|T|


यह वास्तव में वांछित ऑपरेशन का एक उदाहरण है, धन्यवाद। ध्यान दें कि आपके अंतिम उदाहरण समान हैं यदि आप मूल और अतिरिक्त संदर्भों के बीच अंतर नहीं करते हैं।
राफेल

-1

संपादित करें: मैंने सवाल पढ़ा क्योंकि टी और टी I एक ही माता-पिता के बच्चे थे। मैंने पुनरावर्ती होने के लिए संपीड़न की परिभाषा भी ली है, जिसका अर्थ है कि आप दो पहले संकुचित उपशीर्षक को संकुचित कर सकते हैं। यदि यह वास्तविक प्रश्न नहीं है, तो मेरा उत्तर काम नहीं कर सकता है।

O(nlogn)T(n)=2T(n/2)+cn

def Comp(T):
   if T == null:
     return 0
   leftCount = Comp(T.left)
   rightCount = Comp(T.right)
   if leftCount == rightCount:
     if hasSameStructure(T.left, T.right):
       T.right = T.left
       return leftCount + 1
     else
       return leftCount + rightCount + 1    

जहां hasSameStructure()एक फ़ंक्शन है जो दो पहले से संकुचित उप-प्रकारों की तुलना रैखिक समय में करता है यह देखने के लिए कि क्या उनके पास समान संरचना है। एक रेखीय समय के पुनरावर्ती कार्य को लिखना जो प्रत्येक को जांचता है और जाँचता है कि क्या एक सबट्री के पास हर बार एक बचा हुआ बच्चा है जो अन्य को करता है आदि को कठोर नहीं होना चाहिए।

nnr

T(n)=T(n1)+T(n2)+O(1) if nnr
2T(n/2)+O(n) otherwise

क्या होगा अगर उपशीर्षक भाई बहन नहीं हैं? (T1, T1), (T2, T1)) T1 के लिए देखभाल एक सूचक दो तीसरी घटना का उपयोग करके दो बार बचाया जा सकता है।
१२:१२

TT

यह प्रश्न स्पष्ट रूप से बताता है कि दो उपप्रकार को आइसोमॉर्फिक के रूप में पहचाना जाता है। उनके बारे में कुछ भी नहीं कहा जाता है कि उनके समान माता-पिता हैं। यदि एक पेड़ में तीन बार एक सबट्री टी 1 दिखाई देता है, जैसा कि मेरे पिछले उदाहरण ((टी 1, टी 1), (टी 1, टी 2)) में दो घटनाओं को तीसरे ऑर्केन्स की ओर इशारा करके संकुचित किया जा सकता है।
औली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.