সেরা, গড় ও সবচেয়ে খারাপ কেস বিশ্লেষণ
এই পাঠে যা শিখবেন
- best/average/worst case-এর সঠিক গাণিতিক সংজ্ঞা
- linear search-এর তিনটি কেসই হাতে-কলমে ডেরাইভ করা, বিশেষ করে গড় কেসের সূত্র $(n+1)/2$
- কেন worst-case বিশ্লেষণ শিল্পে সবচেয়ে বেশি প্রচলিত
- quicksort-এর মাধ্যমে দেখা যে average ও worst case সম্পূর্ণ ভিন্ন জটিলতা ক্লাসের হতে পারে
- Python কোডে সব সম্ভাব্য টার্গেট পজিশনের উপর লুপ করে তিনটি কেসই সরাসরি গণনা করা
১ · তিনটি সংজ্ঞা
একটি অ্যালগরিদমের জটিলতা বলতে সবসময় একটি একক সংখ্যা বোঝায় না — কারণ একই ইনপুট সাইজ $n$-এর হাজারো ভিন্ন ইনপুট থাকতে পারে, এবং অ্যালগরিদম তাদের প্রতিটিতে ভিন্ন সংখ্যক ধাপ নিতে পারে। তাই তিনটি ভিন্ন প্রশ্ন জিজ্ঞাসা করা হয়:
সাইজ n-এর সব ইনপুটের মধ্যে সবচেয়ে কম ধাপ কোন ইনপুটে লাগে।
সাইজ n-এর সব ইনপুটের মধ্যে সবচেয়ে বেশি ধাপ কোন ইনপুটে লাগে।
একটি ইনপুট বিতরণ (সাধারণত uniform random) ধরে নিয়ে প্রত্যাশিত (expected) ধাপ সংখ্যা।
২ · ওয়ার্কড উদাহরণ — Linear Search
ধরুন একটি $n$ সাইজের array-এ (কোনো নির্দিষ্ট ক্রম ছাড়াই) একটি টার্গেট মান খুঁজছি, একে একে প্রতিটি এলিমেন্ট চেক করে (linear search)।
- Best case: টার্গেট প্রথম এলিমেন্টেই পাওয়া গেল — মাত্র ১ তুলনা — $\Theta(1)$।
- Worst case: টার্গেট শেষ এলিমেন্টে (অথবা array-তে নেইই) — পুরো $n$টি তুলনা — $\Theta(n)$।
- Average case: ধরি টার্গেট অবশ্যই array-তে আছে, এবং এটি সমান সম্ভাব্যতায় (uniformly random) যেকোনো অবস্থানে থাকতে পারে ($1$ থেকে $n$)। তাহলে প্রত্যাশিত তুলনা সংখ্যা: $$E[\text{comparisons}] = \frac{1+2+\cdots+n}{n} = \frac{n(n+1)/2}{n} = \frac{n+1}{2}$$ n=10-এ এটি $\frac{11}{2}=5.5$ — অর্থাৎ গড়ে সাড়ে পাঁচটি তুলনা লাগবে।
গড় কেস ($\Theta(n)$, কনস্ট্যান্ট $\approx 0.5$) এখানে worst case-এর ($\Theta(n)$, কনস্ট্যান্ট $1$) সাথে একই জটিলতা ক্লাসে পড়ে — শুধু কনস্ট্যান্ট ফ্যাক্টর ভিন্ন (অর্ধেক)। উভয়ই লিনিয়ার — একটি গুণগতভাবে দ্রুততর ক্লাস নয়।
def comparisons_to_find(target_pos, n):
# টার্গেট target_pos (0-ইনডেক্সড) অবস্থানে থাকলে, তা খুঁজে পেতে ঠিক (target_pos + 1)টি তুলনা লাগে
return target_pos + 1
n = 10
all_counts = [comparisons_to_find(pos, n) for pos in range(n)]
best = min(all_counts)
worst = max(all_counts)
average = sum(all_counts) / n
print("সব অবস্থানে তুলনা সংখ্যা:", all_counts)
print("Best case :", best)
print("Worst case :", worst)
print("Average :", average)
# হাতে-হিসাবের সূত্র (n+1)/2-এর সাথে মিলিয়ে দেখা
formula_average = (n + 1) / 2
print("সূত্র (n+1)/2 থেকে:", formula_average)
assert average == formula_average, "গড় সূত্রের সাথে মিলছে না!"
print("যাচাই সম্পন্ন — কোড ও সূত্র হুবহু মিলে গেছে।")
৩ · কেন Worst Case সবচেয়ে বেশি ব্যবহৃত হয়
শিল্পে, গবেষণাপত্রে, এবং টেক ইন্টারভিউয়ে যখন কারো "জটিলতা" জিজ্ঞাসা করা হয়, প্রায় সবসময় worst-case বোঝানো হয়। তিনটি কারণ —
- এটি একটি গ্যারান্টি: "এই অ্যালগরিদম কখনোই এর চেয়ে বেশি সময় নেবে না" — এটি একটি নিশ্চিত প্রতিশ্রুতি।
- বিতরণ-নিরপেক্ষ: Average case বের করতে ইনপুটের সম্ভাব্যতা বিতরণ সম্পর্কে একটি অনুমান লাগে (এখানে "uniform random"), যা বাস্তবে সবসময় সত্য নাও হতে পারে। Worst case কোনো অনুমান ছাড়াই সংজ্ঞায়িত।
- নিরাপত্তা-সংবেদনশীল সিস্টেমে জরুরি: একটি বিমান নিয়ন্ত্রণ সিস্টেম বা রিয়েল-টাইম সিস্টেমে "গড়ে দ্রুত" যথেষ্ট নয় — সবচেয়ে খারাপ পরিস্থিতিতেও সময়সীমা মানতে হবে।
৪ · একটি গুরুত্বপূর্ণ ব্যতিক্রম — Quicksort
Quicksort (DSA কোর্সে বিস্তারিত) একটি চমৎকার উদাহরণ যেখানে average ও worst case শুধু কনস্ট্যান্ট নয়, সম্পূর্ণ ভিন্ন জটিলতা ক্লাসের:
- Worst case: $\Theta(n^2)$ — যখন ইনপুট ইতিমধ্যে সাজানো এবং pivot সবসময় সবচেয়ে ছোট/বড় এলিমেন্ট বাছাই করা হয় (naive pivot choice)।
- Average case: $\Theta(n \log n)$ — random বা typical ইনপুটে, যা একই ক্লাসে যেখানে merge sort পড়ে।
এই পার্থক্যই দেখায় কেন "average case" শুধু একটি ছোট অলংকরণ নয় — এটি মাঝে মাঝে একটি অ্যালগরিদমকে ব্যবহারিকভাবে চমৎকার (কারণ worst case বিরল) বনাম সম্পূর্ণ অচল প্রমাণ করতে পারে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ "Average case" বিশ্লেষণ কেন worst-case বিশ্লেষণের চেয়ে গাণিতিকভাবে বেশি কঠিন বলে মনে করা হয়?
Worst case বের করতে শুধু "সবচেয়ে খারাপ সম্ভাব্য ইনপুট কোনটি" খুঁজলেই চলে — একটি সর্বোচ্চকরণ (maximization) সমস্যা। Average case বের করতে প্রথমে ইনপুটের উপর একটি সম্ভাব্যতা বিতরণ ধরে নিতে হয় (এখানে uniform, কিন্তু বাস্তবে সবসময় জানা থাকে না), তারপর সেই বিতরণের অধীনে expected value গণনা করতে হয় — যা প্রায়ই আরও জটিল যোগফল/ইন্টিগ্রাল প্রয়োজন করে।
প্র ০২ Quicksort ছাড়া, average ও worst case ভিন্ন জটিলতা ক্লাসের হতে পারে এমন আরেকটি বাস্তব পরিস্থিতি চিন্তা করুন।
একটি ভালো উদাহরণ হলো hash table lookup: average case $\Theta(1)$ (হ্যাশ ফাংশন সমানভাবে এলিমেন্ট ছড়িয়ে দিলে), কিন্তু worst case $\Theta(n)$ (যদি সব এলিমেন্ট একই hash bucket-এ collision করে, যা একটি খারাপভাবে ডিজাইন করা হ্যাশ ফাংশন বা বিরূপ (adversarial) ইনপুটে ঘটতে পারে)। এটিই কেন ভালো হ্যাশ ফাংশন ডিজাইন এত গুরুত্বপূর্ণ।
প্র ০৩ বাইনারি সার্চে best/average/worst case কি linear search-এর মতোই "একই ক্লাস, ভিন্ন কনস্ট্যান্ট" নাকি গুণগতভাবে ভিন্ন?
বাইনারি সার্চে সেরা কেস $\Theta(1)$ (টার্গেট ঠিক মাঝখানের এলিমেন্ট), কিন্তু average ও worst case উভয়ই $\Theta(\log n)$ — একই ক্লাস, এমনকি কনস্ট্যান্ট ফ্যাক্টরও কাছাকাছি (যেহেতু প্রতিটি ধাপ নিশ্চিতভাবে সমস্যা অর্ধেক করে দেয়, ইনপুট যাই হোক)। এখানে linear search-এর মতো best ও worst-এর মধ্যে $\Theta(1)$ বনাম $\Theta(n)$-এর মতো ব্যাপক ফারাক নেই — কারণ বাইনারি সার্চের গঠনই ইনপুট-নিরপেক্ষভাবে অনুমানযোগ্য।
অনুশীলন
-
পরিবর্তন করুন: কোড সেলে
n = 20করে Run চাপুন। গড় কেস কী হবে, আগে থেকে অনুমান করুন, তারপর কোড চালিয়ে মিলিয়ে দেখুন।সূত্র অনুযায়ী $(n+1)/2 = 21/2 = 10.5$। কোড ঠিক এই মানই দেখাবে — n যত বড় হবে, গড় কেসও সেই অনুপাতে বাড়বে, কারণ এটি সবসময় $n$-এর একটি লিনিয়ার ফাংশন।
-
চিন্তা করুন: এমন একটি বাস্তব সফটওয়্যার সিস্টেমের কথা ভাবুন যেখানে "গড়ে দ্রুত" যথেষ্ট নয়, worst-case গ্যারান্টিই আসল প্রয়োজন। কেন?
উদাহরণ: একটি পেসমেকার বা বিমানের অটোপাইলট সিস্টেম, বা একটি অনলাইন পেমেন্ট গেটওয়ে যার একটি কড়া টাইমআউট আছে। এসব ক্ষেত্রে "৯৯% সময়ে দ্রুত, ১% সময়ে অনেক ধীর" গ্রহণযোগ্য নয় — একটিমাত্র worst-case ব্যর্থতা বিপর্যয়কর হতে পারে, তাই ডিজাইনাররা worst-case জটিলতার উপর ভিত্তি করেই সিদ্ধান্ত নেন।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৪৪টি পাঠ পরবর্তী পাঠ — রিকার্সিভ অ্যালগরিদমের জটিলতা — M6-এর রিকারেন্স গণিতকে এখানে প্রয়োগ করবে।
- পরবর্তী পাঠ L41 রিকার্সিভ অ্যালগরিদমের জটিলতা — Master Theorem ও ক্যারেক্টারিস্টিক ইকুয়েশনের বাস্তব প্রয়োগ।
- Data Structures & Algorithms কোর্স সঙ্গী কোর্স Quicksort-এর পূর্ণ বাস্তবায়ন ও pivot নির্বাচনের কৌশল দেখতে DSA কোর্সটি দেখুন।