সরাসরি পর্বে যান
পর্ব ৪৩ · ৮৩-এর মধ্যে · মডিউল ৭

Probabilistic method আর randomized algorithm

The Probabilistic Method and Randomized Algorithms — Las Vegas and Monte Carlo, Freivalds, Schwartz–Zippel, Karger's Min Cut, Erdős's Ramsey Bound, MAX-CUT and MAX-3SAT

Taught in Bangla, this lesson separates Las Vegas from Monte Carlo algorithms and shows how repetition shrinks one-sided error. It proves the expected comparisons of randomized quickselect, Freivalds's error bound of at most 1/2 per round, the one-variable case of Schwartz–Zippel and Karger's 2/(n(n - 1)) min cut bound. The probabilistic method then gives Erdős's Ramsey lower bound, MAX-CUT of at least m/2 and the 7/8 MAX-3SAT guarantee, all checked in in-page Python by seeded simulation and exact Fraction counts.

এই পর্বে যা শিখবেন

  • Las Vegas আর Monte Carlo algorithm আলাদা করা, আর one-sided error কমাতে বারবার চালানোর হিসাব
  • Randomized quickselect-এর প্রত্যাশিত তুলনা ≤ 8n, আর Freivalds-এর ভুলের সীমা ≤ 1/2-এর পূর্ণ প্রমাণ
  • Schwartz–Zippel-এর বক্তব্য আর এক চলকের ক্ষেত্রে তার প্রমাণ, আর Karger-এর 2/(n(n − 1)) সীমার প্রমাণ
  • Probabilistic method দিয়ে Erdős-এর Ramsey সীমা, MAX-CUT ≥ m/2 আর MAX-3SAT-এর 7/8 প্রমাণ
  • প্রতিটি দাবি seed দেওয়া simulation আর Fraction দিয়ে নির্ভুল গণনায় Python-এ মেলানো

১ · এলোমেলোতা কেন কাজে লাগে — Las Vegas আর Monte Carlo

এই মডিউলের আগের পর্বগুলোতে সম্ভাবনা ছিল বিশ্লেষণের বিষয়: ছক্কা, ত্রুটিপূর্ণ ব্যাচ, hash bucket. শেষ পর্বে দিক বদলাচ্ছে। এবার এলোমেলোতা নিজেই হাতিয়ার: algorithm ইচ্ছা করে মুদ্রা ছোড়ে, আর প্রমাণ ইচ্ছা করে একটি এলোমেলো বস্তু বানায়। দুই ক্ষেত্রেই যে গণিত লাগে তা আপনি এর মধ্যেই শিখেছেন: union bound (পর্ব ৩৮ “বিচ্ছিন্ন সম্ভাবনা — sample space, event আর Laplace-এর সংজ্ঞা”), স্বাধীন ঘটনার গুণ (পর্ব ৩৯ “শর্তসাপেক্ষ সম্ভাবনা, independence আর Bayes-এর উপপাদ্য”), আর indicator দিয়ে প্রত্যাশা (পর্ব ৪০ “Random variable আর প্রত্যাশা — linearity-র জাদু”).

রাজশাহীর আমের আড়তে পাইকার পুরো ট্রাক খুলে প্রতিটি আম দেখেন না। তিনি এলোমেলো কয়েকটি ঝুড়ি থেকে কয়েক মুঠো আম তুলে দেখেন। নিয়মিত ঝুড়ি নয়, এলোমেলো ঝুড়ি, কারণ বিক্রেতা জানলে ভালো আম ঠিক সেই ঝুড়িগুলোতেই রাখতেন। এলোমেলো বাছাই এমন একটি প্রতিপক্ষকেও হারায়, যে আপনার নিয়ম আগে থেকে জানে। Randomized algorithm-এর মূল শক্তি এটিই।

সংজ্ঞা ১.১ (Las Vegas, Monte Carlo, one-sided error)

যে algorithm চলার সময় নিজে এলোমেলো bit ব্যবহার করে, তা একটি randomized algorithm. একটি নির্দিষ্ট ইনপুটে তার আচরণ এলোমেলো bit-গুলোর ওপর একটি random variable.

  • Las Vegas algorithm: প্রতিটি ইনপুটে উত্তর সবসময় সঠিক; শুধু চলার সময় এলোমেলো, আর আমরা তার প্রত্যাশিত মান সীমিত করি।
  • Monte Carlo algorithm: চলার সময় একটি নির্দিষ্ট সীমার মধ্যে; কিন্তু প্রতিটি ইনপুটে একটি ছোট সম্ভাবনা ε পর্যন্ত ভুল উত্তর দিতে পারে।
  • One-sided error: হ্যাঁ/না প্রশ্নে দুই উত্তরের একটি সবসময় সঠিক, ভুল হতে পারে শুধু অন্যটিতে।

একটি সূক্ষ্ম কিন্তু জরুরি কথা: এখানে সম্ভাবনা নেওয়া হয় algorithm-এর মুদ্রার ওপর, ইনপুটের ওপর নয়। “গড় ইনপুটে দ্রুত” (average-case) আর “প্রতিটি ইনপুটে, প্রত্যাশায় দ্রুত” সম্পূর্ণ আলাদা দাবি। প্রথমটি ইনপুটের বণ্টন অনুমান করে; দ্বিতীয়টি সবচেয়ে খারাপ ইনপুটেও খাটে, কারণ প্রতিপক্ষ ইনপুট বাছতে পারে, মুদ্রার ফল বাছতে পারে না।

দিকLas VegasMonte Carlo
উত্তরসবসময় সঠিক≤ ε সম্ভাবনায় ভুল
সময়এলোমেলো; প্রত্যাশা সীমিতনির্দিষ্ট সীমার মধ্যে
উদাহরণrandomized quicksort, quickselectMiller–Rabin, Freivalds, Karger-এর এক run
ভুল কমানোদরকার নেইস্বাধীনভাবে k বার চালানো

এক ধরন থেকে অন্য ধরনে। Las Vegas-কে Monte Carlo বানানো সহজ: প্রত্যাশিত সময় T হলে 2T ধাপে থামিয়ে দিন। Markov-এর অসমতা (পর্ব ৪১ “Variance আর concentration — Markov, Chebyshev আর Chernoff”) বলে P(সময় ≥ 2T) ≤ 1/2, তাই থামানো algorithm বড়জোর 1/2 সম্ভাবনায় “জানি না” বলে। উল্টো দিকে, Monte Carlo-র উত্তর যদি দ্রুত যাচাই করা যায় (যেমন একটি উৎপাদক ভাগ করে মেলানো), তাহলে যাচাই না মেলা পর্যন্ত আবার চালালেই একটি Las Vegas algorithm পাওয়া যায়।

উপপাদ্য ১.২ (one-sided error-এর amplification)

একটি Monte Carlo algorithm-এর “হ্যাঁ” উত্তর সবসময় সঠিক, আর সঠিক উত্তর “হ্যাঁ” হলেও “না” বলার সম্ভাবনা ≤ ε. স্বাধীন এলোমেলোতায় k বার চালিয়ে একবারও “হ্যাঁ” এলে “হ্যাঁ” বললে ভুলের সম্ভাবনা ≤ εk.

  1. ভুল হতে পারে শুধু যখন সঠিক উত্তর “হ্যাঁ” অথচ k বারই “না” এসেছে; সঠিক উত্তর “না” হলে কোনো run “হ্যাঁ” বলে না। — one-sided error
  2. Ei = “i-তম run ভুল বলে”, P(Ei) ≤ ε, আর run-গুলোর এলোমেলো bit আলাদা, তাই E1, …, Ek স্বাধীন। — অনুমান
  3. P(E1 ∩ … ∩ Ek) = P(E1) ⋯ P(Ek) ≤ εk. ∎ — স্বাধীন ঘটনার গুণ (পর্ব ৩৯)

Miller–Rabin পরীক্ষায় (পর্ব ২৫ “Primality test আর factoring — Miller–Rabin থেকে কঠিনতার ধারণা”) এক base-এ ভুলের সম্ভাবনা ≤ 1/4, তাই ২০টি এলোমেলো base-এ ≤ 4−20 ≈ 10−12. একে বলে amplification. ধাপ ২-এর “স্বাধীন” শব্দটিই এখানে সব; একই এলোমেলো bit আবার ব্যবহার করলে প্রমাণ ভেঙে পড়ে (§৮-এর ভুল যুক্তিটি দেখুন)। Code-এর দিকটি, যেমন treap আর reservoir sampling, DSA কোর্সের পর্ব ৬১-এ আছে; এখানে আমরা প্রমাণে মন দেব।

২ · Las Vegas-এর প্রত্যাশিত সময় — randomized quickselect

Randomized quicksort প্রতিটি ধাপে বর্তমান অংশ থেকে সমান সম্ভাবনায় একটি pivot বাছে। পর্ব ৪০-এ indicator random variable দিয়ে দেখানো হয়েছে, n-টি আলাদা সংখ্যায় প্রত্যাশিত তুলনা 2(n + 1)Hn − 4n ≈ 2n ln n, যেখানে Hn = 1 + 1/2 + … + 1/n. সেই ফল এখানে আবার প্রমাণ করছি না; বরং তার ছোট ভাই দেখি।

Quickselect একটি তালিকার k-তম ছোট উপাদান খোঁজে, যেমন বাজারঘরের দিনের সব ডেলিভারি-সময়ের median. এলোমেলো pivot p নিয়ে বাকিদের “p-এর ছোট” আর “p-এর বড়” দুই ভাগ করে (s-টি উপাদানে s − 1টি তুলনা), তারপর শুধু যে ভাগে উত্তর আছে সেখানে এগোয়। Quicksort দুই ভাগেই নামে; quickselect নামে একটিতে। উত্তর সবসময় সঠিক, তাই এটি Las Vegas.

উপপাদ্য ২.১ (quickselect-এর প্রত্যাশিত তুলনা)

n-টি আলাদা উপাদানে যেকোনো k-এর জন্য randomized quickselect-এর প্রত্যাশিত তুলনার সংখ্যা ≤ 8n.

  1. ভালো pivot: বর্তমান অংশে s-টি উপাদান থাকলে pivot-কে “ভালো” বলি যদি দুই ভাগের প্রতিটিতে ≤ 3s/4টি উপাদান থাকে। Pivot-এর rank r হলে শর্তটি s/4 ≤ r ≤ 3s/4 + 1, যা দৈর্ঘ্য s/2 + 1-এর একটি ব্যবধি; তাতে অন্তত s/2টি পূর্ণসংখ্যা। তাই P(ভালো) ≥ 1/2. — গোনা
  2. দশা: অংশের আকার n(3/4)j+1 থেকে বড় আর n(3/4)j-এর সমান বা কম হলে algorithm “দশা j”-তে আছে। একটি ভালো pivot আকারকে 3/4 গুণ বা তার কম করে, তাই দশা j শেষ হয়। — সংজ্ঞা
  3. প্রতি দশায় ধাপ: দশা j-তে প্রতিটি ধাপ স্বাধীনভাবে ≥ 1/2 সম্ভাবনায় ভালো, তাই দশাটি শেষ হতে প্রত্যাশিত ধাপ ≤ 2 (geometric বণ্টনের প্রত্যাশা 1/p, পর্ব ৪০)। — geometric বণ্টন
  4. প্রতি ধাপের খরচ: দশা j-এর প্রতিটি ধাপে তুলনা ≤ n(3/4)j. তাই দশা j-এর প্রত্যাশিত তুলনা ≤ 2n(3/4)j. — ধাপ ২, ৩
  5. যোগ: মোট তুলনা = দশাগুলোর তুলনার যোগ; linearity of expectation আর geometric series (পর্ব ১৭) থেকে E ≤ ∑j≥0 2n(3/4)j = 2n · 1/(1 − 3/4) = 8n. ∎ — linearity, পর্ব ১৭

