पहले खोज में बैकट्रैकिंग और डेप्थ के बीच क्या अंतर है?


108

पहले खोज में बैकट्रैकिंग और डेप्थ के बीच क्या अंतर है?

जवाबों:


99

Backtracking एक अधिक सामान्य प्रयोजन एल्गोरिथ्म है।

गहराई-पहली खोज , पेड़ की संरचनाओं को खोजने से संबंधित बैकट्रैकिंग का एक विशिष्ट रूप है। विकिपीडिया से:

एक रूट पर शुरू होता है (ग्राफ मामले में रूट के रूप में कुछ नोड का चयन करते हुए) और पीछे जाने से पहले प्रत्येक शाखा के साथ जहां तक ​​संभव हो, की खोज करता है।

यह एक पेड़ के साथ काम करने के अपने साधन के रूप में बैकट्रैकिंग का उपयोग करता है, लेकिन एक पेड़ की संरचना तक सीमित है।

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


13
यहां एक प्राचीन पोस्ट का जवाब। अच्छा जवाब, लेकिन ... क्या शतरंज की बिसात को एक पेड़ के रूप में भी प्रस्तुत नहीं किया जा सकता है? :-) किसी दिए गए टुकड़े के लिए बिसात पर किसी भी स्थिति से, क्या भविष्य में फैली संभावित चालों का पेड़ नहीं है? मेरा एक हिस्सा किसी भी मामले की तरह लगता है जहां बैकट्रैकिंग का उपयोग किया जा सकता है, इसे एक पेड़ के रूप में भी तैयार किया जा सकता है, लेकिन मुझे यकीन नहीं है कि मैं उस अंतर्ज्ञान में सही हूं।
११

4
@ The111: वास्तव में, किसी भी खोज समस्या को एक पेड़ के रूप में दर्शाया जा सकता है - आपके पास प्रत्येक संभव आंशिक समाधान के लिए एक नोड है, और प्रत्येक नोड से एक किनारे या एक से अधिक संभावित वैकल्पिक विकल्प जो इस राज्य में किए जा सकते हैं। मुझे लगता है कि lcn का जवाब, कि बैकट्रैकिंग का मतलब आमतौर पर पुनरावृत्ति के दौरान उत्पन्न डीएसएफ (आमतौर पर निहित) खोज ट्री होता है, सच्चाई के सबसे करीब आता है।
j_random_hacker

5
@j_random_hacker तो, एक डीएफएस एक पेड़ (या ग्राफ़ को अधिक सामान्यतः) का पता लगाने का एक तरीका है, जबकि बैकट्रैकिंग एक समस्या को हल करने का एक तरीका है (जो प्रूनिंग के साथ एक डीएफएस को नियोजित करता है)। :-)
The111

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

30

मुझे लगता है कि दूसरे संबंधित प्रश्न का यह उत्तर अधिक अंतर्दृष्टि प्रदान करता है।

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

इसलिए, बैकट्रैकिंग निहित पेड़ के लिए डीएफएस है, जबकि डीएफएस छंटाई के बिना बैकट्रैकिंग है।


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

(जारी) जैसे "उत्तर" स्ट्रिंग के सभी क्रमांकन को प्रिंट करें और मान लें कि 3 चर को चरित्र "ए" होना चाहिए। रिकर्सियन ट्री का पहला 2 स्तर ओ (एन!) का पालन करता है, लेकिन तीसरे स्तर पर सभी शाखा को छोड़कर जो "ए" को जोड़ रहे हैं (पीछे) हैं।
गैंग फैंग

6

