क्या यह एक एल्गोरिथम की "बिग ओ" अंकन की पहचान के लिए एक उचित "नियम" है?


29

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

बिग ओ नोटेशन: एन

function(n) {
    For(var a = 0; i <= n; i++) { // It's N because it's just a single loop
        // Do stuff
    }
}

बिग ओ संकेतन: एन

function(n, b) {
    For(var a = 0; a <= n; a++) {
        For(var c = 0; i <= b; c++) { // It's N squared because it's two nested loops
            // Do stuff
        }
    }
}

बिग ओ नोटेशन: 2 एन

function(n, b) {
    For(var a = 0; a <= n; a++) {
        // Do stuff
    }
    For(var c = 0; i <= b; c++) { // It's 2N the loops are outside each other
        // Do stuff
    }
}

बिग ओ नोटेशन: एनएलओजीएन

function(n) {
    n.sort(); // The NLogN comes from the sort?
    For(var a = 0; i <= n; i++) {
        // Do stuff
    }
}

क्या मेरे उदाहरण और उसके बाद के अंकन सही हैं? क्या अतिरिक्त सूचनाएं हैं जिनकी मुझे जानकारी होनी चाहिए?


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

15
2Nबिग-ओ नोटेशन जैसी कोई चीज नहीं है।
vartec

15
@ JörgWMittag क्योंकि O (2n) = O (n) बिग O की परिभाषा द्वारा
शाफ़्ट फ्रीक

3
@ JörgWMittag: यह वास्तव में ट्रोलिंग के लिए जगह नहीं है।
vartec

3
@vartec - मेरा मानना ​​है कि JörgWMittag उद्देश्यपूर्ण ढंग से ट्रोलिंग नहीं था। अपने हालिया शोध में, मैंने बिग-ओ नोटेशन और "आम वर्नाक्यूलर" के बीच बहुत अधिक भ्रम देखा है जो बिग-ओ, थीटा और अन्य डेरिवेटिव को मिलाता है। मैं यह नहीं कह रहा हूँ कि आम उपयोग सही है; बस इतना है कि यह बहुत कुछ होता है।

जवाबों:


26

औपचारिक रूप से, बिग-ओ नोटेशन जटिलता की डिग्री का वर्णन करता है।

बड़े-ओ संकेतन की गणना करने के लिए:

  1. एल्गोरिथ्म जटिलता के लिए सूत्र की पहचान। उदाहरण के लिए, दो छोरों को एक दूसरे के अंदर घोंसला बनाया गया है, फिर दूसरे तीन छोरों को घोंसला नहीं बनाया गया है:2N² + 3N
  2. उच्चतम अवधि को छोड़कर सब कुछ हटा दें: 2N²
  3. सभी स्थिरांक निकालें:

दूसरे शब्दों में, एक दूसरे के साथ दो छोरों के अंदर घोंसला होता है, फिर दूसरे तीन छोरों से घोंसला नहीं होता है O (N²)

यह निश्चित रूप से मानता है कि आपके छोरों में आपके पास क्या है सरल निर्देश हैं। यदि आपके पास sort()लूप के अंदर उदाहरण के लिए है, तो आपको लूप की जटिलता को उस sort()कार्यान्वयन की जटिलता से गुणा करना होगा जिसे आपकी अंतर्निहित भाषा / लाइब्रेरी उपयोग कर रही है।


सख्ती से बोलना "सभी स्थिरांक हटा दें" में बदल 2N³जाएगा N। "सभी additive और गुणक स्थिरांक को हटा दें" सच्चाई के करीब होगा।
जोकिम सॉयर

@JoachimSauer: N² = N * N, वहाँ कोई स्थिर नहीं है।
vartec

@vartec: उसी तर्क के अनुसार 2N = N+N
जोकिम सॉयर

2
@JoachimSauer, आपका "सख्ती से बोलना" बिल्कुल गैर-पारंपरिक। En.wikipedia.org/wiki/Constant_(mathematics) देखें । बहुपद के बारे में बात करते समय, "स्थिर" हमेशा केवल गुणांक को संदर्भित करता है, न कि घातांक को।
बेन ली

1
@vartec, ऊपर मेरी टिप्पणी देखें। यहां "निरंतर" का आपका उपयोग बिल्कुल सही और पारंपरिक था।
बेन ली

6

यदि आप इन एल्गोरिदम का विश्लेषण करना चाहते हैं, तो आपको // dostuff को परिभाषित करने की आवश्यकता है, क्योंकि यह वास्तव में परिणाम बदल सकता है। मान लीजिए कि डस्टफ को संचालन के लिए निरंतर O (1) संख्या की आवश्यकता है।

