वापसी की क्षमता के बिना भूलभुलैया को हल करना


11

मुझे एक प्रोग्राम लिखना होगा जो भूलभुलैया को हल करेगा। भूलभुलैया में ग्राफ संरचना है, जहां प्रत्येक नोड - कुछ कमरा, और किनारों - अन्य कमरों से बाहर निकलता है:

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

विशिष्टता:

  • हम एक यादृच्छिक कमरे से शुरू करते हैं।
  • भूलभुलैया में मृत-छोर, 0 या कुछ निकास हैं।
  • हम सभी भूलभुलैया के बारे में कुछ भी नहीं जानते हैं , केवल वर्तमान कमरे की संख्या और उसमें से दरवाजे की सूची।
  • जब हम नए कमरे में प्रवेश करते हैं तो हमें नहीं पता होता है कि हम कहाँ से आए हैं (वर्तमान कमरे से कौन सा दरवाजा हमें पिछले कमरे में वापस ले जाता है)।
  • बाहर निकलने पर हम पहचान सकते हैं।
  • प्रत्येक चरण हम वर्तमान कमरे से कुछ उपलब्ध दरवाजे से आगे बढ़ते हैं।
  • यदि हम उदाहरण के लिए कमरे 6 पर हैं, तो हम शुरू करने के लिए कूद नहीं सकते। यह रोबोट आंदोलन की तरह है।
  • हम वर्तमान कमरे की बिल्कुल आईडी जानते हैं। हम वर्तमान कमरे में प्रत्येक दरवाजे की आईडी जानते हैं (सभी भूलभुलैया में नहीं)।
  • हम रोबोट को नियंत्रित करते हैं।

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

कोई सुझाव कैसे और अधिक स्मार्ट तरीके से इस तरह के भूलभुलैया को हल करने के लिए?


2
क्या यह होमवर्क है?
MichaelHouse

2
यह होमवर्क का एक हिस्सा है। (क्या मुझे इसे किसी तरह चिह्नित करना चाहिए?)। सभी कमरों में अद्वितीय आईडी है।
Kyrylo M

2
क्या ड्राइंग रूम में कमरे ऐसे गिने जाते हैं? शायद कुछ अधिक संख्या की ओर बढ़ने के बारे में? (या जहाँ आप शुरू कर दिया पर निर्भर करता है कम)
MichaelHouse

2
क्या निकास की सूचियाँ हमेशा एक ही क्रम में होती हैं? जैसा कि हम जाते हैं, क्या हम एक नक्शा बना सकते हैं? मैं कमरा 5 में हूँ और मैं कमरों की सूची में 2 वें कमरे में जाता हूँ, मुझे कमरा 4 लगता है। इसलिए अब मैं उस कमरे को 5-> 2 (कमरा 4) जानता हूँ।
MichaelHouse

4
@archer, जबकि डबल-पोस्टिंग से आपको अधिक उत्तर मिल सकते हैं - अब, किसी और को जो प्रश्न का उत्तर चाहता है, उसे दो अलग-अलग साइटों को ढूंढना होगा , जिसमें विभिन्न उत्तर होंगे। इसलिए नियम एकल प्रश्न चाहते हैं , जिससे अन्य लोगों को सहायता प्राप्त करना आसान हो सके।
Cyclops

जवाबों:


3

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

कहते हैं कि आप कमरे 4 में हैं और तीन यादृच्छिक निकास में से एक का चयन करें। अब सिस्टम आपको बताता है, आप कमरे 6 में हैं और केवल एक ही निकास बचा है। आप इसे चुनते हैं और कमरे में वापस आ जाते हैं। 4 इस बिंदु पर आपने भूलभुलैया की संरचना के बारे में कुछ जानकारी एकत्र की है। अब आप कमरे में एक और निकास और अंत चुनते हैं। कमरा 4 के बारे में जानकारी (एक से 6 तक बाहर निकलें, 5 से बाहर निकलें)

क्या आप एक विशिष्ट निकास चुन सकते हैं? क्या वे गिने जाते हैं, कहते हैं कि यदि कमरा 4 में आप एक का चयन करते हैं तो आप हमेशा 6 में समाप्त होते हैं? अन्यथा आप कम से कम संभावित मार्गों के बारे में पता कर सकते हैं।

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

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

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

100% निश्चित नहीं है, लेकिन मुझे लगता है कि पीटर नॉरविग ने अपनी पुस्तक "आर्टिफिशियल इंटेलिजेंस: ए मॉडर्न अप्रोच" में इसी तरह की समस्या के बारे में लिखा है। हालांकि अगर मुझे सही याद है, तो यह रास्ता खोजने के बारे में कम था और कुछ जानकारी के बारे में निर्णय लेने के बारे में सिस्टम पड़ोसी कमरे के बारे में प्राप्त कर सकता था।