ধাপ ৫-এর linearity of expectation দশাগুলোর স্বাধীনতা চায় না; সেটাই এর শক্তি। 8n একটি সহজ কিন্তু ঢিলা সীমা: median খুঁজতে আসল প্রত্যাশা প্রায় 2(1 + ln 2)n ≈ 3.39n বলে জানা যায় (Knuth-এর বিশ্লেষণ); আমাদের scratch simulation-এ n = 2001-এ ৪০০ run-এর গড় এসেছে প্রায় 3.42n. খারাপ ক্ষেত্র Θ(n²) এখনো সম্ভব, যদি প্রতিবার সবচেয়ে ছোট pivot ওঠে, কিন্তু তার সম্ভাবনা অতি ক্ষুদ্র। Lomuto/Hoare partition আর নিশ্চিত O(n)-এর median of medians DSA কোর্সের পর্ব ২২-এ।

৩ · Freivalds-এর matrix যাচাই — প্রতি round-এ ভুল ≤ 1/2

বাজারঘরের হিসাব বিভাগ একটি বাইরের সার্ভিসে দুটি বড় matrix A আর B পাঠায় (ধরুন গুদাম × পণ্য আর পণ্য × দাম-ধাপ), আর ফেরত পায় দাবি করা গুণফল C. নিজে AB গুণ করে মেলাতে matrix multiplication-এর সাধারণ পদ্ধতিতে n3টি গুণ লাগে (পর্ব ১৯ “Discrete math-এ matrix — 0-1 matrix আর Boolean product”). তাহলে যাচাই আর নতুন করে হিসাব সমান খরচের। Rūsiņš Freivalds ১৯৭৭ সালে দেখান, এলোমেলোতা দিয়ে যাচাই অনেক সস্তা।

Algorithm ৩.১ (Freivalds-এর এক round)
  1. r = (r1, …, rn) বাছুন, প্রতিটি rj স্বাধীনভাবে সমান সম্ভাবনায় 0 বা 1.
  2. x = Br, তারপর y = Ax, আর z = Cr হিসাব করুন: তিনটি matrix-vector গুণ, প্রতিটিতে n2টি গুণ।
  3. y = z হলে বলুন “C ঠিক মনে হয়”, নইলে “C ভুল”.

C সত্যিই AB হলে A(Br) = (AB)r = Cr, তাই উত্তর সবসময় “ঠিক মনে হয়”: ভুল হয় শুধু এক দিকে, one-sided error. প্রশ্ন হলো C ভুল হলে কত ঘন ঘন ধরা পড়ে। নিচের stepper একটি 2 × 2 উদাহরণে চারটি সম্ভাব্য r-ই দেখায়।

1দাবি C₂₂ = 51, আসল 502r = (1, 0): Br = (5, 7)3A(Br) = (19, 43) = Cr4r = (0, 1): 50 ≠ 51 ✓5৪টি r-এর ২টি ঠকে: 1/26খরচ 3n² বনাম n³
দাবি C = [19 22; 43 51], আসল AB = [19 22; 43 50]
r
Br
A(Br)
Cr
রায়
  1. প্রস্তুতি। A = [1 2; 3 4] আর B = [5 6; 7 8]-এর আসল গুণফল [19 22; 43 50]. সার্ভিস পাঠাল C = [19 22; 43 51]: শুধু (2, 2) ঘরে 1 বেশি।
  2. প্রথম চেষ্টা। r = (1, 0) উঠল। আগে Br = (5, 7), অর্থাৎ B-এর প্রথম কলাম; AB গুণফল কখনো পুরো বানানো হয় না।
  3. তুলনা। A(Br) = (1·5 + 2·7, 3·5 + 4·7) = (19, 43), আর Cr = C-এর প্রথম কলাম (19, 43). সমান, তাই এই r ভুলটি ধরতে পারল না: ভুল ঘরটি দ্বিতীয় কলামে, আর r2 = 0 তাকে ঢেকে দিল।
  4. দ্বিতীয় চেষ্টা। r = (0, 1): Br = (6, 8), A(Br) = (22, 50), কিন্তু Cr = (22, 51). অমিল, তাই “C ভুল”, আর এই উত্তর নিশ্চিত সত্য।
  5. সব r. চারটি সমান সম্ভাব্য r-এর মধ্যে (0, 0) আর (1, 0) ঠকে যায়, (0, 1) আর (1, 1) ধরে ফেলে [(1, 1)-এ (41, 93) বনাম (41, 94)]. ধরা না পড়ার সম্ভাবনা ঠিক 2/4 = 1/2, উপপাদ্য ৩.২-এর সীমার সমান।
  6. খরচ। প্রতি round-এ তিনটি matrix-vector গুণ, মোট 3n2টি গুণ। n = 1000-এ তা ৩০ লাখ, আর সাধারণ গুণফলে ১০০ কোটি। ২০ round-এও ৬ কোটি, আর ভুল ধরা না পড়ার সম্ভাবনা ≤ 2−20.
উপপাদ্য ৩.২ (Freivalds-এর ভুলের সীমা)

যেকোনো n × n পূর্ণসংখ্যার (বা বাস্তব সংখ্যার) matrix A, B, C-তে AB ≠ C হলে, এক round-এ P(A(Br) = Cr) ≤ 1/2.

  1. D = AB − C ধরুন। D ≠ 0, তাই কোনো ঘর dij ≠ 0. আর A(Br) = Cr ⇔ Dr = 0. — matrix গুণের বণ্টন নিয়ম
  2. Dr = 0 হলে বিশেষত তার i-তম উপাদান (Dr)i = dijrj + y = 0, যেখানে y = ∑ℓ≠j diℓrℓ. তাই P(Dr = 0) ≤ P(dijrj + y = 0). — monotonicity (পর্ব ৩৮)
  3. আগে rj ছাড়া বাকি সব rℓ-এর মান বসান; তাতে y একটি নির্দিষ্ট সংখ্যা। rj স্বাধীন, তাই তার মান এখনো সমান সম্ভাবনায় 0 বা 1. এই কৌশলের নাম principle of deferred decisions: যে মুদ্রা দরকার, তা শেষে ছোড়া। — স্বাধীনতা
  4. dijrj + y = 0 মানে rj = −y/dij: একটিমাত্র সংখ্যা। 0 আর 1-এর বড়জোর একটি তার সমান, তাই y-এর প্রতিটি মানে শর্তসাপেক্ষ সম্ভাবনা ≤ 1/2. — dij ≠ 0
  5. সব y-এর ওপর গড় নিলে (total probability, পর্ব ৩৯) P(Dr = 0) ≤ 1/2. ∎ — law of total probability

উপপাদ্য ১.২ অনুযায়ী k স্বাধীন round-এ ভুল C ধরা না পড়ার সম্ভাবনা ≤ 2−k. নিচের ব্লক একটি 5 × 5 উদাহরণে এটি মাপে। প্রথমবার চালালে ব্রাউজারে Python (Pyodide) নামতে কয়েক সেকেন্ড লাগে।

import random

def matmul(A, B):                      # ordinary product: n^3 multiplications
    n = len(A)
    return [[sum(A[i][k] * B[k][j] for k in range(n)) for j in range(n)]
            for i in range(n)]

def matvec(M, x):                      # n^2 multiplications
    return [sum(a * b for a, b in zip(row, x)) for row in M]

def freivalds_round(A, B, C):          # True means "C looks correct"
    r = [random.randint(0, 1) for _ in range(len(A))]
    return matvec(A, matvec(B, r)) == matvec(C, r)

random.seed(43)
n = 5
A = [[random.randint(0, 9) for _ in range(n)] for _ in range(n)]
B = [[random.randint(0, 9) for _ in range(n)] for _ in range(n)]
C = matmul(A, B)
C_bad = [row[:] for row in C]
C_bad[2][4] += 1                       # one wrong entry, off by 1

ok = sum(freivalds_round(A, B, C) for _ in range(1000))
print("correct C accepted:", ok, "of 1000 rounds")

trials = 10_000
for k in (1, 2, 3, 5, 8):
    fooled = sum(all(freivalds_round(A, B, C_bad) for _ in range(k))
                 for _ in range(trials))
    print(f"k = {k}: wrong C accepted {fooled / trials:.4f}"
          f"   bound 2^-k = {0.5 ** k:.4f}")
print("cost per round ~", 3 * n * n, "mults; full product", n ** 3)

আসল আউটপুট (ব্রাউজারের Python):

correct C accepted: 1000 of 1000 rounds
k = 1: wrong C accepted 0.4974   bound 2^-k = 0.5000
k = 2: wrong C accepted 0.2506   bound 2^-k = 0.2500
k = 3: wrong C accepted 0.1159   bound 2^-k = 0.1250
k = 5: wrong C accepted 0.0358   bound 2^-k = 0.0312
k = 8: wrong C accepted 0.0046   bound 2^-k = 0.0039
cost per round ~ 75 mults; full product 125

সঠিক C ১০০০ বারের ১০০০ বারই পাস করে: one-sided error. ভুল C-তে মাপা হার 2−k-এর খুব কাছে, কারণ এখানে D-এর একটিমাত্র ঘর অশূন্য, (3, 5) অবস্থানে। তখন Dr = 0 ঠিক তখনই, যখন r5 = 0, তাই সম্ভাবনা ঠিক 1/2, আর উপপাদ্যের সীমা এই ক্ষেত্রে সমতা। k = 5 আর k = 8-এ মাপা হার সীমার সামান্য ওপরে (0.0358 বনাম 0.0312): এটি ১০,০০০ নমুনার স্বাভাবিক ওঠানামা, কারণ আসল মান এখানে ঠিক 2−k. শেষ লাইন খরচের অনুপাত দেখায়; n = 5-এ লাভ সামান্য (75 বনাম 125), কিন্তু অনুপাত 3/n, তাই n বাড়লে লাভ দ্রুত বাড়ে।

৪ · Polynomial identity testing — Schwartz–Zippel

Freivalds-এর যুক্তির পেছনে একটি সাধারণ সত্য লুকিয়ে আছে: একটি অশূন্য polynomial খুব কম জায়গায় শূন্য হয়। ধরুন বাজারঘরের দুই প্রোগ্রামার একটি ডিসকাউন্ট সূত্র দুইভাবে লিখেছেন: একজন (x + 1)20, অন্যজন তার বিস্তৃত রূপ ২১টি পদে। দুটি কি হুবহু একই polynomial? সব coefficient মেলানো যায়, কিন্তু বহু চলকের polynomial-এ বিস্তার করলে পদ সংখ্যা বিস্ফোরিত হয়। সহজ পথ: একটি এলোমেলো x বসিয়ে দুই পাশের মান মেলানো। এই প্রশ্নটির নাম polynomial identity testing.

উপপাদ্য ৪.১ (Schwartz–Zippel lemma, বক্তব্য)

F একটি field (যেমন ℚ, ℝ বা মৌলিক p-এর জন্য ℤp), p(x1, …, xm) F-এর ওপর মোট degree d-এর একটি অশূন্য polynomial, আর S ⊆ F একটি সসীম সেট। r1, …, rm স্বাধীনভাবে S থেকে সমান সম্ভাবনায় বাছলে

P(p(r1, …, rm) = 0) ≤ d / |S|

বহু চলকের প্রমাণটি চলকের সংখ্যার ওপর induction, এখানে বাদ রাখছি (এটি DeMillo–Lipton, Zippel আর Schwartz-এর ১৯৭৮–৮০ সালের কাজে আলাদাভাবে আসে)। এক চলকের ক্ষেত্রটি পুরো প্রমাণ করি, কারণ বহু চলকের প্রমাণ এর ওপরই দাঁড়ায়।

উপপাদ্য ৪.২ (এক চলক)

