2010-12-15 34 views
56

कहें [ए, बी] एक बी से वास्तविक रेखा पर अंतराल का प्रतिनिधित्व करता है, < बी, समावेशी (यानी, [ए, बी] = सभी एक्स का सेट जैसे कि < = x < = b)। इसके अलावा, [ए, बी] और [सी, डी] 'ओवरलैपिंग' हैं यदि वे किसी भी एक्स को साझा करते हैं जैसे एक्स दोनों [ए, बी] और [सी, डी] में है।अंतराल की सूची में अंतराल ओवरलैप के लिए खोज?

अंतराल की एक सूची को देखते हुए, ([x1, y1], [x2, y2], ...), [x, y] के साथ ओवरलैप होने वाले सभी अंतराल को खोजने का सबसे प्रभावी तरीका क्या है?

जाहिर है, मैं प्रत्येक को आजमा सकता हूं और इसे ओ (एन) में प्राप्त कर सकता हूं। लेकिन मैं सोच रहा था कि क्या मैं कुछ चालाक तरीके से अंतराल की सूची को सॉर्ट कर सकता हूं, मैं एक बाइनरी खोज के माध्यम से ओ (लॉग एन) में आइटम/एक/ओवरलैपिंग आइटम ढूंढ सकता हूं, और फिर सूची में उस स्थिति से 'चारों ओर देखो' ढूंढ सकता है सभी ओवरलैपिंग अंतराल। हालांकि, मैं अंतराल को कैसे क्रमबद्ध करूं ताकि ऐसी रणनीति काम करेगी?

ध्यान दें कि सूची आइटमों में तत्वों के बीच ओवरलैप हो सकते हैं, जो कि यह कठिन बनाता है।

मैंने अंतराल को अपने बाएं छोर, दाएं अंत, मध्य से क्रमबद्ध करके कोशिश की है, लेकिन कोई भी संपूर्ण खोज का कारण नहीं लग रहा है।

सहायता?

+12

+1 क्योंकि यह मेरे कामकाजी दिन को और अधिक रोचक बना देता है। –

उत्तर

23

[ए, बी] [x, y] iff b> x और < y के साथ ओवरलैप करता है। अपने पहले तत्वों द्वारा अंतराल को छंटनी आपको लॉग समय में पहली स्थिति से मेल खाने वाले अंतराल देता है। अपने अंतिम तत्वों द्वारा अंतराल को छंटनी आपको लॉग समय में दूसरी स्थिति से मेल खाने वाले अंतराल देता है। परिणामी सेट के चौराहे ले लो।

+1

चौराहे ओ (एन) समय लेना नहीं होगा? यदि सूची एन तत्व लंबी थी, तो सूची में उन लोगों के लिए 'समान आकार' का एक प्रश्न अंतराल पहली सूची में एम मैचों और दूसरी सूची में एनएम मैचों तक पहुंच जाएगा, और छेड़छाड़ के लिए सभी एन तत्वों को पार करने की आवश्यकता होगी, है ना? – cespinoza

+0

यह ओ ले जाएगा (स्थिति से मेल खाने वाली वस्तुओं की छोटी सूची का आकार)। यदि सभी अंतराल का एक छोटा सा अंश मेल खाता है, तो एफ (एन) कहें, यह ओ (एफ (एन)) लेगा। मैंने माना कि यह मामला होगा-अन्यथा मुझे लगता है कि कोई रणनीति मोटे तौर पर ओ (एन) होगी। – gdj

+19

यह सबसे अच्छा जवाब नहीं है; आपने जो वर्णन किया है वह इस पृष्ठ पर "निष्क्रिय दृष्टिकोण" के अंतर्गत आता है: http://en.wikipedia.org/wiki/Interval_tree। दरअसल दूसरा जवाब अंतराल के पेड़ों को देखने का सुझाव देता है। – johnbakers

1

बोलने के लिए बस एक त्वरित विचार 'कफ ऑफ'।