संपादित करें:

नहीं, यह न केवल यादृच्छिक है। पहले से ही आजमाए गए निकास पर नज़र रखने से आप अनावश्यक अतिरेक को दूर करते हैं। वास्तव में आपको बेतरतीब ढंग से चुनने की भी आवश्यकता नहीं है।

मान लें कि आप कमरे में शुरू करते हैं। 4. आपको जो जानकारी मिलती है: 3 बाहर निकलता है ए, बी, सी आप हमेशा अप्रयुक्त निकास से पहले का चयन करते हैं। तो ए के साथ शुरू करें। आप कमरे में समाप्त होते हैं। 6. अब आपको याद है कि कमरे में 6 में 4 ए => 6 (और इस्तेमाल किया गया) आपको 1 बाहर निकलने की जानकारी मिलती है। फिर से आप पहले अप्रयुक्त (और इस मामले में केवल बाहर निकलने) का चयन करते हैं। 6A => 4 (और कमरा 6 में आगे निकलने के लिए नहीं) जानने के लिए अब आप अगला निकास B चुनें और कक्ष 5 पर पहुँचें ...

जितनी जल्दी या बाद में आपने सभी कमरों को खोजा होगा। लेकिन एक व्यवस्थित मामले में।

एक पथ खोजने की आवश्यकता के लिए एकमात्र कारण यह है, जब आप अपने आप को एक ऐसे कमरे में पाते हैं जहां सभी निकास पहले से ही खोजे जाते हैं। फिर आप अगले कमरे के लिए एक सीधा रास्ता ढूंढना चाहेंगे जिसमें आपकी खोज के साथ जाने के लिए अस्पष्टीकृत निकास हों। तो मुख्य चाल यह जानने के लिए कम है कि कौन सा निकास किस कमरे में जाता है (हालांकि यह सहायक हो सकता है) लेकिन अभी तक बाहर निकलने की कोशिश नहीं की गई है।

इस तरह उदाहरण के लिए आप हर समय हलकों में चलने से बच सकते हैं, विशुद्ध रूप से यादृच्छिक दृष्टिकोण के लिए क्या जोखिम होगा।

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

(मुझे लगता है कि यह बाइट 56 के समान ही है जो गेमर्स में आया था)


हां, मैं कमरे के बाहर विशिष्ट निकास (दरवाजा) चुन सकता हूं। उनके पास यूनिक आईडी हैं। तो, आपका सुझाव पहले पूर्ण भूलभुलैया का पता लगाने और फिर किसी भी ज्ञात एल्गोरिथ्म का उपयोग करने के लिए है?
Kyrylo M

मैंने कार्यक्रम लिखना शुरू कर दिया और एक नया प्रश्न आया ... सबसे पहले मैंने सभी कनेक्शनों के साथ संरचना बनाने के लिए सभी कमरों का पता लगाया। दूसरा कदम रास्ता खोजना होगा। लेकिन मैं निर्माण बंद कर दूंगा जब सभी कनेक्शन जोड़े जाएंगे। लेकिन इस तरह से मैं किसी भी तरह से बाहर निकल जाऊंगा ... इसलिए यह सिर्फ एक यादृच्छिक दिशा एल्गोरिथ्म है ...
Kyrylo M

10

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

ग्राफ प्रतिनिधित्व

ग्राफ को आसानी से एक कुंजी, मान डिक्शनरी के रूप में संग्रहीत किया जा सकता है जहां कुंजी रूम आईडी है, और मूल्य उन कमरों का एक सरणी है जो इसे ले जाता है।

map = {
1:[5, 2],
2:[1, 3, 5],
3:[2, 4],
4:[3, 5, 6],
5:[2, 4, 1],
6:[4]
}

एजेंट इंटरफ़ेस

पहले हमें इस बारे में सोचना चाहिए कि एजेंट को पर्यावरण से कौन सी जानकारी सीखने में सक्षम होना चाहिए, और ऑपरेशन जो इसे करने में सक्षम होना चाहिए। यह एल्गोरिथ्म के बारे में सोच को सरल करेगा।

