বেস্ট, ওয়ার্স্ট ও অ্যাভারেজ কেস অ্যানালাইসিস
এই পাঠে যা শিখবেন
- বেস্ট, ওয়ার্স্ট, ও অ্যাভারেজ কেস কমপ্লেক্সিটির সুনির্দিষ্ট সংজ্ঞা ও একটি সাধারণ ভুল বোঝাবুঝি এড়ানো
- লিনিয়ার সার্চের অ্যাভারেজ-কেস সূত্র $\frac{n+1}{2}$ কীভাবে ডেরাইভ হয়, একটি ছোট সামেশন থেকে
- একটি বড়-স্কেল র্যান্ডম সিমুলেশন লিখে তাত্ত্বিক প্রত্যাশার সাথে এম্পিরিক্যাল ফলাফল মিলিয়ে দেখা
- কেন শুধু ওয়ার্স্ট-কেস দেখে একটি অ্যালগরিদমকে "খারাপ" বলে বাতিল করা সবসময় সঠিক সিদ্ধান্ত নয়
১ · তিনটি ভিন্ন প্রশ্ন, তিনটি ভিন্ন উত্তর
একই অ্যালগরিদম বিভিন্ন ইনপুটে ভিন্ন ভিন্ন সময় নিতে পারে — শুধু ইনপুট সাইজ $n$-এর উপর নয়, ইনপুটের গঠনের উপরও এটি নির্ভর করে। তাই একটি একক সংখ্যা দিয়ে "কমপ্লেক্সিটি" প্রকাশ করা অসম্পূর্ণ — বদলে আমরা তিনটি ভিন্ন প্রশ্ন জিজ্ঞাসা করি:
সবচেয়ে অনুকূল ইনপুটে সময় কত? — একটি নিচের সীমা, বাস্তবে খুব কমই ভরসাযোগ্য।
সবচেয়ে প্রতিকূল ইনপুটে সময় কত? — একটি গ্যারান্টি: "এর চেয়ে বেশি কখনো লাগবে না"।
সব সম্ভাব্য ইনপুটের উপর প্রত্যাশিত (expected) সময় কত? — বাস্তব ব্যবহারের সবচেয়ে কাছাকাছি চিত্র, কিন্তু ইনপুট ডিস্ট্রিবিউশনের একটি অনুমান দরকার।
লক্ষ্য করুন — অ্যাভারেজ কেস সংজ্ঞায়িত করতে হলে ইনপুটের উপর একটি সম্ভাব্যতা ডিস্ট্রিবিউশন ধরে নিতে হয়। এই পাঠে আমরা সবচেয়ে সাধারণ অনুমানটি ব্যবহার করব — সফল সার্চে লক্ষ্য এলিমেন্ট অ্যারের যেকোনো পজিশনে সমান সম্ভাবনায় (uniformly random) থাকতে পারে।
২ · লিনিয়ার সার্চ — তিনটি কেসের গণনা
লিনিয়ার সার্চ (দেখুন DSA কোর্স ইমপ্লিমেন্টেশনের বিস্তারিত জন্য) একটি অ্যারের প্রতিটি এলিমেন্ট একে একে পরীক্ষা করে, লক্ষ্য এলিমেন্ট পাওয়া গেলেই থেমে যায়। $n$ সাইজের একটি অ্যারেতে:
- বেস্ট কেস: লক্ষ্য এলিমেন্ট $\text{arr}[0]$-এ — মাত্র $1$টি তুলনা লাগে, $T_{best}(n) = O(1)$।
- ওয়ার্স্ট কেস: লক্ষ্য এলিমেন্ট $\text{arr}[n-1]$-এ, অথবা অ্যারেতে নেই — ঠিক $n$টি তুলনা লাগে, $T_{worst}(n) = \Theta(n)$।
- অ্যাভারেজ কেস: লক্ষ্য এলিমেন্ট যদি সমান সম্ভাবনায় $\text{arr}[0]$ থেকে $\text{arr}[n-1]$-এর যেকোনো পজিশনে থাকতে পারে, তাহলে পজিশন $i$ (0-ইনডেক্সড)-এ থাকলে ঠিক $i+1$টি তুলনা লাগে। প্রত্যাশিত মান:
$$E[\text{তুলনা}] = \sum_{i=0}^{n-1} \frac{1}{n}(i+1) = \frac{1}{n}\sum_{k=1}^{n} k = \frac{1}{n} \cdot \frac{n(n+1)}{2} = \frac{n+1}{2}$$
অর্থাৎ গড়ে অ্যারের ঠিক অর্ধেক স্ক্যান করতে হয় — একটি পরিষ্কার, ছোট সামেশন থেকে সরাসরি ডেরাইভ করা সূত্র। $n=50$ হলে এই সূত্র অনুযায়ী গড় $\frac{51}{2}=25.5$ হওয়ার কথা।
৩ · কোড সেল — এম্পিরিক্যাল গড় বনাম তাত্ত্বিক গড়
নিচের কোড সেলে $n=50$ সাইজের একটি অ্যারেতে ২ লক্ষ (200,000) স্বতন্ত্র র্যান্ডম ট্রায়াল চালানো হয়েছে — প্রতিবার একটি সমান-সম্ভাবনার লক্ষ্য এলিমেন্ট বেছে নিয়ে লিনিয়ার সার্চ চালিয়ে প্রকৃত তুলনার সংখ্যা গোনা হয়েছে, তারপর সব ট্রায়ালের গড় বের করা হয়েছে। এই এম্পিরিক্যাল গড়কে তাত্ত্বিক $\frac{n+1}{2}$-এর সাথে সরাসরি তুলনা করা হয়েছে।
import random
def linear_search(arr, target):
comparisons = 0
for i, x in enumerate(arr):
comparisons += 1
if x == target:
return i, comparisons
return -1, comparisons
rng = random.Random(42) # ফিক্সড সিড -- ফলাফল পুনরুৎপাদনযোগ্য
n = 50
arr = list(range(n))
trials = 200_000
total_comparisons = 0
for _ in range(trials):
target = rng.randrange(n) # প্রতিটি পজিশন সমান সম্ভাবনায় -- সফল সার্চ, লক্ষ্য সবসময় অ্যারেতে আছে
_, c = linear_search(arr, target)
total_comparisons += c
empirical_avg = total_comparisons / trials
theoretical_avg = (n + 1) / 2
print(f"n = {n}")
print(f"ট্রায়াল সংখ্যা: {trials:,}")
print(f"এম্পিরিক্যাল গড় তুলনার সংখ্যা: {empirical_avg:.4f}")
print(f"তাত্ত্বিক গড় (n+1)/2 = {theoretical_avg:.4f}")
print(f"পার্থক্য: {abs(empirical_avg - theoretical_avg):.4f}")
# --- বেস্ট ও ওয়ার্স্ট কেস সরাসরি দেখা ---
_, best_c = linear_search(arr, arr[0])
_, worst_c = linear_search(arr, arr[-1])
_, notfound_c = linear_search(arr, n) # n অ্যারেতে নেই -- অনুপস্থিত এলিমেন্ট
print(f"\nবেস্ট কেস (arr[0] খোঁজা): {best_c} তুলনা")
print(f"ওয়ার্স্ট কেস (arr[-1] খোঁজা): {worst_c} তুলনা")
print(f"ওয়ার্স্ট কেস (অনুপস্থিত এলিমেন্ট খোঁজা): {notfound_c} তুলনা")
ওয়ার্স্ট-কেস কমপ্লেক্সিটি একটি গ্যারান্টি দেয়, কিন্তু বাস্তব কর্মক্ষমতার পুরো ছবি দেয় না। লিনিয়ার সার্চের ওয়ার্স্ট কেস ও অ্যাভারেজ কেস দুটোই $\Theta(n)$ (গ্রোথ ক্লাস একই), কিন্তু ধ্রুবক গুণিতকে পার্থক্য আছে ($n$ বনাম $n/2$)। L16-এ আমরা দেখব কুইকসর্টে এই পার্থক্য আরও নাটকীয় — ওয়ার্স্ট কেস $\Theta(n^2)$ হলেও অ্যাভারেজ কেস $\Theta(n\log n)$, সম্পূর্ণ ভিন্ন গ্রোথ ক্লাস।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১
উপরের সিমুলেশনে trials = 200_000-এর বদলে trials = 10 ব্যবহার করলে
এম্পিরিক্যাল গড় কি এখনও $25.5$-এর কাছাকাছি থাকবে বলে আপনার ধারণা?
না, সম্ভবত না। মাত্র $10$টি ট্রায়ালে র্যান্ডম ওঠানামা (variance) অনেক বড় ভূমিকা রাখবে — গড় $25.5$ থেকে অনেক দূরে হতে পারে, নিছক দুর্ঘটনাক্রমে। এটিই "বড় সংখ্যার সূত্র" (law of large numbers)-এর একটি ব্যবহারিক প্রদর্শনী — ট্রায়াল সংখ্যা যত বাড়ে, এম্পিরিক্যাল গড় তত্ত্বীয় প্রত্যাশিত মানের তত কাছাকাছি চলে আসে। এই কারণেই এই পাঠে ইচ্ছাকৃতভাবে $200{,}000$-এর মতো বড় সংখ্যক ট্রায়াল ব্যবহার করা হয়েছে, মাত্র কয়েকটি নয়।
প্র ০২ যদি লক্ষ্য এলিমেন্ট অ্যারেতে নাই এমন সব সার্চের কথা ভাবি (সবসময় ব্যর্থ সার্চ), তাহলে "অ্যাভারেজ কেস" ধারণাটি কি অর্থবহ থাকে?
এই নির্দিষ্ট সংস্করণে না — যদি লক্ষ্য এলিমেন্ট সবসময় অনুপস্থিত থাকে, তাহলে প্রতিটি ট্রায়ালেই পুরো অ্যারে স্ক্যান করতে হবে ($n$টি তুলনা), তাই "গড়" আর "ওয়ার্স্ট কেস"-এর মধ্যে কোনো পার্থক্যই থাকবে না — উভয়ই সবসময় $n$। "অ্যাভারেজ কেস" ধারণাটি অর্থবহ হয় তখনই যখন ইনপুটের মধ্যে বৈচিত্র্য থাকে (যেমন এখানে লক্ষ্যের পজিশন পরিবর্তিত হয়) — একটি নির্দিষ্ট, সবসময় ঘটা দৃশ্যপটের কোনো "গড়" ধারণা নেই, সেটিই তখন একমাত্র কেস।
প্র ০৩
উপরের কোডে random.Random(42) (একটি লোকাল, ফিক্সড-সিড জেনারেটর) ব্যবহার করা হয়েছে,
গ্লোবাল random.seed(42)-এর বদলে — এর সুবিধা কী?
random.Random(42) একটি স্বতন্ত্র, স্বয়ংসম্পূর্ণ র্যান্ডম-নাম্বার-জেনারেটর অবজেক্ট তৈরি করে,
যা প্রোগ্রামের বাকি অংশের গ্লোবাল random স্টেট থেকে সম্পূর্ণ আলাদা থাকে। এর মানে এই সিমুলেশনের
ফলাফল অন্য কোনো কোড সেল বা লাইব্রেরি গ্লোবাল random স্টেট পরিবর্তন করলেও প্রভাবিত হবে না —
এটি বড়, বহু-অংশের প্রোগ্রামে reproducibility নিশ্চিত করার একটি নিরাপদ অভ্যাস, যা M12-এর র্যান্ডোমাইজড
অ্যালগরিদম অধ্যায়ে বারবার ব্যবহৃত হবে।
অনুশীলন
-
চিন্তা করুন: যদি $n=200$ ব্যবহার করা হতো, তাত্ত্বিক অ্যাভারেজ-কেস তুলনার সংখ্যা কত হবে
বলে আপনার ধারণা?
$\frac{n+1}{2} = \frac{201}{2} = 100.5$। সূত্রটি যেকোনো $n$-এর জন্য একইভাবে প্রযোজ্য — শুধু $n$-এর মান বসিয়ে দিলেই হয়।
-
পরীক্ষা করুন: উপরের কোড সেলে
n = 50-কেn = 200দিয়ে বদলে চালিয়ে দেখুন — এম্পিরিক্যাল গড় কি $100.5$-এর কাছাকাছি আসে?হ্যাঁ — $200{,}000$ ট্রায়ালে এম্পিরিক্যাল গড় $100.5$-এর খুব কাছাকাছি আসবে (সাধারণত $\pm 0.1$-এর মধ্যে), ঠিক যেমন $n=50$-এর ক্ষেত্রে $25.5$-এর কাছাকাছি এসেছিল। এটি নিশ্চিত করে যে সূত্র $\frac{n+1}{2}$ শুধু $n=50$-এর জন্য নয়, সাধারণভাবে যেকোনো $n$-এর জন্যই সঠিক।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ অ্যাসিম্পটোটিক অ্যানালাইসিস, রিকারেন্স, ডিভাইড অ্যান্ড কনকার, গ্রিডি, DP, গ্রাফ অ্যালগরিদম, ব্যাকট্র্যাকিং, স্ট্রিং অ্যালগরিদম, অ্যামর্টাইজড অ্যানালাইসিস, NP-কমপ্লিটনেস ও অ্যাপ্রক্সিমেশন — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
- Data Structures & Algorithms কোর্স সহোদর কোর্স লিনিয়ার সার্চ ও অন্যান্য সার্চিং অ্যালগরিদমের ইমপ্লিমেন্টেশন বিস্তারিত সেই কোর্সে দেখুন।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks, Mobile App Development, Ethics in Computing & AI Safety, Software Testing & Quality Assurance ও Design and Analysis of Algorithms — সব এক জায়গায়।