क्या आप उन्हें 2 सूचियों में व्यवस्थित कर सकते हैं, एक अंतराल की शुरुआत के लिए और दूसरा अंतराल के अंत के लिए।

इस तरह, आप उस पर आधारित उम्मीदवारों को काटने के लिए अंतराल सूची (बाइनरी खोज द्वारा कहें) की शुरुआत में वस्तुओं की तुलना कर सकते हैं।

आप अंतराल सूची के अंत में वस्तुओं की तुलना में x की तुलना कर सकते हैं।

संपादित

मामला: एक बार

बंद यदि आप एक एक बार बंद स्थिति में अंतराल की सूची में केवल एक अंतराल की तुलना कर रहे हैं, तो मैं तुम्हें बाहर करने में मदद करेगा छँटाई विश्वास नहीं करते since ideal sorting is O(n)

किसी भी असंभव अंतराल को ट्रिम करने के लिए सभी एक्स के माध्यम से एक रैखिक खोज करके शेष वाई के माध्यम से एक और रैखिक खोज कर आप अपने कुल काम को कम कर सकते हैं। हालांकि यह अभी भी ओ (एन) है, इसके बिना आप 2 एन तुलना कर रहे होंगे, जबकि औसतन, आप केवल इस तरह (3 एन -1)/2 तुलना करेंगे।

मेरा मानना ​​है कि यह एक अनारक्षित सूची के लिए आप सबसे अच्छा कर सकते हैं।

मामला: पूर्व छंटाई में नहीं गिना जाता

मामले में जहां आप बार-बार हो जाएगा अंतराल और अपने पूर्व तरह अपनी सूची की इस सूची में एक अंतराल की तुलना, तो आप बेहतर परिणाम प्राप्त कर सकते हैं। ऊपर की प्रक्रिया अभी भी लागू होती है, लेकिन पहली सूची में बाइनरी खोज करके दूसरा आप ओ (एम लॉग एन) प्राप्त कर सकता है क्योंकि ओ (एमएन) के विपरीत, जहां एम तुलना की जा रही एकल अंतराल की संख्या है। नोट, अभी भी आपको कुल तुलना को कम करने का लाभ देता है। [एम (3 (लॉग एन) की तुलना में 2 एम लॉग एन - 1)/2]

+0

आपके उत्तर के शीर्ष पर आपका प्रारंभिक सुझाव इस पृष्ठ पर "निष्क्रिय दृष्टिकोण" के अंतर्गत आता है: en.wikipedia.org/wiki/Interval_tree। – johnbakers

0

आप एक ही समय में बाएं अंत और दाएं छोर दोनों द्वारा क्रमबद्ध कर सकते हैं और दोनों ओवरलैपिंग मानों को खत्म करने के लिए दोनों सूचियों का उपयोग कर सकते हैं।यदि सूची बाएं छोर द्वारा क्रमबद्ध की जाती है तो परीक्षण सीमा के दाहिने छोर के दाईं ओर वाले अंतराल में से कोई भी ओवरलैप नहीं हो सकता है। यदि सूची को दाएं छोर से क्रमबद्ध किया जाता है तो परीक्षण सीमा के बाएं सिरे के बाईं ओर वाले अंतराल में से कोई भी ओवरलैप नहीं हो सकता है।

उदाहरण के लिए यदि अंतराल

[1,4], [3,6], [4,5], [2,8], [5,7], [1,2], [2,2.5] 

रहे हैं और आप [3,4] साथ ओवरलैप पता लगा रहे हैं तो बाएं छोर से छंटाई और (परीक्षण के दाईं ओर की स्थिति अंकन बस से अधिक के रूप में सही अंत के साथ अपने मूल्य ताकि 4 रेंज में शामिल है)

[1,4], [1,2], [2,2.5], [2,8], [3,6], [4,5], *, [5,7] 

क्या आप जानते हैं [5,7] ओवरलैप नहीं कर सकते, तो सही अंत तक छंटाई और परीक्षण के बाएं छोर की स्थिति अंकन

