क्या ऐसे कोई मामले हैं जहां आप निचले एक से अधिक बड़े-ओ समय जटिलता एल्गोरिदम को पसंद करेंगे?


242

क्या ऐसे कोई मामले हैं जहां आप O(log n)समय जटिलता को O(1)समय जटिलता पसंद करेंगे ? या O(n)करने के लिए O(log n)?

क्या आपके पास कोई उदाहरण है?


67
मैं एक O(log n)एल्गोरिथ्म को एक O(1)एल्गोरिथम पसंद करूंगा यदि पूर्व को समझें, लेकिन बाद वाला नहीं ...
कोडर

14
सैद्धांतिक कंप्यूटर विज्ञान से ओ (1) संचालन के साथ अव्यावहारिक डेटा संरचनाओं के टन हैं। एक उदाहरण बिटवेक्टरों पर चयन () होगा, जिसे ओ (एन) अतिरिक्त स्थान और ओ (1) प्रति ऑपरेशन में परोक्ष की 5 परतों का उपयोग करके समर्थित किया जा सकता है। O (1) रैंक () के साथ संयुक्त सरल द्विआधारी खोज, Succinct Data Structure Library
निकल्स बी।

17
लोअर एसिम्प्टोटिक जटिलता तेजी से रनटाइमर नहीं करती है। ठोस उदाहरण के लिए अनुसंधान मैट्रिक्स गुणन।
कोनर क्लार्क

54
इसके अलावा ... किसी भी एल्गोरिथ्म को O (1) में बदला जा सकता है, जिसे पर्याप्त रूप से बड़ी टेबल लुकिंग दी गई है?)
कॉनर क्लार्क

19
@Hoten - यह माना जाता है कि टेबल लुकिंग O (1) है, जो आपके द्वारा बताई जा रही तालिकाओं के आकार के लिए बिल्कुल नहीं दिया गया है! :)
जेंडर

जवाबों:


267

