एक * नेविगेशनल मेष पथ खोज


15

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

मैंने दो ए * प्रोटोटाइप बनाए हैं। एक ग्रिड आधारित है और फिर मैंने एक बनाया जो वेपाइंट के साथ काम करता है इसलिए अब मुझे नोड्स के एक ग्राफ के लिए बाधाओं / इमारतों के 2d "मैप" से निकलने के लिए एक तरह से काम करने की आवश्यकता है जिससे मैं एक रास्ता बना सकता हूं। वास्तविक पाथफाइंडिंग ठीक लगती है, बस मेरी खुली और बंद सूचियाँ एक अधिक कुशल डेटा संरचना का उपयोग कर सकती हैं, लेकिन मुझे इसकी आवश्यकता होगी कि अगर और कब आवश्यकता हो।

मैं aiblog.net पर इस पोस्ट में पंक्तिबद्ध सभी कारणों के लिए एक नेविगेशनल जाल का उपयोग करने का इरादा रखता हूं । हालाँकि, मैंने जो समस्या पेश की है वह यह है कि ए * सोचता है कि बहुभुज केंद्रों / किनारों से सबसे छोटा रास्ता आवश्यक नहीं है यदि आप नोड के किसी भी हिस्से से गुजरते हैं तो सबसे छोटा रास्ता नहीं है। एक बेहतर विचार प्राप्त करने के लिए आप स्टैकओवरफ़्लो पर पूछे गए प्रश्न को देख सकते हैं ।

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

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

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

अंत में, रिकॉर्ड के लिए: मैं इसे स्वयं से खरोंच से प्रोग्राम करना चाहता हूं, भले ही पहले से ही अन्य समाधान उपलब्ध हैं और मैं इस गेम के अलावा किसी अन्य चीज में इस कोड का उपयोग करने का इरादा नहीं करता हूं, इसलिए यह कोई फर्क नहीं पड़ता कि यह अनिवार्य रूप से खराब गुणवत्ता का होगा।


मुझे यकीन नहीं है लेकिन ये लिंक मदद कर सकते हैं: gamedev.stackexchange.com/questions/1327/… gamedev.stackexchange.com/questions/8087/ ... पथ-खोज के बारे में एक और सवाल था जो अभी नहीं मिल सकता है , जिसे एक इनाम मिला और उसका बहुत अच्छा जवाब था।
अली

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

वास्तव में, मैं अभी gamedev.stackexchange.com/questions/8087/… में लेख पढ़ता हूं और यह A * के साथ एक मार्ग को खोजने के लिए काम करता है, फिर एक संशोधित फ़नल एल्गोरिथ्म के साथ इसकी सही लागत की गणना करना और फिर दूसरा मार्ग खोजना और इसकी गणना करना सच्ची लागत फिर से और यह देखने के लिए कि क्या यह अन्य की तुलना में कम है। यह दोहराता है जब तक कि यह नहीं जानता कि यह सबसे छोटा मार्ग है। यह वास्तव में मेरी समस्या को हल करता है, हालांकि, ऐसा लगता है कि यह काफी धीमा होगा क्योंकि आप सीधे और पथ दोनों को दोहरा रहे हैं, जो काफी महंगा होगा।
गुस्से में

बहुभुज भंडारण: केवल दृश्य बहुभुजों को संग्रहीत करें - या प्रत्येक बहुभुज के साथ एक टैग संबद्ध करें (याद रखें कि प्रत्येक बहुभुज को कोने की एक गोलाकार सूची बनाने की आवश्यकता होगी); समान रूप से नोड्स के साथ आप बहुभुज की आईडी को स्टोर कर सकते हैं जो वे उत्पन्न करते हैं - लेकिन मुझे आपको यह बताने की आवश्यकता नहीं है: यह प्राथमिक डेटा भंडारण है। अंत में आपको सच्चे सबसे छोटे रास्ते की परवाह क्यों है ? आपका खेल कुत्ते को धीमा चला सकता है या आपके पास थोड़ा गलत रास्ते हो सकते हैं: एक को चुनें। सच कम से कम पथ प्राप्त करने की आवश्यकता है (एक नोड ग्राफ से अधिक कम से कम) एक पूर्ण चौड़ाई-पहले खोज।
जोनाथन डिकिंसन

