वर्महोल नोड्स के साथ सबसे छोटा रास्ता कैसे खोजें?


25

उदाहरण

यह एक उदाहरण है जो मैं कोड के माध्यम से करना चाहता हूं। मुझे पता है कि आप हरे रंग के नोड से लाल नोड तक आसानी से प्राप्त करने के लिए कूद बिंदु खोज का उपयोग कर सकते हैं, या यहां तक ​​कि ए * भी नहीं। लेकिन आप यह कैसे माल के साथ गणना करते हैं।

छवि में, आप देख सकते हैं कि नीले रास्ते को लेते समय हरे नोड से लाल नोड तक पहुंचने में केवल 8 चालें चलती हैं। नीला रास्ता तुरंत आपकी स्थिति को एक बैंगनी नोड से अगले तक ले जाता है। 2 चालों की लागत के बीच का स्थान दो ताना क्षेत्रों के बीच का एक बिंदु है जिसे पाने के लिए आपको चलना चाहिए।

यह नीला रास्ता लेने के लिए स्पष्ट रूप से तेज़ है, क्योंकि आपको केवल पीले रास्ते के रूप में आधे (लगभग) स्थानांतरित करने की आवश्यकता है, लेकिन मैं इस कार्यक्रम को कैसे करूं?

इस समस्या को हल करने के उद्देश्य से, मान लें कि आप जिस ग्राफ का उपयोग करने में सक्षम हैं उसके चारों ओर कई बैंगनी "ताना" हैं, और हम जानते हैं कि वास्तव में प्रत्येक बैंगनी बिंदु कहाँ पर ताना जाएगा, और वे ग्राफ़ पर कहाँ हैं।

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

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

कार्यक्रम को किसी तरह से यह पता लगाना होगा कि पहली छलांग से चलने के बजाय दूसरा ताना लेना अधिक फायदेमंद है। इसलिए, 6 स्थानों को हिलाने के बजाय, फिर युद्ध करते हुए, फिर शेष 8 चरणों को पैर से हिलाते हुए (जो कि युद्ध का उपयोग न करने की तुलना में भी तेज है), यह 6 चाल लेगा, फिर दोनों दूसरे युद्ध में चले जाएंगे।

संपादित करें: मुझे एहसास हुआ कि नीले रंग का पथ वास्तव में 8 के बजाय 12 चाल लेगा, लेकिन सवाल एक ही है।


4
क्या नीले रंग का रास्ता 12 नहीं होना चाहिए (अंतिम बैंगनी से लाल होने के लिए दो सहित)?
ब्लूराजा - डैनी पफ्लुगुएफ्ट

5
नीला वास्तव में 12 (7 + 3 + 2) चाल है, नहीं?
डैनियल जर्स

उफ़, गड़बड़, धन्यवाद दोस्तों! @ डैनियलजौर और ब्लू
जेफ़ ने

दूरी को मॉडल करने का "सही" तरीका टोपोलॉजी का उपयोग करना होगा और इसे उच्च आयामी सतह के रूप में मॉडल करना होगा। मुझे आश्चर्य है कि अगर इस तरह का उत्तर यहां उचित होगा?
गेकी I

जवाबों:


49

अधिकांश पथप्रदर्शक एल्गोरिदम को ग्राफ़ के संदर्भ में परिभाषित किया गया है, ग्रिड के संदर्भ में नहीं। एक ग्राफ में, दो अन्यथा दूर के नोड्स के बीच एक कनेक्शन वास्तव में एक समस्या नहीं है।

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

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

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

def wormhole_heuristic(x):
  return min(euclidean_distance(x, g) for g in [goal, wormholes...])

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

def wormhole_heuristic(x):
  direct = euclidean_distance(x, goal)
  via_wormhole = min(euclidean_distance(x, w) + wormhole_path_distance(w, goal) for w in wormholes)
  return min(direct, via_wormhole)

