2009-12-13 19 views
10

में है, तो मेरे पास आयत का एक बड़ा संग्रह है, वही आकार। मैं यादृच्छिक बिंदु उत्पन्न कर रहा हूं जो इन आयतों में नहीं आना चाहिए, इसलिए मैं जो करना चाहता हूं वह परीक्षण है यदि उत्पन्न बिंदु आयत में से एक में निहित है, और यदि ऐसा होता है, तो एक नया बिंदु उत्पन्न करें।परीक्षण अगर कुछ आयताकार

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

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

संपादित करें: यह 2 डी में है और आयताकार घुमाए नहीं गए हैं।

+3

क्या आपके आयत के किनारे अक्ष के साथ गठबंधन हैं, या वे अक्षों के मनमानी कोणों पर उन्मुख हैं? –

+0

वे सभी गठबंधन हैं, कोई रोटेशन नहीं है या – pafcu

+0

की तरह कुछ भी फैंसी आयताकार ओवरलैप करते हैं? –

उत्तर

8

यह रेडिट धागा तुम्हारी समस्या पते:

I have a set of rectangles, and need to determine whether a point is contained within any of them. What are some good data structures to do this, with fast lookup being important?

अपने ब्रह्मांड पूर्णांक है, या यदि परिशुद्धता के स्तर में अच्छी तरह से जाना जाता है और बहुत अधिक नहीं है, तो आप से abelsson के सुझाव का उपयोग कर सकते हैं धागा, हे (1) रंग का उपयोग कर देखने का उपयोग कर:

सामान्य आप समय के लिए अंतरिक्ष व्यापार कर सकते हैं यहाँ .. एक हे बहुत कम निरंतर साथ (1) देखने है। init: एक बिटमैप पर्याप्त सटीकता के साथ सभी आयत को लिफाफे के लिए काफी बड़ा बनाएं, को काला में प्रारंभ करें। रंग सभी पिक्सेल जिसमें कोई आयताकार सफेद होता है। ओ (1) लुकअप: बिंदु (एक्स, वाई) सफेद है? यदि तो, एक आयताकार मारा गया था।

मुझे सलाह है कि आप उस पोस्ट पर जाएं और पूरी तरह से ModernRonin के उत्तर को पढ़ें जो सबसे स्वीकार्य है। मैंने इसे यहां चिपकाया:

सबसे पहले, माइक्रो समस्या। आपके पास मनमाने ढंग से घुमावदार आयताकार है, और बिंदु है। आयताकार के अंदर बिंदु क्या है?

ऐसा करने के कई तरीके हैं। लेकिन सबसे अच्छा, मुझे लगता है, 2 डी वेक्टर क्रॉस उत्पाद का उपयोग कर रहा है। सबसे पहले, सुनिश्चित करें कि आयताकार के बिंदु को घड़ी के क्रम में संग्रहीत किया जाता है। फिर वेक्टर क्रॉस उत्पाद 1) वेक्टर पक्ष और 2 के दो बिंदुओं द्वारा गठित किया गया है) परीक्षण बिंदु पर पक्ष के पहले बिंदु से वेक्टर। परिणाम के संकेत देखें - सकारात्मक पक्ष के अंदर (दाईं ओर) नकारात्मक है। यदि यह के अंदर सभी चार तरफ है, तो यह आयताकार के अंदर है। या समकक्ष, यदि यह किसी भी पक्ष के बाहर है, तो यह आयताकार के बाहर है। More explanation here

इस विधि हर पक्ष के लिए 2 वैक्टर, प्लस हर पक्ष के लिए एक उत्पाद पार जो तीन गुणा करता है और दो कहते प्रति वेक्टर 3 घटाता ले जाएगा * गुना।11 प्रति तरफ फ्लॉप, 44 फ्लॉप प्रति आयताकार।

आप पार उत्पाद पसंद नहीं है, तो आप की तरह कुछ कर सकता है: आंकड़ा बाहर उत्कीर्ण और प्रत्येक आयत के लिए घिरा हलकों, देखें कि क्या खुदा एक के अंदर बिंदु। यदि ऐसा है, तो यह आयताकार में भी है। यदि नहीं, तो जांचें कि यह आयताकार के बाहर है। यदि ऐसा है, तो यह आयताकार के बाहर भी है। यदि यह के बीच दो मंडलियों के बीच आता है, तो आप f **** d हैं और आप को इसे कठिन तरीके से जांचना है।