इस नई संकेतन के साथ कुछ उदाहरण इस प्रकार हैं:

आपके पहले उदाहरण के लिए, लीनियर ट्रैवर्सल: यह सही है!

पर):

for (int i = 0; i < myArray.length; i++) {
    myArray[i] += 1;
}

यह रैखिक (O (n)) क्यों है? जैसा कि हम इनपुट में अतिरिक्त तत्वों को जोड़ते हैं (सरणी) हो रही कार्रवाई की मात्रा हम जोड़ने वाले तत्वों की संख्या के लिए आनुपातिक बढ़ जाती है।

इसलिए यदि यह एक ऑपरेशन को एक पूर्णांक को मेमोरी में कहीं बढ़ाने के लिए लेता है, तो हम उस काम को मॉडल कर सकते हैं जो लूप f (x) = 5x = 5 अतिरिक्त ऑपरेशन के साथ करता है। 20 अतिरिक्त तत्वों के लिए, हम 20 अतिरिक्त ऑपरेशन करते हैं। सरणी का एक एकल पास रैखिक हो जाता है। तो बाल्टी सॉर्ट जैसे एल्गोरिदम हैं, जो किसी सरणी के एक एकल पास में एक सॉर्ट करने के लिए डेटा की संरचना का फायदा उठाने में सक्षम हैं।

आपका दूसरा उदाहरण भी सही होगा और इस तरह दिखेगा:

हे (एन ^ 2):

for (int i = 0; i < myArray.length; i++) {
    for (int j = 0; j < myArray.length; j++) {
        myArray[i][j] += 1;
    }
}