Field F-এর ওপর degree d ≥ 0-এর একটি অশূন্য polynomial p(x)-এর মূল (root) বড়জোর d-টি। তাই S থেকে এলোমেলো r নিলে P(p(r) = 0) ≤ d/|S|.

  1. ভিত্তি d = 0: p একটি অশূন্য ধ্রুবক, কোনো মূল নেই: 0 ≤ 0. — সরাসরি
  2. অনুমান: degree d − 1-এর প্রতিটি অশূন্য polynomial-এর মূল ≤ d − 1টি। — induction (পর্ব ১০)
  3. ধাপ: degree d-এর p-এর কোনো মূল না থাকলে দাবি সত্য। একটি মূল a থাকলে factor theorem অনুযায়ী p(x) = (x − a)q(x), যেখানে q-এর degree d − 1 আর q অশূন্য। — polynomial ভাগ
  4. b ≠ a আরেকটি মূল হলে 0 = p(b) = (b − a)q(b), আর b − a ≠ 0. Field-এ দুটি অশূন্যের গুণফল অশূন্য, তাই q(b) = 0. অর্থাৎ a ছাড়া প্রতিটি মূল q-এর মূল, যা অনুমানে ≤ d − 1টি; মোট ≤ d. — field-এ zero divisor নেই
  5. S-এর |S|টি সমান সম্ভাব্য মানের বড়জোর d-টি মূল, তাই P(p(r) = 0) ≤ d/|S|. ∎ — Laplace (পর্ব ৩৮)

ধাপ ৪-এ field-এর শর্তটি সত্যিই লাগে: ℤ8-এ x2 − 1-এর মূল চারটি (1, 3, 5, 7), degree মাত্র 2. তাই mod n-এ এই পরীক্ষা চালাতে n মৌলিক নিন (পর্ব ২২)। দুই প্রোগ্রামারের উদাহরণে পার্থক্য-polynomial p(x) = (x + 1)20 − (বিস্তৃত রূপ)-এর degree ≤ 20. মৌলিক 1000003 নিয়ে ℤ1000003 থেকে x বাছলে, সূত্র দুটি আলাদা হলে একই মান আসার সম্ভাবনা ≤ 20/1000003 ≈ 2 × 10−5, আর পাঁচটি স্বাধীন বিন্দুতে ≤ (2 × 10−5)5.

Freivalds এর একটি বিশেষ রূপ: r-কে চলক ভাবলে (Dr)i হলো r1, …, rn-এর degree 1-এর একটি অশূন্য polynomial, আর S = {0, 1}, তাই সীমা 1/2. S বড় নিলে, যেমন {0, …, 99}, এক round-এই ভুল ≤ 1/100. Polynomial identity testing-এর একটি কৌতূহলজাগানো দিক “আরও গভীরে”-তে আছে: এর কোনো দক্ষ নির্ধারিত (deterministic) algorithm আজও জানা নেই।

৫ · Karger-এর min cut — এলোমেলো edge চেপে চেপে

বাজারঘরের গুদামগুলো রাস্তা দিয়ে যুক্ত একটি graph. প্রশ্ন: সবচেয়ে কম কয়টি রাস্তা বন্ধ হলে নেটওয়ার্ক দুই টুকরো হয়ে যায়? গুদামগুলোকে দুটি অখালি দলে ভাগ করলে যে রাস্তাগুলো দুই দলকে জোড়ে, সেগুলো একটি cut; সবচেয়ে ছোট cut-কে বলে global min cut. এটি নেটওয়ার্কের দুর্বলতম জায়গা। গ্রাফের সংজ্ঞা আর connectivity পর্ব ৫৭ “গ্রাফ — সংজ্ঞা, degree আর handshake theorem” আর পর্ব ৫৯ “Connectivity — path, component, cut vertex আর Menger-এর ধারণা”-এ বিস্তারিত আসবে; এখানে শুধু এটুকু লাগবে যে একটি vertex-এর degree মানে তার সঙ্গে যুক্ত edge-এর সংখ্যা, আর সব degree-র যোগফল 2|E|.

David Karger ১৯৯৩ সালে একটি অবিশ্বাস্য সরল algorithm দেন। একটি এলোমেলো edge বাছুন আর তার দুই প্রান্তকে এক vertex-এ জুড়ে দিন: এই কাজের নাম edge contraction. দুজনের মাঝের edge-গুলো self-loop হয়ে বাদ যায়, বাকি সব edge থেকে যায়, তাই একই দুই vertex-এর মাঝে একাধিক edge জমতে পারে: গ্রাফটি হয়ে যায় একটি multigraph. দুটি vertex বাকি না থাকা পর্যন্ত এভাবে চালান; শেষে দুই “মহা-vertex”-এর মাঝের edge-গুলোই উত্তরের cut. এটি Karger-এর algorithm.

একটি edge contraction: চার vertex থেকে তিন

ওপরে: হলুদ edge ab বাছা হলো। নিচে: a আর b মিলে একটি vertex; ab নিজে self-loop হয়ে বাদ, ac আর bc হয়ে গেল দুটি parallel edge. Cut {d} (২টি edge) টিকে আছে।

Karger contraction: contracting edge ab merges a and b, removes the self-loop, keeps parallel edges আগে: n = 4, ৫টি edge a b c d বাছা edge ab চেপে এক করা পরে: n = 3, ৪টি edge ab c d ২টি parallel self-loop বাদ
উপপাদ্য ৫.১ (Karger-এর সাফল্যের সীমা)

n ≥ 2 vertex-এর একটি সংযুক্ত গ্রাফে K যেকোনো একটি নির্দিষ্ট global min cut হলে, Karger-এর একটি run ঠিক K ফেরত দেয় অন্তত

2 / (n(n − 1)) = 1 / C(n, 2)

সম্ভাবনায়।

  1. |K| = c ধরুন। প্রতিটি vertex v-এর degree ≥ c, কারণ “v একা বনাম বাকি সব” নিজেই একটি cut, আর তার আকার deg(v). — min cut-এর সংজ্ঞা
  2. তাই |E| = (সব degree-র যোগ)/2 ≥ nc/2, আর প্রথম এলোমেলো edge K-এর হওয়ার সম্ভাবনা ≤ c/(nc/2) = 2/n. — handshake, Laplace
  3. K-এর কোনো edge না চাপা পর্যন্ত K নতুন multigraph-এও একটি cut, আর contraction কোনো নতুন cut বানায় না (প্রতিটি নতুন cut পুরোনো গ্রাফের একটি cut), তাই min cut তখনো c. i-টি contraction-এর পরে n − i-টি vertex, প্রতিটির degree ≥ c, edge ≥ (n − i)c/2. — ধাপ ১, ২-এর একই যুক্তি
  4. Ei = “(i + 1)-তম contraction K-এর edge চাপে না”. আগের সব ধাপে K টিকে থাকলে P(Ei | আগের সব) ≥ 1 − 2/(n − i). — ধাপ ৩
  5. Chain rule (পর্ব ৩৯): P(K শেষ পর্যন্ত টেকে) ≥ ∏i=0n−3 (n − i − 2)/(n − i) = (n − 2)/n · (n − 3)/(n − 1) · … · 1/3. লবের প্রতিটি সংখ্যা দুই ধাপ পরে হরে কাটে, বাকি থাকে 2·1/(n(n − 1)). ∎ — telescoping গুণফল

একটি run-এ সাফল্য ছোট, যেমন n = 8-এ মাত্র 1/28. কিন্তু স্বাধীনভাবে T বার চালিয়ে সবচেয়ে ছোট cut রাখলে ব্যর্থতার সম্ভাবনা ≤ (1 − 1/C(n, 2))T ≤ e−T/C(n, 2), অসমতা 1 − x ≤ e−x থেকে (পর্ব ৪২ “Birthday paradox, hash collision আর balls-into-bins”-এ এর প্রমাণ)। T = C(n, 2) · ln n হলে ব্যর্থতা ≤ 1/n. এটিও একটি Monte Carlo algorithm: উত্তর কখনো min cut-এর চেয়ে ছোট হয় না, কিন্তু বড় হতে পারে।

import random
from math import comb, log

# two 4-depot clusters (complete inside), joined by 2 roads
E = [(a, b) for a in range(4) for b in range(a + 1, 4)]
E += [(a, b) for a in range(4, 8) for b in range(a + 1, 8)]
E += [(0, 4), (3, 7)]
n = 8

def karger(edges, n):                 # contract until 2 groups remain
    parent = list(range(n))
    def find(x):
        while parent[x] != x:
            x = parent[x]
        return x
    order = edges[:]
    random.shuffle(order)             # random order = random edge each time
    groups = n
    for u, v in order:
        ru, rv = find(u), find(v)
        if groups > 2 and ru != rv:   # skip self-loops
            parent[ru] = rv
            groups -= 1
    return sum(find(u) != find(v) for u, v in edges)

random.seed(43)
runs = 5000
results = [karger(E, n) for _ in range(runs)]
best = min(results)
print("edges:", len(E), "  smallest cut found:", best)
print(f"P(one run finds it) ~ {results.count(best) / runs:.4f}"
      f"   bound 1/C(8,2) = {1 / comb(n, 2):.4f}")
T = round(comb(n, 2) * log(n))
print(f"T = {T}: P(all fail) <= {(1 - 1 / comb(n, 2)) ** T:.4f}")

আসল আউটপুট (ব্রাউজারের Python):

edges: 14   smallest cut found: 2
P(one run finds it) ~ 0.2094   bound 1/C(8,2) = 0.0357
T = 58: P(all fail) <= 0.1213

গ্রাফটি দুটি চার-গুদামের দল, প্রতিটির ভেতরে সব জোড়া যুক্ত (৬টি করে রাস্তা), আর দল দুটি মাত্র ২টি রাস্তায় জোড়া; প্রতিটি দল একটি K4, যাকে দুই ভাগ করতে অন্তত ৩টি রাস্তা কাটতে হয়, তাই min cut ২, আর সেটি একটিই। একটি run তাকে খুঁজে পায় প্রায় 0.21 হারে, যা সীমা 1/28 ≈ 0.036-এর প্রায় ছয় গুণ: সীমাটি সবচেয়ে খারাপ গ্রাফের জন্য, এই গ্রাফে মাঝের ২টি রাস্তা ১৪টির মধ্যে খুব কমই বাছা পড়ে। কোডের একটি কৌশল লক্ষ করুন: edge-গুলো একবার এলোমেলো ক্রমে সাজিয়ে, যে edge এখন self-loop তা বাদ দিয়ে, ক্রমানুসারে চাপা। প্রতিটি মুহূর্তে বাকি না-চাপা অ-loop edge-গুলোর মধ্যে পরেরটি সমান সম্ভাব্য, তাই এটি “প্রতিবার একটি এলোমেলো edge” বাছারই সমান। শেষ লাইন: ৫৮টি run-এ প্রমাণিত ব্যর্থতার সীমা ≈ 0.12 ≤ 1/8.

৬ · Probabilistic method — Erdős-এর Ramsey সীমা

এতক্ষণ এলোমেলোতা ছিল algorithm-এর হাতিয়ার। এবার তা হলো প্রমাণের হাতিয়ার। পর্ব ৯ “প্রমাণের কৌশল — case, existence, uniqueness আর counterexample”-এ দেখেছেন, একটি existence proof বস্তুটি না দেখিয়েও তার অস্তিত্ব প্রমাণ করতে পারে। Probabilistic method এর একটি শক্তিশালী রূপ।

নীতি ৬.১ (probabilistic method)

একটি সসীম সেট Ω-এর বস্তুগুলোর ওপর একটি probability space বানান। কোনো ধর্ম Q-এর জন্য P(এলোমেলো বস্তুর Q আছে) > 0 হলে Ω-এ Q-যুক্ত অন্তত একটি বস্তু আছে। কারণ Q-যুক্ত বস্তুর event ফাঁকা হলে P(∅) = 0 হতো (পর্ব ৩৮-এর উপপাদ্য)। সমতুল্যভাবে: P(খারাপ) < 1 হলে একটি ভালো বস্তু আছে।

সবচেয়ে বিখ্যাত প্রয়োগটি Ramsey সংখ্যায়। পর্ব ৩২ “Pigeonhole principle — সহজ থেকে generalized”-এ দেখেছেন, ছয়জনের যেকোনো দলে তিনজন পরস্পর পরিচিত বা তিনজন পরস্পর অপরিচিত: R(3, 3) = 6. সাধারণভাবে Ramsey number R(k, k) হলো সবচেয়ে ছোট N, যাতে complete graph KN-এর edge-গুলো লাল-নীলে যেভাবেই রাঙানো হোক, k-টি vertex-এর একটি একরঙা Kk থাকবেই। R(k, k) > n প্রমাণ করতে হলে Kn-এর এমন একটি রং দেখাতে হয়, যাতে কোনো একরঙা Kk নেই। বড় k-তে এমন রং হাতে বানানো কঠিন। Paul Erdős ১৯৪৭ সালে রং না বানিয়েই প্রমাণ করেন যে তা আছে।