अगर एक बिंदु 2 डी में एक चक्र अंदर है ढूँढना दो subtractions और दो squarings (= पलता) लेता है, और फिर आप दूरी एक वर्गमूल क्या करने वाले से बचने के लिए चुकता की तुलना करें। यह 4 फ्लॉप है, बार दो सर्किल 8 फ्लॉप हैं - लेकिन कभी-कभी आपको अभी भी पता नहीं चलेगा। इसके अलावा इस मानता है कि आप घिरा या खुदा हलकों, जो या सच कितना पूर्व अभिकलन आप अपने आयत सेट पर करने के लिए तैयार कर रहे हैं पर निर्भर करता है नहीं हो सकता गणना करने के लिए भुगतान नहीं करते हैं किसी भी CPU समय ।

किसी भी घटना में, यह शायद एक महान विचार हर आयत के खिलाफ बिंदु परीक्षण करने के लिए नहीं है, खासकर यदि आप उनमें से एक सौ करोड़ की है।

जो हमें मैक्रो समस्या में लाता है। सेट में प्रत्येक एकल आयत के खिलाफ बिंदु का परीक्षण करने से कैसे बचें? 2D में, यह शायद quad-tree समस्या है। 3 डी में, जेनेरिक_handle ने कहा - एक ऑक्टेट्री। मेरे हेड के शीर्ष पर, मैं इसे B+ tree के रूप में लागू कर दूंगा। यह डी = 5, का उपयोग करने के लिए मोहक है ताकि प्रत्येक नोड में 4 बच्चे हो सकें, क्योंकि यह नक्शा क्वाड-पेड़ अमूर्तता पर बहुत अच्छी तरह से मानचित्र करता है। लेकिन अगर आयताकारों का सेट पर बहुत बड़ा है, तो मुख्य स्मृति में फिट नहीं है ( इन दिनों बहुत अधिक संभावना नहीं है), तो उसी आकार के रूप में नोड्स को डिस्क ब्लॉक के रूप में जाने का तरीका है।

कष्टप्रद पतित के लिए मामलों से सावधान रहें, एक ही सटीक बिंदु पर केन्द्रों के साथ दस हजार लगभग समान आयतों है कि कुछ डेटा सेट की तरह। : पी

यह समस्या क्यों महत्वपूर्ण है? यह कंप्यूटर ग्राफिक्स में उपयोगी है, जांचने के लिए यदि कोई किरण बहुभुज को छेड़छाड़ करती है। आईई, क्या उस स्निपर राइफल ने आपको शॉट किया था जिस व्यक्ति को आप पर शूटिंग कर रहे थे? इसका उपयोग रीयल-टाइम मानचित्र सॉफ़्टवेयर में भी किया जाता है, जैसे कि जीपीएस इकाइयां। जीपीएस आपको निर्देशांक बताता है कि आप पर हैं, लेकिन नक्शा सॉफ़्टवेयर को यह पता लगाना है कि उस बिंदु पर डेटा की एक बड़ी मात्रा में है, और इसे प्रति सेकंड कई बार करें।

फिर, ModernRonin को ऋण ...

+1

ओवरलैप करते हैं मुझे यह समझने में कठिनाई होती है कि कैसे मॉडर्नरोनिन का "वेक्टर उत्पाद" विधि यह जांचने से तेज हो सकता है कि min_x <= x <= max_x और min_y <= y <= max_y ... I ' मैं quadtree दृष्टिकोण के बारे में निश्चित नहीं है, क्योंकि वे ज्यादातर अंक भंडारण में मदद करते हैं, आयताकार नहीं ... – EOL

+2

वेक्टर उत्पाद मनमाने ढंग से उन्मुखीकरण के आयताकार को अनुमति देता है; मुझे यकीन है कि अन्य आयत अधिक उपयुक्त हैं जब सभी आयताकार कुछ समन्वय प्रणाली के अक्षों के साथ गठबंधन होते हैं। – musicinmybrain

+0

इसके अलावा, वेक्टर उत्पाद विधि किसी को यह जांचने की अनुमति देती है कि कोई बिंदु किसी 4-पक्षीय आकार के अंदर है या नहीं, यह आयताकार है या नहीं। –

0