इस मामले में एजेंट को उस कमरे की आईडी के लिए वातावरण को क्वेरी करने में सक्षम होना चाहिए, जिसमें वह उस कमरे के दरवाजों की एक गिनती प्राप्त करने में सक्षम होना चाहिए जो इसमें है ( ध्यान दें कि यह कमरे का आईडी नहीं है दरवाजे का नेतृत्व करते हैं! ) और उसे दरवाजे के सूचकांक को निर्दिष्ट करके एक दरवाजे से गुजरने में सक्षम होना चाहिए। एक एजेंट को जो कुछ भी पता चलता है उसे एजेंट द्वारा ही पता लगाना होता है।

class AgentInterface(object):
    def __init__(self, map, starting_room):
        self.map = map
        self.current_room = starting_room

    def get_door_count(self):
        return len(self.map[self.current_room])

    def go_through_door(self, door):
        result = self.current_room = self.map[self.current_room][door]
        return result

एजेंट ज्ञान

जब एजेंट पहली बार नक्शे में प्रवेश करता है तो उसे केवल कमरे में दरवाजों की मात्रा पता होती है, और कमरे की आईडी जो वर्तमान में है। मुझे एक ऐसी संरचना बनाने की जरूरत है जो जानकारी को संग्रहीत करती है जो एजेंट ने सीखा था जैसे कि यह कौन से दरवाजे नहीं थे। के माध्यम से, और जहां के दरवाजे के माध्यम से किया गया है।

यह वर्ग एकल कमरे के बारे में जानकारी का प्रतिनिधित्व करता है। मैंने एक setऔर एक के रूप में देखे गए दरवाज़ों को एक के रूप में संग्रहीत करने के लिए चुना dictionary, जहाँ कुंजी दरवाजा आईडी है और मूल्य उस कमरे की आईडी है जिसके लिए वह जाता है।

class RoomKnowledge(object):
    def __init__(self, unvisited_door_count):
        self.unvisited_doors = set(range(unvisited_door_count))
        self.visited_doors = {}

एजेंट एल्गोरिथ्म

  • हर बार जब एजेंट कमरे में प्रवेश करता है तो वह कमरे के बारे में जानकारी के लिए अपना ज्ञानकोष खोजता है। अगर इस कमरे के लिए कोई प्रविष्टि नहीं है, तो यह एक नया बनाता है RoomKnowledgeऔर इसे इसे ज्ञान शब्दकोश में जोड़ता है।

  • यह देखने के लिए जांचता है कि क्या वर्तमान कमरा लक्ष्य कक्ष है, यदि ऐसा है तो यह वापस आ जाता है।

  • अगर इस कमरे में दरवाजे नहीं हैं, जहां हम नहीं गए हैं, तो हम उस दरवाजे और स्टोर से गुजरते हैं जहां यह जाता है। हम फिर लूप जारी रखते हैं।

  • अगर किसी भी तरह के बिना दरवाजे वाले दरवाजे नहीं थे, तो हम उन कमरों से गुजरते हैं, जिन्हें हम बिना दरवाजे वाले किसी एक को खोजने के लिए गए थे।

Agentसे वर्ग inherits AgentInterfaceवर्ग।

class Agent(AgentInterface):

    def find_exit(self, exit_room_id):
        knowledge = { }
        room_history = [] # For display purposes only
        history_stack = [] # Used when we need to backtrack if we've visited all the doors in the room
        while True:
            room_knowledge = knowledge.setdefault(self.current_room, RoomKnowledge(self.get_door_count()))
            room_history.append(self.current_room)

            if self.current_room==exit_room_id:
                return room_history

            if len(room_knowledge.unvisited_doors)==0:
                # I have destination room id. I need door id:
                door = find_key(room_knowledge.visited_doors, history_stack.pop())
                self.go_through_door(door)
            else:   
                history_stack.append(self.current_room)
                # Enter the first unopened door:
                opened_door = room_knowledge.unvisited_doors.pop()
                room_knowledge.visited_doors[opened_door]=self.go_through_door(opened_door)

सहायक कार्य

मुझे एक ऐसा फंक्शन लिखना था, जिसमें एक डिक्शनरी में एक की-वर्ड दिया गया हो, जिसकी वैल्यू देने के बाद से हम जानते हैं कि जिस कमरे में हम जाने की कोशिश कर रहे हैं, उस कमरे की आईडी तो है, लेकिन इसे पाने के लिए कौन से दरवाजे का इस्तेमाल नहीं करना है।

def find_key(dictionary, value):
    for key in dictionary:
        if dictionary[key]==value:
            return key

परिक्षण

मैंने ऊपर दिए गए नक्शे में प्रारंभ / समाप्ति स्थिति के सभी संयोजनों का परीक्षण किया। प्रत्येक संयोजन के लिए यह विज़िट किए गए कमरों को प्रिंट करता है।

