यूक्लिड के एल्गोरिथ्म की समय जटिलता


97

मुझे यह तय करने में कठिनाई हो रही है कि यूक्लिड की सबसे बड़ी सामान्य भाजक एल्गोरिथ्म की समय जटिलता क्या है। छद्म कोड में यह एल्गोरिथ्म है:

function gcd(a, b)
    while b ≠ 0
       t := b
       b := a mod b
       a := t
    return a

यह बी और बी पर निर्भर करता है । मेरी सोच है कि समय जटिलता हे (एक% बी) है। क्या वो सही है? क्या यह लिखने का एक बेहतर तरीका है?


14
Knuth TAOCP, खंड 2 देखें - वह व्यापक कवरेज देता है । बस FWIW, tidbits के एक जोड़े: यह आनुपातिक नहीं है a%b। सबसे खराब स्थिति है जब aऔर bक्रमिक फाइबोनैचि संख्याओं हैं।
जेरी कॉफिन

3
@ जेरेकॉफिन नोट: यदि आप साबित करना चाहते हैं कि सबसे खराब स्थिति वास्तव में अधिक औपचारिक रूप से फाइबोनैचि संख्या है, तो समाप्ति से पहले एन-वें चरण को साबित करने पर विचार करें, गणितीय इंडक्शन के लिए n-th फाइबोनैचि संख्या से gcd गुना बड़ा होना चाहिए।
Mygod

जवाबों:


73

यूक्लिड के एल्गोरिथ्म की समय जटिलता का विश्लेषण करने के लिए एक चाल यह है कि दो पुनरावृत्तियों पर क्या होता है:

a', b' := a % b, b % (a % b)

अब ए और बी दोनों घटेंगे, केवल एक के बजाय, जो विश्लेषण को आसान बनाता है। आप इसे मामलों में विभाजित कर सकते हैं:

  • टिनी A: 2a <= b
  • छोटे बी: 2b <= a
  • छोटा ए: 2a > bलेकिनa < b
  • छोटा बी: 2b > aलेकिनb < a
  • बराबरी का: a == b

अब हम बताएंगे कि हर एक मामले a+bमें कम से कम एक चौथाई की कमी होती है :

  • टिनी ए: b % (a % b) < aऔर 2a <= b, इसलिए bकम से कम आधा a+bघटाया जाता है , इसलिए कम से कम घटाया जाता है25%
  • टाइनी बी: a % b < bऔर 2b <= a, इसलिए aकम से कम आधा a+bघटाया जाता है , इसलिए कम से कम घटाया जाता है25%
  • छोटा A: bबन जाएगा b-a, जो कम से कम b/2, कम a+bसे कम है 25%
  • छोटा बी: aबन जाएगा a-b, जो कम से कम a/2, कम a+bसे कम है 25%
  • समान: के लिए a+bबूँदें 0, जो स्पष्ट रूप से कम a+bसे कम है 25%

इसलिए, मामले के विश्लेषण से, प्रत्येक डबल-स्टेप कम a+bसे कम घटता है 25%a+bनीचे ड्रॉप करने के लिए मजबूर होने से पहले यह अधिकतम बार हो सकता है 1Sजब तक हम 0 को हिट नहीं करते तब तक कुल चरणों की संख्या ( ) होनी चाहिए (4/3)^S <= A+B। अब बस इसे काम:

(4/3)^S <= A+B
S <= lg[4/3](A+B)
S is O(lg[4/3](A+B))
S is O(lg(A+B))
S is O(lg(A*B)) //because A*B asymptotically greater than A+B
S is O(lg(A)+lg(B))
//Input size N is lg(A) + lg(B)
S is O(N)

तो इनपुट अंकों की संख्या में पुनरावृत्तियों की संख्या रैखिक है। सीपीयू रजिस्टरों में फिट होने वाली संख्याओं के लिए, पुनरावृत्तियों को मॉडल करना उचित है क्योंकि निरंतर समय ले रहा है और यह दिखावा करता है कि gcd का कुल चलने का समय रैखिक है।

बेशक, यदि आप बड़े पूर्णांकों के साथ काम कर रहे हैं, तो आपको इस तथ्य पर ध्यान देना चाहिए कि प्रत्येक पुनरावृत्ति के भीतर मापांक संचालन की निरंतर लागत नहीं है। मोटे तौर पर, कुल एसिम्प्टोटिक रनटाइम n ^ 2 गुना पॉलीग्लारिथमिक कारक होने जा रहा है। कुछ इस तरह n^2 lg(n) 2^O(log* n)बाइनरी जीसीडी का उपयोग करने के बजाय पॉलीग्लारिथमिक कारक से बचा जा सकता है ।


