मेरे पास एक ज्ञात परिमित आकार की टाइलों का एक ग्रिड है जो एक मानचित्र बनाता है। नक्शे के अंदर की कुछ टाइलों को एक सेट में रखा जाता है जिसे एक क्षेत्र के रूप में जाना जाता है। यह क्षेत्र जुड़ा हुआ है, लेकिन इसके आकार के बारे में कुछ भी ज्ञात नहीं है। ज्यादातर समय यह काफी नियमित रूप से बूँद होती है, लेकिन यह एक दिशा में बहुत लम्बी हो सकती है, और संभवतः इसमें छेद भी हो सकते हैं। मुझे इस क्षेत्र की बाहरी (बाहरी) सीमा को खोजने में दिलचस्पी है।
यही है, मैं उन सभी टाइलों की एक सूची चाहता हूं जो क्षेत्र में स्वयं के बिना टाइलों में से एक को छूते हैं। इसे खोजने का एक कुशल तरीका क्या है?
अतिरिक्त कठिनाई के लिए, ऐसा होता है कि मेरी टाइलें हेक्स हैं, लेकिन मुझे संदेह है कि इससे बहुत अधिक फर्क नहीं पड़ता है, प्रत्येक टाइल को अभी भी एक पूर्णांक x और y समन्वय के साथ लेबल किया गया है और, एक टाइल दी गई है, मैं आसानी से अपने पड़ोसियों को ढूंढ सकता हूं। नीचे कुछ उदाहरण दिए गए हैं: काला क्षेत्र है, और मैं जिस सीमा को खोजना चाहता हूं वह नीला है। यह अपने आप में, एक कठिन समस्या नहीं है, इसके लिए एक सरल एल्गोरिथ्म, छद्म-अजगर में है:
def find_border_of_territory(territory):
border = []
for tile in territory:
for neighbor in tile.neighbors():
if neighbor not in territory and neighbor not in border:
border.add(neighbor)
हालांकि यह धीमा है और मैं कुछ बेहतर करना चाहूंगा। मेरे पास क्षेत्र में एक ओ (एन) लूप है, सभी पड़ोसियों पर एक और लूप (एक छोटा, लेकिन अभी भी) है और फिर मुझे दो सूचियों पर सदस्यता की जांच करनी है, जिनमें से एक का आकार n है। यह O (n ^ 2) का एक भयानक स्केलिंग देता है। मैं सीमा और क्षेत्र के लिए सूचियों के बजाय सेटों का उपयोग करके ओ (एन) को कम कर सकता हूं ताकि सदस्यता की जांच तेजी से हो, लेकिन यह अभी भी महान नहीं है। मुझे उम्मीद है कि ऐसे कई मामले होंगे जहां क्षेत्र बड़ा है, लेकिन एक साधारण क्षेत्र बनाम लाइन स्केलिंग के कारण सीमा छोटी है। उदाहरण के लिए यदि क्षेत्र 5 त्रिज्या का एक हेक्स है, तो यह आकार 91 का है लेकिन सीमा केवल आकार 36 की है।
किसी को भी कुछ बेहतर प्रस्तावित कर सकते हैं?
संपादित करें:
नीचे दिए गए कुछ सवालों के जवाब देने के लिए। इस क्षेत्र का आकार लगभग 20 से 100 तक हो सकता है। क्षेत्र बनाने वाली टाइलों का सेट एक वस्तु का एक गुण है, और यह वह वस्तु है जिसे सभी सीमा टाइलों के एक सेट की आवश्यकता होती है।
प्रारंभ में इस क्षेत्र को एक ब्लॉक के रूप में बनाया जाता है, और फिर एक-एक करके टाइलें प्राप्त होती हैं। इस मामले में, यह सच है कि सबसे तेज़ तरीका सिर्फ सीमा का एक सेट रखने के लिए है और केवल उस टाइल पर अपडेट करें जो प्राप्त की गई है। कभी-कभी क्षेत्र में एक बड़ा परिवर्तन हो सकता है - इसलिए इसे पूरी तरह से पुनर्गणना करने की आवश्यकता होगी।
मैं अब इस बात पर विचार कर रहा हूं कि एक सरल सीमा-खोज एल्गोरिथ्म करना सबसे अच्छा समाधान है। एकमात्र अतिरिक्त जटिलता यह उठती है कि यह सुनिश्चित करने के लिए कि सीमा हर बार पुनर्गणना की जाती है, जिसकी आवश्यकता हो सकती है, लेकिन इससे अधिक नहीं। मुझे पूरा विश्वास है कि यह मेरे वर्तमान ढांचे में मज़बूती से किया जा सकता है।
टाइमिंग के लिए, मेरे वर्तमान कोड में मेरे पास कुछ रूटीन हैं जो क्षेत्र की प्रत्येक टाइल की जांच करने की आवश्यकता है। हर मोड़ पर नहीं, बल्कि सृजन पर और कभी-कभार। टेस्ट सूट के मेरे चलने के समय का 50% से अधिक समय लगता है, भले ही यह संपूर्ण कार्यक्रम का बहुत छोटा हिस्सा है। इसलिए मैं किसी भी दोहराव को कम करने के लिए उत्सुक था। फिर भी, परीक्षण कोड में प्रोग्राम के एक सामान्य चलने (स्वाभाविक रूप से) की तुलना में बहुत अधिक ऑब्जेक्ट निर्माण शामिल है, इसलिए मुझे एहसास है कि यह बहुत प्रासंगिक नहीं हो सकता है।