for start in range(1, 7):
    for exit in range(1, 7):
        print("start room: %d target room: %d"%(start,exit))
        james_bond = Agent(map, start)
        print(james_bond.find_exit(exit))

टिप्पणियाँ

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


स्मारकीय उत्तर! दुःखद रूप से दो उत्तर नहीं हो सकते हैं :( मैंने पहले ही C # में प्रोग्राम लिखा था और आम तौर पर लगभग समान विचारों का उपयोग किया था। बैकट्रैकिंग के लिए ब्रीथ-डेप्थ सर्च एल्गोरिथ्म का उपयोग किया गया था।
Kyrylo M

4

अनिवार्य रूप से, आपके पास एक दिशात्मक ग्राफ है, जहां प्रत्येक जुड़ा हुआ कमरा दो अज्ञात मार्गों से जुड़ा हुआ है - दोनों में से एक। कहते हैं कि आप नोड में शुरू करते हैं 1, और दरवाजे Aऔर Bबाहर ले जाते हैं। आपको नहीं पता कि प्रत्येक दरवाजे के बाहर क्या है, इसलिए आप सिर्फ दरवाजा चुनें A। आप कमरे के लिए मिलता 2है, जो द्वार हैं C, D, और E। अब आप उस दरवाजे जानते Aकमरे से सुराग 1के कमरे में 2, लेकिन आप वापस पाने के लिए कैसे पता नहीं है, तो आप बेतरतीब ढंग से दरवाजा लेने C। आप कमरे में वापस आ जाओ 1! अब आप जानते हैं कि कमरों के बीच कैसे जाना है 1और 2। बाहर निकलने तक निकटतम अज्ञात दरवाजे के माध्यम से पता लगाना जारी रखें!


4

चूंकि निकास सूचियों में कमरे हमेशा एक ही क्रम में होते हैं, हम बाहर निकलने की तलाश करते हुए कमरों का त्वरित नक्शा बना सकते हैं।

मेरा छद्म कोड कुछ हद तक जावाश है, क्षमा करें, मैं इसे हाल ही में उपयोग कर रहा हूं।

Unvisited_Rooms एक रूम आईडी रखने वाला हैशमैप है, और अन-मैपेड रूम या 2 डी सरणी के इंडेक्स की सूची, जो भी काम करता है।

मुझे लगता है कि एल्गोरिथ्म कुछ इस तरह से जा सकता है:

Unvisited_Rooms.add(currentRoom.ID, currentRoom.exits) //add the starting room exits
while(Unvisited_Rooms.Keys.Count > 0 && currentRoom != end) //keep going while there are unmapped exits and we're not at the end
    Room1 = currentRoom
    ExitID = Room1.get_first_unmapped_Room() //returns the index of the first unmapped room
    if(ExitID == -1) //this room didn't have any more unmapped rooms, it's totally mapped
        PathTo(Get_Next_Room_With_Unmapped_Exits) //we need to go to a room with unmapped exits
        continue //we need to start over once we're there, so we don't create false links
    GoToExit(ExitID) //goes to the room, setting current room to the room on the other side
    Room1.Exits[exitID].connection = currentRoom.ID //maps the connection for later path finding
    Unvisited_Rooms[Room1.ID].remove(exitID) //removes the index so we don't worry about it
    if(Unvisited_Rooms[Room1.ID].size < 1) //checks if all the rooms exits have been accounted for
        Unvisited_Rooms.remove(Room1.ID)  //removes the room if it's exits are all mapped
    Unvisited_Rooms.add(currentRoom.ID, currentRoom.unvisited_exits) //adds more exits to the list

If(currentRoom != end && Unvisited_Rooms.Keys.Count < 1)
   print(No exit found!)
else
   print(exit is roomID: currentRoom.ID)

आपको PathTo () के कमरों में "मैप" के पार सामान्य नोड पाथ फाइंडर्स में से एक का उपयोग करने की आवश्यकता होगी। उम्मीद है कि यह स्पष्ट है कि आपको कुछ पर शुरू करने के लिए पर्याप्त है।


यहाँ एक upvote, @ Byte56 है - जो आपके द्वारा खोए गए चेकमार्क का 2/3 हिस्सा बनाता है। :)
साइक्लॉप्स

2

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

solved = FALSE

SearchRoom(rooms[0], rooms[0])    // Start at room 1 (or any room)
IF solved THEN
  // solvable
ELSE
  // unsolvable
ENDIF
END