बैकट्रैकिंग को आमतौर पर डीएफएस प्लस सर्च प्रुनिंग के रूप में लागू किया जाता है। आप रास्ते में आंशिक समाधानों का निर्माण करते हुए खोज अंतरिक्ष वृक्ष की गहराई का पता लगाते हैं। जानवर बल डीएफएस सभी खोज परिणामों का निर्माण कर सकते हैं, यहां तक ​​कि वे भी, जो व्यावहारिक रूप से समझ में नहीं आते हैं। सभी समाधानों का निर्माण करने के लिए यह बहुत अक्षम हो सकता है (n! या 2 ^ n)। इसलिए वास्तव में जब आप डीएफएस करते हैं, तो आपको आंशिक समाधानों को भी प्राथमिकता देने की आवश्यकता होती है, जो वास्तविक कार्य के संदर्भ में समझ में नहीं आते हैं, और आंशिक समाधानों पर ध्यान केंद्रित करते हैं, जिससे वैध इष्टतम समाधान हो सकते हैं। यह वास्तविक बैकट्रैकिंग तकनीक है - आप आंशिक समाधानों को जल्द से जल्द छोड़ देते हैं, एक कदम पीछे करते हैं और फिर से स्थानीय इष्टतम खोजने की कोशिश करते हैं।

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


6

डोनाल्ड नथ के अनुसार, यह समान है। डांसिंग लिंक एल्गोरिथ्म के बारे में उनके पेपर पर यहां लिंक दिया गया है, जिसका उपयोग "गैर-पेड़" समस्याओं को एन-क्वेंस और सुडोकू सॉल्वर के रूप में हल करने के लिए किया जाता है।

बैकट्रैकिंग, जिसे गहराई-पहली खोज भी कहा जाता है


लिंक किए गए pdf के पेज 1 में उल्लेख किया गया है।
स्टीव चावेज़

5

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


5

मैं कहूंगा, DFS बैकट्रैकिंग का विशेष रूप है; बैकट्रैकिंग डीएफएस का सामान्य रूप है।

यदि हम DFS को सामान्य समस्याओं के लिए विस्तारित करते हैं, तो हम इसे बैकट्रैकिंग कह सकते हैं। यदि हम ट्री / ग्राफ संबंधित समस्याओं के लिए बैकट्रैकिंग का उपयोग करते हैं, तो हम इसे डीएफएस कह सकते हैं।

वे एल्गोरिथम पहलू में समान विचार रखते हैं।


डीएफएस और बैकट्रैकिंग के बीच का संबंध, वास्तव में, केवल कांसेप्ट है। मेरी प्रतिक्रिया की जाँच करें जो यह विवरण देता है।
केज़हतक

5

IMHO, अधिकांश उत्तर या तो बड़े पैमाने पर अभेद्य हैं और / या किसी भी संदर्भ को सत्यापित किए बिना। तो मुझे एक संदर्भ के साथ एक बहुत स्पष्ट स्पष्टीकरण साझा करने दें ।

सबसे पहले, डीएफएस एक सामान्य ग्राफ ट्रैवर्सल (और खोज) एल्गोरिदम है। तो यह किसी भी ग्राफ (या यहां तक ​​कि जंगल) पर लागू किया जा सकता है। ट्री एक खास तरह का ग्राफ है, इसलिए डीएफएस पेड़ के लिए भी काम करता है। संक्षेप में, यह कहना बंद कर दें कि यह केवल एक पेड़, या पसंद के लिए काम करता है।

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

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

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

[१] स्टुअर्ट रसेल और पीटर नोरविग, आर्टिफिशियल इंटेलिजेंस: ए मॉडर्न एप्रोच, ३ थ एड


2

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


2

IMO, बैकट्रैकिंग के किसी भी विशिष्ट नोड पर, आप सबसे पहले उसके प्रत्येक बच्चे में शाखाओं में बँधने की कोशिश करते हैं, लेकिन इससे पहले कि आप बच्चे के किसी भी नोड में शाखा करें, आपको पिछले बच्चे की स्थिति को "समाप्त" करने की आवश्यकता है (यह कदम पीछे के बराबर है। मूल नोड तक चलना)। दूसरे शब्दों में, प्रत्येक भाई-बहन राज्य को एक-दूसरे को प्रभावित नहीं करना चाहिए।

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


