2009-01-09 7 views
13

को देखते हुए आप निम्नलिखित वर्ग (बुरा सी #, लेकिन आप बहाव मिलता है):इस मामले में एक परिपत्र संदर्भ जांच के लिए एक अच्छा एल्गोरिदम क्या होगा?

public abstract class AmICircular 
{ 
    // assume Children is never null 
    private List<AmICircular> Children {get;set;} 

    // assume target is never null 
    public void Add(AmICircular target) 
    { 
    target.PerformCircularReferenceCheck(this); 
    Children.Add(target); 
    } 

    // throws when a circular reference is detected 
    protected abstract void PerformCircularReferenceCheck(AmICircular target); 
} 

आप PerformCircularReferenceCheck कैसे लागू होगा? और, नहीं, यह होमवर्क नहीं है।

अनुभवहीन कार्यान्वयन, imo, this और सभी बच्चों पर एक संदर्भ की जांच करते हैं, तो target पर PerformCircularReferenceCheck फोन, this पारित करने के लिए किया जाएगा। लेकिन मैं सोच रहा हूं कि क्या बेहतर, साबित प्रभावी, ऐसा करने के तरीके हैं, जैसे this और target के संदर्भों के पूरे बच्चों के पेड़ को ध्वस्त करने के लिए विधि जोड़ने और फिर परिणामों की जांच करें (ढेर पर कम दबाव?), या शायद सूची < टी> के अलावा किसी भिन्न (शायद स्वयं-जांच!) संग्रह का उपयोग कर चेक से पूरी तरह से बचें?

आप यह कैसे करेंगे?

संपादित करें: स्टीफन के रूप में बताया है, यह अगर यह लक्ष्य

+1

यदि यह होमवर्क नहीं है, तो मैंने JSON serializer को मेरे लिए यह करने दिया। JsonConvert.SerializeObject (myObject) मौजूद होने पर एक परिपत्र संदर्भ त्रुटि फेंक देगा। –

उत्तर

12

मामले में जहां आप स्वयं संदर्भित जोड़ने कभी नहीं (जो बाद में परिभाषित किया जा करने के लिए) वस्तुओं में, अपने डेटा संरचना एक निर्देशित अचक्रीय ग्राफ (http://en.wikipedia.org/wiki/Directed_acyclic_graph), जहां IAmCircular वर्ग के के प्रत्येक उदाहरण के एक सेट के साथ एक नोड का वर्णन का वर्णन करता है प्रत्यक्ष उत्तराधिकारी नोड्स = बच्चे।

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

जटिलता सिद्धांत के अनुसार, यह समस्या एसटी-कनेक्टिविटी (http://en.wikipedia.org/wiki/St-connectivity) है और कक्षा एनएल (http://en.wikipedia.org/wiki/NL_(complexity)) के लिए पूर्ण है, भले ही आप इनपुट को विश्वकोश ग्राफ (जो आपका मामला है) तक सीमित करते हैं।

विशेष रूप से, साविच के प्रमेय (http://en.wikipedia.org/wiki/Savitch%27s_theorem) ओ (लॉग^2 एन) स्पेस एल्गोरिदम बनाने के लिए एक रचनात्मक तरीका प्रदान करता है (इसके लिए समय ओ (एन^2) में चल रहा है), जहां एन नोड्स की संख्या है।

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

मैं तुच्छ ओ (एन) समय, ओ (एन) स्पेस एल्गोरिदम लागू करने की अनुशंसा करता हूं, जो उत्तराधिकारी के अपने सेट (लक्ष्य) "के लिए उत्पन्न करता है और यह निर्धारित करता है कि" यह "इस सेट में दिखाई देता है या नहीं।

सावधान रहें, सेट का स्पष्ट निर्माण महत्वपूर्ण है। अन्यथा, अगर आप "लक्ष्य" के किसी भी उत्तराधिकारी द्वारा "यह" पहुंचने योग्य है, तो आप केवल पुनरावर्ती रूप से सत्यापित करते हैं, तो आप घातीय समय में भाग लेने का जोखिम रखते हैं।

मैंने ओ (एन) समय/ओ (एन) स्पेस एल्गोरिदम की सिफारिश की क्योंकि यह समय-समय पर सबसे अच्छा कर सकता है, और आप पहले से ही अपनी डेटा संरचना के लिए ओ (एन) स्पेस का उपयोग कर रहे हैं।

7

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

आप R = {this} और CR = {this.children} के साथ शुरू करते हैं।

प्रत्येक चरण में, आप जांचते हैं कि सीआर में this (या target, आपके सटीक लक्ष्य के आधार पर) है। यदि नहीं, तो आप सीआर को आर में जोड़ते हैं और सीआर के बच्चों को सीआर सेट करते हैं, और सीआर से आर के तत्वों को हटाते हैं।

यदि सीआर खाली हो जाता है, तो आर this से पहुंचने योग्य तत्वों का पूरा सेट है।

+0

जब आप सीआर कहते हैं, तो क्या आपका मतलब आरसी है? –

+0

@ पेट्रसहेरॉन: आसपास के अन्य तरीके, लेकिन हाँ - तय। – MSalters

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