व्यवहार्य दृष्टिकोण की एक विशाल विविधता है। जो सबसे उपयुक्त है वह निर्भर करता है
- जो आप दिखाना चाह रहे हैं,
- आपको कितना विवरण चाहिए या आवश्यकता है।
यदि एल्गोरिथ्म एक व्यापक रूप से ज्ञात है जिसे आप सबरूटीन के रूप में उपयोग करते हैं, तो आप अक्सर उच्च स्तर पर रहते हैं। यदि एल्गोरिथ्म जांच के तहत मुख्य वस्तु है, तो आप शायद अधिक विस्तृत होना चाहते हैं। विश्लेषण के लिए भी ऐसा ही कहा जा सकता है: यदि आपको किसी ऊपरी ऊपरी क्रम की आवश्यकता है तो जब आप बयानों की सटीक गणना चाहते हैं तो आप उससे अलग तरीके से आगे बढ़ते हैं।
मैं आपको प्रसिद्ध एल्गोरिथ्म मर्जेसॉर्ट के लिए तीन उदाहरण दूंगा जो उम्मीद करते हैं कि यह सचित्र है।
ऊँचा स्तर
एल्गोरिथ्म मर्जेसर्ट एक सूची लेता है, इसे दो (लगभग) समान रूप से लंबे हिस्सों में विभाजित करता है, उन आंशिक सूचियों पर पुनरावृत्ति करता है और विलय (हल) करता है ताकि अंतिम-परिणाम हल हो। सिंगलटन या रिक्त सूचियों पर, यह इनपुट लौटाता है।
यह एल्गोरिथ्म स्पष्ट रूप से एक सही सॉर्टिंग एल्गोरिथ्म है। सूची को विभाजित करना और इसे विलय करना प्रत्येक को समय में लागू किया जा सकता है , जो हमें सबसे खराब स्थिति रनटाइम टी ( एन ) = 2 टी ( एन ) के लिए पुनरावृत्ति देता हैΘ(n)। द्वारा मास्टर प्रमेय, को यह मूल्यांकन करता हैटी(एन)∈Θ(nलॉग इन करेंn)।T(n)=2T(n2)+Θ(n)T(n)∈Θ(nlogn)
मध्यम स्तर
एल्गोरिथ्म मर्ज्सर्ट निम्नलिखित छद्म कोड द्वारा दिया गया है:
procedure mergesort(l : List) {
if ( l.length < 2 ) {
return l
}
left = mergesort(l.take(l.length / 2)
right = mergesort(l.drop(l.length / 2)
result = []
while ( left.length > 0 || right.length > 0 ) {
if ( right.length == 0 || (left.length > 0 && left.head <= right.head) ) {
result = left.head :: result
left = left.tail
}
else {
result = right.head :: result
right = right.tail
}
}
return result.reverse
}
हम इंडक्शन द्वारा शुद्धता साबित करते हैं। लंबाई शून्य या एक की सूची के लिए, एल्गोरिथ्म तुच्छ रूप से सही है। प्रेरण परिकल्पना के रूप में, मान लें कि कुछ मनमाने ढंग से, लेकिन निश्चित प्राकृतिक n > 1 के लिए mergesortसबसे अधिक लंबाई की सूचियों पर सही ढंग से किया जाता है । अब L को लंबाई n + 1 की सूची दें । प्रेरण परिकल्पना द्वारा, और पहले सम्मान के छांटे गए (गैर-डिक्रिप्ट) छांटे गए संस्करण। पुनरावर्ती कॉल के बाद एल की दूसरी छमाही । इसलिए, लूप हर पुनरावृत्ति में चयन करता है सबसे छोटा तत्व जो अभी तक जांच नहीं किया गया है और इसे जोड़ता है ; इस प्रकार सभी तत्वों से युक्त एक गैर-तेजी से क्रमबद्ध सूची हैnn>1Ln+1leftrightLwhileresultresultleft और और right। रिवर्स L का एक गैर-डिक्रिप्टली सॉर्ट किया गया संस्करण हैL , जो लौटा है - और वांछित - परिणाम।
रनटाइम के लिए, आइए हम तत्वों की तुलना और सूची संचालन (जो कि रनटाइम पर विषमतापूर्वक हावी हो) की गणना करें। लंबाई की सूची न तो दो कारणों से कम है। लंबाई की सूची के लिए , हमारे पास पुनरावर्ती कॉल के लिए इनपुट तैयार करने के कारण होने वाले ऑपरेशन हैं, जो पुनरावर्ती कॉल से खुद को प्लस लूप और एक । दोनों पुनरावर्ती मापदंडों की गणना प्रत्येक n सूची संचालन में की जा सकती है। पाश वास्तव में क्रियान्वित किया जाता है n सबसे एक तत्व तुलना में कई बार और हर यात्रा का कारण बनता है और ठीक दो सूची आपरेशनों। 2 एन का उपयोग करने के लिए अंतिम लागू किया जा सकता हैn>1whilereversenwhilenreverse2nसूची संचालन - हर तत्व को इनपुट से हटा दिया जाता है और आउटपुट सूची में डाल दिया जाता है। इसलिए, ऑपरेशन गणना निम्न पुनरावृत्ति को पूरा करती है:
T(0)=T(1)T(n)=0≤T(⌈n2⌉)+T(⌊n2⌋)+7n
जैसा कि स्पष्ट रूप से कम नहीं है, यह एसिम्प्टोटिक विकास के लिए n = 2 k पर विचार करने के लिए पर्याप्त है । इस मामले में , पुनरावृत्ति सरल हो जाती हैTn=2k
T(0)=T(1)T(n)=0≤2T(n2)+7n
मास्टर प्रमेय के अनुसार, हम पाते हैं , जिनमें से क्रम तक फैली ।T∈Θ(nlogn)mergesort
अति निम्न स्तर
इसाबेल / एचओएल में मर्जेसर्ट के इस (सामान्यीकृत) कार्यान्वयन पर विचार करें :
types dataset = "nat * string"
fun leq :: "dataset \<Rightarrow> dataset \<Rightarrow> bool" where
"leq (kx::nat, dx) (ky, dy) = (kx \<le> ky)"
fun merge :: "dataset list \<Rightarrow> dataset list \<Rightarrow> dataset list" where
"merge [] b = b" |
"merge a [] = a" |
"merge (a # as) (b # bs) = (if leq a b then a # merge as (b # bs) else b # merge (a # as) bs)"
function (sequential) msort :: "dataset list \<Rightarrow> dataset list" where
"msort [] = []" |
"msort [x] = [x]" |
"msort l = (let mid = length l div 2 in merge (msort (take mid l)) (msort (drop mid l)))"
by pat_completeness auto
termination
apply (relation "measure length")
by simp+
इसमें पहले से ही अच्छी तरह से परिभाषित और समाप्ति के प्रमाण शामिल हैं। एक (लगभग) पूर्ण शुद्धता प्रमाण यहां खोजें ।
"रनटाइम" के लिए, जो तुलनाओं की संख्या है, पूर्व खंड में एक के समान पुनरावृत्ति स्थापित की जा सकती है। मास्टर प्रमेय का उपयोग करने और स्थिरांक को भूलने के बजाय, आप इसका अनुमान लगाने के लिए इसका विश्लेषण भी कर सकते हैं कि यह सत्यता की मात्रा के बराबर है। आप [1] में पूर्ण विश्लेषण पा सकते हैं; यहाँ एक कठिन रूपरेखा है (यह जरूरी नहीं कि इसाबेल / एचओएल कोड फिट हो):
जैसा कि ऊपर, तुलना की संख्या के लिए पुनरावृत्ति है
f0=f1fn=0=f⌈n2⌉+f⌊n2⌋+en
जहाँ आंशिक परिणाम को विलय करने के लिए आवश्यक तुलनाओं की संख्या है। मंजिलों और छतों से छुटकारा पाने के लिए, हम एक मामले में भेद करते हैं कि क्या n भी है:enn
{f2mf2m+1=2fm+e2m=fm+fm+1+e2m+1
नेस्ट का उपयोग कर आगे / पीछे मतभेद की और ई एन हमें वह समझfnen
।∑k=1n−1(n−k)⋅Δ∇fk=fn−nf1
यह राशि पेरोन के सूत्र के दाईं ओर से मेल खाती है । हम परिभाषित Dirichlet पैदा श्रृंखला की रूप मेंΔ∇fk
W(s)=∑k≥1Δ∇fkk−s=11−2−s⋅∑k≥1Δ∇ekks=: ⊟(s)
जो पेरोन के सूत्र के साथ मिलकर हमें आगे ले जाता है
।fn=nf1+n2πi∫3−i∞3+i∞⊟(s)ns(1−2−s)s(s+1)ds
का मूल्यांकन इस बात पर निर्भर करता है कि किस मामले का विश्लेषण किया गया है। उसके अलावा, हम कर सकते हैं - कुछ प्रवंचना के बाद - लागू अवशेषों प्रमेय पाने के लिए⊟(s)
fn∼n⋅log2(n)+n⋅A(log2(n))+1
जहाँ [ - 1 , - 0.9 ] में मानों के साथ एक आवधिक कार्य है ।A[−1,−0.9]
- मेलिन ट्रांसफॉर्म और एसिम्पोटिक्स: फ्लाजोलेट और गोलिन (1992) द्वारा मर्जोर्ट पुनरावृत्ति
- en=⌊n2⌋
en=n−1
en=n−⌊n2⌋⌈n2⌉+1−⌈n2⌉⌊n2⌋+1