উপপাদ্য ৬.২ (Erdős, ১৯৪৭)

যদি C(n, k) · 21 − C(k, 2) < 1 হয়, তাহলে R(k, k) > n. বিশেষত প্রতিটি k ≥ 3-এর জন্য R(k, k) > ⌊2k/2⌋.

  1. Kn-এর প্রতিটি edge স্বাধীনভাবে 1/2 সম্ভাবনায় লাল বা নীল করুন; Ω = সব 2C(n, 2) রং, সমান সম্ভাব্য। — মডেল
  2. একটি নির্দিষ্ট k-vertex সেট S-এর ভেতরে C(k, 2)টি edge. S একরঙা মানে সব লাল বা সব নীল: P(AS) = 2 · 2−C(k, 2) = 21 − C(k, 2). — স্বাধীন edge
  3. k-vertex সেট C(n, k)টি। Union bound: P(কোনো একরঙা Kk আছে) ≤ ∑S P(AS) = C(n, k) · 21 − C(k, 2) < 1. — union bound (পর্ব ৩৮)
  4. তাই P(কোনো একরঙা Kk নেই) > 0, আর নীতি ৬.১ অনুযায়ী এমন রং আছে: R(k, k) > n. — নীতি ৬.১
  5. বিশেষ ক্ষেত্র: n = ⌊2k/2⌋ হলে C(n, k) ≤ nk/k! ≤ 2k²/2/k!, তাই সীমা ≤ 2k²/2 + 1 − k(k−1)/2/k! = 21 + k/2/k!, যা k ≥ 3-এ 1-এর কম (k = 3-এ 22.5/6 ≈ 0.94, আর k বাড়লে k! দ্রুত বাড়ে)। ∎ — বীজগণিত

প্রমাণটি একটিও রং দেখায় না, শুধু বলে “বেশিরভাগ রংই ভালো”. নিচের stepper k = 10-এর হিসাব ধাপে ধাপে করে।

1k = 10, n = 2^(k/2) = 322C(32, 10) = 64512240 সেট3এক সেট একরঙা: 2^(1−45)4union bound ≈ 3.67 × 10⁻⁶5< 1 ⇒ R(10, 10) > 326n = 100: 0.984 < 1
Kn-এর এলোমেলো লাল-নীল রং
n
C(n, 10)
P(এক সেট)
সীমা
  1. n বাছাই। k = 10 হলে সাধারণ সূত্রের n = 210/2 = 32. প্রশ্ন: K32-এর কোনো লাল-নীল রঙে কি একরঙা K10 এড়ানো যায়?
  2. কতগুলো সেট। ৩২টি vertex থেকে ১০টির সেট C(32, 10) = 64,512,240টি। প্রতিটিই একটি সম্ভাব্য একরঙা K10.
  3. একটি সেট। ১০টি vertex-এর ভেতরে C(10, 2) = 45টি edge. সব লাল হওয়ার সম্ভাবনা 2−45, সব নীল 2−45; মোট 21−45 = 2−44 ≈ 5.68 × 10−14.
  4. Union bound. কোনো একটি সেট একরঙা হওয়ার সম্ভাবনা ≤ 64,512,240 × 2−44 ≈ 3.67 × 10−6. অর্থাৎ প্রায় দশ লাখ রঙের মধ্যে চারটিরও কম খারাপ।
  5. সিদ্ধান্ত। খারাপ হওয়ার সম্ভাবনা 1-এর কম, তাই অন্তত একটি (আসলে প্রায় সব) রঙে কোনো একরঙা K10 নেই: R(10, 10) > 32. অথচ সেই রঙের একটিও আমরা লিখে দেখাইনি।
  6. আরও ঠেলা। সাধারণ সূত্রটি ঢিলা। একই অসমতা n = 100-এ সরাসরি গুনলে C(100, 10) · 2−44 ≈ 0.984 < 1, কিন্তু n = 101-এ ≈ 1.092. তাই একই যুক্তি R(10, 10) > 100 দেয় (নিচের ব্লকে যাচাই)।

নিচের ব্লক দুটি কাজ করে: প্রতিটি k-এর জন্য সবচেয়ে বড় n খোঁজে যেখানে উপপাদ্য ৬.২-এর শর্ত মেটে, আর k = 4, n = 6-এ K6-এর সব 215 = 32768টি রং গুনে দেখে কতগুলো সত্যিই “ভালো” (একরঙা K4-হীন), union bound-এর নিচের সীমার তুলনায়।

from fractions import Fraction
from itertools import combinations
from math import comb

def first_moment(n, k):               # E[# one-colour K_k] in random colouring
    return Fraction(comb(n, k) * 2, 2 ** comb(k, 2))

for k in (4, 6, 8, 10):
    n = k
    while first_moment(n + 1, k) < 1:
        n += 1
    print(f"k = {k:>2}: largest n with E < 1 is {n:>3}"
          f"  -> R(k,k) > {n}   (2^(k/2) = {2 ** (k / 2):.1f})")

# k = 4, n = 6: check every one of the 2^15 colourings of K6
n, k = 6, 4
edges = list(combinations(range(n), 2))
quads = [[edges.index(e) for e in combinations(q, 2)]
         for q in combinations(range(n), k)]
good = 0
for mask in range(2 ** len(edges)):
    bits = [(mask >> i) & 1 for i in range(len(edges))]
    if all(len({bits[i] for i in q}) == 2 for q in quads):
        good += 1                     # no one-colour K4
print("K6 colourings:", 2 ** len(edges), " good:", good,
      f" share {good / 2 ** len(edges):.4f}")
print("union bound: P(good) >=", 1 - first_moment(n, k),
      f"= {float(1 - first_moment(n, k)):.4f}")

আসল আউটপুট (ব্রাউজারের Python):

k =  4: largest n with E < 1 is   6  -> R(k,k) > 6   (2^(k/2) = 4.0)
k =  6: largest n with E < 1 is  17  -> R(k,k) > 17   (2^(k/2) = 8.0)
k =  8: largest n with E < 1 is  42  -> R(k,k) > 42   (2^(k/2) = 16.0)
k = 10: largest n with E < 1 is 100  -> R(k,k) > 100   (2^(k/2) = 32.0)
K6 colourings: 32768  good: 22484  share 0.6862
union bound: P(good) >= 17/32 = 0.5312

C(n, k) · 21 − C(k, 2) আসলে একরঙা Kk-এর প্রত্যাশিত সংখ্যা (প্রতিটি সেটের indicator-এর যোগ, পর্ব ৪০), তাই কোডে নাম first_moment. প্রথম চার লাইন দেখায়, সরাসরি গুনলে সীমা 2k/2-এর চেয়ে অনেক ভালো, যদিও বৃদ্ধির হার একই ধরনের। শেষ দুই লাইন নির্ভুল গণনা: K6-এর ৩২,৭৬৮টি রঙের ২২,৪৮৪টিতে কোনো একরঙা K4 নেই, ভাগ 0.6862, যা union bound-এর প্রতিশ্রুত 17/32 ≈ 0.53-এর চেয়ে বেশি। Union bound ঢিলা, কারণ দুটি K4 edge ভাগ করলে তাদের “খারাপ” event একসঙ্গে ঘটে, আর যোগফল তাদের দুবার গোনে। আসল মানগুলো এর চেয়ে অনেক বড়: R(4, 4) = 18 (Greenwood আর Gleason, ১৯৫৫), আর R(10, 10)-এর সঠিক মান আজও অজানা।

৭ · প্রত্যাশার যুক্তি — MAX-CUT, derandomization আর MAX-3SAT

Probabilistic method-এর দ্বিতীয় রূপটি সম্ভাবনার বদলে প্রত্যাশা ব্যবহার করে, আর প্রায়ই আরও সহজ।

লেমা ৭.১ (গড়ের চেয়ে ভালো কেউ আছে)

সসীম probability space-এ একটি random variable X-এর expected value E[X] = μ হলে এমন অন্তত একটি outcome আছে যেখানে X ≥ μ, আর একটি যেখানে X ≤ μ.

  1. বিপরীতে ধরুন প্রতিটি outcome ω-তে X(ω) < μ. — contradiction-এর অনুমান
  2. তাহলে E[X] = ∑ω X(ω)p(ω) < ∑ω μ · p(ω) = μ, কারণ ভারগুলো অঋণাত্মক, যোগফল 1, আর অন্তত একটি ভার ধনাত্মক। — প্রত্যাশার সংজ্ঞা
  3. E[X] < μ, বিরোধ। দ্বিতীয় অংশ একইভাবে। ∎ — বিরোধ

MAX-CUT. একটি গ্রাফের vertex-গুলোকে দুই দলে ভাগ করে দুই দলের মাঝের edge সর্বোচ্চ করার সমস্যা MAX-CUT. বাজারঘরের ভাষায়: গুদামগুলোকে দুটি ডেলিভারি অঞ্চলে ভাগ করুন যাতে সবচেয়ে বেশি রাস্তা দুই অঞ্চলের মাঝে পড়ে (যেমন দুই অঞ্চলের গাড়ি যাতে একই রাস্তায় ভিড় না করে)। Karger-এর min cut-এর উল্টো দিক, আর আসলে অনেক কঠিন: MAX-CUT একটি NP-hard সমস্যা (DSA কোর্সের পর্ব ৬৪)।

উপপাদ্য ৭.২ (প্রতিটি গ্রাফে বড় cut)

m-টি edge-এর প্রতিটি গ্রাফে এমন একটি ভাগ আছে যার cut-এ অন্তত m/2টি edge.

  1. প্রতিটি vertex স্বাধীনভাবে 1/2 সম্ভাবনায় বাঁ (L) বা ডান (R) দলে দিন। X = cut-এর edge সংখ্যা। — মডেল
  2. প্রতিটি edge e = uv-এর জন্য indicator Xe = 1 যদি u আর v ভিন্ন দলে। চারটি সমান সম্ভাব্য (u, v) জোড়ার দুটিতে ভিন্ন দল, তাই E[Xe] = 1/2. — E[IA] = P(A)
  3. X = ∑e Xe, তাই linearity থেকে E[X] = m/2; edge-গুলো স্বাধীন না হলেও (একই vertex ভাগ করে) এটি সত্য। — linearity of expectation
  4. লেমা ৭.১: কোনো ভাগে X ≥ m/2. ∎ — লেমা ৭.১
1a–b–c–d–a: m = 4, ১৬ ভাগ2P(ab কাটা) = 1/23E[X] = 4 × 1/2 = 2 = m/24cut 0, 2, 4: ২, ১২, ২টি5কোথাও ≥ 2; সর্বোচ্চ 46greedy: R, L, R, L
চলক
E[Xe]
E[X]
ভাগের সংখ্যা
cut
  1. মডেল। চারটি গুদাম a, b, c, d একটি বৃত্তে যুক্ত: রাস্তা ab, bc, cd, da, মোট m = 4. প্রতিটি গুদাম স্বাধীনভাবে বাঁ (L) বা ডান (R) দলে: 24 = 16টি সমান সম্ভাব্য ভাগ।
  2. একটি রাস্তা। ab cut-এ পড়ে যদি a আর b ভিন্ন দলে: (L, R) বা (R, L), চারটি জোড়ার দুটি। তাই E[Xab] = P(ab কাটা) = 1/2. বাকি তিনটিও একই।
  3. Linearity. E[X] = E[Xab] + E[Xbc] + E[Xcd] + E[Xda] = 4 × 1/2 = 2. Xab আর Xbc দুটিই b-এর ওপর নির্ভর করে, তবু যোগ বৈধ।
  4. নির্ভুল গণনা। ১৬টি ভাগ গুনলে: সবাই এক দলে হলে cut 0 (২টি ভাগ), পর্যায়ক্রমে L, R, L, R হলে cut 4 (২টি ভাগ), বাকি ১২টিতে cut 2. গড় (0·2 + 2·12 + 4·2)/16 = 32/16 = 2, linearity-র সঙ্গে হুবহু মেলে।
  5. অস্তিত্ব। গড় 2, তাই কোনো ভাগে cut ≥ 2 = m/2 (লেমা ৭.১). এখানে ১৬টির ১৪টিই এমন, আর সর্বোচ্চ 4: a, c এক দলে, b, d অন্য দলে। Cycle-টি জোড় দৈর্ঘ্যের, তাই সব রাস্তা কাটা যায়।
  6. Derandomization. গুদামগুলো ক্রমে বসান, প্রত্যেককে সেই দলে যেখানে আগে বসানো প্রতিবেশীদের বেশি অংশ অন্য দলে। a: কোনো প্রতিবেশী নেই, R. b: প্রতিবেশী a = R, তাই L. c: b = L, তাই R. d: a = R, c = R, তাই L. ফল cut 4, কোনো মুদ্রা ছাড়াই।

