जब गंतव्य अगम्य है तो मैं तेजी से ए * खत्म कैसे कर सकता हूं?


31

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

मैं इसे कैसे दरकिनार कर सकता हूं? मुझे लगता है कि मैं स्क्रीन क्षेत्र को पाथफाइंडिंग को कम कर सकता हूं, लेकिन शायद मुझे यहां कुछ स्पष्ट याद आ रहा है?


2
क्या आप जानते हैं कि कौन सी टाइलें अगम्य हैं या क्या आप इसे केवल अस्सरा एल्गोरिथ्म के परिणामस्वरूप जानते हैं?
user000user

आप अपने नेविगेशन ग्राफ़ को कैसे संग्रहीत कर रहे हैं?
एको

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

अगर यह बहुत धीमा है, तो मेरे पास सुझाव देने के लिए अनुकूलन की एक श्रृंखला है - या आप पूरी तरह से खोजों से बचने की कोशिश कर रहे हैं?
स्टीवन

1
यह सवाल शायद कंप्यूटर साइंस के लिए बेहतर रहा होगा ।
राफेल

जवाबों:


45

खोज से बचने पर कुछ विचार जो पूरी तरह से विफल रास्तों के परिणामस्वरूप होते हैं:

द्वीप आईडी

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

ऊपरी सीमा को सीमित करें

मैं खोजे जा सकने वाले नोड्स की अधिकतम सीमा को सीमित करता हूं। यह अगम्य खोजों को हमेशा के लिए चलाने में मदद करता है, लेकिन इसका अर्थ है कि कुछ निष्क्रिय खोजें जो बहुत लंबी हैं वे खो सकती हैं। इस संख्या को देखते रहने की जरूरत है, और यह वास्तव में समस्या को हल नहीं करता है, लेकिन यह लंबी खोजों के साथ जुड़े लागतों को कम करता है।

यदि आप जो खोज रहे हैं वह यह है कि इसमें बहुत अधिक समय लग रहा है तो निम्नलिखित तकनीकें उपयोगी हैं:

इसे अतुल्यकालिक और सीमा परिवर्तन करें

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

सही डेटा संरचना चुनें

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

कैच व्हाट यू कैन

जब आप पहली बार किसी नोड पर जाते हैं और गंतव्य की दूरी की गणना करते हैं, तो उस कैश को स्टेट ऑब्जेक्ट में संग्रहीत किया जाता है। यदि आप फिर से गणना करते हैं तो नोड फिर से गणना करने के बजाय कैश्ड परिणाम का उपयोग करता है। मेरे मामले में यह संशोधित नोड्स पर एक वर्गमूल नहीं करने में मदद करता है। आप पा सकते हैं कि ऐसे अन्य मूल्य हैं जिन्हें आप पूर्वगामी और कैश कर सकते हैं।

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

सौभाग्य, और हमें बताएं कि आप क्या पाते हैं।


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

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

प्रत्येक क्षेत्र में बाढ़ भराव या BFS।
वुल्फडॉन

द्वीप आईडी को स्थिर होने की आवश्यकता नहीं है। एक सरल एल्गोरिथ्म है जो दो अलग-अलग द्वीपों में शामिल होने में सक्षम होने की स्थिति में उपयुक्त होगा, लेकिन यह बाद में एक द्वीप को विभाजित नहीं कर सकता है। इन स्लाइड्स में 20 से पेज 8 बताएं कि विशेष एल्गोरिथ्म: cs.columbia.edu/~bert/courses/3137/Lecture22.pdf
kasperd

@kasperd निश्चित रूप से कुछ भी नहीं है कि द्वीप आईडी को पुनर्गठित किया जा रहा है, रनटाइम पर विलय कर दिया गया है। मुद्दा यह है कि द्वीप आईडी आपको यह पुष्टि करने की अनुमति देता है कि क्या कोई रास्ता दो नोड्स के बीच मौजूद है, जो कि एस्टार खोज किए बिना जल्दी से।
स्टीवन

26

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

