डुप्लीकेट के साथ चतुर्भुज


10

मैं एक क्वाडट्री लागू कर रहा हूं। जो लोग इस डेटा संरचना को नहीं जानते हैं, उनके लिए मैं निम्नलिखित छोटे विवरण शामिल कर रहा हूं:

एक क्वाडट्री एक डेटा संरचना है और यूक्लिडियन विमान में है कि 3-आयामी अंतरिक्ष में एक ऑक्ट्री क्या है। Quadtrees का एक सामान्य उपयोग स्थानिक अनुक्रमण है।

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

तो एक चतुष्कोण या तो एक पत्ती है और इसकी क्षमता से कम तत्व हैं, या 4 चतुर्भुज वाला एक पेड़ है, जिसमें बच्चे (आमतौर पर उत्तर-पश्चिम, उत्तर-पूर्व, दक्षिण-पश्चिम, दक्षिण-पूर्व) हैं।

मेरी चिंता यह है कि यदि आप डुप्लिकेट को जोड़ने की कोशिश करते हैं, तो हो सकता है कि एक ही स्थिति में कई बार एक ही तत्व हो या एक ही स्थिति के साथ कई अलग-अलग तत्व हों, क्वाडट्रिज को किनारों को संभालने के साथ एक मौलिक समस्या है।

उदाहरण के लिए, यदि आप 1 की क्षमता के साथ क्वाडट्री के साथ काम करते हैं और इकाई आयत बाउंडिंग बॉक्स के रूप में:

[(0,0),(0,1),(1,1),(1,0)]

और आप दो बार एक आयत डालने की कोशिश करते हैं जिसमें से ऊपरी-बायीं सीमा मूल होती है: (या इसी तरह यदि आप इसे N + 1 की क्षमता के साथ क्वाडट्री में N + 1 बार डालने की कोशिश करते हैं)

quadtree->insert(0.0, 0.0, 0.1, 0.1)
quadtree->insert(0.0, 0.0, 0.1, 0.1)

पहली प्रविष्टि में कोई समस्या नहीं होगी: सबसे पहले डालें

लेकिन तब पहली प्रविष्टि एक उपखंड को ट्रिगर करेगी (क्योंकि क्षमता 1 है): दूसरी प्रविष्टि, पहला उपखंड

इस प्रकार दोनों आयतें एक ही उपशीर्षक में डाल दी जाती हैं।

फिर से, दो तत्व एक ही क्वाडट्री में आएंगे और एक उपखंड को ट्रिगर करेंगे ... दूसरा इन्सर्ट, दूसरा सबडिवीसन

और इतने पर, और आगे, उपखंड विधि अनिश्चित काल तक चलेगी क्योंकि (0, 0) हमेशा बनाए गए चार में से एक ही उपप्रकार में होगी, जिसका अर्थ है एक अनंत पुनरावृत्ति समस्या होती है।

क्या डुप्लीकेट के साथ चतुर्भुज होना संभव है? (यदि नहीं, तो कोई इसे लागू कर सकता है Set)

चतुर्भुज की वास्तुकला को पूरी तरह से तोड़े बिना हम इस समस्या को कैसे हल कर सकते हैं?


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

@ यह बहुत सच है। हालाँकि इस विषय पर काफी शोध किया गया है और मैं वास्तव में पहिया को फिर से मजबूत नहीं करना चाहता। TBH मैं अभी भी पता नहीं है इस सवाल का अधिक इतने पर, programmers.SE पर, gamedev.SE पर या यहाँ तक कि math.SE पर संबंधित है या नहीं ...
पियरे ARLAUD

: इसके अलावा, देखने के meta.programmers.stackexchange.com/questions/6709/... ...
पियरे ARLAUD

जवाबों:


3

आप डेटा संरचना लागू कर रहे हैं, इसलिए आपको कार्यान्वयन निर्णय लेने होंगे।

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

कार्यान्वयन के निर्णय करना पहिये को सुदृढ़ नहीं कर रहा है , कम से कम पहली बार में अपना स्वयं का कार्यान्वयन लिखने से अधिक नहीं है।

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

अंत में, यदि आपको लगता है कि इस पर कोई शोध है, तो इसे खोजें, और फिर हम इस पर चर्चा कर सकते हैं। हो सकता है कि कुछ चौदह अपरिवर्तनीय हैं जिन्हें मैंने अनदेखा कर दिया है, या कुछ अतिरिक्त बाधाएं हैं जो बेहतर प्रदर्शन की अनुमति देती हैं।


मेरी समस्या यह है कि मुझे यह बताते हुए कोई दस्तावेज नहीं मिल सकता है कि विशिष्टता एक आवश्यकता है। फिर भी, यदि आपने मेरा उदाहरण देखा है, तो आप एक ही समस्या को देख सकते हैं यदि आप एक ही तत्व को कई बार शामिल करते हैं।
पियरे अरलाउद

पेड़ों के प्रकारों के लिए, मूल्य के साथ नोड भी कभी-कभी एक "गिनती" फ़ील्ड नहीं दिया जाता है जो केवल डुप्लिकेट के लिए वेतन वृद्धि और घटता है?
जे ट्राना

2

मुझे लगता है कि यहां गलतफहमी है।

जैसा कि मैं इसे समझता हूं, प्रत्येक क्वाडट्री नोड में एक बिंदु द्वारा अनुक्रमित मूल्य होता है। दूसरे शब्दों में, इसमें त्रिगुण (x, y, मान) शामिल हैं।