// Recursive function, should run until it searches every room or finds the exit
FUNCTION SearchRoom: curRoom, prevRoom
  // Is this room the 'exit' room
  IF curRoom.IsExit() THEN
    solved = TRUE
    RETURN
  ENDIF

  // Deadend?  (skip starting room)
  IF (curRoom.id <> prevRoom.id) AND (curRoom.doors <= 1) THEN RETURN

  // Search each room the current room leads to
  FOREACH door IN curRoom
    // Skip the room we just came from
    IF door.id <> prevRoom.id THEN
      SearchRoom(door, curRoom)
    ENDIF
    IF solved THEN EXIT LOOP
  NEXT

  RETURN
ENDFUNCTION

[संपादित करें] पिछले चेक में 'आईडी' जोड़ा गया, और अधिक वस्तु उन्मुख बनाने के लिए अद्यतन किया गया।


1
मैं हर कदम पर नहीं जानता कि मैं कहाँ से आया हूँ। इसलिए, यह एल्गोरिदम कार्य को हल नहीं करता है। लेकिन कोशिश करने के लिए धन्यवाद।
21:39 पर Kyrylo M

3
तो आप कह रहे हैं कि आप पिछले कमरे को जानने के लिए तैयार नहीं हैं? या कि आप पिछले कमरे को नहीं जानते हैं? उपरोक्त कोड आपके लिए पिछले कमरों का ट्रैक रखता है। यदि आपको जानने की अनुमति नहीं है, तो मुझे नहीं लगता कि 'x' संख्याओं के लिए भूलभुलैया को बेतरतीब ढंग से हटाने के अलावा एक वैध समाधान है, और यदि आपको कोई निकास नहीं मिल रहा है, तो आप मान सकते हैं कि भूलभुलैया बेकार है ।
डौग। एमफर्लेन

1
"मुझे नहीं पता"। मैंने फिर से कोड देखा। दूसरी समस्या यह है कि पुनरावृत्ति का उपयोग समस्याग्रस्त है। कल्पना कीजिए, कि आप इस तरह के भूलभुलैया के अंदर हैं। बाहर निकलने के लिए आप पुनरावर्ती एल्गोरिदम का उपयोग कैसे करेंगे?
Kyrylo M

इसके अलावा, यदि आप कमरे 6 में शुरू करते हैं तो क्या होता है? curRoom.doors <= 1, इसलिए फ़ंक्शन तुरंत लौटता है, यह जानते हुए कि यह एक मृत अंत में है, लेकिन यह सोचकर कि यह पहले से ही भूलभुलैया की संपूर्णता का पता लगाता है।
dlras2

यह करीब है, लेकिन यह स्टैक को उड़ा देगा यदि दो से अधिक लंबाई के ग्राफ में चक्र हैं।
उदार

1

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

अधिक संक्षेप में, मान लें कि हम दिए गए हैं:

// Moves to the given room, which must have a door between
// it and the current room.
moveTo(room);

// Returns the list of room ids directly reachable from
// the current room.
getDoors();

// Returns true if this room is the exit.
isExit();

बाहर निकलने के लिए, हमें बस आवश्यकता है:

void escape(int startingRoom) {
  Stack<int> path = new Stack<int>();
  path.push(startingRoom);
  escape(path);
}

boolean escape(Stack<int> path) {
  for (int door : getDoors()) {
    // Stop if we've escaped.
    if (isExit()) return true;

    // Don't walk in circles.
    if (path.contains(door)) continue;

    moveTo(door);
    path.push(door);
    if (escape(path)) return true;

    // If we got here, the door didn't lead to an exit. Backtrack.
    path.pop();
    moveTo(path.peek());
  }
}

escape()स्टार्ट रूम की आईडी के साथ कॉल करें और यह रोबोट को निकास (कॉल करके moveTo()) पर ले जाएगा।


मुझे लगता है कि escape(int startingRoom)कॉल करना चाहिएescape(Stack<int> path)
CiscoIPPhone

1
मुझे लगता है कि if (path.contains(door)) continue;उनकी आवश्यकताओं का उल्लंघन होता है - एजेंट वास्तव में नहीं जानता है कि क्या एक दरवाजा एक कमरे में वापस जाता है वह पहले से ही है जब तक वह दरवाजे से नहीं जाता है।
CiscoIPPhone

धन्यवाद, निश्चित! हाँ, अब जब मैं आवश्यकताओं को देखता हूं, तो समस्या थोड़ी गड़बड़ लगती है। यदि आप पीछे नहीं हट सकते हैं, तो आप जिस चीज की उम्मीद कर सकते हैं, वह है बेतरतीब चलना।
उदार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.