इसे कम करने के तरीके:

  • यदि आप एक प्राथमिकता जानते हैं कि एक नोड अगम्य है (जैसे कि इसका कोई पड़ोसी नहीं है या इसे चिह्नित नहीं किया गया है UnPassable), तो No Pathकभी भी अस्तर को कॉल किए बिना वापस लौटें।

  • समाप्ति से पहले नोड्स की संख्या का विस्तार किया जाएगा। खुले सेट की जाँच करें। यदि यह कभी बहुत बड़ा हो जाता है, तो समाप्त करें और वापस लौटें No Path। हालाँकि, यह आसार की पूर्णता को सीमित करेगा; तो यह केवल अधिकतम लंबाई के पथ की योजना बना सकता है।

  • एक रास्ता खोजने में लगने वाले समय को सीमित करें । यदि यह समय से बाहर निकलता है, बाहर निकलें और वापस लौटें No Path। यह पिछली रणनीति की तरह पूर्णता को सीमित करता है, लेकिन कंप्यूटर की गति के साथ मापता है। ध्यान दें कि कई खेलों के लिए यह अवांछनीय है, क्योंकि तेज या धीमे कंप्यूटर वाले खिलाड़ी खेल को अलग तरह से अनुभव करेंगे।


13
मैं यह बताना चाहूंगा कि सीपीयू की गति के आधार पर आपके गेम के मैकेनिक्स को बदलना (हाँ, रूट फाइंडिंग एक गेम मैकेनिक है) एक बुरा विचार हो सकता है क्योंकि यह गेम को अप्रत्याशित बना सकता है और कुछ मामलों में अप्रत्याशित भी हो सकता है। अब से 10 साल बाद कंप्यूटर पर। इसलिए मैं सीपीयू समय की तुलना में खुले सेट को कैप करके ए * को सीमित करने की सिफारिश करूंगा।
फिलिप

@Philipp। इसे प्रतिबिंबित करने के लिए उत्तर को संशोधित किया।
मकिंलिंग

1
ध्यान दें कि आप किसी दिए गए ग्राफ़ के लिए दो नोड्स के बीच अधिकतम दूरी निर्धारित कर सकते हैं (यथोचित रूप से कुशल, O (नोड्स))। यह सबसे लंबी पथ समस्या है , और यह आपको जांचने के लिए नोड्स की संख्या के लिए एक सही ऊपरी बाध्य प्रदान करता है।
MSalters

2
@MSalters आप इसे ओ (n) में कैसे करते हैं? और 'यथोचित कुशल' क्या है? यदि यह केवल नोड्स के जोड़े के लिए है तो क्या आप सिर्फ नकल करने के काम में नहीं हैं?
स्टीवन

विकिपीडिया के अनुसार, सबसे लंबा रास्ता समस्या एनपी-कठिन है, दुर्भाग्य से।
डेस्टी

21
  1. लक्ष्य A नोड से एक दोहरी A * खोज को एक ही समय में एक ही लूप में चलाएँ और दोनों खोजों को निरस्त कर दें, जैसे ही कोई अयोग्य पाया जाता है

यदि लक्ष्य के चारों ओर केवल 6 टाइलें हैं और मूल में 1002 टाइलें हैं, तो खोज 6 (दोहरी) पुनरावृत्तियों पर रुकेगी।

जैसे ही एक खोज को दूसरे के विज़िट किए गए नोड्स मिलते हैं, आप खोज क्षेत्र को दूसरे के विज़िट किए गए नोड्स तक सीमित कर सकते हैं और तेज़ी से समाप्त कर सकते हैं।


2
आपके कथन से निहित एक द्विदिश ए-स्टार खोज को लागू करने के लिए और अधिक है, जिसमें यह सत्यापित करना शामिल है कि इस परिस्थिति में हेयोरिस्टिक स्वीकार्य है। (लिंक: homepages.dcc.ufmg.br/~chaimo/public/ENIA11.pdf )
पीटर जेकरेन्स

4
@StephaneHockenhull: असममित लागत के साथ एक इलाके के नक्शे पर एक द्विदिश A- * लागू करने के बाद, मैं आपको विश्वास दिलाता हूं कि अकादमिक ब्ला-ब्ला को नजरअंदाज करने से दोषपूर्ण पथ चयन और गलत लागत गणना हो जाएगी।
पीटर जेकरेन्स 22