इसमें चाइल्ड नोड्स के 4 पॉइंट भी होते हैं, जो कि अशक्त हो सकते हैं। चाबियाँ और बच्चे के लिंक के बीच एक एल्गोरिदमिक संबंध है।

आपके आवेषण इस तरह दिखना चाहिए।

quadtree->insert(0.0, 0.0, value1)
quadtree->insert(0.0, 0.0, value2)

पहला इंसर्ट एक पेरेंट (पैरेंट) नोड बनाता है और उसमें एक वैल्यू डालता है।

दूसरा इन्सर्ट एक बाल नोड बनाता है, इससे लिंक करता है, और इसमें एक वैल्यू सम्मिलित करता है (जो कि पहले मान के समान हो सकता है)।

कौन सा बच्चा नोड त्वरित है एल्गोरिथ्म पर निर्भर करता है। यदि एल्गोरिथ्म फॉर्म [x] में है और समन्वय स्थान [0,1) सीमा में है, तो प्रत्येक बच्चा रेंज [0,0.5) का विस्तार करेगा और बिंदु को NW बच्चे में रखा जाएगा।

मैं कोई अनंत पुनरावृत्ति नहीं देखता।


तो आप कह रहे हैं कि जब बच्चों को विभाजित करने के लिए नोड्स को पुनर्वितरित करने का मेरा तरीका है, तो मेरे विभाजन के साथ क्या गलत है?
पियरे अरलाउंड

शायद समस्या यह है कि आप उस मूल्य को स्थानांतरित करने की कोशिश कर रहे हैं जहां से यह (माता-पिता में) एक बेहतर जगह (एक बच्चे में) के लिए है। यह वास्तव में नहीं है कि यह कैसे किया जाता है। मान जहां है वहीं ठीक है। लेकिन इससे दिलचस्प परिणाम सामने आता है कि दो समान बिंदुओं को अलग-अलग नोड्स (लेकिन हमेशा संबंधित माता-पिता और बच्चे) में रखा जा सकता है।
david.pfx

2

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

मुझे लगता है कि मुख्य बात यह है कि यह करना आसान है।


2

मैं यह मान रहा हूं कि आप ऐसे तत्वों को अनुक्रमित कर रहे हैं जो सभी एक ही आकार के हैं, अन्यथा जीवन जटिल, या धीमा, या दोनों…

एक Quadtree नोड को एक निश्चित क्षमता की आवश्यकता नहीं है। क्षमता का उपयोग किया जाता है

  • प्रत्येक ट्री नोड को स्मृति में या डिस्क पर निश्चित आकार की अनुमति दें - आवश्यक नहीं है यदि ट्री नोड में तत्वों का एक चर आकार सेट है और आप स्पेस आवंटन प्रणाली का उपयोग कर रहे हैं जो कॉपी करता है। (उदाहरण java / c # मेमोरी में ऑब्जेक्ट।)
  • जब एक नोड को विभाजित करने का निर्णय लें।
    • आप बस नियम को फिर से परिभाषित कर सकते हैं, ताकि एक नोड विभाजित हो जाए यदि इसमें "n" जिले तत्व शामिल हैं, जहां तत्वों के स्थान के अनुसार जिले को परिभाषित किया गया है।
    • या " कंपोजिट एलिमेंट" का उपयोग करें , इसलिए यदि एक ही स्थान पर मल्टीप्ल एलिमेंट हैं, तो आप एक नए एलिमेंट का परिचय देते हैं, जिसमें इन मल्टीप्ल एलिमेंट्स की सूची होती है।

2

जब आप स्थानिक अनुक्रमण समस्याओं से निपट रहे हैं, तो मैं वास्तव में एक स्थानिक हैश या मेरे व्यक्तिगत पसंदीदा: सादे पुराने ग्रिड के साथ शुरुआत करने की सलाह देता हूं।

यहां छवि विवरण दर्ज करें

... और इसकी कमजोरियों को समझने से पहले पेड़ की संरचनाओं को स्थानांतरित करने से पहले जो विरल प्रतिनिधित्व की अनुमति देते हैं।

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

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

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

यहां छवि विवरण दर्ज करें

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

हालांकि, संयोग और बड़े पैमाने पर तत्वों के साथ ये दो तत्काल समस्याएं वास्तव में सभी स्थानिक अनुक्रमण संरचनाओं के लिए समस्याग्रस्त हैं । सादे पुराने ग्रिड वास्तव में इन पैथोलॉजिकल मामलों को कई अन्य लोगों की तुलना में थोड़ा बेहतर ढंग से संभालते हैं क्योंकि यह कम-से-कम कोशिकाओं को पुनरावृत्ति नहीं करना चाहता है।

जब आप ग्रिड से शुरू करते हैं और अपने काम की तरह किसी क्वाड-ट्री या केडी-ट्री की तरह काम करते हैं, तो आप जिस मुख्य समस्या को हल करना चाहते हैं, वह समस्या है बहुत सारे सेल में डालने वाले तत्वों के साथ बहुत अधिक सेल और / या इस प्रकार के घने प्रतिनिधित्व के साथ बहुत अधिक कोशिकाओं की जांच करना।

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


Quadtrees के लिए एक अद्यतन के रूप में, किसी ने एक प्रश्न पूछा था जो थोड़े व्यापक था (लेकिन मैं उन लोगों को पसंद करता हूं) कैसे उन्हें टक्कर का पता लगाने के लिए कुशल बनाया जाए, और मैंने उस पर अपनी हिम्मत बढ़ाना शुरू कर दिया कि मैं उन्हें कैसे लागू करता हूं। यह आपके सवालों के जवाब भी देना चाहिए: stackoverflow.com/questions/41946007/…
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.