जैसा कि @ कैलेथ टिप्पणी में बताते हैं, यह सब बहुत ही उचित है और हम पिछले वर्महोल से बाहर निकलने और लक्ष्य के बीच की दूरी को जोड़कर वर्महोल नेटवर्क के माध्यम से पूर्ण पथ खोजने के बिना पहले वर्महोल हेयुरिस्टिक में सुधार कर सकते हैं। क्योंकि हम नहीं जानते कि कौन सा वर्महोल निकास अंतिम रूप से उपयोग किया जाएगा और हमें अधिक नहीं होना चाहिए, हमें लक्ष्य के निकटतम निकास मानना ​​होगा:

def wormhole_heuristic(x):
  direct = euclidean_distance(x, goal)
  to_next_wormhole = min(euclidean_distance(x, w) for w in wormholes)
  from_last_wormhole = min(euclidean_distance(w.exit, goal) for w in wormholes)
  via_wormhole = to_next_wormhole + from_last_wormhole
  return min(direct, via_wormhole)

10
ध्यान देने योग्य बात यह है कि dijkstra_heuristic(x) = 0
दिजाक्षर

मुझे समझ में नहीं आ रहा है कि आप क्या कहते हैं [* वर्महोल, लक्ष्य], क्या आप इसे समझाएंगे?
जेफ़ स्मिथ

1
"निकटतम वर्महोल निकास के लिए यूक्लिडियन दूरी" wormhole_path_distanceसबग्राफ खोज की तुलना में एक सस्ता अनुमान है , और "सभी निकास लक्ष्य की तुलना में कम" हैं।
कालथ

3
@ निश्चित रूप से! यहाँ बहुत अच्छी ट्यूनिंग क्षमता है, उदाहरण के लिए, हम आगे n = 3 जंप करने का निर्णय ले सकते हैं। सबग्राफ खोज सभी एसिसिल वर्महोल कूद के बंद होने से मेल खाती है। आपका सुझाव आगे देखने के लिए n = 1 कूद बहुत ही सुंदर है क्योंकि इसमें मूल रूप से शून्य अतिरिक्त लागत है :)
amon

1
सादगी के शेक के लिए, मान लें कि केवल एक वर्महोल (दो नोड्स) हैं, तो आप इस विमान 1-वर्महोल को 2 दर्पण विमानों में परिवर्तित कर सकते हैं, इन दो बिंदुओं के बीच सममित रेखा के साथ सममित विमान को कॉपी करके सममिति अक्ष। अब आपके पास दो प्लेन हैं, उन्हें असली प्लेन कहते हैं (आप वर्महोल नहीं लेते हैं) और काल्पनिक प्लेन (आपने वर्महोल लिया है)। अब, हम Z समन्वय का परिचय देते हैं। यह समन्वय वास्तविक विमान के प्रत्येक बिंदु के लिए 0 होगा, और यह काल्पनिक विमान के प्रत्येक बिंदु के लिए डिस्ट (वर्महोल, बिंदु) होगा। उसके बाद, 3-आयामी स्थान के लिए ए * लागू करें।
lilezek

5

आपके पास ग्रिड पर 6 कोने के साथ एक ग्राफ है, जिसमें समन्वय है:

A ( 0,0)
B ( 4,7)
C ( 7,4)
D (10,4)
E (16,2)
F (16,0)

आप उन कोने पर एक पूर्ण ग्राफ़ उत्पन्न कर सकते हैं और प्रत्येक किनारे पर एक लागत निर्दिष्ट कर सकते हैं जहाँ लागत MAX( ABS( x1 - x2 ), ABS( y1 - y2 ) )मानक किनारों के लिए है और वर्महोल के लिए 0 की लागत है।

यह आपको लागत (एक आसन्न मैट्रिक्स के रूप में) देगा:

   A  B  C  D  E  F
- -- -- -- -- -- --
A  -  7  7 10 16 16
B  7  -  0  6 12 12
C  7  0  -  3  9  9
D 10  6  3  -  0  6
E 16 12  9  0  -  2
F 16 12  9  6  2  -

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