1
@MingDuck: कुल नोड्स की संख्या अपरिवर्तित है, और प्रत्येक नोड को अभी भी केवल एक बार विज़िट किया जाएगा, इसलिए मानचित्र के आधे भाग में विभाजन का सबसे खराब मामला यूनिडायरेक्शनल A- * के समान है।
पीटर जेकरेन्स

1
@PieterGeerkens: क्लासिक A * में, केवल आधे नोड्स ही उपलब्ध हैं, और इस प्रकार विज़िट किए गए हैं। यदि नक्शा बिल्कुल आधे में विभाजित है, तो जब आप द्विदिश रूप से खोज करते हैं, तो आप प्रत्येक नोड को स्पर्श करते हैं (लगभग)। निश्चित रूप से एक बढ़त मामला है
Mooing Duck

1
@MooDDuck: मैंने गलत बोला; सबसे खराब मामले अलग ग्राफ हैं, लेकिन एक ही व्यवहार है - यूनिडायरेक्शनल के लिए सबसे खराब मामला एक पूरी तरह से अलग लक्ष्य-नोड है, जिसके लिए सभी नोड्स का दौरा किया जाना आवश्यक है।
पीटियर जेकरेन्स

12

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


6
यह अच्छा है। टाइलों को "क्षेत्रों" में समूहित करके और पहले जाँच लें कि आपकी टाइल जिस क्षेत्र में है वह उस क्षेत्र से जुड़ी हो सकती है जो दूसरी टाइल में है, आप नकारात्मक चीजों को बहुत तेजी से फेंक सकते हैं।
कोनरक

2
सही - आम तौर पर HPA के तहत आता है
स्टीवन

@Steven धन्यवाद मुझे यकीन है कि मैं इस तरह के दृष्टिकोण के बारे में सोचने वाला पहला व्यक्ति नहीं था लेकिन यह नहीं जानता था कि इसे क्या कहा जाता है। Preexisting अनुसंधान का लाभ लेना बहुत आसान है।
20

3

विभिन्न विशेषताओं के साथ कई एल्गोरिदम का उपयोग करें

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

"ए" में आप जो "दोष" खोज रहे हैं वह यह है कि यह टोपोलॉजी से अनजान है। आपके पास 2-डी दुनिया हो सकती है, लेकिन यह यह नहीं जानता है। सभी के लिए यह पता है, आपकी दुनिया के दूर के कोने में एक सीढ़ी है जो इसे दुनिया के ठीक नीचे अपनी मंजिल तक पहुंचाती है।

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

ऐसा करने का एक आसान तरीका प्रत्येक टाइल को एक नोड को आवंटित करना होगा। यह दिखाने के लिए तुच्छ है कि आपको केवल प्रत्येक टाइल पर एक नोड आवंटित करने की आवश्यकता है (आप कभी भी दो नोड्स तक नहीं पहुंच सकते हैं जो ग्राफ़ में कनेक्ट नहीं हैं)। फिर ग्राफ़ किनारों को अलग-अलग नोड्स के साथ दो टाइल कहीं भी परिभाषित किया गया है।

इस ग्राफ़ में एक नुकसान है: यह इष्टतम पथ नहीं खोजता है। यह केवल एक रास्ता खोजता है । हालाँकि, अब यह आपको दिखा रहा है कि A * एक इष्टतम पथ खोज सकता है।

यह A * फंक्शन बनाने के लिए आवश्यक अपने कम आंकडों को बेहतर बनाने के लिए एक हेयुरिस्टिक प्रदान करता है, क्योंकि अब आप अपने परिदृश्य के बारे में अधिक जानते हैं। आपको यह पता लगाने की संभावना कम है कि आगे बढ़ने के लिए आपको वापस जाने से पहले एक मृत अंत का पूरी तरह से पता लगाना होगा।


मेरे पास यह विश्वास करने का कारण है कि Google मैप्स के लिए एल्गोरिदम समान (हालांकि अधिक उन्नत) तरीके से काम करते हैं।
कोरट अमोन -