@JonathanDickinson मुझे पता है कि मुझे उस पथ की आवश्यकता नहीं है जो पिछले पिक्सेल के लिए 100% सटीक होगा, और मुझे पता है कि मैं A * का उपयोग उन पथों का उत्पादन करने के लिए कर सकता हूं जो कि अधिकांश p स्वीकार्य होंगे। यह बात बहुत स्पष्ट रूप से एक बाधा को पार कर रही है , जैसा कि स्टैक ओवरफ्लो पर या gamedev.stackexchange.com/questions/8087/… पर मेरे पिछले प्रश्न में बस बहुत अधिक है। मैं अपने एआई को एक बाधा के आसपास चलने नहीं दे सकता!
गुस्से में

जवाबों:


14

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

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

रास्ता पाना

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

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

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

पथ सीधा

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

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

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

आप इस रे-कास्ट परीक्षण को तब भी कर सकते हैं जब फ़नलिंग एल्गोरिथ्म यह निर्धारित करता है कि यह देखने के लिए कि यह वास्तव में करता है या नहीं, लेकिन मुझे लगता है कि जब तक आप एक मोड़ नहीं डालते, तब तक आपको प्रत्येक नोड पर उस परीक्षण को करते रहना होगा। जो बिंदु आप साधारण फ़नल एल्गोरिथ्म में वापस ला सकते हैं)। यह महंगा होने जा रहा है, पथ को सीधा करते हुए लगभग O (n ^ 2)।

नवमेश का प्रतिनिधित्व करना

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


मैंने अभी इसका एक संक्षिप्त विवरण पढ़ा है, लेकिन मैं समझता हूं कि आपको A *: theory.stanford.edu/~amitp/GameProgramming/… के
गुस्सा

मैं वास्तव में इस बारे में चिंतित नहीं हूं कि वास्तव में पथ को सीधा करने के तरीके के बारे में क्या है, जो मैं चिंतित हूं वह यह है कि आप क्या कहते हैं: "आपको यह देखना चाहिए कि यह केवल ए * खोज के दौरान पाए जाने वाले बहुभुजों की सीमा के भीतर पथ को सीधा करेगा। इस तरह, अगर वह एक बाधा के आसपास सबसे तंग रास्ता नहीं खोजता है, तो आपको उस एल्गोरिथ्म को चलाने के बाद एक तंग रास्ता नहीं मिलेगा। "
गुस्से में

मैं एक नेव जाली चाहता हूं, जहां A * हमेशा वह रास्ता खोजेगा, जो एक बार सीधा हो, सबसे छोटा हो, चाहे वह वर्टिकल / मिडपॉइंट से यात्रा करने की लागत हो। मैं सराहना करता हूं कि यह दृश्यता ग्राफ के साथ किया जा सकता है, लेकिन मैं एक नवमेश का उपयोग करना चाहता हूं क्योंकि इसके कई अन्य लाभ हैं और क्योंकि दृश्यता ग्राफ की जटिलता बहुत जल्दी बढ़ सकती है: सिद्धांत.प्रोफोर्डफोर्ड। ईडीयू ~ampp GamProgramming/…
नाराजगी ३०'११

@ गुयेनहोलसाइक्लिक्स आप यूक्लिडियन दूरी का उपयोग कर सकते हैं sqrt(x*x + y*y)- लेकिन सस्ता-प्रति-नोड नहीं x*x + y*y
जोनाथन डिकिंसन

@JonathanDickinson मुझे पता है, इसलिए मेरी बात।
गुस्से में
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.