क्या आप समझा सकते हैं कि "b% (a% b) <a" कृपया?
माइकल हीडलबर्ग

3
@MichaelHeidelberg इससे x % yअधिक नहीं हो सकता है xऔर इससे कम होना चाहिए y। तो a % bसबसे अधिक है a, b % (a%b)कुछ ऐसा करने के लिए मजबूर होना जो सबसे अधिक है aऔर इसलिए समग्र रूप से कम है a
क्रेग गिदनी

@ चेरसन्ध।-अल्फ आप पसंदीदा शब्दावली में थोड़े अंतर को "गंभीर रूप से गलत" मानते हैं? बेशक मैंने सीएस शब्दावली का उपयोग किया था; यह एक कंप्यूटर विज्ञान का सवाल है। भले ही, मैंने "अंकों की संख्या" कहने का उत्तर स्पष्ट कर दिया।
क्रेग गिदनी

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

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

27

एक एल्गोरिथ्म का विश्लेषण करने का उपयुक्त तरीका इसके सबसे खराब स्थिति का निर्धारण करना है। यूक्लिडियन जीसीडी का सबसे खराब मामला तब होता है जब फाइबोनैचि जोड़े शामिल होते हैं। void EGCD(fib[i], fib[i - 1]), जहां मैं> 0।

उदाहरण के लिए, चलिए उस मामले को चुनते हैं जहां लाभांश 55 है, और विभाजक 34 है (याद रखें कि हम अभी भी संख्याओं के साथ काम कर रहे हैं)।

यहां छवि विवरण दर्ज करें

जैसा कि आप देख सकते हैं, इस ऑपरेशन में 8 पुनरावृत्तियों (या पुनरावर्ती कॉल) का खर्च आया।

आइए 121393 और 75025 नाम से बड़ी संख्या में फाइबोनैचि की कोशिश करें। हम यहां यह भी नोटिस कर सकते हैं कि इसमें 24 पुनरावृत्तियों (या पुनरावर्ती कॉल) लगे।

यहां छवि विवरण दर्ज करें

आप यह भी देख सकते हैं कि प्रत्येक पुनरावृत्तियों में एक फाइबोनैचि संख्या होती है। इसलिए हमारे पास बहुत सारे ऑपरेशन हैं। हम वास्तव में केवल फाइबोनैचि संख्याओं के साथ समान परिणाम प्राप्त नहीं कर सकते हैं।

इसलिए, इस बार छोटी ओह (ऊपरी बाध्य) द्वारा समय जटिलता का प्रतिनिधित्व किया जा रहा है। निचली सीमा सहज रूप से ओमेगा (1) है: 500 का मामला, उदाहरण के लिए 2 से विभाजित।

चलो पुनरावृत्ति संबंध हल करें:

यहां छवि विवरण दर्ज करें

हम फिर कह सकते हैं कि यूक्लिडियन जीसीडी अधिकांश में लॉग (xy) ऑपरेशन कर सकता है


2
मुझे लगता है कि यह विश्लेषण गलत है, क्योंकि आधार इनपुट पर निर्भर है।
उम्मीद है कि

क्या आप साबित कर सकते हैं कि एक आश्रित आधार किसी समस्या का प्रतिनिधित्व करता है?
मोहम्मद एन्नहदी एल इदरीसी

1
आधार स्पष्ट रूप से स्वर्णिम अनुपात है। क्यों? क्योंकि यह नोड (13,8) बनाम नोड (8,5) की गणना करने के लिए एक अतिरिक्त कदम उठाता है। निश्चित x के लिए यदि y <x सबसे खराब स्थिति का प्रदर्शन x = fib (n + 1), y = fib (n) है। यहाँ y x पर निर्भर करता है, इसलिए हम केवल x को देख सकते हैं।
Stepan

17

विकिपीडिया लेख पर इस पर एक शानदार नज़र है ।

यहां तक ​​कि मूल्य जोड़े के लिए जटिलता की एक अच्छी साजिश है।

यह नहीं है O(a%b)

यह ज्ञात है (लेख देखें) कि यह छोटी संख्या में अंकों की संख्या के पांच गुना से अधिक कदम कभी नहीं उठाएगा। तो अंकों की अधिकतम संख्या अंकों की संख्या के रूप में बढ़ती है (ln b)। प्रत्येक चरण की लागत भी अंकों की संख्या के रूप में बढ़ती है, इसलिए जटिलता O(ln^2 b)जहां बी छोटी संख्या है, वहां से बंधी है । यह एक ऊपरी सीमा है, और वास्तविक समय आमतौर पर कम है।