এলোমেলোতা ছাড়াই। Stepper-এর শেষ ধাপটি একটি সাধারণ কৌশল, method of conditional expectations, যা derandomization-এর (randomized যুক্তিকে নির্ধারিত algorithm-এ রূপ দেওয়া) সবচেয়ে সহজ উদাহরণ। ধারণাটি: vertex v1, …, vn একে একে বসানো হচ্ছে; আগের সব বসানো ঠিক রেখে বাকিগুলো এলোমেলো রাখলে cut-এর শর্তসাপেক্ষ প্রত্যাশা W. v-এর দুই পছন্দের প্রত্যাশার গড় ঠিক W (পর্ব ৩৯-এর total probability), তাই অন্তত একটি পছন্দ W কমায় না। শুরুতে W = m/2, আর প্রতিটি ধাপে তা কমে না, তাই শেষে, যখন কিছুই এলোমেলো নেই, cut ≥ m/2. v-এর পছন্দে শুধু v আর আগে বসানো প্রতিবেশীর edge-এর প্রত্যাশা বদলায়, তাই “আগে বসানো প্রতিবেশীদের বেশি অংশ যেদিকে নেই, সেদিকে বসান” নিয়মটিই যথেষ্ট। নিচের ব্লক বাজারঘরের সাতটি গুদামের নেটওয়ার্কে দুটিই করে।

from fractions import Fraction
from itertools import product

# warehouse network: 7 depots (0..6), 11 roads
E = [(0, 1), (0, 2), (1, 2), (1, 3), (2, 4), (3, 4),
     (3, 5), (4, 5), (4, 6), (5, 6), (0, 6)]
n, m = 7, len(E)
nbr = {v: [] for v in range(n)}
for u, v in E:
    nbr[u].append(v)
    nbr[v].append(u)

def cut(side):                        # roads whose ends are on different sides
    return sum(side[u] != side[v] for u, v in E)

sizes = [cut(s) for s in product((0, 1), repeat=n)]   # all 2^7 assignments
print("assignments:", len(sizes), "  m =", m)
print("exact E[cut] =", Fraction(sum(sizes), len(sizes)),
      "  m/2 =", Fraction(m, 2))
print("max cut =", max(sizes), "  P(cut >= m/2) =",
      Fraction(sum(c >= m / 2 for c in sizes), len(sizes)))

# derandomise: place depots in order, each on the side that cuts more
side = {}
for v in range(n):
    placed = [side[u] for u in nbr[v] if u in side]
    side[v] = 1 if placed.count(0) >= placed.count(1) else 0
    print(f"depot {v}: neighbours placed {placed} -> side {side[v]}")
s = [side[v] for v in range(n)]
print("greedy sides:", s, "  cut =", cut(s), ">= m/2 =", m / 2)

আসল আউটপুট (ব্রাউজারের Python):

assignments: 128   m = 11
exact E[cut] = 11/2   m/2 = 11/2
max cut = 9   P(cut >= m/2) = 35/64
depot 0: neighbours placed [] -> side 1
depot 1: neighbours placed [1] -> side 0
depot 2: neighbours placed [1, 0] -> side 1
depot 3: neighbours placed [0] -> side 1
depot 4: neighbours placed [1, 1] -> side 0
depot 5: neighbours placed [1, 0] -> side 1
depot 6: neighbours placed [0, 1, 1] -> side 0
greedy sides: [1, 0, 1, 1, 0, 1, 0]   cut = 8 >= m/2 = 5.5

১২৮টি ভাগের নির্ভুল গড় ঠিক 11/2, linearity যা বলে। m বিজোড়, তাই “≥ m/2” মানে cut ≥ 6, আর ১২৮টির মধ্যে 35/64 অংশ তা মেটায়। সর্বোচ্চ cut 9, ১১ নয়, কারণ নেটওয়ার্কে বিজোড় দৈর্ঘ্যের cycle আছে (যেমন 0–1–2), আর একটি বিজোড় cycle-এর সব edge কখনো একসঙ্গে কাটা যায় না। Greedy পদ্ধতি একবার মাত্র প্রতিটি গুদাম দেখে cut 8 পেল: প্রমাণিত সীমা 5.5-এর ওপরে, সর্বোচ্চ 9-এর কাছে। সাধারণভাবে এই পদ্ধতির approximation ratio 2: ফল ≥ m/2 ≥ OPT/2, কারণ কোনো cut-এ m-এর বেশি edge থাকে না।

MAX-3SAT. একই যুক্তি যুক্তিবিদ্যায়। একটি 3-CNF সূত্রে প্রতিটি clause তিনটি ভিন্ন চলকের তিনটি literal-এর “অথবা” (CNF আর satisfiability: পর্ব ৩ “Logical equivalence — De Morgan, normal form আর satisfiability”; আসল SAT solver: পর্ব ৭ “কাজে যুক্তি — specification, ধাঁধা আর SAT solver”). 3-SAT জিজ্ঞেস করে সব clause একসঙ্গে মেটানো যায় কি না; MAX-3SAT জিজ্ঞেস করে সর্বোচ্চ কয়টি মেটানো যায়।

উপপাদ্য ৭.৩ (7/8-এর নিশ্চয়তা)

m-টি clause-এর প্রতিটি 3-CNF সূত্রে (প্রতি clause-এ তিনটি ভিন্ন চলক) এমন একটি মান-বসানো আছে যা অন্তত 7m/8টি clause মেটায়। ফলে m ≤ 7 হলে সূত্রটি সবসময় satisfiable.

  1. প্রতিটি চলক স্বাধীনভাবে 1/2 সম্ভাবনায় সত্য বা মিথ্যা। একটি clause মেটে না শুধু যখন তার তিনটি literal-ই মিথ্যা: 8টি সমান সম্ভাব্য মান-জোড়ার একটি, সম্ভাবনা 1/8. তাই clause-এর indicator-এর প্রত্যাশা 7/8. — তিনটি ভিন্ন চলক, স্বাধীনতা
  2. Linearity: মেটানো clause-এর প্রত্যাশিত সংখ্যা 7m/8; লেমা ৭.১ থেকে কোনো মান-বসানোয় অন্তত 7m/8. — linearity, লেমা ৭.১
  3. m ≤ 7 হলে 7m/8 > m − 1 (কারণ m < 8), আর মেটানো clause-এর সংখ্যা একটি পূর্ণসংখ্যা ≥ 7m/8, তাই তা m: সব clause মেটে। ∎ — পূর্ণসংখ্যার যুক্তি

সীমা 7/8 উন্নত করা যায় না, এমন সূত্রও আছে: x, y, z-এর ৮টি সম্ভাব্য চিহ্ন-বিন্যাসের ৮টি clause (x ∨ y ∨ z), (x ∨ y ∨ ¬z), …, (¬x ∨ ¬y ∨ ¬z) নিন। প্রতিটি মান-বসানো ঠিক একটি clause ভাঙে (যেটির সব literal তার উল্টো), তাই প্রতিটিতে ঠিক ৭টি মেটে; scratch-এ ৮টি মান-বসানোই গুনে মেলানো। আর m = 8-এ সূত্রটি unsatisfiable, তাই “m ≤ 7” শর্তটিও সঠিক সীমা।

যখন খারাপ ঘটনাগুলো প্রায় স্বাধীন: উপরের প্রতিটি যুক্তি union bound বা প্রত্যাশা ব্যবহার করেছে, যা খারাপ ঘটনা অনেক হলে কাজ করে না। Erdős আর László Lovász ১৯৭৫ সালের কাছাকাছি একটি শক্তিশালী হাতিয়ার দেন, Lovász local lemma: খারাপ ঘটনাগুলোর প্রতিটির সম্ভাবনা ছোট আর প্রত্যেকটি অল্প কয়েকটি অন্যটির ওপরই নির্ভর করলে, কোনোটিই না ঘটার সম্ভাবনা ধনাত্মক, যদিও তা অতি ক্ষুদ্র হতে পারে। এই কোর্সে শুধু নামটি রাখছি।

৮ · এলোমেলোতার উৎস, পরীক্ষার অঙ্ক আর একটি ভুল যুক্তি

প্রতিটি প্রমাণে আমরা ধরে নিয়েছি মুদ্রাগুলো সত্যিই ন্যায্য আর স্বাধীন। কম্পিউটারে মুদ্রা আসে একটি pseudorandom number generator থেকে: একটি নির্দিষ্ট সূত্র, যা একটি শুরুর মান বা seed থেকে এলোমেলো দেখতে সংখ্যার ধারা বানায় (পর্ব ২৬ “সংখ্যাতত্ত্বের প্রয়োগ — check digit, hashing আর pseudorandom সংখ্যা”-এর LCG). এই পর্বের এলোমেলো ব্লকগুলোতে random.seed(43): একই seed মানে একই ধারা, তাই আউটপুট বারবার হুবহু মেলে। Simulation আর পরীক্ষার জন্য এটিই চাই।

দুই ধরনের কাজে প্রয়োজন আলাদা। Freivalds বা Karger-এর মতো algorithm-এ প্রতিপক্ষ সাধারণত seed জানে না, আর Python-এর random (Mersenne Twister) পরিসংখ্যানের দিক থেকে যথেষ্ট ভালো। কিন্তু কুপন কোড, OTP বা পাসওয়ার্ড-রিসেট টোকেনে প্রতিপক্ষ আগের আউটপুট দেখে পরেরটি অনুমান করতে চায়; সেখানে CSPRNG লাগে, যেমন Python-এর secrets module. বিস্তারিত Cybersecurity কোর্সের পর্ব ০৭-এ।

অঙ্ক ১: Schwartz–Zippel দিয়ে কয়টি বিন্দু

degree 40-এর দুটি polynomial সমান কি না, S = {1, …, 1000} থেকে এলোমেলো বিন্দু নিয়ে যাচাই করা হচ্ছে। এক বিন্দুতে ভুলের সীমা 40/1000 = 0.04. ভুল ≤ 10−6 করতে কয়টি স্বাধীন বিন্দু লাগে?

  1. k বিন্দুতে ভুল ≤ 0.04k (উপপাদ্য ১.২, কারণ “আলাদা” উত্তর সবসময় সঠিক)।
  2. 0.044 = 2.56 × 10−6 > 10−6, কিন্তু 0.045 ≈ 1.02 × 10−7 ≤ 10−6.
  3. উত্তর: ৫টি বিন্দু।

অঙ্ক ২: Karger-এ কয়টি run

৫টি vertex-এর একটি গ্রাফে Karger চালানো হবে। একটি নির্দিষ্ট min cut না পাওয়ার সম্ভাবনা ≤ 0.05 করতে সর্বনিম্ন কয়টি স্বাধীন run নিশ্চিতভাবে যথেষ্ট (উপপাদ্য ৫.১-এর সীমা দিয়ে)?

  1. এক run-এ সাফল্য ≥ 2/(5 · 4) = 1/10, তাই T run-এ ব্যর্থতা ≤ (9/10)T.
  2. (0.9)28 ≈ 0.0523 > 0.05, (0.9)29 ≈ 0.0471 ≤ 0.05.
  3. উত্তর: ২৯ বার চালানো।