2

डीएफएस उस तरीके का वर्णन करता है जिसमें आप एक ग्राफ का पता लगाना या उसे पार करना चाहते हैं। यह चुनाव को देखते हुए यथासंभव गहरे जाने की अवधारणा पर केंद्रित है।

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


1

एक गहराई से पहली खोज में , आप पेड़ की जड़ से शुरू करते हैं और फिर प्रत्येक शाखा के साथ दूर तक तलाश करते हैं, फिर आप प्रत्येक बाद के मूल नोड में वापस आ जाते हैं और बच्चों को पीछे छोड़ते हैं

बैकट्रैकिंग एक लक्ष्य के अंत में शुरू करने के लिए एक सामान्यीकृत शब्द है, और धीरे-धीरे पीछे की ओर बढ़ते हुए, धीरे-धीरे एक समाधान का निर्माण होता है।


4
बैकट्रैकिंग का मतलब अंत में शुरू करना और पीछे की ओर बढ़ना नहीं है। यह एक मृत अंत पाया जाता है, तो पीछे की ओर जाने के लिए नोड्स का एक लॉग रखता है।
गुंटर जेना

1
"अंत में शुरू ...", हुह !!
7kemZmani

1

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

अब बैकट्रैकिंग और डीएफएस 2 अलग-अलग नाम हैं जो 2 अलग-अलग सार डेटा प्रकारों पर एक ही विचार के लिए दिए गए हैं।

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

अगर यही विचार पेड़ या ग्राफ पर लागू होता है तो हम इसे डीएफएस कहते हैं।

यहां क्लिच यह है कि मैट्रिक्स को ग्राफ में बदला जा सकता है और ग्राफ को मैट्रिक्स में बदला जा सकता है। इसलिए, हम वास्तव में इस विचार को लागू करते हैं। यदि एक ग्राफ पर है तो हम इसे डीएफएस कहते हैं और यदि मैट्रिक्स पर है तो हम इसे बैकट्रैकिंग कहते हैं।

दोनों एल्गोरिथ्म में विचार समान है।


0

बैकट्रैकिंग केवल विशिष्ट समाप्ति स्थितियों के साथ पहली खोज है।

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

इसलिए जब मैं पीछे हटने के बारे में सोचता हूं तो मुझे चिंता होती है

  1. राज्य
  2. निर्णय
  3. आधार मामले (समाप्ति की शर्तें)

मैं उलटे पांव लौटने पर अपने वीडियो में यह समझाने यहाँ

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

class Solution:    

"""

Approach: Backtracking 

State
    -candidates 
    -index 
    -target 

Decisions
    -pick one --> call func changing state: index + 1, target - candidates[index], path + [candidates[index]]
    -pick one again --> call func changing state: index, target - candidates[index], path + [candidates[index]]
    -skip one --> call func changing state: index + 1, target, path

Base Cases (Termination Conditions)
    -if target == 0 and path not in ret
        append path to ret
    -if target < 0: 
        return # backtrack 

"""

def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
    """
    @desc find all unique combos summing to target
    @args
        @arg1 candidates, list of ints
        @arg2 target, an int
    @ret ret, list of lists 
    """
    if not candidates or min(candidates) > target: return []

    ret = []
    self.dfs(candidates, 0, target, [], ret)
    return ret 

def dfs(self, nums, index, target, path, ret):
    if target == 0 and path not in ret: 
        ret.append(path)
        return #backtracking 
    elif target < 0 or index >= len(nums): 
        return #backtracking 


    # for i in range(index, len(nums)): 
    #     self.dfs(nums, i, target-nums[i], path+[nums[i]], ret)

    pick_one = self.dfs(nums, index + 1, target - nums[index], path + [nums[index]], ret)
    pick_one_again = self.dfs(nums, index, target - nums[index], path + [nums[index]], ret)
    skip_one = self.dfs(nums, index + 1, target, path, ret)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.