क्या nप्रतिनिधित्व करता है ?
IVlad

@IVlad: अंकों की संख्या। मैंने जवाब स्पष्ट किया है, धन्यवाद।
जोश

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

@ अलेक्सांद्र सी।: ध्यान रखें n = ln b । बड़े इंट के लिए मापांक की नियमित जटिलता क्या है? क्या यह हे (लॉग एन लॉग ^ 2 लॉग एन)
जोश

@ जोश: यह कुछ ऐसा है, मुझे लगता है कि मैं इस मामले में एक लॉग एन टर्म, अंतिम जटिलता (एल्गोरिदम के साथ एल्गोरिथ्म के लिए) हे (एन ^ 2 लॉग ^ 2 एन लॉग एन) से चूक गया हूं।
अलेक्जेंड्रे सी।

13

देखें यहाँ

विशेष रूप से इस भाग में:

लामे ने दिखाया कि n से कम दो संख्याओं के लिए सबसे बड़े सामान्य भाजक में पहुंचने के लिए आवश्यक चरणों की संख्या है

वैकल्पिक शब्द

तो O(log min(a, b))एक अच्छा ऊपरी बंधन है।


3
यह कदमों की संख्या के लिए सही है, लेकिन यह प्रत्येक चरण की जटिलता के लिए खुद को जिम्मेदार नहीं ठहराता है, जो अंकों की संख्या (ln n) के साथ है।
जोश

9

यहां यूक्लिड के एल्गोरिथ्म की रनटाइम जटिलता की सहज समझ है। औपचारिक साक्ष्य विभिन्न पाठों जैसे कि अल्गोरिद्म और टीएओसीपी वॉल्यूम 2 ​​से जुड़े हैं।

पहले सोचें कि अगर हमने दो फाइबोनैचि संख्या F (k + 1) और F (k) के gcd लेने की कोशिश की तो क्या होगा। आप जल्दी से देख सकते हैं कि यूक्लिड का एल्गोरिथ्म एफ (के) और एफ (के -1) पर पुनरावृति करता है। यही है, प्रत्येक पुनरावृत्ति के साथ हम फाइबोनैचि श्रृंखला में एक नंबर नीचे जाते हैं। चूंकि फाइबोनैचि संख्याएं O (Phi ^ k) हैं जहां Phi स्वर्ण अनुपात है, हम देख सकते हैं कि GCD का रनटाइम O (लॉग एन) था जहां n = मैक्स (a, b) और लॉग का आधार Phi है। इसके बाद, हम यह साबित कर सकते हैं कि यह सबसे खराब स्थिति होगी कि फिबोनाकी संख्या लगातार जोड़े पैदा करती है, जहां प्रत्येक पुनरावृत्ति में अवशेष काफी बड़े बने रहते हैं और कभी भी शून्य नहीं होते हैं जब तक कि आप श्रृंखला की शुरुआत में नहीं आए हों।