गलत। A * को टोपोलॉजी के बारे में बहुत अधिक जानकारी है, जो स्वीकार्य हेयुरिस्टिक के विकल्प के माध्यम से है।
मसलक

Google पर जाएं, अपनी पिछली नौकरी में हमने Google मानचित्र के प्रदर्शन का विश्लेषण किया और पाया कि यह A * नहीं हो सकता था। हमारा मानना ​​है कि वे आर्कफ्लैग या अन्य समान एल्गोरिदम का उपयोग करते हैं जो मानचित्र प्रीप्रोसेसिंग पर निर्भर करते हैं।
मसलक

@MSalters: यह एक दिलचस्प रेखा खींचने के लिए है। मेरा तर्क है कि A * टोपोलॉजी से अनजान है क्योंकि यह केवल निकटतम पड़ोसियों के साथ ही चिंता करता है। मैं यह तर्क दूंगा कि यह शब्द अधिक न्यायसंगत है कि एल्गोरिथ्म को स्वीकार करने वाले विधर्मी पैदा करता है जो कि टोपोलॉजी के बारे में जानता है, बजाय ए * के। एक मामले पर विचार करें जहां एक हीरा है। A * हीरे के दूसरे पक्ष को आज़माने के लिए बैक करने से पहले एक रास्ता थोड़ा सा तय करता है। ए * को सूचित करने का कोई तरीका नहीं है कि उस शाखा से एकमात्र "निकास" एक पहले से ही दौरा किया नोड (बचत संगणना) के माध्यम से है।
कॉर्ट अमोन -

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

2

उपरोक्त उत्तरों के अतिरिक्त कुछ और विचार:

  1. ए * खोज के कैश परिणाम। सेल ए से सेल बी तक पथ डेटा को सहेजें और यदि संभव हो तो पुन: उपयोग करें। यह स्थैतिक मानचित्रों में अधिक लागू होता है और आपको गतिशील मानचित्रों के साथ अधिक काम करना होगा।

  2. प्रत्येक कोशिका के पड़ोसियों को कैश करें। ए * कार्यान्वयन को प्रत्येक नोड का विस्तार करने और खोज के लिए अपने पड़ोसियों को खुले सेट में जोड़ने की आवश्यकता है। यदि इस पड़ोसी की गणना प्रत्येक बार कैश की बजाय की जाती है, तो यह नाटकीय रूप से खोज को धीमा कर सकता है। और यदि आप पहले से ही ऐसा कर रहे हैं, तो A * के लिए प्राथमिकता कतार का उपयोग करें।


1

यदि आपका नक्शा स्थिर है, तो आपके पास बस एक अलग सेक्शन हो सकता है, जिसमें स्वयं का कोड हो और A * चलाने से पहले इसे पहले जांचें। यह मानचित्र निर्माण पर किया जा सकता है या मानचित्र में भी कोडित किया जा सकता है।

इम्पेसेबल टाइल्स का एक झंडा होना चाहिए और एक टाइल की तरह जब आप ए * को चलाने के लिए नहीं चुन सकते हैं या इसके आगे एक टाइल चुन सकते हैं जो कि उपलब्ध है।

यदि आपके पास गतिशील नक्शे हैं जो बार-बार बदलते हैं तो आप भाग्य से बहुत बाहर हैं। आपको अपना निर्णय पूरा करने से पहले अपने एल्गोरिथ्म को रोकना होगा या अनुभागों की जांच अक्सर बंद कर देनी है।


यह वही है जो मैं अपने उत्तर में एक एरिया आईडी के साथ सुझा रहा था।
स्टीवन

यदि आपका नक्शा गतिशील है, तो आप CPU / समय का उपयोग भी कम कर सकते हैं, लेकिन अक्सर बदलता नहीं है। यानी जब भी कोई बंद दरवाजा खुला या लॉक किया जाता है तो आप एरिया आईडी की गणना कर सकते हैं। चूंकि यह आमतौर पर एक खिलाड़ी के कार्यों के जवाब में होता है, आप कम से कम एक तहखाने के बंद क्षेत्रों को बाहर करेंगे।
ulivitness

1

मैं ए * अधिक तेज़ी से कैसे निष्कर्ष निकाल सकता हूं कि एक नोड अगम्य है?