मैं तुम्हें (और साथ ही और संभव quadtrees या octrees, लिंक है कि पृष्ठ पर उपलब्ध) BSP trees पर एक नज़र डालें सुझाव देते हैं। उनका उपयोग पूरे स्थान को दोबारा विभाजित करने के लिए किया जाता है और आपको तुरंत उस बिंदु की जांच करने की अनुमति मिलती है जो आपको आयत की जांच करने की आवश्यकता होती है।

कम से कम आपके पास केवल एक विशाल विभाजन है और सभी आयतों की जांच करने की आवश्यकता है, अधिकतम आपके विभाजन इतने छोटे हो जाते हैं कि वे एकल आयत के आकार तक पहुंच जाते हैं। निश्चित रूप से अधिक बढ़िया विभाजन, जितना लंबा आयत आपको जांचना चाहते हैं उसे खोजने के लिए आपको पेड़ को नीचे जाने की जरूरत है।

हालांकि, आप स्वतंत्र रूप से तय कर सकते हैं कि कितने आयत एक बिंदु के लिए जांचने के लिए उपयुक्त हैं और फिर इसी संरचना को बनाते हैं।

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

0

आपका आर-पेड़ दृष्टिकोण सबसे अच्छा तरीका है जिसे मैं जानता हूं (यही वह दृष्टिकोण है जिसे मैं क्वाड्रिस, बी + पेड़, या बसपा पेड़ों पर चुनता हूं, क्योंकि आर-पेड़ आपके मामले में निर्माण के लिए सुविधाजनक लगते हैं)। चेतावनी: मैं कोई विशेषज्ञ नहीं हूं, भले ही मुझे अपने वरिष्ठ वर्ष विश्वविद्यालय वर्ग एल्गोरिदमिक से कुछ चीजें याद हों!

1

ऐसा क्यों न करें। यह गणना और स्मृति दोनों पर बल्कि प्रकाश लगता है।

अपने आय की आधार रेखा पर सभी आयतों के अनुमानों पर विचार करें।

{[Rl1, Rr1], [Rl2, Rr2],..., [Rln, Rrn]}, ordered by increasing left coordinates. 

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

यदि कोई नहीं करता है, तो आपका बिंदु (x, y) सभी आयतों के बाहर है।

अगर कुछ कहते हैं, [आरएलएल, आरआरके], ..., [आरएलएच, आरआरएच], (के < = एच) तो बस जांचें कि वाई इनमें से किसी भी आयत की ऊर्ध्वाधर सीमा के भीतर है या नहीं।

हो गया।

शुभकामनाएं। पारंपरिक, निचले-बाएं और ऊपर-दाएं कोने -

जॉन पूर्वोत्तर क्षेत्र विकास

2

आयतों कि कुल्हाड़ियों के साथ गठबंधन कर रहे हैं के लिए, आप केवल दो अंक (चार नंबर) आयत की पहचान करने की जरूरत है।क्या एक भी बिंदु (एक्स परीक्षण, वाई परीक्षण) स्थापित करने के लिए एक आयत के साथ ओवरलैप हो (एक्स बीएल, वाई बीएल, एक्स टी.आर., वाई टी.आर.) दोनों का परीक्षण करके:

  • एक्स परीक्षण> = एक्स बीएल & & एक्स परीक्षण < = एक्स टी.आर.
  • वाई परीक्षण> = Y बीएल & & वाई काफी परीक्षण < = Y टी.आर.

जाहिर है, परीक्षण करने के लिए अंक की एक बहुत बड़ी सेट के लिए, यह हो सकता है समय लेने । सवाल यह है कि परीक्षण को अनुकूलित करने का तरीका कैसा है।

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

  • एक्स परीक्षण> = एक्स मिनट & & एक्स परीक्षण < = एक्स अधिकतम
  • वाई परीक्षण> = Y मिनट & & वाई परीक्षण < = Y अधिकतम

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

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

तो, अंतरिक्ष-समय व्यापार-बंद, हमेशा के रूप में हैं। और पूर्व-गणना बनाम खोज व्यापार-बंद। यदि आप दुर्भाग्यपूर्ण हैं, तो पूर्व-गणना कुछ भी प्राप्त नहीं करती है (उदाहरण के लिए, केवल दो बॉक्स हैं, और वे अक्ष पर ओवरलैप नहीं करते हैं)। दूसरी तरफ, यह काफी खोज-समय लाभ प्राप्त कर सकता है।

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