অঙ্ক ৩: MAX-3SAT-এর নিশ্চয়তা

২০টি clause-এর একটি 3-CNF (প্রতি clause-এ তিনটি ভিন্ন চলক)। সবসময় অন্তত কয়টি clause একসঙ্গে মেটানো যায়? উত্তর: 7 × 20/8 = 17.5, আর মেটানো clause-এর সংখ্যা পূর্ণসংখ্যা, তাই অন্তত ১৮টি।

যুক্তির ভুল ধরুন: “একই seed, দশ round”

একজন Freivalds-এর ভুল কমাতে এই কোড লিখলেন আর দাবি করলেন, “১০ round চালিয়েছি, তাই ভুল C ধরা না পড়ার সম্ভাবনা ≤ 2−10 = 1/1024.”

for _ in range(10):
    random.seed(7)                  # reset "for reproducibility"
    if not freivalds_round(A, B, C):
        print("C is wrong"); break

ভুল কোথায়: উপপাদ্য ১.২-এর ধাপ ২ স্বাধীন run চায়। কিন্তু প্রতি round-এর আগে seed 7-এ ফেরানো হয়েছে, তাই দশবারই হুবহু একই r. প্রথম round ঠকলে বাকি নয়টিও ঠকে: ভুলের সম্ভাবনা এখনো ১ round-এর সমান, 1/2 পর্যন্ত, 1/1024 নয়। এক round-এর ভুলের ঘটনা E1 হলে এখানে E1 = E2 = … = E10, আর P(E1 ∩ … ∩ E10) = P(E1). Seed ঠিক করুন একবার, পুরো পরীক্ষার শুরুতে, প্রতিটি round-এর আগে নয়।

আরও গভীরে: Polynomial identity testing-এর একটি দক্ষ নির্ধারিত algorithm পাওয়া একটি বড় খোলা সমস্যা; Kabanets আর Impagliazzo ২০০৪ সালের কাছাকাছি দেখান যে এমন algorithm পেলে circuit-এর নিচের সীমা নিয়ে কঠিন প্রশ্নের অগ্রগতি হবে, তাই প্রশ্নটি সহজ নয়। Ramsey-তে, Erdős-এর 2k/2 নিচের সীমা আর 4k-এর কাছাকাছি পুরোনো ঊর্ধ্বসীমার ফাঁক বহু দশক প্রায় অনড় ছিল; ২০২৩ সালে Campos, Griffiths, Morris আর Sahasrabudhe ঊর্ধ্বসীমায় সূচকীয় উন্নতি দেখান বলে ব্যাপকভাবে জানা যায়। আর R(5, 5)-এর মান আজও অজানা, শুধু ৪৩ আর ৪৬-এর মধ্যে বলে জানা যায় (ঊর্ধ্বসীমা ৪৬ এসেছে ২০২৪ সালের একটি কম্পিউটার-সহায়িত কাজে)।

পরীক্ষা ও ইন্টারভিউতে: বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় এই ধরনের প্রশ্ন প্রায়ই আসে:

  • Las Vegas আর Monte Carlo-র পার্থক্য? Las Vegas: উত্তর সবসময় সঠিক, সময় এলোমেলো; Monte Carlo: সময় নির্দিষ্ট, উত্তর ছোট সম্ভাবনায় ভুল।
  • Freivalds-এ k round-এর পর ভুল? ≤ 2−k, প্রতি round-এ 3n2টি গুণ।
  • Karger-এর এক run-এর সাফল্যের সীমা? ≥ 2/(n(n − 1)); ফলে কোনো গ্রাফে min cut-এর সংখ্যা ≤ C(n, 2).
  • প্রতিটি গ্রাফে কত বড় cut নিশ্চিত? m/2, এলোমেলো ভাগ আর linearity of expectation দিয়ে।
  • ৭টি clause-এর 3-CNF কি সবসময় satisfiable? হ্যাঁ, যদি প্রতি clause-এ তিনটি ভিন্ন চলক থাকে: প্রত্যাশা 49/8 > 6.

৯ · AI-এর যুগে — randomized যুক্তি যাচাই

Randomized algorithm আর probabilistic method-এর প্রমাণ ছোট আর মসৃণ, তাই AI সহকারী এগুলো আত্মবিশ্বাসের সঙ্গে লেখে। ভুলগুলো সাধারণত একটি শব্দে লুকিয়ে থাকে: “স্বাধীন”, “প্রত্যাশা”, “অন্তত”. এই পর্বের বিষয়ে কয়েকটি ভুল নিয়মিত দেখা যায়:

AI-এর ভুলকীভাবে ধরবেন
“প্রত্যাশিত সংখ্যা ≥ 1, তাই সবসময় অন্তত একটি থাকে”প্রত্যাশা শুধু “কোথাও ≥” দেয়; ছোট ক্ষেত্রে সব outcome গুনে counterexample খুঁজুন
বারবার চালানোর ভুল-সীমা গুণ করা, অথচ run-গুলো স্বাধীন নয় (একই seed, একই r)প্রতিটি run-এর এলোমেলো bit কোথা থেকে আসে, তা কোডে দেখুন
Las Vegas আর Monte Carlo উল্টে বলা, বা Karger-কে Las Vegas বলাজিজ্ঞেস করুন: উত্তর কি কখনো ভুল হতে পারে? সময় কি নির্দিষ্ট?
Schwartz–Zippel ℤn-এ যৌগিক n-এ খাটানো, বা degree d-এর জায়গায় চলকের সংখ্যা বসানোField আর মোট degree-র শর্ত চান; ℤ8-এ x2 − 1-এর মতো উদাহরণে পরীক্ষা করুন
Karger-এর সীমা 1/n বা 1/n2 বলা, বা কত run লাগে তা ভুল হিসাবTelescoping গুণফলটি নিজে n = 4, 5-এ লিখে মেলান
Erdős বা Freivalds-এর সাল, বা Ramsey সংখ্যার মান বানিয়ে বলাবিশ্বস্ত পাঠ্যবই বা মূল প্রবন্ধে মেলান; অজানা মান “অজানা” বলা হয়েছে কি না দেখুন

AI-এর কাছে randomized যুক্তি চাইলে এমন কাঠামো দিন, যাতে প্রতিটি সম্ভাবনার দাবি আলাদা করে যাচাই করা যায়:

নিচের randomized algorithm বা probabilistic যুক্তিটি ধাপে ধাপে বিশ্লেষণ করো: বিষয়: [যেমন Karger-এর min cut, বা MAX-CUT ≥ m/2] ১. Probability space স্পষ্ট লেখো: কোন মুদ্রা ছোড়া হয়, কোনগুলো স্বাধীন। ২. Algorithm-টি Las Vegas না Monte Carlo, আর ভুল কোন দিকে হতে পারে, তা বলো। ৩. প্রতিটি সম্ভাবনা বা প্রত্যাশার ধাপের পাশে নিয়মটির নাম লেখো (union bound, linearity, chain rule, স্বাধীনতা)। ৪. প্রতিটি উপপাদ্যের শর্ত (field, তিনটি ভিন্ন চলক, সংযুক্ত গ্রাফ) উল্লেখ করো। ৫. শেষে itertools আর fractions.Fraction দিয়ে ছোট ক্ষেত্রের নির্ভুল গণনা, আর seed দেওয়া একটি simulation-এর Python কোড দাও। ৬. কোনো সাল বা নাম নিয়ে নিশ্চিত না হলে তা স্পষ্ট করে বলো।

AI-এর উত্তর হাতে পেলে — যাচাইয়ের চেকলিস্ট

এই পর্বের সব যুক্তি একটি ছোট সরঞ্জাম-বাক্স থেকে এসেছে: union bound, স্বাধীন ঘটনার গুণ, chain rule আর linearity of expectation. AI-এর যুক্তি পড়ার সময় প্রতিটি ধাপে জিজ্ঞেস করুন, এখানে এই চারটির কোনটি খাটানো হলো, আর তার শর্ত মেটে কি না। তাহলে বেশিরভাগ ভুল নিজেই ধরা পড়ে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।

প্র ০১Erdős-এর ১৯৪৭ সালের Ramsey প্রমাণকে কেন “probabilistic method”-এর জন্ম ধরা হয়? যে বস্তুর অস্তিত্ব প্রমাণ হলো, তা নিজে বানানো এত কঠিন কেন?

Hungarian গণিতবিদ Paul Erdős ১৯৪৭ সালে Bulletin of the American Mathematical Society-তে একটি ছোট প্রবন্ধে R(k, k) > 2k/2 প্রমাণ করেন। প্রমাণটি এই পর্বের উপপাদ্য ৬.২-এর মতোই: এলোমেলো রং, একটি সেট একরঙা হওয়ার সম্ভাবনা, আর সব সেটের ওপর union bound. Erdős নিজে মূল প্রবন্ধে সম্ভাবনার ভাষা ব্যবহার না করে গোনার ভাষায় লিখেছিলেন বলে জানা যায়: “খারাপ রঙের সংখ্যা মোট রঙের সংখ্যার চেয়ে কম”. দুটি একই কথা, কারণ সসীম সমান সম্ভাব্য Ω-এ সম্ভাবনা মানেই গোনা (পর্ব ৩৮)। এর আগেও এলোমেলো যুক্তির নমুনা ছিল, যেমন Szele-র ১৯৪৩ সালের tournament-এর একটি ফল, কিন্তু Erdős এই কৌশলকে একটি পদ্ধতি হিসেবে বারবার ব্যবহার করে জনপ্রিয় করেন, আর পরে Joel Spencer-সহ অন্যরা একে পূর্ণ একটি শাখায় পরিণত করেন।

প্রমাণটির অদ্ভুত দিক হলো, এটি বলে প্রায় সব রংই ভালো, অথচ একটিও দেখায় না। স্বাভাবিক প্রশ্ন: প্রায় সবই যদি ভালো, তাহলে একটি খুঁজে নেওয়া কঠিন কেন? এলোমেলো একটি রং নিয়ে যাচাই করলেই তো হয়। সমস্যা হলো যাচাইয়ে: Kn-এর একটি রঙে একরঙা Kk আছে কি না দেখতে C(n, k)টি সেট দেখতে হয়, যা k বাড়লে অসম্ভব রকম বড়। তাই “এলোমেলোভাবে বানাও, প্রায় নিশ্চিতভাবে ভালো” বলা যায়, কিন্তু “এটি ভালো” বলে প্রমাণসহ দেখানো যায় না। একটি নির্দিষ্ট সূত্রে (explicit) এমন রং বানানো, যা 2k/2-এর কাছাকাছি n-এ কাজ করে, বহু দশক ধরে একটি গবেষণার প্রশ্ন; Erdős নিজে এর জন্য পুরস্কার ঘোষণা করেছিলেন বলে জানা যায়, আর explicit নির্মাণ এখনো এলোমেলো যুক্তির সমান শক্তিশালী নয়।

কম্পিউটার বিজ্ঞানে এই ফাঁকটি বারবার দেখা যায়। ভালো error-correcting code, ভালো expander graph, ভালো hash function family: প্রতিটির ক্ষেত্রেই এলোমেলো বস্তু প্রায় নিশ্চিতভাবে ভালো, কিন্তু নির্দিষ্টভাবে বানানো কঠিন। এই কারণেই derandomization আর pseudorandomness তত্ত্বের এত গুরুত্ব।

মূল উপলব্ধি: Probabilistic method অস্তিত্ব প্রমাণ করে গোনার সাহায্যে, কিন্তু খুঁজে পাওয়া আর যাচাই করা আলাদা সমস্যা, যা অনেক সময় অনেক কঠিন।

প্র ০২“Monte Carlo” আর “Las Vegas” নাম দুটি কোথা থেকে এল? Algorithm-এ এলোমেলোতা কীভাবে গবেষণার মূলধারায় এল?