अपने Node.IsPassable()फ़ंक्शन को प्रोफाइल करें , सबसे धीमे भागों का पता लगाएं, उन्हें गति दें।

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

लेकिन यह एकल नोड की जांच करने के लिए तेजी से बनाने के लिए है। आप यह देखने के लिए प्रोफाइल कर सकते हैं कि नोड्स को क्वेरी करने में कितना समय लगता है, लेकिन लगता है कि आपकी समस्या यह है कि बहुत सारे नोड्स की जाँच की जा रही है।

जब मैं एक अगम्य टाइल पर क्लिक करता हूं, तो एल्गोरिथ्म स्पष्ट रूप से अगम्य टाइल के लिए एक मार्ग खोजने के लिए पूरे नक्शे से गुजरता है

यदि गंतव्य टाइल स्वयं अगम्य है, तो एल्गोरिथ्म को किसी भी टाइल की जांच नहीं करनी चाहिए। पाथफाइंडिंग करना शुरू करने से पहले, यह गंतव्य टाइल को यह जांचने के लिए क्वेरी करना चाहिए कि क्या यह संभव है, और यदि नहीं, तो कोई पथ परिणाम नहीं लौटाएं।

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

यदि उत्तरार्द्ध का मामला है, तो आप एक द्विदिश खोज करके इसे गति दे सकते हैं - इस तरह गंतव्य से शुरू होने वाली खोज जल्दी से पा सकती है कि कोई रास्ता नहीं है और खोज को रोक दें। इस उदाहरण को देखें , गंतव्य को दीवारों से घेरें और द्विदिश बनाम एकल दिशा की तुलना करें।


0

पथ-खोज पीछे की ओर करें।

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


यह भी धीमी है अगर अगम्य टाइल पहुंच से बाहर हो जाए तो टाइल
मूंग बतख

1
@MooDDuck आपके द्वारा जुड़े जाने योग्य टाइलों से जुड़ा हुआ है। यह एक ऐसा समाधान है जो बहुत अधिक किसी भी मैप मैप डिज़ाइन के साथ काम करता है, और इसे लागू करना बहुत आसान है। मैं सटीक समस्या के बेहतर ज्ञान के बिना कुछ भी कट्टरता का सुझाव नहीं देने जा रहा हूं, जैसे कि ए * कार्यान्वयन इतना धीमा कैसे हो सकता है कि सभी टाइलों का दौरा करना वास्तव में एक समस्या है।
आआआआआआआआआआआ आआआआआना

0

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


यह बिंदु नियमित A * से तेज होना था।
हेकेल

0

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

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

यह अहंकार से एक प्रारंभिक निकास होना चाहिए:

if not IsPassable(A) or not IsPasable(B) then
    return('NoWayExists');

0

दो नोड्स के बीच एक ग्राफ में सबसे लंबी दूरी की जांच करने के लिए:

(यह मानते हुए कि सभी किनारों का वजन समान है)

  1. किसी भी शीर्ष से BFS चलाएँ v
  2. परिणामों का उपयोग करने के लिए दूर से एक शीर्ष का चयन करें v, हम इसे कॉल करेंगे d
  3. से BFS चलाते हैं u
  4. वर्टेस्ट से दूर का पता लगाएं u, हम इसे कॉल करेंगे w
  5. के बीच की दूरी uऔर wग्राफ में सबसे लंबी दूरी है।

प्रमाण:

                D1                            D2
(v)---------------------------r_1-----------------------------(u)
                               |
                            R  | (note it might be that r1=r2)
                D3             |              D4
(x)---------------------------r_2-----------------------------(y)
  • चलो कहते हैं कि के बीच की दूरी yऔर xअधिक है!
  • फिर इसी के अनुसार D2 + R < D3
  • फिर D2 < R + D3
  • तब के बीच की दूरी vऔर xकी तुलना में अधिक है vऔर u?
  • फिर uपहले चरण में नहीं उठाया गया।

क्रेडिट के लिए प्रो। श्लोमी रुबिनस्टीन

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

कृपया ध्यान दें कि मैं इसे एक जुड़ा हुआ ग्राफ मान रहा हूँ। मैं इसे अप्रत्यक्ष भी मान रहा हूं।


