पहले, यह इंगित करने के लिए थोड़ा पृष्ठभूमि कि यह एक कठिन समस्या क्यों नहीं है। एक नदी के माध्यम से प्रवाह की गारंटी देता है कि उसके खंडों, अगर सही ढंग से डिजीटल हैं, तो हमेशा एक निर्देशित चक्रीय ग्राफ (डीएजी) बनाने के लिए उन्मुख किया जा सकता है । बदले में, एक ग्राफ को रेखीय रूप से आदेश दिया जा सकता है यदि और केवल अगर यह एक डीएजी है, तो एक सामयिक प्रकार के रूप में ज्ञात तकनीक का उपयोग करके । टोपोलॉजिकल सॉर्टिंग तेज है: इसकी समय और स्थान की आवश्यकताएं दोनों O (| E | + | V) हैं। (E = किनारों की संख्या, V = संख्याओं की संख्या), जो जितना अच्छा हो उतना अच्छा होता है। इस तरह के लीनियर ऑर्डर बनाने से बड़ी स्ट्रीम बेड का पता लगाना आसान हो जाता है।
यहाँ, तब, एक एल्गोरिथ्म का एक स्केच है । धारा का मुंह अपने प्रमुख बिस्तर के साथ स्थित है। मुंह से जुड़ी प्रत्येक शाखा के साथ ऊपर की ओर ले जाएं (यदि मुंह एक संगम है, तो एक से अधिक हो सकता है) और प्रमुख रूप से उस शाखा के नीचे जाने वाले प्रमुख बिस्तर का पता लगाएं। उस शाखा का चयन करें, जिसके लिए कुल लंबाई सबसे बड़ी है: यह आपकी "बैकलिंक" प्रमुख बिस्तर के साथ है।
इसको स्पष्ट करने के लिए, मैं कुछ (अनुपचारित) स्यूडोकोड प्रस्तुत करता हूं । इनपुट लाइन सेगमेंट (या आर्क्स) एस (डिजीटल स्ट्रीम शामिल ) का एक सेट है , प्रत्येक में दो अलग-अलग एंडपॉइंट्स शुरू होते हैं (एस) और अंत (एस) और एक सकारात्मक लंबाई, लंबाई (एस); और नदी मुंह पी , जो एक बिंदु है। आउटपुट सबसे दूर के अपस्ट्रीम बिंदु के साथ मुंह को एकजुट करने वाले खंडों का एक क्रम है।
हमें "चिह्नित सेगमेंट" (एस, पी) के साथ काम करने की आवश्यकता होगी। इनमें से एक सेगमेंट एस के साथ-साथ इसके दो एंडपॉइंट में से एक है, पी । हम सभी क्षेत्रों खोजने की जरूरत होगी एस है कि शेयर एक जांच बिंदु के साथ एक अंतबिंदु क्ष , उनके साथ उन क्षेत्रों को चिह्नित अन्य सेट लौट अंतिम बिंदुओं, और:
Procedure Extract(q: point, A: set of segments): Set of marked segments.
जब ऐसा कोई खंड नहीं मिल सकता है, तो अर्क को खाली सेट वापस करना होगा। एक साइड इफेक्ट के रूप में, एक्स्ट्रेक्ट को ए से लौट रहे सभी सेगमेंट को हटाना होगा , जिससे ए खुद को संशोधित किया जा सकेगा ।
मैं निकालें के एक कार्यान्वयन नहीं दे रही हूँ: अपने जीआईएस क्षमता का चयन करने के क्षेत्रों प्रदान करेगा एस के साथ कि समाप्ति बिंदु साझा करने क्ष । उन्हें चिह्नित करना बस स्टार्ट (एस) और एंड (एस) दोनों की तुलना q के साथ करना है और जो भी दो एंडपॉइंट्स में से लौट रहा है वह मेल नहीं खाता है।
अब हम समस्या को हल करने के लिए तैयार हैं।
Procedure LongestUpstreamReach(p: point, A: set of segments): (Array of segments, length)
A0 = A // Optional: preserves A
C = Extract(p, A0) // Removes found segments from the set A0!
L = 0; B = empty array
For each (S,q) in C: // Loop over the segments meeting point p
(B0, M) = LongestUpstreamReach(q, A0)
If (length(S) + M > L) then
B = append(S, B0)
L = length(S) + M
End if
End for
Return (B, L)
End LongestUpstreamReach
प्रक्रिया "परिशिष्ट (एस, बी 0)" खंड बी 0 के अंत में सेगमेंट एस को चिपकाती है और नया सरणी लौटाती है।
(यदि धारा वास्तव में एक पेड़ है: कोई द्वीप, झील, ब्रैड, आदि - तो आप A को A0 में कॉपी करने के कदम से दूर कर सकते हैं ।)
मूल प्रश्न का उत्तर LongestUpstreamReach द्वारा लौटाए गए खंडों के मिलन से बनता है।
वर्णन करने के लिए , आइए मूल नक्शे में धारा पर विचार करें। मान लीजिए कि यह सात आर्क के संग्रह के रूप में डिजीटल है। आर्क एक (नीचे आंकड़ा है, जो घुमाया है में सही पर, नक्शे के शीर्ष) बिंदु 0 पर मुंह से चला जाता है बिंदु 1. पहली बार में संगम के लिए नदी के ऊपर यह एक लंबे चाप है, 8 इकाइयों लंबे कहते हैं। आर्क बी शाखाओं के बाईं ओर (मानचित्र में) और छोटा है, लगभग 2 इकाइयाँ लंबा। आर्क c दायीं ओर और लगभग 4 इकाइयाँ लंबी हैं, आदि "b", "d", और "f" को बाईं ओर की शाखाओं को दर्शाते हैं जैसा कि हम मानचित्र पर ऊपर से नीचे तक जाते हैं, और "a" "सी", "ई", और "जी" अन्य शाखाओं, और 7 के माध्यम से कोने 0 की संख्या, हम सार को आर्क्स के संग्रह के रूप में ग्राफ का प्रतिनिधित्व कर सकते हैं
A = {a=(0,1), b=(1,2), c=(1,3), d=(3,4), e=(3,5), f=(5,6), g=(5,7)}
मैं वे लंबाई 8, 2, 4, 1, 2, 2, 2 के लिए मान लीजिए होगा एक के माध्यम से ग्राम क्रमशः। मुंह वर्टेक्स 0 है।
पहला उदाहरण एक्सट्रैक्ट (5, {f, g}) को कॉल है। यह चिह्नित सेगमेंट {(एफ, 6), (जी, 7)} के सेट को लौटाता है। ध्यान दें कि वर्टेक्स 5 आर्क्स एफ और जी (नक्शे के निचले भाग में दो आर्क्स) के संगम पर है और यह (एफ, 6) और (जी, 7) प्रत्येक आर्क्स को उनके अपस्ट्रीम एंडपॉइंट्स के साथ चिह्नित करता है ।
अगला उदाहरण LongestUpstreamReach (0, A) के लिए कॉल है। पहली कार्रवाई यह एक्स्ट्रेक्ट (0, ए) के लिए कॉल है। यह रिटर्न एक सेट उल्लेखनीय खंड (क, 1) युक्त और यह खंड को हटा एक सेट से A0 है, जो अब बराबर {बी, सी, डी, ई, एफ, जी}। लूप का एक चलना है, जहां (एस, क्यू) = (ए, 1)। इस यात्रा के दौरान एक कॉल LongestUpstreamReach (1, A0) से की जाती है। पुनरावर्ती रूप से, इसे या तो अनुक्रम (g, e, c) या (f, e, c) पर लौटना चाहिए: दोनों समान रूप से मान्य हैं। इसकी लंबाई (M) यह 4 + 2 + 2 = 8. है (ध्यान दें कि LongestUpstreamReach A0 को संशोधित नहीं करता है ।) लूप के अंत में, खंड a।को स्ट्रीम बेड में जोड़ दिया गया है और लंबाई 8 + 8 = 16 तक बढ़ा दी गई है। इस प्रकार पहले रिटर्न मान में अनुक्रम (g, e, c, a) या (f, e, c, a) शामिल हैं, दूसरी वापसी के मूल्य के मामले में 16 की लंबाई के साथ। इससे पता चलता है कि लॉन्गस्टुपस्ट्रीम कैसे सिर्फ मुंह से ऊपर की ओर बढ़ता है, प्रत्येक संगम पर जाने के लिए सबसे लंबी दूरी के साथ शाखा का चयन करता है, और अपने मार्ग के साथ आने वाले खंडों का ट्रैक रखता है।
कई ब्रैड और द्वीप होने पर एक अधिक कुशल कार्यान्वयन संभव है, लेकिन अधिकांश प्रयोजनों के लिए बहुत कम प्रयास करना होगा यदि LongestUpstreamReach को बिल्कुल दिखाया गया है, क्योंकि प्रत्येक संगम पर विभिन्न शाखाओं में खोजों के बीच कोई ओवरलैप नहीं है: कंप्यूटिंग समय (और स्टैक डेप्थ) कुल खंडों के सीधे आनुपातिक होगा।