C ++ में Backtracking को समझना


12

मुझे C ++ के मूल सिद्धांतों की अच्छी बुनियादी समझ है, मुझे इस बात की भी समझ है कि रिकर्सन कैसे काम करता है। मुझे क्लासिक आठ रानियों की समस्या और बैकट्रैकिंग के साथ सुडोकू को हल करने जैसी कुछ समस्याएं आईं ।

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

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

और हाँ मुझे पता है कि कार्यात्मक भाषाओं में यह आसान होगा लेकिन मैं अनिवार्य भाषाओं में कार्यान्वयन को समझना चाहूंगा।


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

यह सही होगा यदि कोई व्यक्ति एक विस्तृत विवरण दे सकता है, लेकिन मुझे संदर्भों को पढ़ने में कोई आपत्ति नहीं होगी। इसका सिर्फ इतना है कि मुझे नहीं पता कि कहां से शुरू करना है।
निखिल

जवाबों:


9

... मैं इस समस्या को हल करने के लिए पुनरावृत्ति के ढेर में वापस जाने और फिर से शुरू करने की अवधारणा के आसपास अपने दिमाग को प्राप्त करने में सक्षम प्रतीत नहीं हो सकता ।

बैकट्रैकिंग में, आप फिर से शुरू नहीं कर रहे हैं। इसके बजाय, आप वर्तमान स्थिति में सभी विकल्पों के माध्यम से पुनरावृति करते हैं।

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

EDIT : निम्नलिखित एक छद्म कोड है जो बैकट्रैकिंग को समझने में मदद करता है।

# depending on the problem, backtracking is not necessarily calling the
# method itself directly. for now, let's just stick with the simple case.

def backtracking(state)
  option_list = state.get_all_options
  option_list.each {|option|
    state.apply option
    return resolved if state.is_resolved
    return resolved if backtracking(state) == resolved
    state.undo option
  }
  return not_resolved
end

8Q प्रश्न के लिए:

  • State.get_all_options अगली रानी के लिए संभावित पदों की सूची लौटाएगा
  • यदि सभी रानियाँ बोर्ड पर हैं और यदि वे एक-दूसरे के साथ अच्छी हैं, तो state.is_resolve परीक्षण करेगा।
  • State.apply और state.undo एक स्थिति लागू करने या पूर्ववत करने के लिए बोर्ड को संशोधित करेगा।

पहला पुनरावर्ती कोड मैंने (1984 में पास्कल का उपयोग करते हुए) एक असाइनमेंट के लिए एक भूलभुलैया हल एल्गोरिदम था।
गेरू

कुछ सरल असाइनमेंट के बारे में जानें जहां मैं वास्तव में इस सामान की वास्तविक अनुभूति प्राप्त करने के लिए कोड लिख सकता हूं।
निखिल

@ अखिल: आप पूछ रहे हैं कि क्या कोई साधारण समस्या है? बैकट्रैकिंग के जेनेरिक रूटिंग को प्रदर्शित करने के लिए कुछ छद्म कोड लिखना बेहतर है। मैं एक उत्तर में बाद में कोशिश करूंगा।
कोडवाद

हाँ बिल्कुल, यह सबसे उपयोगी होगा।
निखिल

बहुत बहुत धन्यवाद, मैं हाल ही में कुछ सामान पढ़ रहा हूं। धीरे-धीरे लेकिन लगातार मेरी समझ में सुधार हो रहा है।
निखिल

5

आपने बाइनरी ट्री, सही चलने के लिए एक कार्यक्रम देखा है? यह इस तरह दिख रहा है:

void walk(node* p){
  if (p == NULL) return;  // this is backtracking
  else if (WeWin(p)){
    // print We Win !!
    // do a Throw, or otherwise quit
  }
  else {
    walk(p->left);   // first try moving to the left
    walk(p->right);  // if we didn't win, try moving to the right
                     // if we still didn't win, just return (i.e. backtrack)
  }
}

वहाँ अपने पीछे है।

आप वास्तव में एक भौतिक पेड़ की जरूरत नहीं है। आप सभी की जरूरत है एक रास्ता बनाने के लिए और बाद में इसे पूर्ववत करें, या बताएं कि क्या आप जीत गए हैं, या बताएं कि क्या आप आगे नहीं जा सकते हैं।


1
यदि आप सबट्री में समाधान पाए जाते हैं तो क्या आप जाँच करने के लिए एक बूल / इंट नहीं लौटा सकते हैं? अपेक्षित परिणाम के else{return walk(p->left)||walk(p->right));}लिए फेंकने की आवश्यकता नहीं है
शाफ़्ट फ्रीक

@ तीर्थ: बिलकुल। वह भी इसे करने का एक अच्छा तरीका है। (मैं सिर्फ उदाहरण को खत्म करने की कोशिश कर रहा था। मैं वास्तव में इसे आपके तरीके से
करूंगा

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