Big-O, Big-Omega ও Big-Theta
এই পাঠে যা শিখবেন
- $O$, $\Omega$, $\Theta$-এর সঠিক, আনুষ্ঠানিক ($\exists c, n_0$-ভিত্তিক) সংজ্ঞা
- একটি O-বাউন্ড claim যাচাই করতে ঠিক কী প্রমাণ করতে হয় — এবং কীভাবে তা কম্পিউটেশনালি পরীক্ষা করা যায়
- কেন "$c$-এর জন্য কোনো একটি মান কাজ করলেই যথেষ্ট" — $c$ যত ইচ্ছা বড় হতে পারে, কিন্তু তা অবশ্যই $n$-নির্ভর নয়
- একটি ভুল দাবি ($n^2 = O(n)$) কেন কোনো $c$-এর জন্যই কাজ করে না, তা কম্পিউটেশনালি প্রত্যক্ষ করা
১ · Big-O — আনুষ্ঠানিক সংজ্ঞা
$$f(n) = O(g(n)) \iff \exists\, c > 0,\ n_0 > 0 \text{ এমন যে } 0 \le f(n) \le c \cdot g(n) \text{ সব } n \ge n_0\text{-এর জন্য}$$
এই সংজ্ঞার প্রতিটি অংশ গুরুত্বপূর্ণ। $\exists c, n_0$ মানে — এমন অন্তত একটি জোড়া $(c, n_0)$ পাওয়া গেলেই দাবিটি সত্য, একাধিক জোড়া থাকতে পারে এবং তাদের মধ্যে "সবচেয়ে ভালো" কোনোটি খোঁজার দরকার নেই। $n \ge n_0$ মানে — ছোট $n$-এ (যেমন $n < n_0$) ইনইকুয়ালিটি ভাঙলেও কোনো সমস্যা নেই; শুধু $n_0$-এর পর থেকে সবসময় সত্য থাকতে হবে। এটিই আসলে L05-এ আমরা কম্পিউটেশনালি যা খুঁজেছিলাম তার আনুষ্ঠানিক রূপ — "স্থায়ী ক্রসওভার পয়েন্ট" হলো ঠিক এই $n_0$।
২ · Big-Omega ও Big-Theta
$\Omega$ (নিচের সীমা) এবং $\Theta$ (টাইট বাউন্ড) একইভাবে সংজ্ঞায়িত, শুধু ইনইকুয়ালিটির দিক পাল্টায়:
$$f(n) = \Omega(g(n)) \iff \exists\, c > 0,\ n_0 > 0 \text{ এমন যে } 0 \le c \cdot g(n) \le f(n) \text{ সব } n \ge n_0\text{-এর জন্য}$$
$$f(n) = \Theta(g(n)) \iff \exists\, c_1, c_2 > 0,\ n_0 > 0 \text{ এমন যে } c_1 \cdot g(n) \le f(n) \le c_2 \cdot g(n) \text{ সব } n \ge n_0\text{-এর জন্য}$$
$\Omega(g(n))$ মানে $f(n)$ কমপক্ষে $g(n)$-এর সমান দ্রুত বাড়ে (একটি ধ্রুবক গুণিতক পর্যন্ত) — এটি $O$-এর আয়না-প্রতিবিম্ব। আর $\Theta(g(n))$ মানে $f(n)$ ঠিক $g(n)$-এর সমান গ্রোথ ক্লাসে আটকে আছে, উপরে ও নিচে দুই দিক থেকেই। একটি গুরুত্বপূর্ণ সমতুল্যতা মনে রাখার মতো:
$$f(n) = \Theta(g(n)) \iff f(n) = O(g(n)) \text{ এবং } f(n) = \Omega(g(n))$$
"সবচেয়ে খারাপ হলেও এর চেয়ে ধীরে বাড়বে না" — worst-case guarantee।
"সবচেয়ে ভালো হলেও এর চেয়ে দ্রুত বাড়তে পারবে না" — একটি lower bound guarantee।
উপরে ও নিচে দুই দিকেই বাঁধা — প্রকৃত গ্রোথ ক্লাস, সবচেয়ে তথ্যবহুল দাবি।
৩ · কোড সেল — একটি বৈধ (c, n₀) কম্পিউটেশনালি খুঁজে বের করা
নিচের কোড সেলে দুটি কাজ করা হয়েছে। প্রথমত, $f(n) = 3n^2 + 5n + 2$ যে $O(n^2)$ তার একটি বৈধ $(c, n_0)$ জোড়া কম্পিউটেশনালি খোঁজা হয়েছে ($c=1$ থেকে শুরু করে ছোট থেকে বড় দিকে পরীক্ষা করে)। দ্বিতীয়ত, একটি ভুল দাবি — $f(n) = n^2$ হলো $O(n)$ — পরীক্ষা করে দেখানো হয়েছে $c=10$-এর মতো "প্রথম দেখায় যুক্তিসঙ্গত" একটি ধ্রুবকও ছোট $n$-এ কাজ করলেও বড় $n$-এ স্থায়ীভাবে ব্যর্থ হয় — কারণ $n^2$ আসলে $O(n)$ শ্রেণির নয়।
def f_quad(n):
return 3 * n**2 + 5 * n + 2
def g_quad(n):
return n ** 2
def check_bound(f, g, c, n0, test_range):
"""f(n) <= c*g(n) সব n in test_range (n >= n0) -তে সত্য কিনা যাচাই করে;
ব্যর্থ হলে প্রথম ব্যর্থ n সহ রিপোর্ট করে।"""
failures = [n for n in test_range if n >= n0 and f(n) > c * g(n)]
return (len(failures) == 0), (failures[0] if failures else None)
test_ns = range(1, 1001)
# --- ধাপ ১: সঠিক দাবি -- f(n)=3n^2+5n+2 হলো O(n^2); n0=1 ধরে বৈধ c খোঁজা ---
n0 = 1
best_c = None
for c_candidate in range(1, 21):
ok, _ = check_bound(f_quad, g_quad, c_candidate, n0, test_ns)
if ok:
best_c = c_candidate
break
print("claim: f(n) = 3n^2 + 5n + 2 হলো O(n^2)")
print(f"কম্পিউটেশনালি খুঁজে পাওয়া বৈধ (c, n0): (c={best_c}, n0={n0})")
ok, _ = check_bound(f_quad, g_quad, best_c, n0, test_ns)
print(f"n=1 থেকে 1000 পর্যন্ত সব n-এ f(n) <= {best_c}*g(n) সত্য? {ok}")
# --- ধাপ ২: ভুল দাবি -- f(n)=n^2 হলো O(n) দাবি করলে কী হয় ---
def f_sq(n):
return n ** 2
def g_lin(n):
return n
wrong_c = 10
ok2, fail_n2 = check_bound(f_sq, g_lin, wrong_c, 1, test_ns)
print(f"\nভুল claim: f(n) = n^2 হলো O(n), c={wrong_c} দিয়ে চেষ্টা:")
print(f"n=1 থেকে 1000 পর্যন্ত সব n-এ f(n) <= {wrong_c}*g(n) সত্য? {ok2}")
print(f"প্রথম যে n-এ ব্যর্থ হয়: n = {fail_n2} "
f"(f({fail_n2})={f_sq(fail_n2)}, {wrong_c}*g({fail_n2})={wrong_c * g_lin(fail_n2)})")
still_failing = all(f_sq(n) > wrong_c * g_lin(n) for n in range(fail_n2, fail_n2 + 20))
print(f"n={fail_n2} থেকে {fail_n2 + 19} পর্যন্ত পরের ২০টি n-ও কি ব্যর্থ থাকে? {still_failing}")
একটি O-বাউন্ড প্রমাণ করতে একটি বৈধ $(c, n_0)$ দেখালেই যথেষ্ট — কিন্তু একটি O-বাউন্ড ভুল প্রমাণ করতে হলে দেখাতে হবে যে কোনো $(c, n_0)$-ই কাজ করে না, যা সাধারণত সীমা ($\lim_{n\to\infty} f(n)/g(n)$) ব্যবহার করে করা সহজ — ঠিক পরের পাঠ (L07)-এ আমরা যা শিখব।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ উপরের কোডে $(c=10, n_0=1)$ ছাড়াও কি $f(n)=3n^2+5n+2 = O(n^2)$-এর জন্য অন্য কোনো বৈধ $(c, n_0)$ জোড়া থাকতে পারে?
হ্যাঁ, অসংখ্য। উদাহরণস্বরূপ $(c=100, n_0=1)$ও বৈধ (যেহেতু $c=10$ কাজ করলে যেকোনো বড় $c$-ও কাজ করবে)। এমনকি $(c=4, n_0=100)$-ও বৈধ হতে পারে, কারণ $n_0$ বড় হলে ratio $\frac{f(n)}{g(n)} = 3+\frac{5}{n}+\frac{2}{n^2}$ আরও $3$-এর কাছাকাছি চলে আসে, তাই ছোট $c$-ও তখন যথেষ্ট। সংজ্ঞা অনুযায়ী অন্তত একটি জোড়া পাওয়া গেলেই দাবিটি সত্য — "সবচেয়ে টাইট" জোড়া খোঁজার কোনো বাধ্যবাধকতা নেই।
প্র ০২ যদি $c=10$-এর বদলে $c=1{,}000{,}000$ ব্যবহার করে $f(n)=n^2 = O(n)$ যাচাই করতাম, তাহলে কি ফলাফল পাল্টে যেত?
না, শুধু ব্যর্থতার বিন্দু অনেক পরে সরে যেত ($n=1{,}000{,}001$-এর কাছাকাছি), কিন্তু ব্যর্থতা এড়ানো যেত না। যেহেতু $n^2/n=n$ অসীমের দিকে যায়, যেকোনো সসীম $c$-এর জন্য একটি $n$ পাওয়া যাবে যেখানে $n > c$, আর তখনই $n^2 > c \cdot n$ হয়ে যাবে। এই কারণেই $n^2 \ne O(n)$ — কোনো ধ্রুবক $c$-ই "যথেষ্ট বড়" নয়, কারণ $n$ নিজেই অসীম পর্যন্ত বাড়তে পারে।
প্র ০৩ $f(n) = 3n^2 + 5n + 2$ কি $\Omega(n^2)$-ও বটে? আর তাই কি $\Theta(n^2)$?
হ্যাঁ। $c_1=1$ এবং $n_0=1$ নিলে $1 \cdot n^2 \le 3n^2+5n+2$ সব $n \ge 1$-এ স্পষ্টতই সত্য (যেহেতু $2n^2+5n+2 \ge 0$ সবসময়)। যেহেতু $f(n)$ একই সাথে $O(n^2)$ (উপরের কোড সেলে দেখানো হয়েছে, $c_2=10$) এবং $\Omega(n^2)$ ($c_1=1$), তাই সংজ্ঞা অনুযায়ী $f(n) = \Theta(n^2)$ — এটিই $f(n)$-এর প্রকৃত, টাইট গ্রোথ ক্লাস।
অনুশীলন
-
চিন্তা করুন: $f(n) = 100n + 50$ হলো $O(n)$ প্রমাণ করতে $n_0=1$ ধরলে সবচেয়ে ছোট পূর্ণসংখ্যা
$c$ কত হবে বলে আপনার ধারণা?
$c=150$। কারণ ratio $\frac{100n+50}{n} = 100+\frac{50}{n}$, যা $n=1$-এ সর্বোচ্চ মান $150$ নেয় এবং $n$ বাড়ার সাথে সাথে $100$-এর দিকে কমতে থাকে। তাই $n_0=1$ ধরলে $c$-কে কমপক্ষে $150$ হতে হবে যেন $n=1$-এও ইনইকুয়ালিটি সত্য থাকে।
-
পরীক্ষা করুন: উপরের কোড সেলে
f_quad-কেdef f_quad(n): return 100*n + 50এবংg_quad-কেdef g_quad(n): return nদিয়ে বদলে চালিয়ে দেখুন — খুঁজে পাওয়াbest_cকি আপনার অনুমানের সাথে মেলে?হ্যাঁ, কোড
best_c = 150খুঁজে বের করবে (যদি লুপের সীমাrange(1, 21)-এর বদলেrange(1, 200)-এর মতো যথেষ্ট বড় করা হয়) — ঠিক আগের প্রশ্নের হাতে-করা হিসাবের সাথে মিলে যাবে। এটিই দেখায় কম্পিউটেশনাল যাচাই ও হাতে-করা বীজগণিত সবসময় একই উত্তরে পৌঁছায়।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ অ্যাসিম্পটোটিক অ্যানালাইসিস, রিকারেন্স, ডিভাইড অ্যান্ড কনকার, গ্রিডি, DP, গ্রাফ অ্যালগরিদম, ব্যাকট্র্যাকিং, স্ট্রিং অ্যালগরিদম, অ্যামর্টাইজড অ্যানালাইসিস, NP-কমপ্লিটনেস ও অ্যাপ্রক্সিমেশন — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
- Discrete Mathematics কোর্স সহোদর কোর্স লিমিট, সামেশন ও প্রমাণ কৌশল (ইনডাকশন, কন্ট্রাডিকশন) নিয়ে ভিত্তি সেই কোর্সে দেখুন — এই পাঠের ঔপচারিক সংজ্ঞাগুলোর পেছনের গণিত।
- সব 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 — সব এক জায়গায়।