निम्न एक से अधिक बड़े O समय जटिलता वाले एल्गोरिदम को पसंद करने के कई कारण हो सकते हैं:

  • अधिकांश समय, कम बिग-ओ जटिलता को प्राप्त करना कठिन है और कुशल कार्यान्वयन, बहुत अधिक ज्ञान और बहुत सारे परीक्षण की आवश्यकता होती है।
  • big-O एक निरंतर के बारे में विवरण छिपाता है : एल्गोरिथ्म जो प्रदर्शन करता है, 10^5वह 1/10^5 * log(n)( O(1)बनाम O(log(n)) की तुलना में बड़े-ओ दृष्टिकोण से बेहतर है , लेकिन अधिकांश के nलिए पहले वाला बेहतर प्रदर्शन करेगा। उदाहरण के लिए मैट्रिक्स गुणन के लिए सबसे अच्छी जटिलता है, O(n^2.373)लेकिन निरंतरता इतनी अधिक है कि कोई (मेरी जानकारी के लिए) कम्प्यूटेशनल पुस्तकालयों का उपयोग नहीं करता है।
  • बड़ा-ओ समझ में आता है जब आप किसी बड़ी चीज की गणना करते हैं। यदि आपको तीन नंबर की सरणी को क्रमबद्ध करने की आवश्यकता है, तो यह वास्तव में बहुत कम मायने रखता है कि आप उपयोग करते हैं O(n*log(n))या O(n^2)एल्गोरिथ्म।
  • कभी-कभी लोअरकेस टाइम जटिलता का लाभ वास्तव में नगण्य हो सकता है। उदाहरण के लिए एक डेटा संरचना टैंगो ट्री है जो O(log log N)किसी आइटम को खोजने के लिए एक समय की जटिलता देता है , लेकिन एक बाइनरी ट्री भी है जो समान में पाता है O(log n)। यहां तक n = 10^20कि अंतर की भारी संख्या के लिए भी नगण्य है।
  • समय जटिलता सब कुछ नहीं है। एक एल्गोरिथ्म की कल्पना करें जो स्मृति में चलती है O(n^2)और O(n^2)स्मृति की आवश्यकता होती है। यह O(n^3)समय और O(1)स्थान पर बेहतर हो सकता है जब n वास्तव में बड़ा नहीं है। समस्या यह है कि आप लंबे समय तक प्रतीक्षा कर सकते हैं, लेकिन अत्यधिक संदेह है कि आप अपने एल्गोरिथ्म के साथ इसका उपयोग करने के लिए एक रैम को काफी बड़ा पा सकते हैं
  • हमारी वितरित दुनिया में समानांतरकरण एक अच्छी सुविधा है। ऐसे एल्गोरिदम हैं जो आसानी से समानांतर होते हैं, और कुछ ऐसे हैं जो बिल्कुल भी समानांतर नहीं हैं। कभी-कभी यह एक बेहतर जटिलता के साथ एक मशीन का उपयोग करने की तुलना में उच्च जटिलता के साथ 1000 कमोडिटी मशीनों पर एक एल्गोरिथ्म चलाने के लिए समझ में आता है।
  • कुछ स्थानों (सुरक्षा) में एक जटिलता की आवश्यकता हो सकती है। कोई भी ऐसा हैश एल्गोरिथ्म नहीं रखना चाहता, जो हैरत से तेज़ हो सकता है (क्योंकि तब दूसरे लोग आपको तेजी से आगे बढ़ा सकते हैं)
  • हालांकि यह जटिलता के स्विच से संबंधित नहीं है, लेकिन कुछ सुरक्षा कार्यों को समय पर हमले को रोकने के तरीके से लिखा जाना चाहिए । वे ज्यादातर एक ही जटिलता वर्ग में रहते हैं, लेकिन उन्हें इस तरह से संशोधित किया जाता है कि कुछ करने के लिए हमेशा बदतर स्थिति होती है। एक उदाहरण तुलना कर रहा है कि तार बराबर हैं। अधिकांश अनुप्रयोगों में यह तेजी से तोड़ने के लिए समझ में आता है यदि पहले बाइट्स अलग हैं, लेकिन सुरक्षा में आप अभी भी बुरी खबर को बताने के लिए बहुत इंतजार करेंगे।
  • किसी ने कम-जटिलता एल्गोरिथ्म का पेटेंट कराया और किसी कंपनी के लिए पैसे का भुगतान करने की तुलना में उच्च जटिलता का उपयोग करना अधिक किफायती है।
  • कुछ एल्गोरिदम विशेष परिस्थितियों में अच्छी तरह से अनुकूल होते हैं। सम्मिलन प्रकार, उदाहरण के लिए, एक औसत समय-जटिलता है O(n^2), क्विकॉर्ट्स या मर्जेसर्ट से भी बदतर, लेकिन एक ऑनलाइन एल्गोरिथ्म के रूप में यह कुशलता से मूल्यों की एक सूची को सॉर्ट कर सकता है जैसा कि उन्हें प्राप्त होता है (उपयोगकर्ता इनपुट के रूप में) जहां अधिकांश अन्य एल्गोरिदम केवल कुशलता से काम कर सकते हैं। मूल्यों की पूरी सूची पर।

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

@Luaan "वास्तव में, आधुनिक सीपीयू के निर्माण के कारण, यहां तक ​​कि द्विआधारी खोज की तरह कुछ भी एक रेखीय खोज के रूप में छांटे गए सरणियों पर तेज हो सकता है - प्रोफाइलिंग एक आवश्यकता है।" दिलचस्प! क्या आप बता सकते हैं कि द्विआधारी खोज और रैखिक खोज एक आधुनिक सीपीयू पर समान समय कैसे ले सकते हैं?
डीजेजी

3
: - @Luaan कोई बात नहीं, मैं इस पाया schani.wordpress.com/2010/04/30/linear-vs-binary-search
DJG

2
@DenisdeBernardy: नहीं, वास्तव में यह नहीं है। वे पी। में एल्गोरिदम हो सकते हैं और यहां तक ​​कि अगर ये समानांतर परिभाषा के तहत नहीं थे, तो इसका मतलब यह है कि इसका मतलब पी! = एनपी या तो होगा। यह भी याद रखें कि गैर-नियतात्मक ट्यूरिंग मशीन के संभावित रनों के स्थान की खोज काफी समानांतर है।
ईनपोकलम

228

हमेशा छिपा हुआ स्थिरांक होता है, जो O (लॉग एन ) एल्गोरिथम पर कम हो सकता है। तो यह वास्तविक जीवन डेटा के लिए अभ्यास में तेजी से काम कर सकता है।

अंतरिक्ष संबंधी चिंताएँ भी हैं (जैसे कि टोस्टर पर चलना)।

डेवलपर समय की चिंता भी है - (लॉग एन ) को लागू करने और सत्यापित करने के लिए 1000 × आसान हो सकता है।


अच्छा आपका धन्यवाद। मैं सोच रहा था कि कार्यक्रम स्थिरता (जैसे स्व-संतुलित बाइनरी पेड़ों में) सुनिश्चित करने के लिए ओ (लॉगन) एल्गोरिदम पर विचार करने के लायक हो सकता है
वी। लेमरी डे

16
एक उदाहरण जो मैं सोच सकता हूं: एक छोटे से क्रमबद्ध सरणी के लिए, प्रोग्रामर के लिए बाइनरी सर्च फंक्शन को लागू करने के लिए पूर्ण हैश मैप कार्यान्वयन लिखना और इसके बजाय इसका उपयोग करना आसान और अधिक कॉम्पैक्ट होगा।
कर्नल थर्टी दो

5
जटिलता का एक उदाहरण: एक अनसुलझी सूची का माध्य ढूंढना O (n * log n) में करना आसान है लेकिन O (n) में करना कठिन है।
पॉल ड्रेपर

1
-1, अपने टोस्टर में लॉग न डालें ... अलग हटकर, यह स्पॉट पर है। lg nऐसा है, इसलिए, इतने kबड़े के करीब है nकि ज्यादातर ऑपरेशनों में अंतर पर ध्यान नहीं दिया जाएगा।
corsiKa

3
तथ्य यह भी है कि एल्गोरिथम की जटिलताएं ज्यादातर लोग परिचित हैं जो कैश प्रभावों को ध्यान में नहीं रखते हैं। अधिकांश लोगों के अनुसार बाइनरी ट्री में कुछ देखना हे (log2 (n)) है लेकिन वास्तव में यह बहुत बुरा है क्योंकि बाइनरी ट्री में ख़राब एकता है।
डोभाल

57

मुझे आश्चर्य है कि किसी ने अभी तक मेमोरी-बाउंड एप्लिकेशन का उल्लेख नहीं किया है।

एक एल्गोरिथ्म हो सकता है जिसमें कम फ़्लोटिंग पॉइंट ऑपरेशन हों या तो इसकी जटिलता के कारण (जैसे O (1) < O (log n )) या क्योंकि जटिलता के सामने स्थिरांक छोटा है (यानी 2 n 2 <6 n 2 ) । भले ही, आप अभी भी अधिक FLOP के साथ एल्गोरिथम पसंद कर सकते हैं यदि कम FLOP एल्गोरिथ्म अधिक स्मृति-बद्ध है।

"मेमोरी-बाउंड" से मेरा तात्पर्य यह है कि आप अक्सर ऐसे डेटा को एक्सेस कर रहे हैं जो लगातार आउट-ऑफ-कैश है। इस डेटा को लाने के लिए, आपको अपने कैश में वास्तव में मेमोरी स्पेस से मेमोरी खींचनी होगी, इससे पहले कि आप इस पर अपना ऑपरेशन कर सकें। यह कदम आपके ऑपरेशन की तुलना में बहुत धीमा है।

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


1
एलिस्ट्रा ने इसे अप्रत्यक्ष रूप से संबोधित किया जब "अंतरिक्ष चिंताओं" के बारे में बात कर रहे थे
Zach Saucier

2
कैश की विशाल मात्रा केवल अंतिम मान को एक स्थिर मान से गुणा करती है (जो 4-कोर 3.2GHz सीपीयू के लिए 1.6GHz RAM के साथ 8 से अधिक नहीं है, आमतौर पर यह बहुत कम है) इसलिए इसे बड़े में स्थिर स्थिर के रूप में गिना जाता है -ओ संकेतन। इस प्रकार केवल एक चीज जिससे कैश मिस हो जाता है, वह n की सीमा को आगे बढ़ा रहा है, जहां O (n) समाधान O (1) समाधान की तुलना में धीमा होने लगता है।
मैरिएन स्पैनिक

1
@MarianSpanik आप निश्चित रूप से सही हैं। लेकिन यह सवाल एक ऐसी स्थिति के लिए पूछा गया, जहां हम O(logn)अधिक पसंद करेंगे O(1)। आप बहुत आसानी से ऐसी स्थिति की कल्पना कर सकते हैं जहां आपके सभी व्यवहार्य के लिए n, कम मेमोरी-बाउंड एप्लिकेशन तेज दीवार-समय में चलेगा, यहां तक ​​कि उच्च जटिलता पर भी।
NoseKnowsAll

@MarianSpanik 300 घड़ी चक्र तक कैश नहीं है? 8 कहां से आ रहा है?
उम्मीद है कि 12

43

संदर्भों में जहां डेटा सुरक्षा एक चिंता का विषय है, अधिक जटिल एल्गोरिदम कम जटिल एल्गोरिदम के लिए बेहतर हो सकता है यदि अधिक जटिल एल्गोरिथ्म में समय के हमलों के लिए बेहतर प्रतिरोध है ।


6
जबकि आपने जो कहा वह सच है, उस स्थिति में, O (1) में निष्पादित एक एल्गोरिथ्म परिभाषा के अनुसार समय के हमलों के लिए अयोग्य है।
जस्टिन लेसर

17
@JustinLessard: O (1) होने का मतलब है कि कुछ इनपुट आकार है जिसके बाद एल्गोरिथ्म का रनटाइम एक निरंतर द्वारा बाध्य होता है। इस सीमा के नीचे क्या होता है यह अज्ञात है। इसके अलावा, थ्रेशोल्ड भी एल्गोरिथ्म के किसी भी वास्तविक दुनिया के उपयोग के लिए पूरा नहीं किया जा सकता है। एल्गोरिथ्म रेखीय हो सकता है और इस प्रकार इनपुट की लंबाई के बारे में जानकारी लीक कर सकता है, उदाहरण के लिए।
जोर्ग डब्ल्यू मित्तग

12
रनटाइम अलग-अलग तरीकों से भी उतार-चढ़ाव कर सकता है, जबकि अभी भी बंधा हुआ है। यदि रनटाइम आनुपातिक है (n mod 5) + 1, तो यह अभी भी हैO(1) , फिर जानकारी के बारे में पता चलता है n। चिकनी चाल के साथ एक अधिक जटिल एल्गोरिथ्म बेहतर हो सकता है, भले ही यह asymptotically (और संभवतः व्यवहार में भी) धीमा हो सकता है।
क्रिश्चियन सेमरू

यह मूल रूप से इसलिए है कि bcrypt को अच्छा माना जाता है; यह चीजों को धीमा कर देता है
डेविड कहते हैं कि मोनिका

@DavidGrinberg यही कारण है कि bcrypt का उपयोग किया जाता है, और सवाल फिट बैठता है। लेकिन यह इस उत्तर से संबंधित नहीं है, जो समय के हमलों के बारे में बात करता है।
क्रिश्चियन सेमराऊ

37

एलिस्ट्रा ने इसे बंद कर दिया लेकिन मैं ऐसा कोई भी उदाहरण देने में असफल रहा।

आपके पास अपने स्टोर को बेचने के लिए 10,000 यूपीसी कोड की एक सूची है। 10 अंकों का यूपीसी, मूल्य के लिए पूर्णांक (पैसे में कीमत) और रसीद के लिए विवरण के 30 अक्षर।

O (लॉग एन) दृष्टिकोण: आपके पास एक क्रमबद्ध सूची है। 44 बाइट्स अगर ASCII, 84 अगर यूनिकोड। वैकल्पिक रूप से, यूपीसी को इंटि 64 के रूप में मानते हैं और आपको 42 और 72 बाइट्स मिलते हैं। 10,000 रिकॉर्ड - उच्चतम मामले में आप भंडारण की मेगाबाइट के तहत थोड़ा देख रहे हैं।

O (1) दृष्टिकोण: UPC को संग्रहीत न करें, इसके बजाय आप इसे सरणी में प्रविष्टि के रूप में उपयोग करते हैं। सबसे कम मामले में आप लगभग एक तिहाई स्टोरेज स्टोरेज को देख रहे हैं।

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


2
मैं यहाँ थोड़ा उलझन में हूँ। क्या आप 10-बिलियन-एंट्री एरे (जिसमें से अधिकांश अपरिभाषित होंगे) बनाने की बात कर रहे हैं और यूपीसी को उस एरे में इंडेक्स के रूप में मान रहे हैं?
डेविड जेड

7
@ दाविद हाँ। यदि आप विरल सरणी का उपयोग करते हैं, तो आपको O (1) नहीं मिल सकता है, लेकिन यह केवल 1MB मेमोरी का उपयोग करेगा। यदि आप एक वास्तविक सरणी का उपयोग करते हैं, तो आपको O (1) एक्सेस की गारंटी है लेकिन यह 1/3 टीबी मेमोरी का उपयोग करेगा।
नवीन

आधुनिक प्रणाली में, यह 1/3 टीबी पता स्थान का उपयोग करेगा, लेकिन इसका मतलब यह नहीं है कि यह कहीं भी आवंटित बैकिंग मेमोरी के करीब आ जाएगा। अधिकांश आधुनिक OSes आवंटन के लिए भंडारण नहीं करते हैं जब तक कि उन्हें ज़रूरत न हो। ऐसा करते समय, आप अनिवार्य रूप से OS / हार्डवेयर वर्चुअल मेमोरी सिस्टम के अंदर अपने डेटा के लिए एक सहयोगी लुकअप संरचना छिपा रहे हैं।
फिल मिलर

@ नोवेलोक्रेट ट्रू, लेकिन अगर आप इसे रैम पर कर रहे हैं तो लुकअप टाइम गति नहीं करेगा, 1mb के बजाय 40mb का उपयोग करने का कोई कारण नहीं है। सरणी संस्करण केवल तभी समझ में आता है जब भंडारण पहुंच महंगी होती है - आप डिस्क पर जा रहे हैं।
लोरेन Pechtel

1
या जब यह एक प्रदर्शन-महत्वपूर्ण संचालन नहीं होता है, और डेवलपर का समय महंगा होता है - यह कहना malloc(search_space_size)और इसे वापस लाने के रूप में आसान हो जाता है।
फिल मिलर

36

एक लाल-काले पेड़ पर विचार करें। इसमें एक्सेस, सर्च, इंसर्ट और डिलीट है O(log n)। एक सरणी की तुलना करें, जिसमें पहुंच है O(1)और बाकी ऑपरेशन हैं O(n)

इसलिए एक एप्लिकेशन दिया गया है जहां हम पहुंचते हैं, हटाते हैं, या जितनी बार हम पहुंचते हैं और केवल इन दो संरचनाओं के बीच कोई विकल्प खोजते हैं, हम लाल-काले पेड़ को पसंद करेंगे। इस मामले में, आप कह सकते हैं कि हम लाल-काले पेड़ की अधिक बोझिलता को पसंद करते हैंO(log n) पहुंच समय को ।

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

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


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

@ony एक लाल-काले पेड़ का उपयोग मानचित्र / शब्दकोश प्रकार की संरचना को परिभाषित करने के लिए किया जा सकता है, लेकिन इसकी आवश्यकता नहीं है। नोड्स केवल तत्व हो सकते हैं, अनिवार्य रूप से एक क्रमबद्ध सूची को लागू कर रहे हैं।
jpmc26

तत्वों की क्रम को परिभाषित करने वाली क्रमबद्ध सूची और सरणी में अलग-अलग जानकारी होती है। एक तत्वों और सेट के बीच क्रम पर आधारित है और अन्य मनमाना अनुक्रम को परिभाषित करता है जो तत्वों के बीच आदेश को परिभाषित नहीं करता है। दूसरी बात यह है कि "पहुंच" और "खोज" क्या है जिसे आप O(log n)"लाल-काले पेड़" के रूप में घोषित करते हैं ? 5सरणी 2 की स्थिति में डालने के [1, 2, 1, 4]परिणामस्वरूप [1, 2, 5, 1 4](तत्व 43 से 4 तक सूचकांक को अपडेट किया जाएगा) प्राप्त होगा। आप O(log n)"लाल-काले पेड़" में इस व्यवहार को कैसे प्राप्त करने जा रहे हैं जिसे आप "क्रमबद्ध सूची" के रूप में संदर्भित करते हैं?
on

तत्वों की क्रम को परिभाषित करने वाली @ony "सॉर्ट की गई सूची और सरणी में अलग-अलग जानकारी होती है।" हां, और इसका एक कारण यह भी है कि उनके पास अलग-अलग प्रदर्शन विशेषताएं हैं। आप बात याद कर रहे हैं। एक सभी स्थितियों में दूसरे के लिए प्रतिस्थापन में एक बूंद नहीं है। वे अलग-अलग चीजों का अनुकूलन करते हैं और अलग-अलग ट्रेड ऑफ करते हैं , और मुद्दा यह है कि डेवलपर्स उन ट्रेड ऑफ के बारे में लगातार निर्णय ले रहे हैं।
jpmc26

एल्गोरिथ्म प्रदर्शन के संदर्भ में @ony पहुंच, खोज, सम्मिलित करें और हटाएं के विशिष्ट अर्थ हैं। पहुंच स्थिति से एक तत्व प्राप्त कर रहा है। खोज एक तत्व को मूल्य के आधार पर पता लगा रहा है (जिसमें केवल गैर-मानचित्र संरचना के लिए एक जांच के रूप में कोई व्यावहारिक अनुप्रयोग है)। सम्मिलित करें और हटाएं हालांकि सीधा होना चाहिए। उदाहरण का उपयोग यहां देखा जा सकता है
jpmc26

23

हाँ।

एक वास्तविक मामले में, हमने छोटी और लंबी स्ट्रिंग कुंजी दोनों के साथ टेबल लुकअप करने पर कुछ परीक्षण किए।

हम एक प्रयोग किया जाता है std::map, एक std::unordered_mapएक हैश के साथ कि स्ट्रिंग की लंबाई से अधिक नमूने ज्यादा से ज्यादा 10 बार (हमारे चाबियाँ, होना करने के लिए GUID की तरह करते हैं तो यह सभ्य है), और एक हैश कि नमूने हर चरित्र (सिद्धांत में कम टकराव), एक अनकांशेड वेक्टर जहां हम एक ==तुलना करते हैं, और (अगर मुझे सही याद है) एक अनकांशेड वेक्टर जहां हम एक हैश भी स्टोर करते हैं, पहले हैश की तुलना करें, फिर वर्णों की तुलना करें।

ये एल्गोरिदम O(1)(unordered_map) से O(n)(रैखिक खोज) तक होते हैं।

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

O(lg n)दोनों के बीच मौजूद है। मुझे याद नहीं कि यह कैसे हुआ।

प्रदर्शन अंतर इतना बड़ा नहीं था, और बड़े डेटा पर हैश-आधारित एक बहुत बेहतर प्रदर्शन करता है। इसलिए हम हैश-आधारित अनवार्डेड मैप के साथ अटक गए।

व्यवहार में, उचित आकार n के लिए, O(lg n)है O(1)। यदि आपके कंप्यूटर में केवल आपकी तालिका में 4 बिलियन प्रविष्टियों के लिए जगह है, तो O(lg n)इसके बाद के संस्करण की सीमा होती है 32। (lg (2 ^ 32) = 32) (कंप्यूटर विज्ञान में, lg लॉग आधारित 2 के लिए छोटा हाथ है)।

व्यवहार में, lg (n) एल्गोरिदम O (1) एल्गोरिदम की तुलना में धीमा है क्योंकि लघुगणक वृद्धि कारक के कारण नहीं है, लेकिन क्योंकि lg (n) भाग का आम तौर पर अर्थ होता है कि एल्गोरिथ्म में जटिलता का एक निश्चित स्तर होता है, और यह जटिलता जोड़ता है। lg (n) टर्म से किसी भी "वृद्धि" की तुलना में बड़ा निरंतर कारक।

हालांकि, जटिल ओ (1) एल्गोरिदम (जैसे हैश मैपिंग) में आसानी से एक समान या बड़ा स्थिर कारक हो सकता है।


21

एक एल्गोरिथ्म को समानांतर में निष्पादित करने की संभावना।

मुझे नहीं पता कि कक्षाओं के लिए एक उदाहरण है O(log n)और O(1), लेकिन कुछ समस्याओं के लिए, आप एक उच्च जटिलता वर्ग के साथ एक एल्गोरिथ्म चुनते हैं जब एल्गोरिथ्म समानांतर में निष्पादित करना आसान होता है।

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


लेकिन जो सब समानांतर चलता है वह उस निरंतर कारक को कम कर देता है जिसके बारे में दूसरों ने बात की है, है ना?
गेंगकेव

1
हां, लेकिन एक समानांतर एल्गोरिदम लगातार कारक को 2 से विभाजित कर सकता है जब आप निष्पादन मशीनों की संख्या को दोगुना कर देते हैं। एक और एकल थ्रेडेड एल्गोरिथ्म निरंतर कारक को एक समय में एक बार कम कर सकता है। तो एक समानांतर एल्गोरिथ्म के साथ आप गतिशील रूप से n के आकार पर प्रतिक्रिया कर सकते हैं और दीवार घड़ी निष्पादन समय में तेज हो सकते हैं।
Simulant

15

मान लें कि आप एक एम्बेडेड सिस्टम पर एक ब्लैकलिस्ट लागू कर रहे हैं, जहां 0 और 1,000,000 के बीच की संख्या को ब्लैकलिस्ट किया जा सकता है। इससे आपको दो संभावित विकल्प मिलते हैं:

  1. 1,000,000 बिट्स के बिटसेट का उपयोग करें
  2. ब्लैकलिस्ट किए गए पूर्णांकों की क्रमबद्ध सरणी का उपयोग करें और उन्हें एक्सेस करने के लिए एक द्विआधारी खोज का उपयोग करें

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

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

और यहां तक ​​कि अगर आप एक एम्बेडेड सिस्टम के लिए विकसित नहीं करते हैं जहां मेमोरी दुर्लभ है, तो मैं सिर्फ 1,000,000 की मनमानी सीमा को बढ़ाकर 1,000,000,000,000 कर सकता हूं और वही तर्क कर सकता हूं। तब बिटसेट को लगभग 125G मेमोरी की आवश्यकता होगी। O (1) की गारंटीकृत सबसे खराब स्थिति वाली जटिलता होने के कारण आपको अपने बॉस को ऐसा शक्तिशाली सर्वर प्रदान करने के लिए राजी नहीं कर सकता है।

यहाँ, मैं दृढ़ता से ओ (1) बिटसेट पर एक बाइनरी सर्च (ओ (लॉग एन)) या बाइनरी ट्री (ओ (एन एन)) पसंद करूंगा। और शायद, हे (एन) की सबसे खराब स्थिति के साथ एक हैश तालिका उन सभी को अभ्यास में हरा देगी।


13

मेरा जवाब यहां एक स्टोकेस्टिक मैट्रिक्स की सभी पंक्तियों में तेजी से यादृच्छिक भारित चयन एक उदाहरण है जहां जटिलता ओ (एम) के साथ एक एल्गोरिथ्म जटिलता ओ (लॉग (एम)) के साथ एक से अधिक तेज है, जब mबहुत बड़ा नहीं है।


12

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

बहुत सारे "ओ (1) समय" एल्गोरिदम और डेटा संरचनाएं वास्तव में केवल अपेक्षित ओ (1) समय लेती हैं , जिसका अर्थ है कि उनका औसत चलने का समय ओ (1) है, संभवतः केवल कुछ मान्यताओं के तहत।

सामान्य उदाहरण: हैशटेबल्स, "सरणी सूचियों" का विस्तार (उर्फ गतिशील रूप से सरणियों / वैक्टर)।

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


11

एक अधिक सामान्य सवाल है, तो स्थितियों में, जहां एक एक पसंद करेंगे देखते हैं है O(f(n))एक करने के लिए एल्गोरिथ्म O(g(n))भले ही एल्गोरिथ्म g(n) << f(n)के रूप में nअनंत को जाता है। जैसा कि दूसरों ने पहले ही उल्लेख किया है, इस मामले में जवाब स्पष्ट रूप से "हां" है जहां f(n) = log(n)और g(n) = 1। यह कभी-कभी इस मामले में भी हाँ होता है कि f(n)बहुपद है, लेकिन g(n)घातीय है। एक प्रसिद्ध और महत्वपूर्ण उदाहरण रैखिक प्रोग्रामिंग समस्याओं को हल करने के लिए सिम्पलेक्स एल्गोरिथम है। 1970 के दशक में यह दिखाया गया था O(2^n)। इस प्रकार, इसका बदतर मामला व्यवहारनीय है। लेकिन - इसका कर्मकार आंतरिक बिंदु एल्गोरिथ्म है औसत मामला व्यवहार अत्यंत अच्छा है, यहां तक ​​कि हजारों चर और बाधाओं के साथ व्यावहारिक समस्याओं के लिए भी। 1980 के दशक में, बहुपद समय एल्गोरिदम (जैसे एक) लीनियर प्रोग्रामिंग के लिए खोज की गई थी, लेकिन 30 साल बाद सिंप्लेक्स एल्गोरिथ्म अभी भी पसंद का एल्गोरिदम लगता है (कुछ बहुत बड़ी समस्याओं को छोड़कर)। यह स्पष्ट कारण के लिए है कि औसत-केस व्यवहार अक्सर बदतर-केस व्यवहार की तुलना में अधिक महत्वपूर्ण है, लेकिन यह भी अधिक सूक्ष्म कारण के लिए है कि सिंप्लेक्स एल्गोरिथ्म कुछ अर्थों में अधिक जानकारीपूर्ण है (जैसे संवेदनशीलता की जानकारी निकालना आसान है)।


10

मेरे 2 सेंट लगाने के लिए:

कभी-कभी एक बेहतर जटिलता के स्थान पर एक बेहतर जटिलता एल्गोरिथ्म का चयन किया जाता है, जब एल्गोरिथ्म एक निश्चित हार्डवेयर वातावरण पर चलता है। मान लीजिए कि हमारी O (1) एल्गोरिथ्म गैर-क्रमिक रूप से हमारी समस्या को हल करने के लिए एक बहुत बड़े, निश्चित आकार के सरणी के हर तत्व तक पहुंचती है। फिर उस सरणी को एक यांत्रिक हार्ड ड्राइव, या एक चुंबकीय टेप पर रखें।

उस स्थिति में, O (logn) एल्गोरिथ्म (मान लीजिए कि यह डिस्क को क्रमिक रूप से एक्सेस करता है), अधिक अनुकूल हो जाता है।


मैं यहाँ यह कह सकता हूँ कि अनुक्रमिक-पहुँच ड्राइव या टेप पर, O (n) के बजाय O (1) एल्गोरिथ्म हो जाता है, यही कारण है कि अनुक्रमिक समाधान अधिक अनुकूल हो जाता है। कई ओ (1) संचालन एक निरंतर समय एल्गोरिथ्म होने के कारण जोड़ने और अनुक्रमित देखने पर निर्भर करते हैं, जो कि यह एक अनुक्रमिक-पहुंच स्थान में नहीं है।
TheHansinator

9

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


9

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

हैकर डिक्शनरी से निम्नलिखित उदाहरण पर विचार करें, क्वांटम यांत्रिकी के कई संसारों की व्याख्या पर निर्भर एक छँटाई एल्गोरिथ्म का प्रस्ताव :

  1. एक क्वांटम प्रक्रिया का उपयोग करके यादृच्छिक रूप से सरणी की अनुमति दें,
  2. यदि सरणी सॉर्ट नहीं है, तो ब्रह्मांड को नष्ट कर दें।
  3. सभी शेष ब्रह्मांड अब छांटे गए हैं [जिसमें आप शामिल हैं]।

(स्रोत: http://catb.org/~esr/jargon/html/B/bogo-sort.html )

ध्यान दें कि इस एल्गोरिथम का बड़ा-ओ है O(n), जो जेनेरिक वस्तुओं पर तारीख करने के लिए किसी भी ज्ञात सॉर्टिंग एल्गोरिथ्म को धड़कता है। रैखिक कदम का गुणांक भी बहुत कम है (क्योंकि यह केवल एक तुलना है, एक स्वैप नहीं है, जो रैखिक रूप से किया जाता है)। एक समान एल्गोरिथ्म, वास्तव में, एनपी और सह-एनपी दोनों में किसी भी समस्या को हल करने के लिए उपयोग किया जा सकता है बहुपद समय में , क्योंकि प्रत्येक संभव समाधान (या संभव प्रमाण नहीं है कि कोई समाधान नहीं है) क्वांटम प्रक्रिया का उपयोग करके उत्पन्न किया जा सकता है, फिर सत्यापित किया जाएगा। बहुपदी समय फलन।

हालांकि, ज्यादातर मामलों में, हम शायद यह जोखिम नहीं उठाना चाहते हैं कि मल्टीपल वर्ल्ड्स सही नहीं हो सकते हैं, यह उल्लेख नहीं करने के लिए कि चरण 2 को लागू करने का कार्य अभी भी "पाठक के लिए एक अभ्यास के रूप में छोड़ दिया गया है"।


7

किसी भी बिंदु पर जब n को बाध्य किया जाता है और O (1) एल्गोरिथ्म का निरंतर गुणक लॉग (n) पर बंधे से अधिक होता है। उदाहरण के लिए, हैशसेट में मानों को संचयित करना O (1) है, लेकिन हैश फ़ंक्शन की महंगी गणना की आवश्यकता हो सकती है। यदि डेटा आइटम की तुलना तुच्छ रूप से की जा सकती है (कुछ आदेश के संबंध में) और n पर बाउंड ऐसा है कि लॉग एन किसी भी आइटम पर हैश की तुलना में काफी कम है, तो एक संतुलित बाइनरी ट्री में भंडारण से अधिक तेजी से हो सकता है एक हैशसेट।


6

एक वास्तविक स्थिति में जहां आपको एक ऊपरी ऊपरी सीमा की आवश्यकता होती है आप एक उदाहरण के लिए एक Quicksort के विपरीत एक ढेर का चयन करेंगे, क्योंकि heapsort का औसत व्यवहार भी इसका सबसे खराब व्यवहार है।


6

पहले से ही अच्छे उत्तरों में जोड़ना। व्यावहारिक उदाहरण पोस्टग्रेज डेटाबेस में हैश इंडेक्स बनाम बी-ट्री इंडेक्स होगा।

हैश इंडेक्स डिस्क को डेटा का उपयोग करने के लिए हैश टेबल इंडेक्स बनाते हैं जबकि बीटीआरआई जैसा कि नाम से पता चलता है कि बीटीआरआई डेटा संरचना का उपयोग करता है।

बिग-ओ समय में ये O (1) बनाम O (logN) हैं।

हैश इंडेक्स को वर्तमान में पोस्टग्रेज में हतोत्साहित किया जाता है क्योंकि विशेष रूप से डेटाबेस सिस्टम में वास्तविक जीवन की स्थिति में, टकराव के बिना हैशिंग को प्राप्त करना बहुत कठिन है (ओ (एन) सबसे खराब स्थिति जटिलता पैदा कर सकता है) और इस वजह से, इसे बनाना और भी कठिन है उन्हें सुरक्षित क्रैश (लॉग इन आगे लॉगिंग - पोस्टग्रेज में वाल) कहा जाता है।

यह ट्रेडऑफ़ इस स्थिति में बना है क्योंकि O (logN) इंडेक्स के लिए पर्याप्त है और O (1) को लागू करना बहुत कठिन है और समय का अंतर वास्तव में मायने नहीं रखेगा।


4

जब nछोटा होता है, और O(1)लगातार धीमा होता है।


3
  1. जब O (1) में "1" वर्क यूनिट O (लॉग एन) में वर्क यूनिट के सापेक्ष बहुत अधिक है और अपेक्षित सेट का आकार छोटा-ईश है। उदाहरण के लिए, यह संभवतः दो या तीन आइटम हैं, तो सरणी को पुनरावृत्त करने की तुलना में शब्दकोश हैश कोड की गणना करने के लिए धीमी है।

या

  1. जब O (1) एल्गोरिथ्म में मेमोरी या अन्य गैर-समय संसाधन आवश्यकताएँ असाधारण रूप से O (लॉग एन) एल्गोरिथम के सापेक्ष बड़ी होती हैं।

3
  1. जब किसी प्रोग्राम को नया स्वरूप दिया जाता है, तो एक प्रक्रिया O (lgN) के बजाय O (1) के साथ अनुकूलित पाई जाती है, लेकिन यदि यह इस प्रोग्राम की अड़चन नहीं है, और O (1) alg को समझना कठिन है। तब आपको O (1) एल्गोरिदम का उपयोग नहीं करना होगा
  2. जब O (1) को बहुत अधिक मेमोरी की आवश्यकता होती है जिसे आप आपूर्ति नहीं कर सकते, जबकि O (lgN) के समय को स्वीकार किया जा सकता है।

1

सुरक्षा अनुप्रयोगों के लिए अक्सर ऐसा होता है कि हम उन समस्याओं को डिज़ाइन करना चाहते हैं जिनके एल्गोरिदम उद्देश्य से धीमी गति से होते हैं ताकि किसी समस्या का उत्तर प्राप्त करने से किसी को जल्दी से रोका जा सके।

यहाँ मेरे सिर के ऊपर से कुछ उदाहरण हैं।

  • पासवर्ड हैशिंग को कभी-कभी मनमाने ढंग से धीमा कर दिया जाता है, ताकि ब्रूट-बल द्वारा पासवर्ड का अनुमान लगाना कठिन हो जाए। इस सूचना सुरक्षा पोस्ट में इसके बारे में एक बुलेट बिंदु है (और भी बहुत कुछ)।
  • बिट कॉइन "खदान" के सिक्कों को हल करने के लिए कंप्यूटरों के नेटवर्क के लिए नियंत्रित रूप से धीमी समस्या का उपयोग करता है। यह मुद्रा को सामूहिक प्रणाली द्वारा नियंत्रित दर पर खनन करने की अनुमति देता है।
  • असममित ciphers ( RSA की तरह ) एन्क्रिप्शन को दरार करने के लिए निजी कुंजी के बिना किसी और को रोकने के लिए जानबूझकर धीमी गति से डिक्रिप्शन बनाने के लिए डिज़ाइन किए गए हैं। एल्गोरिदम को उम्मीद के O(2^n)समय दरार करने के लिए डिज़ाइन किया गया है जहां nकुंजी की लंबाई-लंबाई है (यह जानवर बल है)।

सीएस में कहीं और, क्विक सॉर्ट O(n^2)सबसे खराब स्थिति में है लेकिन सामान्य मामले में है O(n*log(n))। इस कारण से, "बिग ओ" विश्लेषण कभी-कभी केवल एक चीज नहीं है जिसे आप एल्गोरिथ्म दक्षता का विश्लेषण करते समय परवाह करते हैं।

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