फिर आप प्राथमिकता कतार के साथ दिज्क्स्ट्रा के एल्गोरिथ्म का उपयोग कर सकते हैं ।

से शुरू करें Aऔर प्रत्येक किनारे को प्राथमिकता कतार पर धकेलें:

प्रारूप: (पथ: लागत)

queue     = [ (A-B : 7), (A-C : 7), (A-D : 10), (A-E : 16), (A-F : 16) ]

चूंकि आइटम कतार में धकेल दिए जाते हैं - प्रत्येक वर्टेक्स के लिए न्यूनतम लागत का ट्रैक रखें और मौजूदा न्यूनतम लागत की तुलना में कम लागत होने पर कतार पर केवल पथ धक्का दें।

min-costs = { A: 0, B: 7, C: 7, D: 10, E: 16, F: 16 }

पहले आइटम को कतार से निकालें और, यदि इसकी लागत अभी भी न्यूनतम लागत से मेल खाती है, तो उस पथ और इसके आस-पास के किनारों से बने सभी मिश्रित रास्तों को प्राथमिकता कतार पर वापस धकेलें (यदि समग्र पथ में मौजूदा न्यूनतम से कम लागत है):

हटाना: (A-B : 7)

  • कोशिश (A-B-A : 14)- उच्च लागत के रूप में अस्वीकार
  • कोशिश करें (A-B-C : 7)- समान लागत को अस्वीकार करें
  • कोशिश (A-B-D : 13)- उच्च लागत के रूप में अस्वीकार
  • कोशिश (A-B-E : 19)- उच्च लागत के रूप में अस्वीकार
  • कोशिश (A-B-F : 19)- उच्च लागत के रूप में अस्वीकार

हटाना (A-C : 7)

  • कोशिश (A-C-A : 14)- उच्च लागत के रूप में अस्वीकार
  • कोशिश करें (A-C-B : 7)- समान लागत को अस्वीकार करें
  • कोशिश करें (A-C-D : 10)- समान लागत को अस्वीकार करें
  • कोशिश करें (A-C-E : 16)- समान लागत को अस्वीकार करें
  • कोशिश करें (A-C-F : 16)- समान लागत को अस्वीकार करें

हटाना (A-D : 10)

  • कोशिश (A-D-A : 20)- उच्च लागत के रूप में अस्वीकार
  • कोशिश (A-D-B : 16)- उच्च लागत के रूप में अस्वीकार
  • कोशिश (A-D-C : 13)- उच्च लागत के रूप में अस्वीकार
  • कोशिश करें (A-D-E : 10)- कतार में डालें
  • कोशिश करें (A-D-F : 16)- समान लागत को अस्वीकार करें

अब कतार दिखेगी:

queue     = [ (A-D-E : 10), (A-E : 16), (A-F : 16) ]
min-costs = { A: 0, B: 7, C: 7, D: 10, E: 10, F: 16 }

हटाना (A-D-E : 10)

  • कोशिश (A-D-E-A : 26)- उच्च लागत के रूप में अस्वीकार
  • कोशिश (A-D-E-B : 22)- उच्च लागत के रूप में अस्वीकार
  • कोशिश (A-D-E-C : 19)- उच्च लागत के रूप में अस्वीकार
  • कोशिश करें (A-D-E-D : 10)- समान लागत को अस्वीकार करें
  • कोशिश करें (A-D-E-F : 12)- कतार में डालें

फिर कतार है:

queue     = [ (A-D-E-F : 12), (A-E : 16), (A-F : 16) ]
min-costs = { A: 0, B: 7, C: 7, D: 10, E: 10, F: 12 }

निकालें (A-D-E-F : 12), पता लगाएं कि आप 12 की लागत में गंतव्य नोड पर पहुंच गए हैं।

नोट: पथ (A-B-C-D-E-F), (A-C-D-E-F)और (A-D-E-F)सभी में 12 की समान न्यूनतम लागत है।


0

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

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