পাঠ ০৬ · ৫৭-এর মধ্যে · মডিউল ২

Big-O, Big-Omega ও Big-Theta

The formal definitions of O, Ω, and Θ notation
১০ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • $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$।

দাবি f(n) = O(g(n)) c, n₀ বাছাই (অনুমান/গণনা) যাচাই সব n≥n₀-এ f(n)≤c·g(n)? সিদ্ধান্ত বাউন্ড সঠিক?
একটি O-বাউন্ড claim প্রমাণ করতে হলে অন্তত একটি বৈধ (c, n₀) জোড়া দেখানো যথেষ্ট — তারপর সেই জোড়া দিয়ে ইনইকুয়ালিটি সব n ≥ n₀-এ সত্য থাকে কিনা যাচাই করতে হয়।

২ · 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))$$

O — উপরের সীমা
"সবচেয়ে খারাপ হলেও এর চেয়ে ধীরে বাড়বে না" — 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)$ শ্রেণির নয়।

Python
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}")

    
আউটপুট দেখাচ্ছে $c=10, n_0=1$ জোড়াটি $f(n)=3n^2+5n+2$-এর জন্য বৈধ (কারণ $n=1$-এ ratio $\frac{f(n)}{g(n)}$ সবচেয়ে বেশি — ঠিক $10$ — এবং $n$ বাড়ার সাথে সাথে এই অনুপাত $3$-এর দিকে কমতে থাকে, তাই $c=10$ সব $n \ge 1$-এ নিরাপদ)। কিন্তু $f(n)=n^2$-কে $O(n)$ দাবি করে $c=10$ ব্যবহার করলে, $n=1$ থেকে $n=10$ পর্যন্ত ইনইকুয়ালিটি সত্য থাকলেও ($n \le 10$ হলে $n^2 \le 10n$), $n=11$-এই এটি ভেঙে যায় ($121 > 110$) এবং এরপর আর কখনো ফিরে আসে না — কারণ $n^2/n = n$ যা $n \to \infty$ হলে অসীমের দিকে যায়। এখানে $c$ যত বড়ই নেওয়া হোক না কেন, একই ঘটনা ঘটবে, শুধু ব্যর্থতার বিন্দু পিছিয়ে যাবে — কোনো সসীম $c$-ই কখনো কাজ করবে না। এটিই প্রমাণ করে $n^2 \ne O(n)$।
মূল কথা · Key takeaway

একটি 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)$-এর প্রকৃত, টাইট গ্রোথ ক্লাস।

অনুশীলন

  1. চিন্তা করুন: $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$-এও ইনইকুয়ালিটি সত্য থাকে।

  2. পরীক্ষা করুন: উপরের কোড সেলে 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 — সব এক জায়গায়।
আগের পাঠ
ফাংশনের গ্রোথ রেট