[1,2], [2,2.5], *, [1,4], [4,5], [3,6], [5,7], [2,8] 

आप [1,2] जानते हैं और [2,2.5] ओवरलैप नहीं कर सकते

सुनिश्चित नहीं हैं कि यह कैसे कुशल होगा जब से तुम दो प्रकार के और खोज करने के लिए कर रहे हैं।

4

'quadtree' एक डेटा संरचना अक्सर 2 आयामों में टक्कर पहचान की दक्षता में सुधार करने के लिए उपयोग की जाती है।

मुझे लगता है कि आप एक समान 1-डी संरचना के साथ आ सकते हैं। इसके लिए कुछ पूर्व-गणना की आवश्यकता होगी लेकिन परिणामस्वरूप ओ (लॉग एन) प्रदर्शन होना चाहिए।

असल में आप रूट 'नोड' से शुरू होते हैं जो सभी संभावित अंतराल को कवर करता है, और पेड़ पर नोड जोड़ते समय, आप तय करते हैं कि यह बाईं ओर या मध्य बिंदु के दाईं ओर आता है या नहीं। यदि यह मध्य बिंदु को पार करता है, तो आप इसे दो अंतराल में तोड़ते हैं (लेकिन मूल अभिभावक को रिकॉर्ड करते हैं) और वहां से आगे बढ़ते हैं। आप पेड़ की गहराई पर एक सीमा निर्धारित कर सकते हैं, जो स्मृति को बचा सकता है और प्रदर्शन में सुधार कर सकता है, लेकिन कुछ जटिल चीजों की कीमत पर आता है (आपको अपने नोड्स में अंतराल की एक सूची स्टोर करने की आवश्यकता है)।

फिर अंतराल की जांच करते समय, आप मूल रूप से सभी पत्ते नोड्स को पाते हैं जिन्हें इसे डाला जाएगा, घुसपैठ के लिए उन नोड्स के आंशिक अंतराल की जांच करें, और उसके बाद उनके द्वारा दर्ज की गई अंतराल की रिपोर्ट करें 'माता-पिता

+2

इसी तरह की संरचना, विचित्र रूप से पर्याप्त, को बाइनरी पेड़ कहा जाता है। –

+1

@ निक विगिल - यह एक प्रकार का बाइनरी पेड़ है, यकीन है, लेकिन बाइनरी पेड़ और एल्गोरिदम के लिए बहुत सारे उपयोग हैं जो मैं वर्णन कर रहा हूं थोड़ा और विस्तृत है। – sje397

0

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

इस मामले में, अपने प्रश्न को पूरा नहीं कर रहा है:

  • आप पूरी सूची दी जाती है या यह जो वास्तव में यह बनाता है आप है?

  • क्या आपको केवल एक ऐसा लुकअप या उनमें से कई प्रदर्शन करना है?

  • क्या आपके पास संचालन के लिए कोई अनुमान है जिसका समर्थन करना चाहिए और उनकी आवृत्तियों?

उदाहरण के लिए, यदि आपको केवल एक ऐसा लुकअप करना है, तो पहले सूची को सॉर्ट करने योग्य नहीं है। यदि कई लोग हैं, तो "1 डी क्वाड्री" की अधिक महंगी सॉर्टिंग या पीढ़ी को अमूर्त किया जाएगा।

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

एक सरल कार्यान्वयन एक आदेश (समन्वय द्वारा) सूची होगी जहां आप ध्वज प्रारंभ/अंत और सेगमेंट नंबर के साथ सभी सेगमेंट सिरों को सम्मिलित करते हैं। इस तरह, इसे पार्स करके (अभी भी ओ (एन), लेकिन मुझे संदेह है कि यदि आप ओवरलैप किए गए सभी सेगमेंट की सूची की भी आवश्यकता रखते हैं तो आप इसे तेज़ी से बना सकते हैं), और सभी खुले खंडों का ट्रैक रखते हुए जो " अंक की जांच करें "।

52

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

यह सीएलआरएस 14.3 में वर्णित है।

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