क्यों कहते हैं कि समय में पहली-पहली खोज चलती है


9

यह अक्सर कहा जाता है (उदाहरण के लिए, विकिपीडिया में ) कि एक ग्राफ पर चौड़ाई-पहली खोज (बीएफएस) का समय चल रहा हैG=(V,E) है O(|V|+|E|)। हालाँकि, कोई भी जुड़ा हुआ ग्राफ़ है|V||E|+1और, गैर-कनेक्टेड ग्राफ़ में भी, बीएफएस घटक के बाहर एक शीर्ष पर कभी नहीं दिखेगा, जिसमें प्रारंभ शीर्ष शामिल है। उस घटक में अधिकांश शामिल हैं|E| किनारों, तो यह अधिक से अधिक शामिल हैं |E|+1 कोने, और वे ही हैं जो एल्गोरिथ्म का दौरा करेंगे।

इस का मतलब है कि |V|+|E|2|E|+1, इसलिए हम यह नहीं कहते कि दौड़ने का समय बस है O(|E|)?

यह डिस्कजस्ट्रा के एल्गोरिथ्म के चलने के समय के बारे में एक सवाल पर टिप्पणी में आया था ।


आप क्यों मानते हैं कि एक शुरुआती शिखर है? उदाहरण के लिए अधिकतम मिलान समस्या में BFS, हॉपक्राफ्ट करप एल्गोरिथ्म में सभी बेजोड़ शीर्षकों से शुरू होता है। इस स्थिति में, यदि दिया गया ग्राफ़ कई जुड़े हुए घटकों का जंगल है, तो हमारे पास
संपादकों की

2
@narekBojikian जबकि BFS का उपयोग विभिन्न तरीकों से किया जा सकता है, जब एक स्टैंड-अलोन एल्गोरिथ्म के रूप में प्रस्तुत किया जाता है, तो यह हमेशा एक शुरुआत वाला शीर्ष होता है।
डेविड रिचेर्बी

जवाबों:


9

बीएफएस आमतौर पर निम्नलिखित ( विकिपीडिया से ) की तरह कुछ वर्णित है ।

 1  procedure BFS(G,start_v):
 2      let Q be a queue
 3      label start_v as discovered
 4      Q.enqueue(start_v)
 5      while Q is not empty
 6          v = Q.dequeue()
 7          if v is the goal:
 8              return v
 9          for all edges from v to w in G.adjacentEdges(v) do
10             if w is not labeled as discovered:
11                 label w as discovered
12                 w.parent = v
13                 Q.enqueue(w)

मुद्दा कुछ हद तक सूक्ष्म है: यह पंक्ति 3 में छिपा है! सवाल यह है कि हम कौन सी डेटा संरचना का उपयोग करने जा रहे हैं जो कि कोने की खोज की गई है?

सबसे सरल समाधान प्रति शीर्ष एक प्रविष्टि के साथ बूलियन सरणी का उपयोग करना है। इस मामले में, हमें सरणी के प्रत्येक तत्व को आरंभ करना चाहिए falseऔर इसमें समय लगता हैΘ(|V|)। यह हर ग्राफ के लिए लागू होता है, भले ही कोई भी किनारा क्यों न हो, इसलिए हम किसी भी रिश्ते को नहीं मान सकते|V| तथा |E| और हमें एक समय मिलता है O(|V|+|E|)

क्या हम डेटा संरचना के साथ होने से बच सकते हैं Θ(|V|)आरंभीकरण समय? हमारा पहला प्रयास एक लिंक की गई सूची का उपयोग करना हो सकता है। हालांकि, अब परीक्षण अगर एक शिखर की खोज की गई है (पंक्ति 10) पहले की तरह निरंतर समय के बजाय, देखे गए कोने की संख्या में समय रेखीय लेता है। इसका मतलब है कि रनिंग टाइम बन जाता हैO(|V||E|), जो सबसे खराब स्थिति में बहुत खराब है। (ध्यान दें कि हम इसे फिर से लिखना नहीं चाहते हैंO(|E|2) चूंकि यह और भी बुरा है: यह उतना ही बुरा हो सकता है |V|4, जहाँ तक |V||E||V|3।)

डायनामिकली रिसाइज़्ड ऐरे का उपयोग करने से हम सूची को क्रमबद्ध रख सकते हैं, इसलिए अब लुक-अप में केवल समय लगेगा O(log|V|) लेकिन यह अभी भी केवल समय का चलन देता है O(|E|log|V|), जो अभी भी मानक से भी बदतर है।

अंत में, हम गतिशील रूप से आकार की हैश तालिका का उपयोग कर सकते हैं: निरंतर आकार की तालिका के साथ शुरू करें cऔर हर बार इसे आधा भरा हुआ पाते हैं। इसका मतलब यह है कि एल्गोरिथ्म समाप्त होने से पहले खोजे गए वर्टिकल की तालिका का अंतिम आकार अधिकतम दो बार है, और यह सबसे अधिक है|E|+1क्योंकि हम स्टार्ट वर्टेक्स के घटक के बाहर कभी भी कुछ नहीं खोजते हैं। इसके अलावा, काम की कुल राशि का विस्तार करने के लिए हैश तालिका की नकल की गई हैc+2c+4c++2|E|4|E|। हैश तालिका में लुकअप और प्रविष्टि amortized हैं O(1) इसलिए हम वास्तव में एक चलने का समय प्राप्त करते हैं O(|E|)

इसलिए O(|E|)संभव है, लेकिन एक वास्तविक कार्यान्वयन में ऐसा करना चाहते हैं? मैं कहूंगा कि शायद नहीं। जब तक आपके पास यह विश्वास करने का कारण नहीं है कि आपके इनपुट ग्राफ़ में कई छोटे घटक होंगे, हैश टेबल को बनाए रखने का ओवरहेड रनिंग टाइम में एक ध्यान देने योग्य स्थिर कारक जोड़ने वाला है। हैश टेबल बढ़ने में समय लग सकता है4|E|और हैश फ़ंक्शन की गणना करने के लिए आपको लुकअप की आवश्यकता होगी और औसतन, तालिका में एक से अधिक स्लॉट देखें। हैश टेबल के खराब कैश प्रदर्शन से आपको वास्तविक कंप्यूटर पर चोट भी लग सकती है। मानक सरणी कार्यान्वयन के साथ अधिकांश मामलों में,O(|E|) भाग का प्रमुख शब्द है O(|V|+|E|) ऐसा करने की व्यावहारिक लागत को देखते हुए, चल रहे समय को वर्चस्व वाले शब्द को हटाने के लिए हैश टेबल का उपयोग करने के लायक नहीं है।


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

वाकई शानदार जवाब! एक सीमांत नोट हालांकि, गतिशील रूप से आकार की हैश टेबल वास्तव में एक अच्छा विकल्प है न केवल अगर कई छोटे घटक हैं, बल्कि यह भी कि किसी भी शीर्ष के लिए हैश मान एक उचित निरंतरता से बंधा हुआ है और ऐसा अक्सर होता है। अच्छा जवाब!
कार्लोस लिनारेस लोपेज

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