“Monte Carlo” নামটি ১৯৪০-এর দশকের শেষে Los Alamos-এর গবেষণা থেকে আসে। Stanisław Ulam, John von Neumann আর Nicholas Metropolis নিউট্রনের চলাচলের মতো সমস্যায় এলোমেলো নমুনা দিয়ে হিসাব করার পদ্ধতি ব্যবহার করেন, আর Metropolis মোনাকোর বিখ্যাত জুয়ার শহরের নামে পদ্ধতিটির নাম দেন বলে সাধারণত বলা হয়; Metropolis আর Ulam ১৯৪৯ সালে এই নামে একটি প্রবন্ধ প্রকাশ করেন। এখানে আমরা নামটি শুধু একটি শহরের নাম হিসেবেই দেখি; পদ্ধতিটির সঙ্গে জুয়ার কোনো সম্পর্ক নেই, শুধু এলোমেলোতার মিল। “Las Vegas algorithm” নামটি অনেক পরে, László Babai ১৯৭৯ সালের কাছাকাছি একটি graph isomorphism-এর কাজে দেন বলে জানা যায়, Monte Carlo-র বিপরীত ধরন বোঝাতে: সময় এলোমেলো, কিন্তু উত্তর নিশ্চিত।

১৯৭০-এর দশকে randomized algorithm তাত্ত্বিক কম্পিউটার বিজ্ঞানের কেন্দ্রে আসে। Robert Solovay আর Volker Strassen ১৯৭৭ সালে একটি randomized primality test দেন; Michael Rabin, Gary Miller-এর আগের একটি নির্ধারিত পরীক্ষাকে ভিত্তি করে, ১৯৭৬–৮০ সালে Miller–Rabin পরীক্ষা দেন (পর্ব ২৫)। একই সময়ে Rūsiņš Freivalds ১৯৭৭ সালে matrix যাচাই দেখান। এই কাজগুলোর পর একটি প্রশ্ন জোরালো হয়: এলোমেলোতা কি গণনাকে মৌলিকভাবে বেশি শক্তিশালী করে? এ থেকে জটিলতা-শ্রেণি BPP, RP আর ZPP-এর সংজ্ঞা আসে, যা যথাক্রমে দুই-দিকের ভুল, এক-দিকের ভুল আর Las Vegas ধরনের polynomial-time algorithm-কে ধরে।

পরে randomized quicksort, Karger-এর min cut, hashing-এর universal family, আর আজকের streaming ও machine learning-এর বহু পদ্ধতি এই ধারাতেই আসে। বাস্তব system-এ এলোমেলোতা ব্যবহারের দুটি বড় কারণ: সবচেয়ে খারাপ ইনপুট এড়ানো (প্রতিপক্ষ ইনপুট বাছে, মুদ্রা নয়), আর সরলতা (Karger-এর algorithm কয়েক লাইনের, যেখানে নির্ধারিত min cut algorithm অনেক জটিল)।

মূল উপলব্ধি: দুটি নাম শুধু শহরের নাম, কিন্তু তারা দুটি সত্যিই ভিন্ন নিশ্চয়তা বোঝায়: সময় নিশ্চিত, উত্তর প্রায় নিশ্চিত; বনাম উত্তর নিশ্চিত, সময় প্রত্যাশায়।

প্র ০৩এলোমেলোতা কি সত্যিই দরকার? Primality-র AKS পরীক্ষা, BPP আর derandomization নিয়ে আজ কী জানা আছে?

দীর্ঘদিন primality testing ছিল এলোমেলোতার সাফল্যের প্রধান উদাহরণ: Miller–Rabin দ্রুত আর বাস্তবে নির্ভরযোগ্য, অথচ কোনো নির্ধারিত polynomial-time পরীক্ষা জানা ছিল না (Miller-এর নির্ধারিত সংস্করণ একটি অপ্রমাণিত অনুমান, generalized Riemann hypothesis, ধরে নেয়)। ২০০২ সালে কানপুরের IIT-র Manindra Agrawal আর তাঁর দুই ছাত্র Neeraj Kayal ও Nitin Saxena একটি নির্ধারিত polynomial-time primality test প্রকাশ করেন, যা AKS নামে পরিচিত। এটি দেখায়, অন্তত এই সমস্যায় এলোমেলোতা অপরিহার্য নয়। মজার ব্যাপার, AKS-এর মূল ভাবনা একটি polynomial identity: n মৌলিক হলে (x + a)n ≡ xn + a (mod n), অর্থাৎ এই পর্বের polynomial identity testing-এর একটি বিশেষ নির্ধারিত সমাধান। তবু বাস্তবে Miller–Rabin-ই ব্যবহৃত হয়, কারণ তা অনেক দ্রুত।

সাধারণ প্রশ্নটি হলো BPP = P কি না: polynomial সময়ে, ছোট ভুলসহ, এলোমেলোতা দিয়ে যা করা যায়, তা কি এলোমেলোতা ছাড়াও করা যায়? এটি অপ্রমাণিত, কিন্তু Russell Impagliazzo আর Avi Wigderson ১৯৯৭ সালের কাছাকাছি দেখান, কিছু সমস্যা যদি যথেষ্ট কঠিন হয় (একটি বিশ্বাসযোগ্য কিন্তু অপ্রমাণিত অনুমান), তাহলে BPP = P. এই “hardness versus randomness” ধারণা অনুযায়ী কঠিনতা থেকে ভালো pseudorandom generator বানানো যায়, যা algorithm-এর মুদ্রার জায়গা নিতে পারে। তাই অনেক গবেষক বিশ্বাস করেন, এলোমেলোতা polynomial-time গণনার শক্তি মৌলিকভাবে বাড়ায় না, শুধু অনেক algorithm-কে সরল আর দ্রুত করে।

উল্টো দিকে, কিছু ক্ষেত্রে এলোমেলোতা প্রমাণিতভাবে অপরিহার্য: যোগাযোগ-জটিলতা (দুজনের দুটি বড় ফাইল সমান কি না যাচাই, যেখানে এলোমেলো fingerprint সূচকীয় কম bit পাঠায়), cryptography-র key, আর প্রতিপক্ষের বিরুদ্ধে খেলা। এই পর্বের method of conditional expectations হলো derandomization-এর সবচেয়ে সহজ, সরাসরি কৌশল, যা MAX-CUT আর MAX-3SAT-এ পুরোপুরি কাজ করে।

মূল উপলব্ধি: এলোমেলোতা অনেক সমস্যায় সরলতা আর গতি দেয়; সেটি গণনার মৌলিক শক্তি বাড়ায় কি না, তা একটি বড় খোলা প্রশ্ন, যার উত্তর সম্ভবত “না” বলে অনেকে মনে করেন।

প্র ০৪Min cut-এর জন্য নির্ধারিত algorithm থাকতে Karger-এর এলোমেলো algorithm এত আলোচিত কেন? এর প্রমাণ থেকে আর কী শেখা যায়?

Global min cut-এর একটি পুরোনো নির্ধারিত পথ ছিল max-flow ব্যবহার করা: একটি vertex s স্থির রেখে প্রতিটি t-এর জন্য s-t min cut বের করা (max-flow min-cut theorem, DSA কোর্সের পর্ব ৪৭), অর্থাৎ n − 1টি flow সমস্যা। পরে Nagamochi আর Ibaraki, আর তাদের ওপর ভিত্তি করে Stoer আর Wagner (১৯৯৭ সালের কাছাকাছি) flow ছাড়াই একটি নির্ধারিত algorithm দেন। David Karger ১৯৯৩ সালে, ছাত্রাবস্থায়, contraction algorithm দেন, যার বিশ্লেষণ এই পর্বের উপপাদ্য ৫.১. তাৎক্ষণিক নজর কাড়ে এর সরলতা: কোনো flow নেই, কোনো জটিল তথ্য-কাঠামো নেই, শুধু এলোমেলো edge চাপা। পরে Karger আর Clifford Stein ১৯৯৬ সালে recursive সংস্করণে (শুধু শুরুর ধাপগুলো একবার, শেষের ঝুঁকিপূর্ণ ধাপগুলো বারবার) সময় অনেক কমান।

প্রমাণের সবচেয়ে সুন্দর উপজাত হলো একটি গণনার উপপাদ্য: যেকোনো n-vertex গ্রাফে আলাদা global min cut-এর সংখ্যা ≤ C(n, 2). কারণ প্রতিটি নির্দিষ্ট min cut-কে Karger অন্তত 1/C(n, 2) সম্ভাবনায় ফেরত দেয়, আর “min cut K1 ফেরত” আর “K2 ফেরত” পরস্পর বর্জনশীল ঘটনা; তাদের সম্ভাবনার যোগ ≤ 1. এটি একটি এলোমেলো algorithm দিয়ে একটি নির্ধারিত গণনার ফল প্রমাণ, probabilistic method-এর আরেক রূপ। n-টি vertex-এর একটি cycle দেখায় সীমাটি সঠিক: যেকোনো দুটি edge কাটলে cycle দুই টুকরো হয়, তাই min cut ঠিক C(n, 2)টি।

নেটওয়ার্কের নির্ভরযোগ্যতায় এটি কাজে লাগে: প্রতিটি রাস্তা স্বাধীনভাবে একটি সম্ভাবনায় বন্ধ হলে নেটওয়ার্ক বিচ্ছিন্ন হওয়ার সম্ভাবনার হিসাব ছোট cut-গুলোর সংখ্যার ওপর নির্ভর করে, আর Karger-এর সীমা বলে সেগুলো বেশি নয়। Karger এই ভাবনায় network reliability-র একটি approximation algorithm-ও দিয়েছিলেন বলে জানা যায়।

মূল উপলব্ধি: একটি ভালো randomized algorithm শুধু দ্রুত উত্তর দেয় না, তার বিশ্লেষণ থেকেই সমস্যাটির কাঠামো সম্পর্কে নতুন উপপাদ্য বেরিয়ে আসে।

প্র ০৫MAX-CUT-এ 1/2 আর MAX-3SAT-এ 7/8 এত সহজে পাওয়া গেল; এর চেয়ে ভালো করা কি সম্ভব? Goemans–Williamson আর Håstad-এর ফল কী বলে?

এলোমেলো ভাগ MAX-CUT-এ সর্বোত্তমের অন্তত অর্ধেক দেয়, আর বহু বছর এর চেয়ে ভালো কোনো polynomial-time নিশ্চয়তা জানা ছিল না। ১৯৯৫ সালে Michel Goemans আর David Williamson একটি নতুন পথ দেখান: প্রতিটি vertex-কে একটি সংখ্যার বদলে উচ্চমাত্রিক একটি unit vector দেওয়া, semidefinite programming দিয়ে vector-গুলো এমনভাবে সাজানো যাতে প্রতিবেশীরা যতটা সম্ভব উল্টো দিকে থাকে, তারপর একটি এলোমেলো hyperplane দিয়ে vector-গুলো দুই ভাগে কাটা। একটি edge কাটা পড়ার সম্ভাবনা তার দুই vector-এর মাঝের কোণের ওপর নির্ভর করে, আর বিশ্লেষণে প্রায় 0.878-এর নিশ্চয়তা আসে। এলোমেলোতা এখানেও আছে, শুধু অনেক বুদ্ধিমান রূপে।

MAX-3SAT-এ গল্পটি আরও নাটকীয়। এলোমেলো মান-বসানোর 7/8 এতই সহজ যে মনে হতে পারে আরও ভালো সহজেই পাওয়া যাবে। কিন্তু Johan Håstad ১৯৯৭ সালের সম্মেলনে, আর ২০০১ সালের journal সংস্করণে, PCP theorem-এর ভিত্তিতে প্রমাণ করেন যে যেকোনো ε > 0-এর জন্য 7/8 + ε নিশ্চয়তার polynomial-time algorithm থাকলে P = NP. অর্থাৎ যদি P ≠ NP (যা প্রায় সবাই বিশ্বাস করেন), তাহলে এই পর্বের দুই লাইনের এলোমেলো algorithm আর তার derandomized রূপই সেরা সম্ভব নিশ্চয়তা দেয়। খুব কম সমস্যায় এমন নিখুঁত “সহজ = সর্বোত্তম” ফল জানা আছে।

