2009-02-27 14 views
6

(? रिवर्स दर्पण बारी के अंदर से बाहर) मैं एक एल्गोरिथ्म के लिए देख रहा हूँ "की विपरीत" (? रिवर्स बारी के अंदर से बाहर) एक DAG:को उलटने के लिए एल्गोरिथ्म की तलाश एक DAG

 A*  # I can't ascii-art the arrows, so just 
    /\  # pretend the slashes are all pointing 
    B C  # "down" (south-east or south-west) 
    //\ # e.g. 
    G E D # A -> (B -> G, C -> (E -> F, D -> F)) 
     \/
     F 

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

  F* 
     /\ 
    G* E D # F -> (E -> C -> A, D -> C -> A), G -> B -> A 
    \ \/ # 
    B C  # Again, arrows point "down" 
     \/ # 
     A  # 

तो इनपुट "जड़ें" (यहां, {ए}) का एक सेट है। आउटपुट ग्राफ़ में "जड़ों" का सेट होना चाहिए: {G, F}। (रूट से मेरा कोई भेजे संदर्भ के साथ एक नोड मतलब है। एक पत्ता नहीं निवर्तमान संदर्भ के साथ एक नोड है।)

इनपुट की जड़ों उत्पादन और वीजा विपरीत की पत्तियों हो जाते हैं। परिवर्तन स्वयं का एक उलटा होना चाहिए।

(उत्सुक के लिए, मैं एक पुस्तकालय मैं लिए उपयोग कर रहा हूँ करने के लिए एक सुविधा जोड़ना चाहते हैं संरचनात्मक क्वेरी किए जाने के लिए एक्सएमएल जिसके द्वारा मैं में अपनी "दर्पण छवि" करने के लिए पहले पेड़ में प्रत्येक नोड मैप कर सकते हैं प्रतिनिधित्व करते हैं दूसरे पेड़ (और फिर से वापस ) मेरी क्वेरी नियम के लिए और अधिक नौवहन लचीलापन प्रदान करने)

+1

क्या कोई कारण है कि आप "पैरेंट" पॉइंटर्स को स्टोर नहीं कर सकते हैं? मैं कल्पना करता हूं कि पत्ती नोड से शुरू होने वाली गहराई से पहली खोज (या जो कुछ भी) करके, उलटा ऑपरेशन मुफ्त में प्रदान करेगा। – Ben

उत्तर

7

ग्राफ़ बिल्डिंग को उल्टा किनारों का एक सेट और पत्ती नोड्स की एक सूची को पार करें।

पत्ते (जो अब रूट हैं) नोड्स के साथ शुरू करने के लिए उल्टा किनारों का एक स्थलीय प्रकार करें।

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

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

A -> (B -> G, C -> (E -> F, D -> F)) 

original roots: [ A ] 
original links: [ AB, BG, AC, CE, EF, CD, DF ] 
reversed links: [ BA, GB, CA, EC, FE, DC, FD ] 
reversed roots: [ G, F ] 
reversed links: [ BA, CA, DC, EC, FE, FD, GB ] (in order of source) 
topologically sorted: [ G, B, F, E, D, C, A ] 
construction order : A, C->A, D->C, E->C, F->(D,E), B->A, G->B 
+0

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

+1

(यह एक शर्म की बात है कि कोई चालाक रिकर्सिव समाधान नहीं है जिसके लिए कई मध्यवर्ती डेटा संरचनाओं की आवश्यकता नहीं है।) – bendin

-1

Depth-first search उत्पन्न करने के लिए आप क्या कर रहे हैं के बाद सक्षम हो सकता है:। पेड़ के माध्यम से अपना रास्ता नोट और हर बार जब आप रिवर्स जोड़ने पार परिणामी डीएजी (पत्तियां जड़ों हैं) के लिए।

+0

कैसे और क्यों? इसका उपयोग करने के लिए आपको इस उत्तर पर विस्तार करने की आवश्यकता है। – SpoonMeiser

+0

मुझे बहुत स्पष्ट लगता है। +1। –

+0

विशेष रूप से एक लिंक के साथ जो डीएफएस काम करता है ... –

2

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

2

मेरा सहज सुझाव आपके ग्राफ का गहराई पहला ट्रैवर्सल करना होगा, और साथ ही साथ अपने प्रतिबिंबित ग्राफ का निर्माण करना होगा।

प्रत्येक नोड को घुमाने पर, प्रतिबिंबित ग्राफ में एक नया नोड बनाएं, और नए ग्राफ में इसके और उसके पूर्ववर्ती के बीच एक किनारा बनाएं।

यदि किसी भी समय आप किसी नोड तक पहुंचते हैं जिसमें कोई बच्चा नहीं है, तो इसे रूट के रूप में चिह्नित करें।

+0

मुश्किल बात यह है कि नोड्स * अपरिवर्तनीय * एक बार बनाए जाते हैं। इसलिए जब मैं नोड बनाता हूं तो मुझे अपने सभी बच्चों को जानने की ज़रूरत है और उन्हें पूरा होना चाहिए। मैं सामान को बढ़ाना नहीं जोड़ सकता। – bendin

+0

@bendin: डीएफएस के दौरान, आपको नोड्स के लिए एक परिवर्तनीय डेटाटाइप का उपयोग करके एक दूसरा डीएजी बनाना होगा। इसके बाद, वांछित अपरिवर्तनीय डेटाटाइप के नोड्स का उत्पादन करने के लिए इस नए डीएजी पर बाद के डीएफएस का उपयोग करें। –

+0

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

1

मैंने इसे एक साधारण ग्राफ ट्रैवर्सल के साथ हल किया। ध्यान रखें टोपोलॉजिकल सॉर्टिंग केवल निर्देशित विश्वकोश ग्राफ के लिए उपयोगी होगी।

मैंने आसन्नता सूची का उपयोग किया, लेकिन आप आसन्न मैट्रिक्स के साथ एक ही चीज़ कर सकते हैं।

अजगर में यह इस तरह दिखता है:

# Basic Graph Structure 
g = {} 
g[vertex] = [v1, v2, v3] # Each vertex contains a lists of its edges 

वी के लिए सभी किनारों को खोजने के लिए, अब आप सूची छ [V] पार और है कि आप सभी (V, यू) किनारों दे देंगे।

उलट ग्राफ निर्माण करने के लिए एक नया शब्दकोश बनाने के लिए और यह कुछ इस तरह का निर्माण:

reversed = {} 
    for v in g: 
     for e in g[v]: 
      if e not in reversed: 
       reversed[e] = [] 
      reversed[e].append(v) 

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

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