A * 2 डी टाइल आधारित गेम के लिए वास्तव में उपयोगी नहीं है क्योंकि अगर मैं सही ढंग से समझूं, तो यह मानते हुए कि जीव 4 दिशाओं में चलते हैं, BFS समान परिणाम प्राप्त करेगा। भले ही जीव 8 दिशाओं में स्थानांतरित कर सकते हैं, आलसी बीएफएस जो लक्ष्य के करीब नोड्स पसंद करते हैं, अभी भी वही परिणाम प्राप्त करेंगे। A * एक संशोधन Dijkstra है जो BFS का उपयोग करते हुए अधिक कम्प्यूटेशनल रूप से महंगा है।

BFS = O (| | V |) माना जाता है कि O (| V | + | E |) लेकिन वास्तव में टॉप डाउन मैप के मामले में नहीं है। A * = O (| V | लॉग | V | V |

अगर हमारे पास सिर्फ 32 x 32 टाइल वाला एक नक्शा है, तो BFS की कीमत अधिकतम 1024 होगी और एक सच्चे A * की कीमत आपको 10,000 रु। हो सकती है। यह 0.5 सेकंड और 5 सेकंड के बीच का अंतर है, संभवतः यदि आप कैश को खाते में लेते हैं तो अधिक। इसलिए सुनिश्चित करें कि आपका ए * एक आलसी बीएफएस की तरह व्यवहार करता है जो टाइल्स को पसंद करता है जो वांछित लक्ष्य के करीब हैं।

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

तो हाँ बीएफएस> ए * कई मामलों में जब यह टाइल्स की बात आती है।


मुझे यकीन नहीं है कि मैं इस हिस्से को समझता हूं "अगर हमारे पास सिर्फ 32 x 32 टाइल्स के साथ एक नक्शा है, तो बीएफएस की लागत अधिकतम 1024 होगी और एक सच्चा ए * आपको 10,000 खर्च कर सकता है" क्या आप बता सकते हैं कि आप 10k पर कैसे आए? कृपया नंबर दें?
Kromster का कहना है कि

"आलसी बीएफएस जो लक्ष्य के करीब नोड्स पसंद करते हैं" से वास्तव में आपका क्या तात्पर्य है? क्या आपका मतलब है दिज्क्स्त्र, सादे बीएफएस, या एक हेयुरिस्टिक के साथ एक (अच्छी तरह से आपने ए * यहाँ पुनः बनाया है, या आप एक खुले सेट से बाहर अगले सर्वश्रेष्ठ नोड का चयन कैसे करते हैं)? कि log|V|A * की जटिलता वास्तव में उस ओपन-सेट, या फ्रिंज के आकार को बनाए रखने से आती है, और ग्रिड मैप्स के लिए यह आपके संकेतन का उपयोग करके लॉग (sqrt (| V |)) के बारे में बहुत छोटा है। लॉग | वी | केवल हाइपर-कनेक्टेड ग्राफ़ में दिखाई देता है। यह एक उदाहरण है जहां सबसे खराब स्थिति की भोली आवेदन एक गलत निष्कर्ष देती है।
कॉंगसबोंगस

@congusbongus यह वास्तव में मेरा मतलब है। ए *
वुल्फडॉन

@KromStern मान लें कि आप टाइल आधारित गेम के लिए A * की वेनिला कार्यान्वयन का उपयोग करते हैं, तो आपको V * logV जटिलता प्राप्त होती है, V को टाइलों की संख्या, 32 के एक ग्रिड के लिए 32 यह 1024 है। logV, लगभग बिट्स की संख्या के बराबर है। 1024 का प्रतिनिधित्व करने की आवश्यकता है जो 10. है। इसलिए आप एक लंबे समय तक अनावश्यक रूप से चल रहे हैं। बेशक, यदि आप टाइल के ग्रिड पर चल रहे तथ्य का लाभ उठाने के लिए कार्यान्वयन के विशेषज्ञ हैं, तो आप इस सीमा को पार कर लेते हैं, जो कि मैं ठीक-ठीक जिक्र कर रहा था
wolfdawn
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.