इस मामले में, पहले सरणी में प्रत्येक अतिरिक्त तत्व के लिए, मुझे, हमें सभी जम्मू को संसाधित करना होगा। 1 से i जोड़ना वास्तव में j की लंबाई (j की लंबाई) जोड़ देता है। इस प्रकार, आप सही हैं! यह पैटर्न O (n ^ 2) है, या हमारे उदाहरण में यह वास्तव में O (i * j) (या n ^ 2 है यदि i == j है, जो अक्सर मैट्रिक्स ऑपरेशन या एक वर्ग डेटा संरचना के साथ होता है।

आपका तीसरा उदाहरण है, जहां चीजें डस्टफ के आधार पर बदलती हैं; यदि कोड लिखित है और क्या सामान स्थिर है, तो यह वास्तव में केवल O (n) है क्योंकि हमारे पास आकार n की एक सरणी के 2 पास हैं, और 2n n को कम कर देता है। एक दूसरे के बाहर होने वाले लूप प्रमुख कारक नहीं हैं जो 2 ^ n कोड का उत्पादन कर सकते हैं; यहाँ एक फ़ंक्शन का एक उदाहरण है जो 2 ^ n है:

var fibonacci = function (n) {
    if (n == 1 || n == 2) {
        return 1;
    }

    else {
        return (fibonacci(n-2) + fibonacci(n-1));
    }
}

यह फ़ंक्शन 2 ^ n है, क्योंकि फ़ंक्शन के प्रत्येक कॉल फ़ंक्शन (Fibnote) को दो अतिरिक्त कॉल उत्पन्न करता है। हर बार जब हम फ़ंक्शन को कॉल करते हैं, तो हमें काम की मात्रा दोगुनी करनी होती है! यह सुपर जल्दी से बढ़ता है, जैसे कि एक हाइड्रा का सिर काटना और हर बार दो नए अंकुरित होना!

अपने अंतिम उदाहरण के लिए, यदि आप मर्ज-सॉर्ट की तरह एक nlgn तरह का उपयोग कर रहे हैं तो आप सही हैं कि यह कोड O (nlgn) होगा। हालाँकि, आप विशिष्ट स्थितियों में तेज़ी से विकास करने के लिए डेटा की संरचना का उपयोग कर सकते हैं (जैसे 1-100 से मूल्यों की एक ज्ञात, सीमित सीमा।) आप सोच में सही हैं, हालांकि, उच्चतम क्रम कोड हावी है। इसलिए यदि O (nlgn) समय से कम समय तक चलने वाले किसी भी ऑपरेशन के बगल में O (nlgn) सॉर्ट होता है, तो कुल समय जटिलता O (nlgn) होगी।

जावास्क्रिप्ट में (कम से कम फ़ायरफ़ॉक्स में) Array.prototype.sort () में डिफ़ॉल्ट सॉर्ट वास्तव में मर्जस्टॉर्ट है, इसलिए आप अपने अंतिम परिदृश्य के लिए O (nlgn) देख रहे हैं।


क्या आपका फाइबोनैचि उदाहरण वास्तव में फाइबोनैचि है? मुझे पता है कि यह उस बिंदु के खिलाफ बहस नहीं करता है जिसे आप बनाने की कोशिश कर रहे थे, लेकिन नाम दूसरों के लिए भ्रामक हो सकता है और इसलिए विचलित हो सकता है अगर यह वास्तव में फिबोनाची नहीं है।
पॉल निकोविक्ज़

1

आपका दूसरा उदाहरण (0 से n तक बाहरी लूप , आंतरिक लूप से 0 से b ) O ( nb ) होगा, न कि O ( n 2 )। नियम यह है कि आप कुछ n बार कंप्यूटिंग कर रहे हैं , और उनमें से प्रत्येक के लिए आप b बार कुछ और कंप्यूटिंग कर रहे हैं , इस प्रकार इस फ़ंक्शन का विकास पूरी तरह से n * b की वृद्धि पर निर्भर करता है ।

आपका तीसरा उदाहरण सिर्फ O ( n ) है - आप सभी स्थिरांक निकाल सकते हैं क्योंकि वे n के साथ नहीं बढ़ते हैं और विकास क्या है, Big-O संकेतन सभी के बारे में है।

अपने अंतिम उदाहरण के लिए, हां, आपका बिग-ओ नोटेशन निश्चित रूप से सॉर्ट विधि से होगा, अगर यह तुलना-आधारित है (जैसा कि आमतौर पर मामला है), यह सबसे कुशल रूप में है, ओ ( एन * लॉगन ) ।


0

याद रखें कि यह रन-टाइम का एक अनुमानित प्रतिनिधित्व है। "नियम-से-अंगूठे" अनुमानित है, क्योंकि यह अभेद्य है, लेकिन मूल्यांकन के उद्देश्यों के लिए एक अच्छा प्रथम-क्रम सन्निकटन देता है।

वास्तविक रन-टाइम इस बात पर निर्भर करेगा कि प्रोसेसर, इंस्ट्रक्शन सेट, प्रीफिक्स या पोस्ट-फिक्स इन्क्रीमेंट ऑपरेटर्स आदि का कितना तेज़, स्पेस, याद्दा है। उचित रन-टाइम विश्लेषण स्वीकृति का निर्धारण करने की अनुमति देगा लेकिन मूल बातों का ज्ञान होने से आप शुरुआत से ही सही कार्यक्रम कर सकते हैं।

मैं सहमत हूं कि आप यह समझने के लिए सही ट्रैक पर हैं कि बिग-ओ को पाठ्यपुस्तक से व्यावहारिक अनुप्रयोग तक कैसे तर्कसंगत बनाया जाता है। जिससे उबरना मुश्किल पड़ सकता है।

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


-1

बिग ओह, परिभाषा से मतलब है: एक समारोह के लिए च (टी) वहाँ एक समारोह ग * जी (टी) मौजूद है जहां ग एक मनमाना स्थिर है जैसे कि च (टी) <= सी * जी (टी) के लिए टी> एन जहां एन एक मनमाना स्थिरांक है, तो O (g (t)) में f (t) मौजूद है। यह एक गणितीय अंकन है जिसका उपयोग कंप्यूटर विज्ञान में एल्गोरिदम का विश्लेषण करने के लिए किया जाता है। यदि आपका भ्रमित मैं निकट संबंधों को देखने की सिफारिश करूंगा, तो आप इस तरह से अधिक विस्तृत दृश्य में देख सकते हैं कि कैसे इन एल्गोरिदम को ये बड़े-ओह मान मिलते हैं।

इस परिभाषा के कुछ परिणाम: O (n) वास्तव में O (2n) के लिए बधाई है।

इसके अलावा कई अलग-अलग प्रकार के एल्गोरिदम हैं। तुलनात्मक प्रकार के लिए न्यूनतम बिग-ओह मान O (nlogn) है, हालांकि बिग बिग-ओह के साथ बहुत सारे प्रकार हैं। उदाहरण के लिए चयन प्रकार में O (n ^ 2) है। कुछ गैर तुलनात्मक प्रकार में कभी भी बेहतर बड़े-ओह मान हो सकते हैं। एक बाल्टी प्रकार, उदाहरण के लिए O (n) है।

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