MAX-CUT-এর 0.878-ও হয়তো সর্বোত্তম: Subhash Khot-এর ২০০২ সালের Unique Games Conjecture সত্য হলে, Khot, Kindler, Mossel আর O'Donnell-এর ২০০৭ সালের কাজ অনুযায়ী Goemans–Williamson-এর ধ্রুবকের চেয়ে ভালো করা NP-hard. Conjecture-টি এখনো অপ্রমাণিত, তাই এটি শর্তসাপেক্ষ সত্য। এই গল্পগুলো দেখায় কেন এই পর্বের সহজ প্রত্যাশার যুক্তি শুধু একটি অনুশীলনী নয়: অনেক সময় এটিই সমস্যার আসল সীমা ছুঁয়ে ফেলে।

মূল উপলব্ধি: সহজ এলোমেলো ভাগ একটি ভিত্তিরেখা দেয়; MAX-3SAT-এ সেটিই সেরা সম্ভব (P ≠ NP হলে), আর MAX-CUT-এ এলোমেলো hyperplane তাকে ছাড়িয়ে যায়।

অনুশীলন

আগে খাতায় করুন, তারপর উত্তর খুলে মেলান।

  1. প্রমাণ: উপপাদ্য ৫.১ (Karger-এর সীমা) ব্যবহার করে প্রমাণ করুন, n ≥ 2 vertex-এর যেকোনো সংযুক্ত গ্রাফে আলাদা global min cut-এর সংখ্যা বড়জোর C(n, 2) = n(n − 1)/2.
    1. ধরুন আলাদা min cut K1, …, Kt. প্রতিটি i-এর জন্য Fi = “Karger-এর একটি run ঠিক Ki ফেরত দেয়”. — সংজ্ঞা
    2. একটি run শেষে একটিই cut ফেরত দেয়, তাই i ≠ j হলে Fi ∩ Fj = ∅. — mutually exclusive
    3. উপপাদ্য ৫.১: প্রতিটি P(Fi) ≥ 1/C(n, 2). — উপপাদ্য ৫.১
    4. Additivity আর P(Ω) = 1: 1 ≥ P(F1 ∪ … ∪ Ft) = ∑ P(Fi) ≥ t/C(n, 2), তাই t ≤ C(n, 2). ∎ — Kolmogorov-এর স্বতঃসিদ্ধ

    সীমাটি সঠিক: n-টি vertex-এর cycle-এ যেকোনো দুটি edge সরালে ঠিক দুটি টুকরো হয়, আর একটি edge সরালে হয় না, তাই min cut-এর আকার 2 আর তাদের সংখ্যা ঠিক C(n, 2); scratch-এ n = 5-এ সব ভাগ গুনে ১০টি মেলানো।

  2. হিসাব: (ক) Freivalds-এ ভুল C ধরা না পড়ার সম্ভাবনা ≤ 10−6 করতে সর্বনিম্ন কয়টি round যথেষ্ট? (খ) ১০টি vertex-এর গ্রাফে Karger-এর সীমা দিয়ে, একটি নির্দিষ্ট min cut না পাওয়ার সম্ভাবনা ≤ 0.01 করতে সর্বনিম্ন কয়টি স্বাধীন run যথেষ্ট?

    (ক) 2−k ≤ 10−6 মানে 2k ≥ 106. 219 = 524288 যথেষ্ট নয়, 220 = 1048576 যথেষ্ট। উত্তর ২০ round.

    (খ) এক run-এ সাফল্য ≥ 2/(10 · 9) = 1/45, তাই T run-এ ব্যর্থতা ≤ (44/45)T. সবচেয়ে ছোট T যাতে এটি ≤ 0.01: T = 205 (scratch-এ Fraction দিয়ে খোঁজা)। সহজ সূত্র e−T/45 ≤ 0.01 দেয় T ≥ 45 ln 100 ≈ 207.2, অর্থাৎ 208: সামান্য বেশি, কিন্তু নিরাপদ দিকে।

  3. আউটপুট অনুমান: কোড না চালিয়ে বলুন কী ছাপা হবে। তারপর যেকোনো Python-এ চালিয়ে মেলান।
    from fractions import Fraction
    from math import comb
    print(comb(6, 4), Fraction(2, 2 ** comb(4, 2)))
    print(comb(6, 4) * Fraction(2, 2 ** comb(4, 2)))
    print(Fraction(7, 8) * 16, Fraction(1, 2) ** 10)
    15 1/32
    15/32
    14 1/1024

    প্রথম লাইন: K6-এ ৪-vertex সেট C(6, 4) = 15টি, আর একটি সেটের ৬টি edge একরঙা হওয়ার সম্ভাবনা 2/26 = 1/32. দ্বিতীয় লাইন: একরঙা K4-এর প্রত্যাশিত সংখ্যা 15/32 < 1, তাই R(4, 4) > 6. তৃতীয় লাইন: ১৬টি clause-এর 3-CNF-এ প্রত্যাশিত মেটানো clause 14, আর Freivalds-এর ১০ round-এর সীমা 1/1024. Fraction লঘিষ্ঠ আকারে ছাপে, আর 14/1 ছাপা হয় শুধু 14. আউটপুট CPython-এ চালিয়ে মেলানো।

  4. প্রমাণের ভুল ধরুন: একজন লিখলেন: “দাবি: K6-এর প্রতিটি লাল-নীল রঙে একটি একরঙা ত্রিভুজ আছে। প্রমাণ: এলোমেলো রঙে প্রতিটি ত্রিভুজ 2 · 2−3 = 1/4 সম্ভাবনায় একরঙা, আর ত্রিভুজ C(6, 3) = 20টি। তাই একরঙা ত্রিভুজের প্রত্যাশিত সংখ্যা 20/4 = 5 ≥ 1, অর্থাৎ প্রতিটি রঙে অন্তত একটি একরঙা ত্রিভুজ থাকে। ∎” দাবিটি সত্য (R(3, 3) = 6), কিন্তু প্রমাণটি কোথায় ভুল?
    • ভুল ধাপ: “প্রত্যাশা ≥ 1, তাই প্রতিটি রঙে ≥ 1”. লেমা ৭.১ শুধু বলে কোনো রঙে সংখ্যাটি ≥ 5, সব রঙে নয়। গড় বড় হলেও কিছু ফল 0 হতে পারে।
    • একই যুক্তির counterexample: K5-এ প্রত্যাশা C(5, 3)/4 = 10/4 = 2.5 ≥ 1, অথচ K5-এর একটি রঙে কোনো একরঙা ত্রিভুজ নেই: বাইরের পঞ্চভুজ লাল, ভেতরের তারা নীল। Scratch-এ ১০টি ত্রিভুজই পরীক্ষা করে মেলানো। একই যুক্তি তাই একটি মিথ্যা দাবিও “প্রমাণ” করত।
    • সঠিক পথ: R(3, 3) ≤ 6-এর আসল প্রমাণ pigeonhole (পর্ব ৩২): একটি vertex-এর ৫টি edge-এর অন্তত ৩টি এক রঙের, তারপর সেই ৩ প্রতিবেশীর মাঝের edge দেখা। প্রত্যাশা দিয়ে “সবসময়” প্রমাণ করা যায় না; “কখনো কখনো” বা “অস্তিত্ব” প্রমাণ করা যায়।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমErdős-এর প্রমাণ R(k, k) > n-এর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. Kn-এর প্রতিটি edge স্বাধীনভাবে 1/2 সম্ভাবনায় লাল বা নীল করা
  2. একটি নির্দিষ্ট k-vertex সেট একরঙা হওয়ার সম্ভাবনা 21 − C(k, 2) বের করা
  3. Union bound: কোনো একরঙা Kk থাকার সম্ভাবনা ≤ C(n, k) · 21 − C(k, 2)
  4. n-এর মান বসিয়ে এই সীমা 1-এর কম দেখানো
  5. সম্ভাবনা ধনাত্মক বলে একরঙা Kk-হীন রং আছে, তাই R(k, k) > n

Randomized quicksort সবসময় সঠিকভাবে সাজায়, শুধু তুলনার সংখ্যা এলোমেলো। এটি কোন ধরনের algorithm?

  • Las Vegas
  • Monte Carlo
  • Deterministic
  • Approximation algorithm

C ≠ AB হলে Freivalds-এর প্রতিটি round-এ ভুল ধরা না পড়ার সম্ভাবনা ≤ 1/2. স্বাধীন এলোমেলো vector নিয়ে ১০ round চালালে ভুল C পাস করার সম্ভাবনা সবচেয়ে বেশি কত?

  • 1/2
  • 1/20
  • 1/1024
  • 0

৬টি vertex-এর একটি সংযুক্ত গ্রাফে Karger-এর contraction algorithm একবার চালালে একটি নির্দিষ্ট global min cut ফেরত দেওয়ার সম্ভাবনা অন্তত কত বলে প্রমাণিত?

  • 1/6
  • 1/15
  • 1/36
  • 1/2

Kn-এর edge-গুলো স্বাধীনভাবে 1/2 সম্ভাবনায় লাল বা নীল করা হলো। ৪টি নির্দিষ্ট vertex-এর মাঝের সব edge এক রঙের হওয়ার সম্ভাবনা কত?

  • 1/16
  • 1/64
  • 1/8
  • 1/32

১০টি edge-এর একটি গ্রাফে প্রতিটি vertex স্বাধীনভাবে 1/2 সম্ভাবনায় দুই দলের একটিতে দেওয়া হলো। নিচের কোন বক্তব্য প্রমাণিতভাবে সত্য?

  • প্রতিটি এলোমেলো ভাগে cut-এ ঠিক ৫টি edge
  • কোনো একটি ভাগে সব ১০টি edge কাটা যায়
  • অন্তত একটি ভাগে cut-এ ৫ বা তার বেশি edge
  • edge-গুলো স্বাধীন নয় বলে প্রত্যাশা হিসাব করা যায় না

১৬টি clause-এর একটি 3-CNF সূত্রে প্রতিটি clause-এ তিনটি ভিন্ন চলক। প্রমাণিতভাবে অন্তত কয়টি clause একসঙ্গে মেটানো যায়?

  • 8
  • 14
  • 16
  • 12

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. দুই ধরন: Las Vegas = উত্তর নিশ্চিত, সময় এলোমেলো (quickselect-এর প্রত্যাশা ≤ 8n); Monte Carlo = সময় নির্দিষ্ট, ভুল ≤ ε; স্বাধীন k run-এ one-sided ভুল ≤ εk.
  2. এলোমেলো যাচাই: Freivalds-এ প্রতি round-এ ভুল ≤ 1/2, খরচ 3n2; Schwartz–Zippel: degree d-এর অশূন্য polynomial এলোমেলো বিন্দুতে শূন্য ≤ d/|S| সম্ভাবনায় (field-এ)।
  3. Karger: একটি run একটি নির্দিষ্ট min cut পায় ≥ 2/(n(n − 1)) সম্ভাবনায় (degree ≥ c, telescoping); ফলে min cut-এর সংখ্যা ≤ C(n, 2).
  4. Probabilistic method: P(ভালো) > 0 হলে ভালো বস্তু আছে; C(n, k) · 21 − C(k, 2) < 1 হলে R(k, k) > n, বিশেষত R(k, k) > 2k/2.
  5. প্রত্যাশার যুক্তি: E[X] = μ হলে কোথাও X ≥ μ; প্রতিটি গ্রাফে cut ≥ m/2, প্রতিটি 3-CNF-এ ≥ 7m/8 clause; conditional expectations দিয়ে তা নির্ধারিতভাবে খোঁজা যায়।

পরের পর্বে: পর্ব ৪৪ “Recurrence দিয়ে মডেল — Fibonacci, Hanoi আর bit string”: নতুন মডিউল ৮ শুরু। গণনার প্রশ্নকে ছোট প্রশ্নের ভাষায় লেখা, যেমন Hanoi টাওয়ারে কয়টি চাল লাগে বা পরপর দুটি 0 ছাড়া কয়টি bit string আছে, তার মডেল বানানোর কৌশল।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান