मुख्य रूप से DFS का उपयोग ग्राफ़ में एक चक्र खोजने के लिए किया जाता है न कि BFS में। कोई कारण? दोनों पा सकते हैं कि क्या पेड़ / ग्राफ को पार करते समय एक नोड पहले ही आ चुका है।
मुख्य रूप से DFS का उपयोग ग्राफ़ में एक चक्र खोजने के लिए किया जाता है न कि BFS में। कोई कारण? दोनों पा सकते हैं कि क्या पेड़ / ग्राफ को पार करते समय एक नोड पहले ही आ चुका है।
जवाबों:
गहराई पहली खोज अधिक याददाश्त से भरी हुई है, जो पहली खोज है क्योंकि आप जल्द ही पीछे हट सकते हैं। यदि आप कॉल स्टैक का उपयोग करते हैं तो इसे लागू करना भी आसान है लेकिन यह सबसे लंबे पथ पर निर्भर करता है जो स्टैक से अधिक नहीं बहता है।
इसके अलावा यदि आपका ग्राफ निर्देशित है तो आपको यह याद नहीं रखना है कि आप नोड पर गए हैं या नहीं, बल्कि यह भी कि आपको वहां कैसे जाना है। अन्यथा आप सोच सकते हैं कि आपको एक चक्र मिल गया है लेकिन वास्तव में आपके पास दो अलग-अलग रास्ते हैं A-> B लेकिन इसका मतलब यह नहीं है कि एक रास्ता B-> A है। उदाहरण के लिए,
यदि आप BFS से शुरू करते हैं 0
, तो यह पता लगाएगा कि चक्र मौजूद है लेकिन वास्तव में कोई चक्र नहीं है।
गहराई से पहले खोज के साथ आप नोड्स को चिह्नित कर सकते हैं जैसा कि आप नीचे उतरते हैं और उन्हें पीछे की तरफ चिह्नित करते हैं। इस एल्गोरिथ्म के प्रदर्शन में सुधार के लिए टिप्पणियां देखें।
के लिए एक निर्देशित ग्राफ में चक्र का पता लगाने के लिए सबसे अच्छा एल्गोरिथ्म अपने आप को देखो सकता है Tarjan एल्गोरिथ्म ।
यदि ग्राफ़ अप्रत्यक्ष है तो BFS उचित हो सकता है (BFS का उपयोग करके एक कुशल एल्गोरिथ्म दिखाने में मेरे अतिथि बनें जो कि एक निर्देशित ग्राफ़ में चक्रों की रिपोर्ट करेगा!), जहां प्रत्येक "क्रॉस एज" एक चक्र को परिभाषित करता है। यदि क्रॉस एज है {v1, v2}
, और रूट (BFS ट्री में) जिसमें वो नोड्स हैं r
, तो साइकल r ~ v1 - v2 ~ r
( ~
एक रास्ता है, -
सिंगल एज), जिसे लगभग DFS की तरह ही आसानी से रिपोर्ट किया जा सकता है।
बीएफएस का उपयोग करने का एकमात्र कारण यह होगा कि यदि आप जानते हैं कि आपका (अप्रत्यक्ष) ग्राफ लंबा पथ और छोटा पथ कवर है (दूसरे शब्दों में, गहरे और संकीर्ण)। उस स्थिति में, BFS को DFS के स्टैक की तुलना में अपनी कतार के लिए आनुपातिक रूप से कम मेमोरी की आवश्यकता होगी (दोनों अभी भी रैखिक हैं)।
अन्य सभी मामलों में, DFS स्पष्ट रूप से विजेता है। यह निर्देशित और अप्रत्यक्ष दोनों तरह के रेखांकन पर काम करता है, और यह चक्रों की रिपोर्ट करने के लिए तुच्छ है - पूर्वजों से वंश तक के रास्ते में किसी भी पीछे के किनारे को संक्षिप्त करें, और आपको चक्र मिलता है। सभी में, इस समस्या के लिए बीएफएस की तुलना में बहुत बेहतर और व्यावहारिक है।
BFS साइकिल खोजने में एक निर्देशित ग्राफ के लिए काम नहीं करेगा। एक ग्राफ में A- B से पथ के रूप में A-> B और A-> C-> B पर विचार करें। बीएफएस कहेंगे कि बी के एक पथ के साथ जाने के बाद। अगले पथ की यात्रा जारी रखने पर यह कहेगा कि चिह्नित नोड बी फिर से मिल गया है, इसलिए, एक चक्र है। स्पष्ट रूप से यहाँ कोई चक्र नहीं है।
मुझे नहीं पता कि इस तरह के पुराने सवाल मेरे फीड में क्यों आए, लेकिन पिछले सभी उत्तर खराब हैं, इसलिए ...
डीएफएस का उपयोग निर्देशित ग्राफ़ में चक्र खोजने के लिए किया जाता है, क्योंकि यह काम करता है ।
डीएफएस में, प्रत्येक शीर्ष को "विज़िट" किया जाता है, जहां एक शीर्ष पर जाने का अर्थ है:
उस शीर्ष से आने वाले सबग्राफ का दौरा किया जाता है। इसमें सभी अपरिवर्तित किनारों को ट्रेस करना शामिल है, जो उस शीर्ष से पुन: प्राप्य हैं, और सभी पहुंच से बाहर के अपरिवर्तित शीर्षों पर जाएँ।
शिखर समाप्त हो गया है।
महत्वपूर्ण विशेषता यह है कि एक शीर्ष से पहुंचने वाले सभी किनारों का पता लगाया जाता है, जब शीर्ष समाप्त होने से पहले। यह डीएफएस की एक विशेषता है, लेकिन बीएफएस नहीं। वास्तव में यह डीएफएस की परिभाषा है।
इस विशेषता के कारण, हम जानते हैं कि एक चक्र में पहला शीर्ष कब शुरू होता है:
इसलिए, यदि कोई चक्र है, तो हम शुरू-लेकिन-अपूर्ण वर्टेक्स (2) के लिए एक किनारे खोजने की गारंटी देते हैं, और अगर हमें ऐसी कोई बढ़त मिलती है, तो हम गारंटी देते हैं कि एक चक्र (3) है।
यही कारण है कि डीएफएस का उपयोग निर्देशित ग्राफ़ में चक्र खोजने के लिए किया जाता है।
BFS ऐसी कोई गारंटी नहीं देता है, इसलिए यह काम नहीं करता है। (बीएफएस या एक उप-प्रक्रिया के समान शामिल होने वाले पूरी तरह से अच्छे चक्र-खोज एल्गोरिदम के बावजूद)
एक अप्रत्यक्ष ग्राफ, दूसरी ओर, एक चक्र होता है जब भी किसी भी जोड़ी के शीर्षों के बीच दो रास्ते होते हैं, अर्थात, जब यह एक पेड़ नहीं होता है। बीएफएस या डीएफएस के दौरान यह पता लगाना आसान है - नए शीर्षों के लिए खोजे गए किनारे एक पेड़ बनाते हैं, और किसी भी अन्य किनारे से एक चक्र का संकेत मिलता है।
यदि आप एक पेड़ पर एक यादृच्छिक स्थान पर एक चक्र लगाते हैं, तो डीएफएस चक्र को हिट करेगा जब यह लगभग आधे पेड़ को कवर करेगा, और आधे समय में यह पहले से ही पता लगाया जाएगा कि चक्र कहां जाता है, और आधा समय ऐसा नहीं होगा ( और यह पेड़ के बाकी हिस्सों में औसतन पाया जाएगा), इसलिए यह पेड़ के औसतन 0.5 * 0.5 + 0.5 * 0.75 = 0.625 का मूल्यांकन करेगा।
यदि आप एक पेड़ पर एक यादृच्छिक स्थान पर एक चक्र लगाते हैं, तो BFS उस चक्र को केवल तभी हिट करेगा जब उस गहराई पर पेड़ की परत का मूल्यांकन किया जाएगा। इस प्रकार, आप आमतौर पर एक संतुलन बाइनरी ट्री की पत्तियों का मूल्यांकन करने के लिए समाप्त होते हैं, जिसके परिणामस्वरूप आमतौर पर पेड़ का अधिक मूल्यांकन होता है। विशेष रूप से, 3/4 समय में कम से कम दो में से एक लिंक पेड़ की पत्तियों में दिखाई देता है, और उन मामलों पर आपको पेड़ के औसत 3/4 पर मूल्यांकन करना होगा (यदि एक लिंक है) या 7 / पेड़ के 8 (यदि दो हैं), तो आप पहले से ही 1/2 * 3/4 + 1/4 * 7/8 = (7 + 12) / 32 = 21/32 = की खोज की उम्मीद पर कायम हैं 0.656 ... पेड़ की खोज के बिना एक चक्र के साथ एक पेड़ की खोज की लागत को जोड़ने के अलावा पत्ती नोड्स से दूर हो गया।
इसके अलावा, डीएफएस बीएफएस की तुलना में लागू करना आसान है। इसलिए यह तब तक उपयोग करने वाला है जब तक आप अपने चक्रों के बारे में कुछ नहीं जानते हैं (उदाहरण के लिए, चक्र की जड़ के पास होने की संभावना है जहां से आप खोजते हैं, जिस बिंदु पर BFS आपको लाभ देता है)।
यह साबित करने के लिए कि एक ग्राफ चक्रीय है, आपको सिर्फ यह साबित करने की जरूरत है कि इसका एक चक्र है (सीधे या परोक्ष रूप से खुद की ओर इशारा करते हुए)।
डीएफएस में हम एक बार में एक शीर्ष लेते हैं और जांचते हैं कि क्या यह चक्र है। जैसे ही एक चक्र मिलता है हम अन्य कोने की जाँच को छोड़ सकते हैं।
बीएफएस में हमें कई वर्टेक्स किनारों को एक साथ रखने की आवश्यकता होती है और अधिक बार अंत में आपको पता नहीं चलता है कि क्या यह चक्र है। जैसे-जैसे ग्राफ का आकार बढ़ता है, DFS की तुलना में BFS को अधिक स्थान, संगणना और समय की आवश्यकता होती है।
यह निर्भर करता है कि क्या आप पुनरावर्ती या पुनरावृत्त कार्यान्वयन के बारे में बात कर रहे हैं।
रिकर्सिव-डीएफएस हर नोड पर दो बार जाता है। Iterative-BFS प्रत्येक नोड पर एक बार जाता है।
यदि आप एक चक्र का पता लगाना चाहते हैं, तो आपको नोड से पहले और उसके बाद दोनों नोड्स की जांच करने की आवश्यकता है - जब आप नोड पर "शुरू" करते हैं और जब आप नोड के साथ "समाप्त" करते हैं।
इसके लिए Iterative-BFS में अधिक कार्य की आवश्यकता होती है, इसलिए अधिकांश लोग Recursive-DFS चुनते हैं।
ध्यान दें कि, के साथ Iterative-DFS का एक सरल कार्यान्वयन, std :: stack में Iterative-BFS जैसी ही समस्या है। उस स्थिति में, आपको नोड पर काम करने के दौरान डमी तत्वों को ट्रैक करने के लिए स्टैक में रखना होगा।
Iterative-DFS को नोड के साथ "समाप्त" करने के लिए यह निर्धारित करने के लिए अतिरिक्त कार्य की आवश्यकता है कि कैसे (TopoSort के संदर्भ में जवाब दिया गया है):
पुनरावृत्ति के बिना डीएफएस का उपयोग कर सामयिक प्रकार
उम्मीद है कि यह बताता है कि लोग उन समस्याओं के लिए पुनरावर्ती-डीएफएस का पक्ष क्यों लेते हैं, जहां आपको यह निर्धारित करने की आवश्यकता होती है कि आप नोड को संसाधित करते समय "खत्म" करते हैं।
BFS
जब आप किसी दिए गए नोड में एक निर्देशित ग्राफ में सबसे छोटा चक्र ढूंढना चाहते हैं तो आपको इसका उपयोग करना होगा।
यदि दिए गए नोड 2 हैं, तो तीन चक्र हैं जहां यह - [2,3,4]
, [2,3,4,5,6,7,8,9]
& का हिस्सा है [2,5,6,7,8,9]
। सबसे छोटा है[2,3,4]
बीएफएस का उपयोग करके इसे लागू करने के लिए, आपको उचित डेटा संरचनाओं का उपयोग करके विज़िट किए गए नोड्स के इतिहास को स्पष्ट रूप से बनाए रखना होगा।
लेकिन अन्य सभी उद्देश्यों के लिए (उदाहरण के लिए: किसी भी चक्रीय पथ को खोजने के लिए या यह जांचने के लिए कि क्या कोई चक्र मौजूद है या नहीं), DFS
दूसरों द्वारा उल्लिखित कारणों के लिए स्पष्ट विकल्प है।