हम ओ (लॉग एन) बना सकते हैं जहां n = अधिकतम (ए, बी) और भी अधिक तंग है। मान लें कि b> = a तो हम O (लॉग बी) पर बाध्य लिख सकते हैं। पहले, निरीक्षण करें कि GCD (ka, kb) = GCD (a, b)। K का सबसे बड़ा मान है gcd (a, c), हम b को b / gcd (a, b) से बदल सकते हैं, हमारे रनटाइम में O (लॉग b / gcd (a, b) से अधिक तंग बाउंड की ओर रुख करेंगे।


क्या आप एक औपचारिक प्रमाण दे सकते हैं कि फाइबोनैचि नोज़ यूक्लिड्स के लिए सबसे बुरा मामला है?
आकाश

4

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

जब n और m a और b के अंकों की संख्या होती है, तो n> = m मानकर, एल्गोरिथ्म O (m) विभाजनों का उपयोग करता है।

ध्यान दें कि जटिलताएं हमेशा इनपुट के आकार के संदर्भ में दी जाती हैं, इस मामले में अंकों की संख्या।


4

सबसे खराब स्थिति तब उत्पन्न होगी जब n और m दोनों लगातार फाइबोनैचि संख्या होते हैं।

gcd (Fn, Fn) 1) = gcd (Fn F 1, Fn) 2) = (= gcd (F1, F0) = 1 और nth फाइबोनैचि संख्या 1.618 ^ n है, जहाँ 1.618 स्वर्णिम अनुपात है।

तो, gcd (n, m) को खोजने के लिए, पुनरावर्ती कॉलों की संख्या log (logn) होगी।


3

मार्क एलन वीस द्वारा सी में डेटा संरचना और एल्गोरिथम विश्लेषण में पुस्तक का विश्लेषण यहां दिया गया है (दूसरा संस्करण, 2.4.4):

यूक्लिड का एल्गोरिथ्म 0 तक पहुंचने तक लगातार कंप्यूटिंग अवशेषों द्वारा काम करता है। अंतिम नॉनजरो शेष उत्तर है।

यहाँ कोड है:

unsigned int Gcd(unsigned int M, unsigned int N)
{

    unsigned int Rem;
    while (N > 0) {
        Rem = M % N;
        M = N;
        N = Rem;
    }
    Return M;
}

यहाँ एक THEOREM है जिसका हम उपयोग करने जा रहे हैं:

यदि M> N, तो M mod N <M / 2 है।

सबूत:

दो मामले हैं। यदि एन <= एम / 2, तो चूंकि शेष एन की तुलना में छोटा है, इस मामले के लिए प्रमेय सही है। अन्य मामला एन> एम / 2 है। लेकिन तब N एक शेष M - N <M / 2 के साथ एक बार M में जाता है, जो प्रमेय साबित होता है।

तो, हम निम्नलिखित निष्कर्ष बना सकते हैं:

Variables    M      N      Rem

initial      M      N      M%N

1 iteration  N     M%N    N%(M%N)

2 iterations M%N  N%(M%N) (M%N)%(N%(M%N)) < (M%N)/2

इसलिए, दो पुनरावृत्तियों के बाद, शेष अपने मूल मूल्य के अधिकांश भाग पर है। इससे पता चलता है कि पुनरावृत्तियों की संख्या सबसे अधिक है2logN = O(logN)

ध्यान दें कि, एल्गोरिथ्म Gcd (M, N) की गणना करता है, यह मानते हुए कि M> = N. (यदि N> M है, तो लूप का पहला पुनरावृत्ति उन्हें स्वैप करता है।)


2

गेब्रियल लैम के प्रमेय लॉग (1 / sqrt (5) * (a + 1/2) - 2 द्वारा चरणों की संख्या को बांधता है, जहां लॉग का आधार (1 + sqrt (5)) / 2 है। यह एल्गोरिथ्म के लिए सबसे खराब स्थिति स्केनेरियो के लिए है और यह तब होता है जब इनपुट लगातार फाइबोनैचि संख्या होते हैं।

थोड़ी अधिक उदार बाध्यता है: लॉग ए, जहां लॉग का आधार (sqrt (2)) कोबीजित्ज़ द्वारा निहित है।

क्रिप्टोग्राफ़िक प्रयोजनों के लिए हम आमतौर पर एल्गोरिदम की बिटवाइज़ जटिलता पर विचार करते हैं, इस बात को ध्यान में रखते हुए कि बिट आकार लगभग k =a द्वारा दिया जाता है।

यहां यूक्लिड एल्गोरिदम की बिटवाइज़ जटिलता का विस्तृत विश्लेषण दिया गया है:

यद्यपि अधिकांश संदर्भों में यूक्लिड एल्गोरिथम की बिटवाइज़ जटिलता ओ (लोगा) ^ 3 द्वारा दी गई है, जिसमें एक टाई बाउंड मौजूद है जो O (loga) ^ 2 है।

विचार करें; r0 = a, r1 = b, r0 = q1.r1 + r2। । । , ri-1 = qi.ri + ri + 1,। । । , rm-2 = qm-1.rm-1 + rm rm-1 = qm.rm

निरीक्षण करें कि: a = r0> = b = r1> r2> r3 ...> rm-1> rm> 0 .......... (1)

और rm a और b का सबसे बड़ा सामान्य भाजक है।

कोब्लिट्ज की किताब में एक दावे (थ्योरी और क्रिप्टोग्राफी में एक कोर्स) में यह साबित किया जा सकता है कि: री + 1 <(ri-1) / 2 ................ ( 2)

Koblitz में फिर से एक बिट-बिट पॉजिटिव पूर्णांक (मान k> = l) द्वारा k-bit पॉजिटिव पूर्णांक को विभाजित करने के लिए आवश्यक बिट संचालन की संख्या इस प्रकार दी गई है: (k-l + 1) .l ...... ............. (3)

By (1) और (2) विभाजनों की संख्या O (loga) है और इसलिए (3) कुल जटिलता O (loga) ^ 3 है।

अब कोब्लिट्ज में एक टिप्पणी के द्वारा इसे घटाकर O (loga) ^ 2 किया जा सकता है।

विचार करना = लोगरी +1

by (1) और (2) हमारे पास: ki + 1 <= ki for i = 0,1, ..., m-2, m-1 और ki + 2 <= (ki) -1 for i = 0 है। , 1, ..., एम-2

और (3) m डिवीजन की कुल लागत से घिरा है: SUM [(ki-1) - (((ki) -1))] * ki for i = 0,1,2, .., m

इसे पुन: व्यवस्थित करना: SUM [(ki-1) - (((ki) -1))] * ki <= 4 * k0 ^ 2

यूक्लिड के एल्गोरिथ्म की बिटवाइज़ जटिलता हे (लोगा) ^ 2 है।


1

हालाँकि, पुनरावृत्ति एल्गोरिथ्म के लिए, हमारे पास:

int iterativeEGCD(long long n, long long m) {
    long long a;
    int numberOfIterations = 0;
    while ( n != 0 ) {
         a = m;
         m = n;
         n = a % n;
        numberOfIterations ++;
    }
    printf("\nIterative GCD iterated %d times.", numberOfIterations);
    return m;
}

फाइबोनैचि जोड़े के साथ, कोई अंतर नहीं है iterativeEGCD()और iterativeEGCDForWorstCase()बाद वाले को निम्नलिखित की तरह दिखता है:

int iterativeEGCDForWorstCase(long long n, long long m) {
    long long a;
    int numberOfIterations = 0;
    while ( n != 0 ) {
         a = m;
         m = n;
         n = a - n;
        numberOfIterations ++;
    }
    printf("\nIterative GCD iterated %d times.", numberOfIterations);
    return m;
}

हां, फिबोनाची जोड़े के साथ, n = a % nऔर n = a - n, यह बिल्कुल एक ही बात है।

हम यह भी जानते हैं कि, इसी प्रश्न के लिए पहले की प्रतिक्रिया में, एक प्रचलित घटता कारक है factor = m / (n % m):।

इसलिए, यूक्लिडियन जीसीडी के पुनरावृत्त संस्करण को परिभाषित रूप में आकार देने के लिए, हम इस तरह से "सिम्युलेटर" के रूप में चित्रित कर सकते हैं:

void iterativeGCDSimulator(long long x, long long y) {
    long long i;
    double factor = x / (double)(x % y);
    int numberOfIterations = 0;
    for ( i = x * y ; i >= 1 ; i = i / factor) {
        numberOfIterations ++;
    }
    printf("\nIterative GCD Simulator iterated %d times.", numberOfIterations);
}

डॉ। जौहर अली के काम (अंतिम स्लाइड) के आधार पर , ऊपर का लूप लॉगरिदमिक है।

यहां छवि विवरण दर्ज करें

हां, छोटे ओह क्योंकि सिम्युलेटर सबसे अधिक पुनरावृत्तियों की संख्या बताता है । यूक्लिडियन जीसीडी पर जांच करने पर गैर-फाइबोनैचि जोड़े फाइबोनैचि की तुलना में कम पुनरावृत्तियों को ले लेंगे।


जैसा कि यह अध्ययन सी भाषा का उपयोग करके किया गया था, सटीक मुद्दों में गलत / अशुद्ध मान उत्पन्न हो सकते हैं। यही कारण है कि लंबे समय तक इस्तेमाल किया गया था, फ़्लोटिंग पॉइंट चर नामांकित कारक को बेहतर ढंग से फिट करने के लिए । संकलक का उपयोग MinGW 2.95 है।
मोहम्मद एन्नहदी एल इदरीसी

1

हर कदम पर, दो मामले हैं

b> = a / 2, फिर a, b = b, एक% b अपने पिछले मूल्य के अधिकांश भाग में b बना देगा

बी </ 2, फिर ए, बी = बी, एक% बी अपने पिछले मूल्य के अधिकांश आधे पर बना देगा, क्योंकि बी एक / २ से कम है

तो हर कदम पर, एल्गोरिदम कम से कम एक संख्या को कम से कम आधा कम कर देगा।

अधिकांश ओ (लॉग ए) + ओ (लॉग बी) कदम में, यह सरल मामलों में कम हो जाएगा। जो O (लॉग एन) एल्गोरिथ्म का उत्पादन करता है, जहां n, a और b की ऊपरी सीमा है।

मैंने इसे यहां पाया है

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