এই পর্বে যা শিখবেন
- Formal power series-এর সংজ্ঞা, যোগ-গুণ, কখন উল্টানো (1/A) যায় তার প্রমাণ, আর convolution উপপাদ্যের প্রমাণ
- প্রমিত ধারার সারণি থেকে সহগ বের করা, আর শর্তসহ বণ্টন ও খুচরো টাকার প্রশ্ন generating function দিয়ে গোনা
- Generating function আর partial fraction দিয়ে linear recurrence সমাধান, আর Catalan-এর closed form-এর বীজগাণিতিক প্রমাণ
- Exponential generating function কখন লাগে, আর Euler-এর partition উপপাদ্যের generating function প্রমাণ
- প্রতিটি সূত্র Python-এ ধারার list দিয়ে গুণ-ভাগ করে brute force-এর সঙ্গে মেলানো
১ · ধারাকে একটি থলেতে ভরা — formal power series
এই মডিউলে এ পর্যন্ত একটি ধারা মানে ছিল আলাদা আলাদা সংখ্যা: H(0), H(1), H(2), …, আর তাদের মাঝে একটি recurrence. পর্ব ৪৪ “Recurrence দিয়ে মডেল — Fibonacci, Hanoi আর bit string”-এ মডেল বানানো, পর্ব ৪৫ “Linear recurrence সমাধান — characteristic equation” আর পর্ব ৪৬ “Non-homogeneous recurrence আর particular solution”-এ সমাধান। এবার একটি সম্পূর্ণ ভিন্ন কৌশল: পুরো ধারাটিকে একসঙ্গে একটি বস্তু হিসেবে ধরা, আর সেই বস্তুর ওপর বীজগণিত চালানো।
ঈদের আগে বাজারঘরের গুদামে প্রতিটি তাকে একটি করে লেবেল: “তাক ০”, “তাক ১”, “তাক ২”, … প্রতিটি তাকে কয়টি বাক্স আছে, তা একটি ধারা। পুরো আলমারিটি একটি জিনিস; আপনি তাকে ঠেলে সরাতে পারেন (সব বাক্স এক তাক ওপরে), দুটি আলমারি পাশাপাশি জোড়া দিতে পারেন, কিন্তু কোনো বাক্স হারায় না, কারণ প্রতিটি তাকের লেবেল আলাদা। Generating function-এ xn হলো সেই লেবেল: “এই সংখ্যাটি n নম্বর তাকের”.
ধারা (an)n≥0-এর ordinary generating function (OGF) হলো
A(x) = ∑n≥0 anxn = a0 + a1x + a2x2 + ⋯
একে একটি formal power series হিসেবে পড়া হয়: আসলে এটি সহগের অসীম তালিকা (a0, a1, …) মাত্র, আর x একটি চিহ্ন। xn-এর সহগকে লেখা হয় [xn]A(x) = an. দুটি series সমান মানে প্রতিটি সহগ সমান। যোগ আর গুণ:
A + B = ∑(an + bn)xn, A · B = ∑n (∑k=0n akbn−k) xn
দুটি ছোট উদাহরণ। বাজারঘরের তিনটি পণ্য থেকে কয়েকটি বাছাইয়ের উপায় ধারা 1, 3, 3, 1 (k-টি বাছাই C(3, k) উপায়ে), তাই generating function 1 + 3x + 3x2 + x3 = (1 + x)3: প্রতিটি পণ্যের জন্য একটি গুণনীয়ক (1 + x), “নেব না” বা “নেব”. আর দৈর্ঘ্য n-এর bit string-এর সংখ্যা 2n-এর generating function 1 + 2x + 4x2 + ⋯, যার একটি ছোট রূপ একটু পরেই পাবেন। প্রথমটি সসীম polynomial, দ্বিতীয়টি অসীম series; দুটিই এই পর্বের বস্তু।
“Formal” কেন। ক্যালকুলাসে 1 + x + x2 + ⋯ = 1/(1 − x) শুধু |x| < 1 হলে সত্য, কারণ সেখানে x একটি সংখ্যা আর যোগফলটি একটি limit. এখানে আমরা কখনো x-এ সংখ্যা বসাই না। গুণফলের প্রতিটি সহগ ∑k=0n akbn−k মাত্র n + 1টি পদের সসীম যোগ। তাই যেকোনো সহগ সসীম হিসাবে বের হয়, আর “অসীম যোগ মেলে কি না” প্রশ্নটি অপ্রাসঙ্গিক। n! xn-এর মতো series, যা কোনো x ≠ 0-তে মেলে না, তা-ও একটি বৈধ formal power series. তাহলে 1/(1 − x) লেখার মানে কী? উত্তর উল্টানোর সংজ্ঞায়।
A(x)-এর এমন একটি series B(x) আছে যাতে A(x)B(x) = 1, যদি এবং কেবল যদি a0 ≠ 0 (সহগগুলো ℚ বা ℝ-এর মতো field থেকে)। তখন B অনন্য, আর তাকে 1/A(x) লেখা হয়।
- AB = 1-এর মানে [x0]: a0b0 = 1, আর n ≥ 1-এ [xn]: ∑k=0n akbn−k = 0. — গুণের সংজ্ঞা, সহগ মেলানো
- a0 = 0 হলে প্রথম সমীকরণ 0 = 1 হয়ে যায়, তাই B নেই। — বিরোধ
- a0 ≠ 0 হলে b0 = 1/a0, আর n ≥ 1-এ bn = −(1/a0) ∑k=1n akbn−k: ডান পাশে শুধু আগের b, তাই প্রতিটি bn একভাবেই নির্ধারিত। — strong induction (পর্ব ১১)
- এভাবে বানানো B সব সমীকরণ মেটায়, আর প্রতিটি ধাপে বিকল্প ছিল না, তাই B অনন্য। ∎ — নির্মাণ
উদাহরণ: A = 1 − x হলে b0 = 1, আর bn = −(−1 · bn−1) = bn−1, তাই সব bn = 1. অর্থাৎ 1/(1 − x) = 1 + x + x2 + ⋯ একটি বীজগাণিতিক সত্য, কোনো limit ছাড়াই। সরাসরি যাচাই: (1 − x)(1 + x + x2 + ⋯)-এ xn-এর সহগ 1 − 1 = 0 (n ≥ 1). এই ধারাটি geometric series (পর্ব ১৭ “Sequence আর summation — closed form আর বিখ্যাত যোগফল”), তবে এবার সসীম যোগফলের সূত্র নয়, পুরো অসীম ধারাটিই একটি বস্তু।
এই পর্বের পথ। প্রথমে দেখব series-এর গুণ কী গোনে (§২), তারপর শর্তসহ বণ্টন আর খুচরো টাকা (§৩–৪), recurrence আর Catalan (§৫–৬), partition (§৭), আর শেষে লেবেলযুক্ত বস্তুর জন্য আরেক ধরনের থলে (§৮)। প্রতিটি জায়গায় একই ছন্দ: গণনার প্রশ্নকে একটি series-এর সমীকরণে লেখা, বীজগণিতে সরল করা, তারপর একটি সহগ পড়া।
২ · অপারেশন আর convolution — গুণফলের আসল অর্থ
ধারার ওপর যা করতে চান, generating function-এ তার একটি সরল রূপ আছে। A(x) = ∑anxn ধরে:
| ধারায় কাজ | নতুন ধারা | Generating function |
|---|---|---|
| যোগ, ধ্রুবক গুণ | αan + βbn | αA(x) + βB(x) |
| ডানে সরানো (shift) | 0, a0, a1, … | xA(x) |
| বাঁয়ে সরানো | a1, a2, … | (A(x) − a0)/x |
| cn দিয়ে গুণ | cnan | A(cx) |
| n দিয়ে গুণ | nan | xA′(x) (formal derivative) |
| আংশিক যোগফল | a0 + ⋯ + an | A(x)/(1 − x) |
| convolution | ∑k akbn−k | A(x)B(x) |
Formal derivative-ও সংজ্ঞায়: A′(x) = ∑ nanxn−1, কোনো limit নেই। “বাঁয়ে সরানো”-তে x দিয়ে ভাগ বৈধ, কারণ A(x) − a0-এর ধ্রুবক পদ 0. সারণির শেষ সারিটিই সবচেয়ে গুরুত্বপূর্ণ; তার convolution নামটি এই পর্বে বারবার আসবে।
গুণফলের একটি সহগ = একটি কর্ণ বরাবর যোগ
সারি i মানে A থেকে xi, কলাম j মানে B থেকে xj. ঘর (i, j) গুণফলে aibjxi+j দেয়; i + j = 3-এর হলুদ কর্ণের যোগই c3.
ধরুন ak = আকার k-এর “বাঁ বস্তু”-র সংখ্যা আর bj = আকার j-এর “ডান বস্তু”-র সংখ্যা, আর একটি জোড়ার আকার = দুই আকারের যোগ। তাহলে আকার n-এর জোড়ার সংখ্যা cn = ∑k=0n akbn−k, অর্থাৎ C(x) = A(x)B(x).
- আকার n-এর জোড়াগুলোকে বাঁ অংশের আকার k অনুযায়ী ভাগ করুন, k = 0, 1, …, n. ভাগগুলো পরস্পর বিচ্ছিন্ন আর মিলে সব জোড়া। — যোগের নিয়ম (পর্ব ৩১)
- বাঁ আকার k হলে ডান আকার ঠিক n − k; বাঁ অংশ ak উপায়ে আর ডান অংশ স্বাধীনভাবে bn−k উপায়ে। — গুণের নিয়ম
- তাই cn = ∑k akbn−k, যা সংজ্ঞা ১.১ অনুযায়ী [xn]A(x)B(x). ∎ — গুণের সংজ্ঞা
বীজগণিতের দিক থেকে এটি শুধু xk · xn−k = xn: ঘাতগুলো যোগ হয়, আর গণনায় আকারও যোগ হয়। এটিই পুরো পদ্ধতির চাবি। এর প্রথম বড় ফল:
প্রতিটি পূর্ণসংখ্যা n ≥ 1-এর জন্য
1/(1 − x)n = ∑k≥0 C(n + k − 1, k) xk
- 1/(1 − x)n হলো n-টি একই series (1 + x + x2 + ⋯)-এর গুণফল; i-তম গুণনীয়ক থেকে xei পদটি বাছলে মোট ঘাত e1 + ⋯ + en. — উপপাদ্য ২.১ বারবার
- তাই [xk] = e1 + ⋯ + en = k-এর অঋণাত্মক পূর্ণসংখ্যা সমাধানের সংখ্যা। — প্রতিটি পদের সহগ 1
- পর্ব ৩৫ “পুনরাবৃত্তিসহ বাছাই — stars and bars আর multinomial”-এর stars and bars অনুযায়ী সেই সংখ্যা C(n + k − 1, k). ∎ — stars and bars
এখান থেকে একটি ছোট সারণি পাওয়া যায়, যা মুখস্থ রাখলে বেশিরভাগ অঙ্ক হয়ে যায়:
| Generating function | ak = [xk] | কোথা থেকে |
|---|---|---|
| 1/(1 − x) | 1 | উপপাদ্য ১.২ |
| 1/(1 − cx) | ck | x-এর জায়গায় cx |
| 1/(1 − xr) | r ∣ k হলে 1, নইলে 0 | x-এর জায়গায় xr |
| (1 − xm+1)/(1 − x) | k ≤ m হলে 1 | সসীম geometric যোগ |
| (1 + x)n | C(n, k) | binomial theorem (পর্ব ৩৪) |
| 1/(1 − x)n | C(n + k − 1, k) | উপপাদ্য ২.২ |
| x/(1 − x)2 | k | n = 2, তারপর ডানে সরানো |
একটি পুরোনো যোগফল নতুন পথে। 12 + 22 + ⋯ + n2-এর closed form পর্ব ১৭-এ induction দিয়ে প্রমাণ হয়েছে। Generating function দিয়ে সূত্রটি খুঁজে পাওয়া যায়, আগে থেকে জানা ছাড়াই:
- ধারা k-এর generating function x/(1 − x)2 (সারণি)। “n দিয়ে গুণ” নিয়মে আরেকবার: x · d/dx[x/(1 − x)2] = x(1 + x)/(1 − x)3, যা ধারা k2-এর generating function.
- আংশিক যোগফল নিতে 1/(1 − x) দিয়ে গুণ: ∑n (∑k≤n k2) xn = x(1 + x)/(1 − x)4 = x/(1 − x)4 + x2/(1 − x)4.
- উপপাদ্য ২.২-এ n = 4: [xm](1 − x)−4 = C(m + 3, 3). তাই উত্তর C(n + 2, 3) + C(n + 1, 3) = n(n + 1)(2n + 1)/6.
- যাচাই n = 4: C(6, 3) + C(5, 3) = 20 + 10 = 30 = 1 + 4 + 9 + 16. (Scratch-এ n ≤ 7 পর্যন্ত মেলানো।)
শেষ সমতায় দুটি C(·, 3) যোগ করে সরল করা হয়েছে; এই বীজগণিত আপনি নিজে করে দেখতে পারেন। মূল কথা: derivative, shift আর 1/(1 − x) মিলে যোগফলের প্রশ্নকে সারণি পড়ার প্রশ্নে বদলে দেয়।
৩ · সহগ বের করা আর শর্তসহ বণ্টন
পর্ব ৩৫-এ x1 + x2 + x3 = n ধরনের সমীকরণ গুনেছেন। নিম্নসীমা সরল প্রতিস্থাপনে সরে যেত, ঊর্ধ্বসীমায় বাদ দেওয়ার হিসাব লাগত। Generating function-এ প্রতিটি চলকের শর্ত তার নিজের গুণনীয়কে ঢোকে, আর গুণফল বাকি কাজ করে: প্রতিটি চলকের জন্য একটি গুণনীয়ক, প্রতিটি অনুমোদিত মানের জন্য একটি পদ।
উদাহরণ (বাজারঘরের ভাউচার)। বাজারঘর n-টি একই রকম উপহার-ভাউচার তিন শাখায় ভাগ করবে। রাজশাহী শাখা ভাউচার নেয় জোড়ায় জোড়ায় (জোড় সংখ্যা, শূন্যও চলে), সিলেট শাখায় জায়গা আছে বড়জোর ৩টির, আর খুলনা শাখা অন্তত ১টি পাবেই। কয় উপায়ে?
- রাজশাহী: 1 + x2 + x4 + ⋯ = 1/(1 − x2). সিলেট: 1 + x + x2 + x3. খুলনা: x + x2 + ⋯ = x/(1 − x).
- উত্তর = [xn] G(x), যেখানে G(x) = (1 + x + x2 + x3) · x / ((1 − x2)(1 − x)).
- সরল করুন: 1 + x + x2 + x3 = (1 + x)(1 + x2) আর 1 − x2 = (1 − x)(1 + x). তাই G(x) = x(1 + x2)/(1 − x)2.
- x/(1 − x)2-এর সহগ k (সারণি), তাই x3/(1 − x)2-এর xn-এর সহগ n − 2. যোগ করে n ≥ 3 হলে উত্তর n + (n − 2) = 2n − 2.
- n = 10: ১৮টি উপায়। Scratch-এ তিনটি nested loop দিয়ে গুনে মেলানো; নিচের প্রথম Python ব্লকও এটি দেখায়।
| একটি চলকের শর্ত | গুণনীয়ক |
|---|---|
| যেকোনো অঋণাত্মক মান | 1/(1 − x) |
| অন্তত a | xa/(1 − x) |
| বড়জোর u | (1 − xu+1)/(1 − x) |
| জোড় / বিজোড় | 1/(1 − x2) / x/(1 − x2) |
| r-এর গুণিতক (r টাকার কয়েন) | 1/(1 − xr) |
| শুধু 0 বা 1 (হ্যাঁ/না) | 1 + x |
খেয়াল করুন, একটি রাশি (2n − 2) সব n-এর উত্তর একসঙ্গে দিল। এটিই generating function-এর বড় সুবিধা: একটি প্রশ্ন নয়, প্রশ্নের পুরো পরিবার।
ঊর্ধ্বসীমা বীজগণিতে। চারজন গ্রাহকের প্রত্যেকে একটি প্রচারণায় ০ থেকে ৩টি পর্যন্ত পণ্য নিতে পারেন; মোট ১০টি পণ্য কয় উপায়ে যেতে পারে? উত্তর [x10](1 + x + x2 + x3)4 = [x10](1 − x4)4/(1 − x)4. লবকে binomial theorem-এ খুলে 1 − 4x4 + 6x8 − ⋯, আর হরের সহগ C(k + 3, 3) নিলে convolution দেয়
C(13, 3) − 4 · C(9, 3) + 6 · C(5, 3) = 286 − 336 + 60 = 10
x12-এর পদ লাগে না, কারণ 12 > 10. যোগ-বিয়োগের এই ধাঁচ পর্ব ৩৫-এর ঊর্ধ্বসীমার হিসাবের সঙ্গে হুবহু মেলে; আসলে এটি inclusion–exclusion, যার সাধারণ রূপ আর প্রমাণ পরের পর্ব ৪৯ “Inclusion–exclusion আর derangement”-এ। Generating function চিহ্নগুলো নিজে থেকেই ঠিক রাখে।
৪ · খুচরো টাকার প্রশ্ন — ১, ২ আর ৫ টাকার কয়েন
বাজারঘরের ডেলিভারি রাইডারের থলেতে ১, ২ আর ৫ টাকার অনেক কয়েন। একজন গ্রাহককে n টাকা খুচরো ফেরত দিতে হবে। কয়েনের সংগ্রহ কয় রকম হতে পারে (কোন কয়েন আগে দেওয়া হলো তা গোনা হবে না)? এটি একটি coin change প্রশ্ন, আর এর সমীকরণ a + 2b + 5c = n, যেখানে a, b, c অঋণাত্মক। ভিন্ন ওজন থাকায় stars and bars এখানে সরাসরি খাটে না।
১, ২ আর ৫ টাকার কয়েনে n টাকা দেওয়ার উপায় cn হলে
∑n≥0 cnxn = 1 / ((1 − x)(1 − x2)(1 − x5))
- শুধু ৫ টাকার কয়েনে আকার (টাকা) 5c-এর ঠিক একটি সংগ্রহ: generating function 1 + x5 + x10 + ⋯ = 1/(1 − x5). ২ আর ১ টাকার জন্যও একইভাবে 1/(1 − x2) আর 1/(1 − x). — সারণি
- একটি সংগ্রহ = (১ টাকার অংশ, ২ টাকার অংশ, ৫ টাকার অংশ), আর মোট টাকা তিন অংশের টাকার যোগ। — সংগ্রহের গঠন
- উপপাদ্য ২.১ দুবার খাটালে মোট generating function তিনটির গুণফল। ∎ — উপপাদ্য ২.১
এখন x10-এর সহগ হাতে বের করি, গুণনীয়কগুলো একটি একটি করে গুণ করে।
1G = 1/((1−x)(1−x²)(1−x⁵))2শুধু ১ টাকা: aₙ = 13× 1/(1−x²): bₙ = ⌊n/2⌋ + 14× 1/(1−x⁵): b₁₀+b₅+b₀5c₁₀ = 6 + 3 + 1 = 106তালিকা করে মেলানো ✓
| কয়েন | |
| ধারা | |
| [x¹⁰] |
- লক্ষ্য। G(x) = 1/((1 − x)(1 − x2)(1 − x5))-এর x10-এর সহগ চাই। গুণ সহযোগী (associative), তাই একটি একটি গুণনীয়ক নিয়ে এগোনো যায়।
- শুধু ১ টাকা। 1/(1 − x)-এর প্রতিটি সহগ 1: যেকোনো n টাকা ঠিক এক উপায়ে, n-টি ১ টাকার কয়েনে।
- ২ টাকা যোগ। 1/(1 − x) · 1/(1 − x2)-এর xn-এর সহগ bn = দুই টাকার কয়েনের সংখ্যা b-এর পছন্দ, 0 ≤ b ≤ ⌊n/2⌋, তাই ⌊n/2⌋ + 1. n = 0…10-এ 1 1 2 2 3 3 4 4 5 5 6.
- ৫ টাকা যোগ। 1/(1 − x5)-এর শুধু x0, x5, x10-এর সহগ 1. Convolution-এ c10 = b10 · 1 + b5 · 1 + b0 · 1: পাঁচ টাকার কয়েন 0, 1 বা 2টি, বাকি টাকা ১ আর ২ দিয়ে।
- হিসাব। b10 = 6, b5 = 3, b0 = 1, তাই c10 = 10.
- যাচাই। সব সংগ্রহ লিখলে: ৫ টাকা নেই ছয়টি (দুই টাকা 0 থেকে 5টি), একটি ৫ টাকা তিনটি (৫+১×৫, ৫+২+১×৩, ৫+২+২+১), দুটি ৫ টাকা একটি। মোট 6 + 3 + 1 = 10.
শর্ত বদলালে। যদি রাইডারকে অন্তত একটি ৫ টাকার কয়েন দিতেই হয়, ৫ টাকার গুণনীয়ক হয় x5/(1 − x5), তাই উত্তর cn−5: ১০ টাকায় c5 = 4, stepper-এর তালিকার “একটি বা দুটি ৫ টাকা” অংশের 3 + 1. আর ২ টাকার কয়েন যদি শেষ হয়ে যায় আর বড়জোর ২টি থাকে, গুণনীয়ক 1 + x2 + x4. প্রতিটি নতুন শর্ত শুধু একটি গুণনীয়ক বদলায়; বাকি হিসাব একই থাকে।
হাতের হিসাব ১০ পর্যন্ত চলে; তারপর কম্পিউটার। Series-কে Python-এ একটি list হিসেবে রাখা যায়: list-এর k-তম ঘর = xk-এর সহগ। নিচের ব্লক একটি mul function দিয়ে গুণ করে (শুধু xN পর্যন্ত রাখে, কারণ উঁচু ঘাত নিচের সহগে কখনো প্রভাব ফেলে না), তারপর brute force-এর সঙ্গে মেলায়, আর শেষে §৩-এর ভাউচারের প্রশ্নটি করে। প্রথমবার চালালে ব্রাউজারে Python (Pyodide) নামতে কয়েক সেকেন্ড লাগে।
def mul(a, b, N): # product of two series, cut at x^N
c = [0] * (N + 1)
for i, x in enumerate(a):
if x:
for j in range(N + 1 - i):
c[i + j] += x * b[j]
return c
def coin(v, N): # 1 + x^v + x^2v + ... = 1/(1 - x^v)
return [1 if k % v == 0 else 0 for k in range(N + 1)]
N = 100
G = [1] + [0] * N # the series "1"
for v in (1, 2, 5): # 1, 2 and 5 taka coins
G = mul(G, coin(v, N), N)
print("ways to pay 0..20 taka:", G[:21])
def brute(n): # choose #5s and #2s; 1s fill the rest
return sum(1 for c in range(n // 5 + 1)
for b in range((n - 5 * c) // 2 + 1))
print("GF == brute force for all n <= 100:",
all(G[n] == brute(n) for n in range(N + 1)))
print("10 taka:", G[10], " 50 taka:", G[50], " 100 taka:", G[100])
# vouchers: branch A even, branch B at most 3, branch C at least 1
A = [1 if k % 2 == 0 else 0 for k in range(N + 1)]
B = [1, 1, 1, 1] + [0] * (N - 3)
C = [0] + [1] * N
V = mul(mul(A, B, N), C, N)
print("vouchers n = 0..12:", V[:13])
print("2n - 2 for n = 3..12:", [2 * n - 2 for n in range(3, 13)])আসল আউটপুট (ব্রাউজারের Python):
ways to pay 0..20 taka: [1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 16, 18, 20, 22, 24, 26, 29]
GF == brute force for all n <= 100: True
10 taka: 10 50 taka: 146 100 taka: 541
vouchers n = 0..12: [0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
2n - 2 for n = 3..12: [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
প্রথম লাইনের ১০ নম্বর ঘরে 10, stepper-এর উত্তর; ২০ টাকায় ২৯টি উপায়। Brute force প্রতিটি n-এ ৫ আর ২ টাকার কয়েনের সংখ্যা বাছে (১ টাকা বাকিটা পূরণ করে), আর ১০১টি n-এর প্রতিটিতে মিলেছে। ১০০ টাকায় ৫৪১টি সংগ্রহ। ভাউচারের সারিতে n ≥ 3 থেকে মান ঠিক 2n − 2; n = 2-এ সূত্রটি মিলে যায় (2), কিন্তু n = 1-এ খাটে না (0 দিত, আসল 1), কারণ সেখানে x3/(1 − x)2-এর অংশটি এখনো শুরু হয়নি: n − 2 শুধু n ≥ 2-এ বৈধ। খেয়াল করুন, mul-এর দুই loop আর DSA কোর্সের পর্ব ৫৩-এর coin change DP একই হিসাব; DP টেবিলটি আসলে এই গুণফলের সহগ।
৫ · Recurrence সমাধান — Fibonacci থেকে partial fraction
পর্ব ৪৫-এ characteristic equation দিয়ে linear recurrence সমাধান হয়। Generating function একই উত্তরে পৌঁছায় অন্য পথে, আর সেই পথ এমন অনেক recurrence-এও চলে যেখানে characteristic equation-এর ধাঁচ খাটে না (Catalan, §৬)। পদ্ধতিটি সবসময় চার ধাপের:
- A(x) = ∑anxn ধরুন।
- Recurrence যে n-গুলোতে খাটে, তাদের প্রতিটিতে দুই পাশে xn গুণ করে যোগ করুন।
- প্রতিটি যোগফলকে A(x) আর শুরুর মান দিয়ে লিখুন (shift-এর নিয়ম), তারপর A(x) বের করুন।
- A(x)-কে partial fraction-এ ভেঙে প্রতিটি অংশের সহগ সারণি থেকে পড়ুন।
1F(x) = ∑ Fₙxⁿ, F₀=0, F₁=12(1 − x − x²)F(x)-এর সহগ3F(x) = x/(1 − x − x²)41 − x − x² = (1−φx)(1−ψx)5A = 1/√5, B = −1/√56Fₙ = (φⁿ − ψⁿ)/√5
| [x⁰] | |
| [x¹] | |
| [xⁿ], n≥2 | |
| φ, ψ |
- শুরু। F(x) = F0 + F1x + F2x2 + ⋯, যেখানে F0 = 0, F1 = 1 আর n ≥ 2-এ Fn = Fn−1 + Fn−2 (পর্ব ১২)।
- গুণ করে দেখা। (1 − x − x2)F(x)-এর xn-এর সহগ Fn − Fn−1 − Fn−2 (ঋণাত্মক সূচকের পদ ধরা হয় 0). n = 0-এ F0 = 0, n = 1-এ F1 − F0 = 1, আর n ≥ 2-এ recurrence অনুযায়ী 0.
- A(x) বের করা। তাই (1 − x − x2)F(x) = x, আর 1 − x − x2-এর ধ্রুবক পদ 1 ≠ 0 বলে উপপাদ্য ১.২ অনুযায়ী ভাগ বৈধ: F(x) = x/(1 − x − x2).
- উৎপাদকে ভাঙা। φ = (1 + √5)/2 আর ψ = (1 − √5)/2 হলে φ + ψ = 1 আর φψ = −1, তাই (1 − φx)(1 − ψx) = 1 − x − x2. এখানে φ হলো golden ratio.
- Partial fraction. x = A(1 − ψx) + B(1 − φx). ধ্রুবক পদ: A + B = 0; x-এর সহগ: −Aψ − Bφ = 1, তাই A(φ − ψ) = 1, আর φ − ψ = √5 বলে A = 1/√5, B = −1/√5.
- সহগ পড়া। 1/(1 − cx)-এর সহগ cn, তাই Fn = (φn − ψn)/√5, যা পর্ব ৪৫-এর Binet-এর সূত্র। n = 10-এ φ10 ≈ 122.99, ψ10 ≈ 0.0081, পার্থক্য/√5 = 55.
আরেকটি উদাহরণ: Hanoi. H0 = 0 আর n ≥ 1-এ Hn = 2Hn−1 + 1. ধাপ ২-এ শুধু n ≥ 1-এ যোগ করুন: ∑n≥1 Hnxn = 2x∑n≥1 Hn−1xn−1 + ∑n≥1 xn, অর্থাৎ H(x) − H0 = 2xH(x) + x/(1 − x). তাই H(x) = x/((1 − x)(1 − 2x)) = 1/(1 − 2x) − 1/(1 − x), আর Hn = 2n − 1. শেষ অংশটি x/(1 − x), 1/(1 − x) নয়: “+1” শুধু n ≥ 1-এ যোগ হয়েছে। এই সূক্ষ্মতাটি ভুলে গেলে কী হয়, তা অনুশীলন ৪-এ দেখবেন।
Non-homogeneous recurrence-এও (পর্ব ৪৬) পদ্ধতি একই: ডান পাশের অতিরিক্ত পদ F(n) নিজের generating function নিয়ে আসে (Hanoi-তে x/(1 − x)), আর তা হরে একটি নতুন উৎপাদক যোগ করে। পর্ব ৪৬-এ particular solution-এর “অনুমান” যেখানে লাগে, এখানে তা partial fraction-এর একটি অংশ হিসেবে নিজেই আসে; শুধু হিসাব একটু লম্বা।
নিচের ব্লক উপপাদ্য ১.২-এর প্রমাণটিকেই algorithm বানায়: হরের ধ্রুবক পদ 1 হলে num/den-এর সহগ এক এক করে বের হয়। তারপর §৬-এর Catalan সমীকরণ C = 1 + xC2-কে বারবার নিজের মধ্যে বসিয়ে তার সহগও বের করে।
from math import comb
def divide(num, den, N): # coefficients of num/den, den[0] = 1
a = []
for n in range(N + 1):
s = num[n] if n < len(num) else 0
for k in range(1, min(n, len(den) - 1) + 1):
s -= den[k] * a[n - k]
a.append(s) # from (den * a)[n] = num[n]
return a
N = 15
print("x/(1-x-x^2) :", divide([0, 1], [1, -1, -1], N))
print("x/((1-x)(1-2x)) :", divide([0, 1], [1, -3, 2], 8))
print("2^n - 1 :", [2 ** n - 1 for n in range(9)])
print("(1-x)/(1-5x+6x^2):", divide([1, -1], [1, -5, 6], 7))
print("2*3^n - 2^n :", [2 * 3 ** n - 2 ** n for n in range(8)])
def mul(a, b, N):
return [sum(a[i] * b[n - i] for i in range(n + 1)) for n in range(N + 1)]
C = [1] + [0] * N # start from C(x) = 1
for step in range(N + 1): # repeat C <- 1 + x * C(x)^2
C = [1] + mul(C, C, N)[:N]
print("C = 1 + xC^2 :", C[:12])
print("C(2n,n)/(n+1):", [comb(2 * n, n) // (n + 1) for n in range(12)])আসল আউটপুট (ব্রাউজারের Python):
x/(1-x-x^2) : [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
x/((1-x)(1-2x)) : [0, 1, 3, 7, 15, 31, 63, 127, 255]
2^n - 1 : [0, 1, 3, 7, 15, 31, 63, 127, 255]
(1-x)/(1-5x+6x^2): [1, 4, 14, 46, 146, 454, 1394, 4246]
2*3^n - 2^n : [1, 4, 14, 46, 146, 454, 1394, 4246]
C = 1 + xC^2 : [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786]
C(2n,n)/(n+1): [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786]
প্রথম লাইন x/(1 − x − x2)-কে ভাগ করে Fibonacci দেয়; ভাগের ভেতরের loop আসলে Fn = Fn−1 + Fn−2-ই, কারণ হর −1, −1 সহগ নিয়ে recurrence-টিকে বহন করে। পরের দুই জোড়া লাইন দেখায় partial fraction-এ পাওয়া closed form প্রতিটি সহগে মেলে: Hanoi-র 2n − 1, আর §৯-এর অঙ্ক ২-এর 2 · 3n − 2n. শেষ দুই লাইনে C ← 1 + xC2 বারবার বসানোয় প্রতিবার অন্তত একটি নতুন সহগ স্থির হয় (x দিয়ে গুণ এক ঘাত ওপরে ঠেলে), তাই N + 1 বারে xN পর্যন্ত সব নির্ভুল, আর সেগুলো C(2n, n)/(n + 1)-এর সঙ্গে হুবহু মেলে। সব হিসাব পূর্ণসংখ্যায়, তাই কোনো rounding নেই; Binet-এর float সূত্রে বড় n-এ যে ভুল আসে, এখানে তা আসে না।
৬ · Catalan-এর generating function — একটি দ্বিঘাত সমীকরণ
পর্ব ৩৭ “গণনার কৌশল — lattice path, bijection আর double counting”-এ reflection দিয়ে Catalan সংখ্যা Cn = C(2n, n)/(n + 1) প্রমাণ হয়েছে, আর বন্ধনীর প্রথম জোড়া ধরে ভেঙে recurrence C0 = 1, Cn+1 = ∑i=0n CiCn−i পাওয়া গেছে। এই recurrence linear নয় (C·C গুণফল), তাই characteristic equation এখানে অচল। কিন্তু ডান পাশটি দেখতে হুবহু একটি convolution.
C(x) = ∑n≥0 Cnxn হলে C(x) = 1 + x C(x)2, আর
C(x) = (1 − √(1 − 4x)) / (2x), Cn = C(2n, n)/(n + 1)
- [xn]C(x)2 = ∑i=0n CiCn−i = Cn+1, তাই xC(x)2 = ∑n≥0 Cn+1xn+1 = C(x) − C0 = C(x) − 1. — convolution, shift
- তাই xC2 − C + 1 = 0. দ্বিঘাত সূত্রের মতো (2xC − 1)2 = 1 − 4x: বাঁ পাশ খুললে 4x2C2 − 4xC + 1 = 4x(xC2 − C + 1) + 1 − 4x. — বর্গ পূর্ণ করা
- যে series-এর বর্গ 1 − 4x আর ধ্রুবক পদ 1, তাকে √(1 − 4x) লিখি (উপপাদ্য ১.২-এর মতো সহগ এক এক করে নির্ধারিত হয়, ধ্রুবক পদের চিহ্ন বেছে নিলে অনন্য)। 2xC − 1-এর ধ্রুবক পদ −1, তাই 2xC − 1 = −√(1 − 4x). — চিহ্ন বাছাই
- অতএব 2xC(x) = 1 − √(1 − 4x). Generalized binomial theorem (নিচে) অনুযায়ী √(1 − 4x) = 1 − ∑k≥1 (2/k) C(2k − 2, k − 1) xk. — Newton-এর ধারা
- তাই 2xC(x) = ∑k≥1 (2/k) C(2k − 2, k − 1) xk; দুই পাশ 2x দিয়ে ভাগ করে n = k − 1 বসালে Cn = C(2n, n)/(n + 1). ∎ — সহগ মেলানো
চিহ্ন কেন বিয়োগ। দ্বিঘাত সূত্র দুটি “মূল” দেয়: (1 ± √(1 − 4x))/(2x). যোগ চিহ্ন নিলে লবের ধ্রুবক পদ 2, আর 2/(2x) = 1/x কোনো power series নয় (x-এর ঋণাত্মক ঘাত)। বিয়োগ চিহ্নে লবের ধ্রুবক পদ 0, তাই x দিয়ে ভাগ বৈধ। এটি পরীক্ষায় প্রায়ই জিজ্ঞাসিত একটি যুক্তি।
যেকোনো মূলদ α-এর জন্য C(α, k) = α(α − 1)⋯(α − k + 1)/k! ধরে (1 + x)α = ∑k≥0 C(α, k)xk একটি formal power series, যার ধ্রুবক পদ 1, আর α = 1/m হলে তার m-তম ঘাত ঠিক 1 + x. α ঋণাত্মক পূর্ণসংখ্যা −n হলে C(−n, k) = (−1)kC(n + k − 1, k), যা উপপাদ্য ২.২-এর সঙ্গে মেলে।
প্রমাণ এখানে বাদ (সহগের polynomial identity, Vandermonde-এর ধাঁচে); Newton ১৬৬০-এর দশকে এটি খুঁজে পান বলে জানা যায় (পর্ব ৩৪-এর “আরও গভীরে”)। α = 1/2, x-এর জায়গায় −4x বসালে C(1/2, k)(−4)k = −(2/k)C(2k − 2, k − 1) (k ≥ 1), যা ধাপ ৪-এ লেগেছে; প্রথম কয়েকটি পদ √(1 − 4x) = 1 − 2x − 2x2 − 4x3 − 10x4 − ⋯ (scratch-এ Fraction দিয়ে k = 1…14 মেলানো)। 2, 2, 4, 10 = 2C0, 2C1, 2C2, 2C3: ধাপ ৫ চোখের সামনেই।
খেয়াল করুন, এই প্রমাণে reflection বা কোনো ছবি লাগেনি: “প্রথম অংশে ভাঙা” থেকে পাওয়া recurrence একটি দ্বিঘাত সমীকরণ হলো, আর বাকিটা বীজগণিত। একই কৌশল সব “একটি root আর দুটি ছোট একই ধরনের অংশ” গঠনে খাটে, যেমন n-টি node-এর binary tree, আর পর্ব ৫০-এ Catalan পরিবারের অন্য সদস্যদের জন্যও এটি কাজে লাগবে।
৭ · Partition-এর generating function আর Euler-এর উপপাদ্য
একটি পূর্ণসংখ্যা n-এর partition মানে n-কে ধনাত্মক পূর্ণসংখ্যার যোগফলে লেখা, যেখানে ক্রম গুরুত্বহীন: 4 = 3 + 1 = 2 + 2 = 2 + 1 + 1 = 1 + 1 + 1 + 1, তাই p(4) = 5. বাজারঘরের ভাষায়: যেকোনো মাপের প্যাকেট আছে, n কেজি চাল কয় রকম প্যাকেট-সংগ্রহে ভরা যায়? এটি আসলে সব মানের কয়েনের খুচরো প্রশ্ন, তাই উপপাদ্য ৪.১-এর মতোই
∑n≥0 p(n)xn = ∏k≥1 1/(1 − xk)
অসীম গুণফল কীভাবে বৈধ? xn-এর সহগে শুধু k ≤ n-এর গুণনীয়কগুলো প্রভাব ফেলে, কারণ k > n-এর গুণনীয়ক 1 + xk + ⋯ থেকে 1 ছাড়া যেকোনো পদ ঘাতকে n-এর ওপরে নিয়ে যায়। তাই প্রতিটি সহগ একটি সসীম গুণফল থেকে আসে। একই যুক্তিতে, প্রতিটি অংশ বড়জোর একবার ব্যবহারের partition (আলাদা অংশ) গোনে ∏(1 + xk), আর শুধু বিজোড় অংশের partition গোনে ∏k বিজোড় 1/(1 − xk). Partition-এর বিস্তারিত (Ferrers diagram, pentagonal number theorem) পর্ব ৫০ “বিশেষ সংখ্যা — Catalan, Stirling আর partition”-এ আসবে।
গুণনীয়ক 1 + xk-কে একটি হ্যাঁ/না প্রশ্ন হিসেবে পড়ুন: “অংশ k কি আছে?” না হলে 1, হ্যাঁ হলে xk. যেমন n = 5-এ (1 + x)(1 + x2)(1 + x3)(1 + x4)(1 + x5) খুললে x5 আসে তিনভাবে: x5, x4 · x, x3 · x2. অর্থাৎ 5, 4+1, 3+2: q(5) = 3. বিজোড় অংশে: 5, 3+1+1, 1+1+1+1+1, এখানেও তিনটি। কাকতালীয়? নিচের উপপাদ্য বলে, না।
প্রতিটি n ≥ 0-এর জন্য n-এর আলাদা অংশের partition-এর সংখ্যা q(n) = n-এর শুধু বিজোড় অংশের partition-এর সংখ্যা o(n).
1Q = ∏(1+xᵏ), O: বিজোড়21 + xᵏ = (1 − x²ᵏ)/(1 − xᵏ)3Q = ∏(1−x²ᵏ) / ∏(1−xᵏ)4জোড় হর কাটে ⇒ Q = O5n = 6: q = o = 46Glaisher: 3+3 → 6
| লব | |
| হর | |
| আলাদা | |
| বিজোড় |
- দুই series. আলাদা অংশের generating function Q(x) = (1 + x)(1 + x2)(1 + x3)⋯, বিজোড় অংশের O(x) = 1/((1 − x)(1 − x3)(1 − x5)⋯). দেখাতে হবে Q = O.
- এক গুণনীয়ক। (1 + xk)(1 − xk) = 1 − x2k, আর 1 − xk-এর ধ্রুবক পদ 1, তাই 1 + xk = (1 − x2k)/(1 − xk).
- সব k. গুণ করলে Q = [(1 − x2)(1 − x4)(1 − x6)⋯] / [(1 − x)(1 − x2)(1 − x3)⋯]. লবে শুধু জোড় ঘাত, হরে সব ঘাত।
- কাটাকাটি। লবের প্রতিটি 1 − x2k হরের একই গুণনীয়ককে কাটে। হরে বাকি থাকে শুধু বিজোড় ঘাত: Q = O. প্রতিটি সহগ শুধু k ≤ n-এর সসীম গুণফলে নির্ভর করে, তাই অসীম কাটাকাটি বৈধ। তাই q(n) = o(n).
- n = 6 মেলানো। আলাদা অংশে: 6, 5+1, 4+2, 3+2+1 (৪টি)। বিজোড় অংশে: 5+1, 3+3, 3+1+1+1, 1+1+1+1+1+1 (৪টি)।
- সরাসরি জোড়া (Glaisher). বিজোড় অংশ o যদি m বার থাকে, m-কে ২-এর ঘাতে ভাঙুন: 3+3 → 6; 3+1+1+1 → 3 + 1 + 2; 1×6 → 2 + 4; 5+1 যেমন আছে। ফল ঠিক আলাদা অংশের চারটি।
শেষ ধাপের জোড়াটি J. W. L. Glaisher ১৮৮৩ সালে দেন বলে জানা যায়; এটি একটি bijective proof. Generating function প্রমাণ চার লাইনের, কিন্তু কোন partition কোনটির সঙ্গে জোড়া, তা বলে না; bijection বলে। দুটি প্রমাণ একে অন্যের পরিপূরক। নিচের ব্লক n ≤ 30-এ তিনটি গুণফল হিসাব করে, আর n = 12-এ সব partition তালিকা করে গোনে।
def mul(a, b, N):
c = [0] * (N + 1)
for i, x in enumerate(a):
if x:
for j in range(N + 1 - i):
c[i + j] += x * b[j]
return c
N = 30
distinct = odd = allp = [1] + [0] * N
for k in range(1, N + 1):
plus = [1] + [0] * N
plus[k] = 1 # 1 + x^k
geo = [1 if j % k == 0 else 0 for j in range(N + 1)] # 1/(1 - x^k)
distinct = mul(distinct, plus, N)
allp = mul(allp, geo, N)
if k % 2 == 1:
odd = mul(odd, geo, N)
print("n:", list(range(16)))
print("q:", distinct[:16])
print("o:", odd[:16])
print("q == o for every n <= 30:", distinct == odd)
print("q(30) =", distinct[30], " p(30) =", allp[30])
def brute(n, largest): # partitions of n, parts <= largest
if n == 0:
return [[]]
return [[k] + rest for k in range(min(n, largest), 0, -1)
for rest in brute(n - k, k)]
P = brute(12, 12)
print("brute force n = 12: all", len(P),
" distinct", sum(len(set(p)) == len(p) for p in P),
" odd", sum(all(x % 2 for x in p) for p in P))আসল আউটপুট (ব্রাউজারের Python):
n: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
q: [1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 15, 18, 22, 27]
o: [1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 15, 18, 22, 27]
q == o for every n <= 30: True
q(30) = 296 p(30) = 5604
brute force n = 12: all 77 distinct 15 odd 15
q আর o সারি দুটি হুবহু এক, আর ৩১টি n-এর প্রতিটিতে মিলেছে; n = 6-এ 4, stepper-এর উত্তর। ৩০-এর ৫৬০৪টি partition-এর মধ্যে মাত্র ২৯৬টির অংশ সব আলাদা। Brute force দ্বিতীয় যুক্তি দেয়: ১২-এর ৭৭টি partition তালিকা করে গুনলে আলাদা অংশের ১৫টি আর বিজোড় অংশের ১৫টি, generating function-এর সঙ্গে মেলে। কোডে একটি কৌশল লক্ষ করুন: k > N-এর গুণনীয়ক কখনো গুণ করা হয়নি, কারণ ওপরে যুক্তি দেখানো হয়েছে যে xN পর্যন্ত সহগে সেগুলোর কোনো প্রভাব নেই। এটি অসীম গুণফলের “formal” অর্থেরই কোড রূপ। Brute force-এর তালিকা n বাড়লে দ্রুত বাড়ে (p(100) প্রায় ১৯ কোটি), কিন্তু গুণফলের হিসাব শুধু N-এর বহুপদী হারে বাড়ে: এই কোডে N-টি গুণ, প্রতিটি মোটামুটি N2 ধাপ, তাই মোট প্রায় N3 ধাপ।
৮ · Exponential generating function — লেবেলযুক্ত বস্তু
খুচরো টাকায় দুটি ৫ টাকার কয়েন অভিন্ন; কোনটি “প্রথম” তা অর্থহীন। কিন্তু অনেক প্রশ্নে বস্তুগুলোর নাম আছে: n জন গ্রাহক, n-টি অর্ডার নম্বর। তখন দুটি অংশ জোড়া লাগাতে শুধু আকার যোগ হয় না, কোন লেবেল কোন অংশে গেল তা-ও বাছতে হয়। এর জন্য আরেক রকম থলে।
(an)-এর exponential generating function (EGF) Â(x) = ∑n≥0 anxn/n!. দুটি EGF-এর গুণফলে
n! [xn] Â(x)B̂(x) = ∑k=0n C(n, k) akbn−k
- [xn]ÂB̂ = ∑k (ak/k!)(bn−k/(n − k)!). — সাধারণ গুণের সংজ্ঞা
- n! দিয়ে গুণ করলে প্রতিটি পদে n!/(k!(n − k)!) = C(n, k) আসে। ∎ — binomial coefficient-এর সূত্র
গণনায় অর্থ: n-টি লেবেলের মধ্যে কোন k-টি বাঁ অংশে যাবে তা C(n, k) উপায়ে বাছুন, তারপর বাঁ অংশে ak আর ডান অংশে bn−k রকম গঠন। এই “binomial convolution” লেবেলযুক্ত বস্তুর জন্য উপপাদ্য ২.১-এর ভূমিকা নেয়। দুটি মৌলিক EGF: সব an = 1 হলে Â = ∑xn/n! = ex (প্রতিটি সেটে “কিছু না করার” একটিই উপায়), আর an = n! (সব permutation) হলে Â = ∑xn = 1/(1 − x). এখানে ex একটি formal power series-এর নাম, কোনো সংখ্যার ঘাত নয়; ex · e−x = 1 সহগ মিলিয়ে যাচাই করা যায় (∑k C(n, k)(−1)k = 0, n ≥ 1, পর্ব ৩৪)।
Derangement, এক নজরে। একটি derangement হলো এমন permutation যাতে কোনো উপাদান নিজের জায়গায় নেই, যেমন বাজারঘরের n জন কর্মীর উপহার-বিনিময়ে কেউ নিজের নামের প্যাকেট পান না। পর্ব ৪০ “Random variable আর প্রত্যাশা — linearity-র জাদু”-এ দেখেছেন, fixed point-এর প্রত্যাশিত সংখ্যা 1. এখন গোনা: প্রতিটি permutation অনন্যভাবে ভাঙে “কোন k-টি উপাদান স্থির” (একভাবেই বসানো) আর “বাকি n − k-টির একটি derangement”-এ। তাই n! = ∑k C(n, k) · 1 · Dn−k, আর উপপাদ্য ৮.২ অনুযায়ী EGF-এ
1/(1 − x) = ex · D̂(x) ⇒ D̂(x) = e−x/(1 − x) ⇒ Dn = n! ∑k=0n (−1)k/k!
শেষ ধাপে e−x-এর সহগ (−1)k/k! আর 1/(1 − x)-এর সব 1-এর convolution আংশিক যোগফল দেয় (§২-এর সারণি)। একই সূত্রের inclusion–exclusion প্রমাণ আর Dn/n! → 1/e পর্ব ৪৯-এ আসবে; এখানে শুধু দেখুন EGF কত দ্রুত সেখানে পৌঁছায়।
আরেকটি ছোট উদাহরণ। n-টি আলাদা অর্ডার দুজন রাইডারের মধ্যে ভাগ করতে হবে, প্রত্যেকে অন্তত একটি পাবেন। একজন রাইডারের ভাগে k-টি অর্ডার নেওয়ার একটিই উপায় (k ≥ 1), তাই তার EGF ∑k≥1 xk/k! = ex − 1. উপপাদ্য ৮.২ অনুযায়ী দুজনের EGF (ex − 1)2 = e2x − 2ex + 1, আর n ≥ 1-এ উত্তর 2n − 2: সব 2n ভাগ থেকে “সব একজনের কাছে” এমন দুটি বাদ। এটি n-টি থেকে ২-টিতে onto ফাংশনের সংখ্যা (পর্ব ১৬)। k জন রাইডারে (ex − 1)k, আর তার সহগ থেকে পর্ব ৪৯-এর onto সূত্র আর পর্ব ৫০-এর Stirling সংখ্যা বেরিয়ে আসে।
from fractions import Fraction
from math import factorial
from itertools import permutations
N = 8
e_minus = [Fraction((-1) ** k, factorial(k)) for k in range(N + 1)] # e^(-x)
geo = [Fraction(1)] * (N + 1) # 1/(1-x)
prod = [sum(e_minus[i] * geo[n - i] for i in range(n + 1))
for n in range(N + 1)]
D = [prod[n] * factorial(n) for n in range(N + 1)] # a_n = n! [x^n]
print("D_n from e^(-x)/(1-x):", [int(d) for d in D])
def brute(n): # permutations with no fixed point
return sum(all(p[i] != i for i in range(n))
for p in permutations(range(n)))
print("brute force, n <= 7 :", [brute(n) for n in range(8)])
print("D_8 / 8! =", D[8] / factorial(8), "=", float(D[8] / factorial(8)))
ex = [Fraction(1, factorial(k)) for k in range(N + 1)] # e^x
sq = [sum(ex[i] * ex[n - i] for i in range(n + 1)) * factorial(n)
for n in range(N + 1)]
print("n! [x^n] e^x * e^x :", [int(s) for s in sq])আসল আউটপুট (ব্রাউজারের Python):
D_n from e^(-x)/(1-x): [1, 0, 1, 2, 9, 44, 265, 1854, 14833]
brute force, n <= 7 : [1, 0, 1, 2, 9, 44, 265, 1854]
D_8 / 8! = 2119/5760 = 0.36788194444444444
n! [x^n] e^x * e^x : [1, 2, 4, 8, 16, 32, 64, 128, 256]
EGF থেকে পাওয়া Dn আর ৭ পর্যন্ত সব permutation (৫০৪০টি পর্যন্ত) গুনে পাওয়া সংখ্যা হুবহু এক: 1, 0, 1, 2, 9, 44, 265, 1854. Fraction ব্যবহার করায় সহগগুলো নির্ভুল; D8/8! = 2119/5760 ≈ 0.367882, যা 1/e ≈ 0.367879-এর খুব কাছে। শেষ লাইন উপপাদ্য ৮.২-এর একটি পরীক্ষা: ex · ex-এর EGF সহগ ∑k C(n, k) = 2n, অর্থাৎ n-টি লেবেলকে দুই দলে ভাগ করার উপায়, আর formal series হিসেবেও exex = e2x.
৯ · পরীক্ষার অঙ্ক আর একটি ভুল যুক্তি
অঙ্ক ১: ঊর্ধ্বসীমাসহ বণ্টন
x1 + x2 + x3 + x4 = 10, প্রতিটি 0 ≤ xi ≤ 3. পূর্ণসংখ্যা সমাধান কয়টি?
- উত্তর [x10](1 + x + x2 + x3)4 = [x10](1 − x4)4 · (1 − x)−4.
- (1 − x4)4 = 1 − 4x4 + 6x8 − 4x12 + x16; (1 − x)−4-এর xm-এর সহগ C(m + 3, 3).
- Convolution: C(13, 3) − 4C(9, 3) + 6C(5, 3) = 286 − 336 + 60 = 10.
- সহজ যাচাই: ৪টি চলকের সর্বোচ্চ যোগ 12, তাই 10 মানে “12 থেকে মোট 2 কম”: হয় একটি চলক 1 (৪ উপায়), নয়তো দুটি চলক 2 (C(4, 2) = 6 উপায়)। মোট ১০। উত্তর: ১০টি।
অঙ্ক ২: Generating function দিয়ে recurrence
a0 = 1, a1 = 4, আর n ≥ 2-এ an = 5an−1 − 6an−2. Closed form বের করুন।
- (1 − 5x + 6x2)A(x)-এর সহগ: x0-এ a0 = 1, x1-এ a1 − 5a0 = −1, n ≥ 2-এ 0. তাই A(x) = (1 − x)/(1 − 5x + 6x2) = (1 − x)/((1 − 2x)(1 − 3x)).
- 1 − x = P(1 − 3x) + Q(1 − 2x). x = 1/2 বসালে 1/2 = −P/2, তাই P = −1; x = 1/3 বসালে 2/3 = Q/3, তাই Q = 2.
- A(x) = −1/(1 − 2x) + 2/(1 − 3x), তাই an = 2 · 3n − 2n. যাচাই: a2 = 18 − 4 = 14 = 5 · 4 − 6 · 1. (দ্বিতীয় Python ব্লকে ৮টি পদ মেলানো।)
এখানে x = 1/2 বসানো কি “formal” নীতির বিরোধী? না: 1 − x = P(1 − 3x) + Q(1 − 2x) একটি polynomial-এর অভেদ, আর polynomial-এ মান বসানো সবসময় বৈধ। কোনো অসীম series-এ মান বসানো হয়নি।
অঙ্ক ৩: সহগ সরাসরি
[x12] x6/(1 − x)3 কত, আর এর গণনার অর্থ কী? উত্তর: [x6](1 − x)−3 = C(6 + 2, 2) = 28. অর্থ: তিন রকম পণ্য থেকে ১২টি বাছাই, প্রতিটি রকম অন্তত ২টি (প্রতিটি গুণনীয়ক x2/(1 − x)).
অঙ্ক ৪: পুনরাবৃত্ত মূল
a0 = 1, a1 = 6, আর n ≥ 2-এ an = 6an−1 − 9an−2. Closed form কী?
- (1 − 6x + 9x2)A(x)-এর সহগ: x0-এ 1, x1-এ a1 − 6a0 = 0, n ≥ 2-এ 0. তাই A(x) = 1/(1 − 6x + 9x2) = 1/(1 − 3x)2.
- উপপাদ্য ২.২-এ n = 2, তারপর x-এর জায়গায় 3x: [xn](1 − 3x)−2 = C(n + 1, n) · 3n = (n + 1)3n.
- যাচাই: a2 = 36 − 9 = 27 = 3 · 9, a3 = 162 − 54 = 108 = 4 · 27. উত্তর: an = (n + 1)3n. (Scratch-এ n ≤ 7 মেলানো।)
পর্ব ৪৫-এর পুনরাবৃত্ত মূলের “n · rn” পদটি এখানে আলাদা কোনো নিয়ম ছাড়াই এল: হরে (1 − 3x)-এর বর্গ মানেই সহগে n-এর একটি ঘাত। ভাবনার প্রশ্ন ৪-এ এর সাধারণ যুক্তি আছে।
যুক্তির ভুল ধরুন: “1/(1 − x)3-এর সহগ”
একজন লিখলেন: “উপপাদ্য ২.২-এ n = 3, তাই 1/(1 − x)3-এর xk-এর সহগ C(k + 3, k). তাই x1 + x2 + x3 = 5-এর অঋণাত্মক সমাধান C(8, 5) = 56টি।”
ভুল কোথায়: সূত্রটি C(n + k − 1, k), n + k নয়। n = 3-এ C(k + 2, k) = C(k + 2, 2), তাই সঠিক উত্তর C(7, 2) = 21. ছোট মানে পরীক্ষা করলেই ধরা পড়ে: k = 1-এ (1 + x + ⋯)3-এ x-এর সহগ 3 (কোন গুণনীয়ক থেকে x আসবে), কিন্তু ভুল সূত্র C(4, 1) = 4 দেয়। Off-by-one ভুল এড়াতে প্রতিটি সূত্র k = 0 আর k = 1-এ মিলিয়ে নিন।
আরও গভীরে: Generating function শুধু সহগ ধরে রাখে না, তার “সমস্যার বিন্দু” (singularity) থেকে সহগের বৃদ্ধির হারও পড়া যায়: যেমন 1 − 4x = 0 বিন্দুটি থেকে Cn ≈ 4n/(n3/2√π) আসে। এই শাখার নাম analytic combinatorics, যার প্রমিত বই Philippe Flajolet আর Robert Sedgewick-এর (২০০৯)। আরেকটি দিক: series-এর গুণ আসলে polynomial গুণ, যা FFT দিয়ে n2-এর বদলে প্রায় n log n সময়ে করা যায় (DSA কোর্সের পর্ব ৪৯), তাই বড় গণনায় generating function শুধু তত্ত্ব নয়, দ্রুত algorithm-ও।
পরীক্ষা ও ইন্টারভিউতে: বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় এই ধরনের প্রশ্ন প্রায়ই আসে:
- 1/(1 − x)n-এর xk-এর সহগ? C(n + k − 1, k), stars and bars-এর সংখ্যা।
- ৫, ১০ আর ২০ টাকার নোটে n টাকার generating function? 1/((1 − x5)(1 − x10)(1 − x20)).
- Fibonacci-র generating function? x/(1 − x − x2), F0 = 0, F1 = 1 ধরে।
- Catalan-এ কেন √-এর আগে বিয়োগ চিহ্ন? যোগ চিহ্নে লবের ধ্রুবক পদ 2, তাই 1/x পদ আসে, যা power series নয়।
- ৭-এর আলাদা অংশের partition কয়টি? ৫টি (7, 6+1, 5+2, 4+3, 4+2+1), বিজোড় অংশের সংখ্যাও ৫।
১০ · AI-এর যুগে — generating function-এর হিসাব যাচাই
Generating function-এর হিসাবে অনেক ছোট বীজগাণিতিক ধাপ, আর প্রতিটিতে একটি চিহ্ন বা সূচক উল্টে যেতে পারে। AI সহকারী এসব হিসাব আত্মবিশ্বাসের সঙ্গে লেখে, কিন্তু কয়েকটি ভুল নিয়মিত দেখা যায়:
| AI-এর ভুল | কীভাবে ধরবেন |
|---|---|
| C(n + k − 1, k)-এর জায়গায় C(n + k, k) বা C(n + k − 1, n) | k = 0, 1-এ সহগ হাতে গুনে মেলান |
| Recurrence যে n-এ খাটে না সেখানেও যোগ করা, শুরুর মান বাদ দেওয়া | পাওয়া A(x)-এর প্রথম দুই সহগ শুরুর মানের সঙ্গে মেলান |
| Partial fraction-এ ভুল ধ্রুবক, বা পুনরাবৃত্ত উৎপাদক (1 − 2x)2-এ শুধু একটি পদ রাখা | ভাঙা অংশগুলো আবার যোগ করে মূল ভগ্নাংশ ফেরত আসে কি না দেখুন |
| Catalan-এ যোগ চিহ্ন নেওয়া, বা “x = 1/4 বসালে” ধরনের অপ্রাসঙ্গিক convergence যুক্তি | ধ্রুবক পদ দেখুন; formal series-এ মান বসানো লাগে না |
| OGF আর EGF মিশিয়ে ফেলা (লেবেলযুক্ত প্রশ্নে OGF-এর গুণ) | বস্তুগুলোর নাম আছে কি না জিজ্ঞেস করুন; ছোট n-এ brute force |
| ইতিহাসের সাল বা কে প্রথম লিখেছেন, তা নিশ্চিত সুরে বানিয়ে বলা | বিশ্বস্ত পাঠ্যবই বা মূল উৎসে মেলান |
AI-এর কাছে generating function-এর সমাধান চাইলে এমন কাঠামো দিন, যাতে প্রতিটি ধাপ আলাদা করে যাচাই করা যায়:
AI-এর উত্তর হাতে পেলে — যাচাইয়ের চেকলিস্ট
এই পর্বের সব হিসাব আসলে দুটি নিয়মের ওপর দাঁড়িয়ে: গুণফল মানে convolution, আর ধ্রুবক পদ অশূন্য হলে ভাগ বৈধ। AI-এর উত্তর পড়ার সময় প্রতিটি ধাপে জিজ্ঞেস করুন এই দুটির কোনটি খাটানো হলো, আর তারপর একটি ছোট Python list দিয়ে সহগগুলো মিলিয়ে নিন। দশ লাইনের কোড বেশিরভাগ ভুল ধরে ফেলে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।
প্র ০১Convergence না থাকলেও 1/(1 − x) = 1 + x + x2 + ⋯ লেখা কেন বৈধ? Generating function-এর ধারণা ইতিহাসে কীভাবে এল?
প্রশ্নটির উত্তর §১-এর উপপাদ্য ১.২-এ: formal power series-এর জগতে 1/(1 − x) মানে “যে series-কে 1 − x দিয়ে গুণ করলে 1 হয়”, আর সেটি সহগ মিলিয়ে অনন্যভাবে পাওয়া যায়। এখানে কোনো সংখ্যা বসানো হয় না, কোনো limit নেওয়া হয় না। গণিতের ভাষায়, সহগগুলো একটি field থেকে হলে formal power series-গুলো যোগ আর গুণে একটি ring গঠন করে, আর তাতে ধ্রুবক পদ অশূন্য এমন প্রতিটি উপাদানের গুণের বিপরীত আছে। ঠিক যেমন ℤ7-এ 3-এর বিপরীত 5 (পর্ব ২২), সংখ্যা “ছোট” হওয়ার কোনো প্রশ্ন ছাড়াই।
ইতিহাসে ধারণাটি ধীরে ধীরে আসে। Abraham de Moivre ১৭২০–৩০-এর দশকে linear recurrence-এর ধারাকে একটি ভগ্নাংশ দিয়ে প্রকাশ করার কৌশল ব্যবহার করেন বলে সাধারণত বলা হয়, যা আজকের partial fraction পদ্ধতির পূর্বসূরি; Fibonacci-র closed form-ও প্রায়ই de Moivre-এর নামে যুক্ত করা হয়, যদিও Binet-এর নামে পরিচিত (১৮৪৩)। Leonhard Euler ১৭৪০-এর দশকে partition-এর প্রশ্নে অসীম গুণফল ব্যবহার করেন, আর এই পর্বের উপপাদ্য ৭.১ তাঁর ১৭৪৮ সালের Introductio in analysin infinitorum বইয়ে আছে বলে জানা যায়। Pierre-Simon Laplace ১৮১২ সালের সম্ভাবনার বইয়ে “fonction génératrice” নামটি জনপ্রিয় করেন।
তখন বিশ্লেষণ (analysis) আর বীজগণিতের সীমারেখা আজকের মতো কড়া ছিল না; Euler প্রায়ই convergence নিয়ে মাথা না ঘামিয়ে অসীম ধারা নাড়াচাড়া করতেন, আর বেশিরভাগ সময় সঠিক উত্তর পেতেন। পরে উনিশ শতকে গণিত কঠোর হলে প্রশ্ন ওঠে: এসব হিসাব কেন সঠিক? Formal power series-এর বীজগাণিতিক সংজ্ঞা তার পরিষ্কার উত্তর দেয়: যতক্ষণ প্রতিটি সহগ সসীম হিসাবে বের হয়, ততক্ষণ সব বৈধ। Herbert Wilf তাঁর ১৯৯০ সালের generatingfunctionology বইয়ে generating function-কে একটি কাপড় শুকানোর দড়ির সঙ্গে তুলনা করেন, যেখানে সংখ্যার ধারা সাজিয়ে ঝোলানো থাকে; এই পর্বের “থলে” বা “আলমারি”-র উপমা সেই ভাবনারই।
মূল উপলব্ধি: Generating function একটি সংখ্যার ফাংশন নয়, সহগের একটি তালিকা; তাই convergence অপ্রয়োজনীয়, আর ধ্রুবক পদ অশূন্য হলেই ভাগ বৈধ।
প্র ০২Euler-এর partition উপপাদ্যের generating function প্রমাণ আর Glaisher-এর bijection — কোনটি “ভালো” প্রমাণ? Partition তত্ত্বে generating function আর কী দিয়েছে?
§৭-এর প্রমাণ চার লাইনের: 1 + xk = (1 − x2k)/(1 − xk), গুণ, কাটাকাটি। এর শক্তি হলো যান্ত্রিকতা: কোনো চতুর বুদ্ধি ছাড়াই দুটি গুণফলের সমতা দেখানো যায়। দুর্বলতা হলো এটি কিছু “দেখায়” না: n = 6-এ 3+3 কোন আলাদা-অংশের partition-এর সঙ্গে জোড়া, তা প্রমাণ থেকে পড়া যায় না। Glaisher-এর ১৮৮৩ সালের bijection ঠিক সেটি দেয়: সমান বিজোড় অংশগুলো জুড়ে দিন (m-টি o-কে m-এর binary রূপ অনুযায়ী o, 2o, 4o, …-এর কয়েকটিতে), আর উল্টো দিকে প্রতিটি অংশ থেকে ২-এর ঘাত বের করে ভাঙুন। প্রতিটি পূর্ণসংখ্যা অনন্যভাবে (বিজোড়) × 2j, আর binary রূপ অনন্য, তাই এটি সত্যিই bijection.
গণিতবিদেরা সাধারণত দুটিকেই মূল্য দেন। Generating function প্রমাণ নতুন সত্য খুঁজে পেতে সাহায্য করে, কারণ গুণফল নিয়ে খেলা সহজ; bijection বোঝায় কেন সত্য, আর প্রায়ই সাধারণীকরণের পথ খোলে। Partition তত্ত্বের অনেক বিখ্যাত ফলে এই দুই ধারা পাশাপাশি চলেছে। Euler-এর pentagonal number theorem (পর্ব ৫০-এ এর বক্তব্য আর ব্যবহার) প্রথমে generating function দিয়ে প্রমাণ হয়; Franklin ১৮৮১ সালে এর একটি সুন্দর bijective প্রমাণ দেন বলে জানা যায়।
উপমহাদেশের গণিতে এর সবচেয়ে বিখ্যাত অধ্যায় Srinivasa Ramanujan-এর কাজ। তিনি ১৯১৯ সালের কাছাকাছি p(5n + 4) সবসময় ৫ দিয়ে বিভাজ্য, এমন congruence প্রমাণ করেন, আর G. H. Hardy-র সঙ্গে ১৯১৮ সালে p(n)-এর asymptotic সূত্র দেন। দুটি কাজই ∏1/(1 − xk) generating function-এর গভীর বিশ্লেষণ থেকে আসে। Ramanujan-এর congruence-গুলোর “কেন” বোঝাতে Freeman Dyson ১৯৪৪ সালে partition-এর একটি সংখ্যাগত পরিমাপ প্রস্তাব করেন, যা আবার একটি combinatorial ব্যাখ্যা খোঁজার চেষ্টা।
মূল উপলব্ধি: Generating function প্রমাণ সত্যটি দ্রুত আর নিশ্চিতভাবে দেয়, bijection তার কারণ দেখায়; ভালো গণিতে দুটি একে অন্যকে পথ দেখায়।
প্র ০৩Coin change-এর dynamic programming আর generating function কি আসলে একই জিনিস? বড় হিসাবে কোনটি কখন ভালো?
প্রথম Python ব্লকের mul দিয়ে 1/(1 − xv) গুণ করা মানে প্রতিটি n-এ নতুন cn = পুরোনো cn + পুরোনো cn−v + পুরোনো cn−2v + ⋯. একে আরও সরল করা যায়: 1/(1 − xv) দিয়ে গুণ মানে (1 − xv) দিয়ে ভাগ, অর্থাৎ নতুন cn = পুরোনো cn + নতুন cn−v. এটি হুবহু DSA কোর্সের পর্ব ৫৩-এর coin change DP-র এক লাইনের হালনাগাদ: ways[s] += ways[s - v], s ছোট থেকে বড় ক্রমে। তাই হ্যাঁ, DP টেবিলটি generating function-এর সহগ, আর loop-এর ক্রম (বাইরে কয়েন, ভেতরে টাকা) গুণনীয়কগুলো একটি একটি করে গুণ করার সমান। Loop উল্টালে (বাইরে টাকা) কয়েনের ক্রমও গোনা হয়ে যায়, যা composition-এর প্রশ্ন, আর তার generating function আলাদা: 1/(1 − x − x2 − x5).
তাহলে generating function-এর আলাদা মূল্য কী? প্রথমত, closed form: §৩-এ ভাউচারের উত্তর 2n − 2 এক লাইনে এল, DP কখনো সূত্র দেয় না। দ্বিতীয়ত, প্রমাণ: Euler-এর উপপাদ্য DP দিয়ে প্রতিটি n-এ যাচাই করা যায়, সব n-এর জন্য প্রমাণ করা যায় না। তৃতীয়ত, গতি: অনেক গুণনীয়কের গুণফল একসঙ্গে লাগলে polynomial গুণ FFT দিয়ে করা যায় (DSA কোর্সের পর্ব ৪৯), আর partition-এর মতো ধারায় pentagonal recurrence আরও দ্রুত।
উল্টো দিকে DP সবসময় সহজে কোডে নামে, আর এমন শর্তও নিতে পারে যা সুন্দর গুণফলে ধরা কঠিন, যেমন “শেষ দুটি কয়েন একই হতে পারবে না” ধরনের ক্রম-নির্ভর শর্ত। বাস্তবে প্রায়ই দুটি একসঙ্গে লাগে: generating function দিয়ে সূত্র অনুমান বা প্রমাণ, DP দিয়ে মান যাচাই।
মূল উপলব্ধি: Coin change DP হলো generating function-এর গুণফল সংখ্যায় হিসাব করা; generating function তার ওপরে closed form, প্রমাণ আর দ্রুত algorithm-এর দরজা খোলে।
প্র ০৪Recurrence সমাধানে characteristic equation (পর্ব ৪৫) আর generating function — দুটি পদ্ধতির সম্পর্ক কী? পুনরাবৃত্ত মূল হলে কী হয়?
an = c1an−1 + ⋯ + cdan−d-এর generating function সবসময় P(x)/Q(x) আকারের, যেখানে Q(x) = 1 − c1x − ⋯ − cdxd আর P-এর degree d-এর কম (শুরুর মান থেকে আসে)। Characteristic polynomial হলো rd − c1rd−1 − ⋯ − cd, আর একটু হিসাব করলে Q(x) = xd · (characteristic polynomial)(1/x). অর্থাৎ Q-এর উৎপাদক (1 − rx) মানে characteristic equation-এর মূল r. Fibonacci-তে 1 − x − x2 = (1 − φx)(1 − ψx), আর φ, ψ হলো r2 = r + 1-এর মূল। তাই দুই পদ্ধতি একই উত্তর দেয়, শুধু হিসাবের ক্রম ভিন্ন।
পুনরাবৃত্ত মূলে generating function পদ্ধতির সুবিধা স্পষ্ট হয়। an = 6an−1 − 9an−2-এ Q(x) = (1 − 3x)2. Partial fraction-এ তখন A/(1 − 3x) + B/(1 − 3x)2 রাখতে হয়, আর উপপাদ্য ২.২-এর মতো 1/(1 − 3x)2-এর সহগ (n + 1)3n. তাই an = (α + βn)3n: পর্ব ৪৫-এর “n·rn” নিয়ম এখানে কোনো অনুমান ছাড়াই নিজে থেকে বেরিয়ে আসে। Characteristic equation পদ্ধতিতে এই নিয়মটি আলাদা করে প্রমাণ করতে হয়; generating function-এ তা সারণির একটি সারি মাত্র। একইভাবে পর্ব ৪৬-এর non-homogeneous ক্ষেত্রে, যখন F(n) = sn আর s নিজেই একটি মূল, তখন “n দিয়ে গুণ করা অনুমান” আসলে হরের (1 − sx)-এর ঘাত এক বাড়ার ফল।
অন্যদিকে characteristic equation পদ্ধতি পরীক্ষার খাতায় দ্রুত, আর linear algebra-র দৃষ্টিতে (companion matrix-এর eigenvalue, পর্ব ১৯) গভীর অর্থ বহন করে। Generating function-এর আসল জয় non-linear বা convolution-ধর্মী recurrence-এ, যেমন Catalan, যেখানে characteristic equation-এর কোনো অর্থই নেই।
মূল উপলব্ধি: হরের উৎপাদক = characteristic equation-এর মূল; পুনরাবৃত্ত মূলের n·rn পদ generating function-এ উপপাদ্য ২.২ থেকে স্বয়ংক্রিয়ভাবে আসে।
প্র ০৫সম্ভাবনায় generating function কোথায় লাগে? Probability generating function আর moment generating function-এর সঙ্গে এই পর্বের সম্পর্ক কী?
X যদি অঋণাত্মক পূর্ণসংখ্যার মান নেয়, তাহলে ধারা pk = P(X = k)-এর ordinary generating function GX(s) = ∑ pksk = E[sX], যাকে বলে probability generating function. এই পর্বের নিয়মগুলো সরাসরি খাটে। প্রথমত, GX(1) = ∑pk = 1. দ্বিতীয়ত, formal derivative নিয়ে s = 1 বসালে (সহগ অঋণাত্মক আর যোগফল সসীম হলে এখানে মান বসানো বৈধ) G′(1) = ∑ k pk = E[X]. তৃতীয়ত, X আর Y স্বাধীন হলে X + Y-এর বণ্টন দুই বণ্টনের convolution, তাই GX+Y = GXGY: উপপাদ্য ২.১-এর সম্ভাবনা রূপ।
উদাহরণ: একটি ন্যায্য মুদ্রায় মাথার সংখ্যার G = (1 + s)/2, তাই n-টি স্বাধীন মুদ্রায় ((1 + s)/2)n, যার sk-এর সহগ C(n, k)/2n: binomial বণ্টন এক লাইনে। দুটি ছক্কার যোগফলের বণ্টন ((s + s2 + ⋯ + s6)/6)2-এর সহগ। একটি পুরোনো ধাঁধা: অন্য সংখ্যা লেখা দুটি ছক্কা কি সাধারণ দুটি ছক্কার মতো একই যোগফল-বণ্টন দিতে পারে? s + ⋯ + s6-কে উৎপাদকে ভেঙে নতুনভাবে জোড়া দিলে উত্তর মেলে: হ্যাঁ, একটিতে 1, 2, 2, 3, 3, 4 আর অন্যটিতে 1, 3, 4, 5, 6, 8 (Sicherman-এর ছক্কা নামে পরিচিত, ১৯৭০-এর দশকের শেষে জনপ্রিয়)। এটি বীজগণিত দিয়ে গণনার একটি চমৎকার উদাহরণ।
পর্ব ৪১-এ Chernoff সীমার জন্য যে moment generating function E[etX] দেখেছেন, তা আসলে GX(et), আর তার ধারায় সহগগুলো E[Xk]/k!: অর্থাৎ moment-গুলোর exponential generating function. তাই এই পর্বের দুই ধরনের থলে সম্ভাবনাতেও দুই রূপে ফেরত আসে: বণ্টনের জন্য OGF, moment-এর জন্য EGF.
মূল উপলব্ধি: স্বাধীন random variable-এর যোগফল মানে বণ্টনের convolution, তাই probability generating function-এর গুণফল; generating function সম্ভাবনারও একটি প্রধান হাতিয়ার।
অনুশীলন
আগে খাতায় করুন, তারপর উত্তর খুলে মেলান।
-
প্রমাণ: Generating function ব্যবহার করে প্রমাণ করুন, প্রতিটি n ≥ 0-এর জন্য ∑k=0n C(n, k)2 = C(2n, n).
- (1 + x)n(1 + x)n = (1 + x)2n, কারণ formal series-এর গুণ সহযোগী আর polynomial-এর ঘাতের নিয়ম মানে। — বীজগণিত
- ডান পাশে [xn] = C(2n, n). — binomial theorem (পর্ব ৩৪)
- বাঁ পাশে উপপাদ্য ২.১ অনুযায়ী [xn] = ∑k C(n, k) · C(n, n − k). — convolution
- C(n, n − k) = C(n, k), তাই বাঁ পাশ ∑ C(n, k)2. দুই পাশ একই series-এর একই সহগ, তাই সমান। ∎ — প্রতিসাম্য
যাচাই n = 5: 1 + 25 + 100 + 100 + 25 + 1 = 252 = C(10, 5). এটি Vandermonde identity-র একটি বিশেষ রূপ, যার combinatorial প্রমাণ পর্ব ৩৪-এ আছে; এখানে একই ফল শুধু সহগ মিলিয়ে।
-
হিসাব: (ক) ১, ২ আর ৫ টাকার কয়েনে ৩০ টাকা কয় উপায়ে দেওয়া যায়? (খ) তিন রকম মিষ্টি থেকে ১২টির একটি বাক্স বানাতে হবে, প্রতিটি রকম অন্তত ২টি। কয় রকম বাক্স সম্ভব? দুটিই generating function দিয়ে লিখুন।
(ক) [x30] 1/((1 − x)(1 − x2)(1 − x5)). ৫ টাকার কয়েন c = 0…6টি; বাকি 30 − 5c টাকা ১ আর ২ দিয়ে ⌊(30 − 5c)/2⌋ + 1 উপায়ে: 16 + 13 + 11 + 8 + 6 + 3 + 1 = 58. (Scratch-এ প্রথম ব্লকের মতো গুণ করে মেলানো।)
(খ) প্রতিটি রকমের গুণনীয়ক x2 + x3 + ⋯ = x2/(1 − x), তাই উত্তর [x12] x6/(1 − x)3 = [x6](1 − x)−3 = C(8, 2) = 28. পর্ব ৩৫-এর নিম্নসীমার প্রতিস্থাপনের সঙ্গে মেলে: y1 + y2 + y3 = 6-এর সমাধান C(8, 2).
-
আউটপুট অনুমান: কোড না চালিয়ে বলুন কী ছাপা হবে, আর c-এর সারিটি কোন generating function-এর সহগ। তারপর যেকোনো Python-এ চালিয়ে মেলান।
from math import comb a = [1] * 6 b = [comb(3, k) for k in range(4)] + [0, 0] c = [sum(a[i] * b[n - i] for i in range(n + 1)) for n in range(6)] print(b) print(c)[1, 3, 3, 1, 0, 0] [1, 4, 7, 8, 8, 8]b হলো (1 + x)3-এর সহগ, a হলো 1/(1 − x)-এর প্রথম ৬টি। c তাদের convolution, তাই (1 + x)3/(1 − x)-এর সহগ, অর্থাৎ b-এর আংশিক যোগফল (§২-এর সারণি): 1, 1 + 3, 1 + 3 + 3, 8, 8, 8. n ≥ 3-এ মান 23 = 8-এ থেমে যায়, কারণ b-এর সব পদ ততক্ষণে যোগ হয়ে গেছে। আউটপুট CPython-এ চালিয়ে মেলানো।
-
প্রমাণের ভুল ধরুন: একজন Hanoi-র recurrence H0 = 0, Hn = 2Hn−1 + 1 (n ≥ 1) এভাবে সমাধান করলেন: “সব n-এ xn গুণ করে যোগ করি: H(x) = 2xH(x) + 1/(1 − x). তাই H(x) = 1/((1 − x)(1 − 2x)) = 2/(1 − 2x) − 1/(1 − x), আর Hn = 2n+1 − 1.” ভুল কোথায়, আর সঠিক উত্তর কী?
- লক্ষণ: সূত্রটি H0 = 2 − 1 = 1 দেয়, অথচ H0 = 0. প্রথম সহগ মেলালেই ভুল ধরা পড়ে।
- ভুল ধাপ: recurrence শুধু n ≥ 1-এ খাটে, কিন্তু যোগটি n = 0-ও ধরেছে। n = 0-এ “H0 = 2H−1 + 1 = 1” দাবি করা হয়েছে, যা মিথ্যা। আসলে যোগ n ≥ 1-এ: H(x) − H0 = 2xH(x) + x/(1 − x).
- সংশোধন: H(x) = x/((1 − x)(1 − 2x)) = 1/(1 − 2x) − 1/(1 − x), তাই Hn = 2n − 1: 0, 1, 3, 7, 15, … (দ্বিতীয় Python ব্লকে মেলানো)। ভুল উত্তরের ধারা 1, 3, 7, 15, … আসলে সঠিক ধারার এক ঘর বাঁয়ে সরানো রূপ।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমGenerating function দিয়ে একটি linear recurrence সমাধানের ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- A(x) = ∑ anxn ধরা
- Recurrence যে n-গুলোতে খাটে, সেখানে xn গুণ করে যোগ করা
- যোগফলগুলো A(x) আর শুরুর মান দিয়ে লিখে A(x) = P(x)/Q(x) বের করা
- Q(x)-কে উৎপাদকে ভেঙে partial fraction করা
- প্রতিটি অংশের xn-এর সহগ সারণি থেকে পড়ে an-এর closed form লেখা
1/(1 − x)3-এ x5-এর সহগ কত?
- 21
- 56
- 15
- 6
ধারা an = 3n (n = 0, 1, 2, …)-এর ordinary generating function কোনটি?
- 3/(1 − x)
- 1/(1 − 3x)
- 1/(1 + 3x)
- x/(1 − 3x)
(1 + x)2/(1 − x)-এ x5-এর সহগ কত?
- 1
- 3
- 4
- 6
C(x) = 1 + xC(x)2 সমাধানে C(x) = (1 − √(1 − 4x))/(2x) নেওয়া হয়, (1 + √(1 − 4x))/(2x) নয়। কারণ কী?
- যোগ চিহ্নের series কোনো x-এ converge করে না
- √(1 − 4x) একটি formal power series নয়
- যোগ চিহ্নে সহগগুলো ঋণাত্মক হয়
- যোগ চিহ্নে লবের ধ্রুবক পদ 2, তাই 1/x পদ আসে
৭-কে আলাদা আলাদা ধনাত্মক পূর্ণসংখ্যার যোগফলে (ক্রম গুরুত্বহীন) কয় উপায়ে লেখা যায়?
- 5
- 4
- 15
- 7
n জন গ্রাহকের প্রত্যেককে নিজের নয় এমন একটি অর্ডার দেওয়ার উপায় Dn (derangement). এর exponential generating function কোনটি?
- 1/(1 − x)
- e−x/(1 − x)
- e−x
- ex/(1 − x)
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- Formal power series: A(x) = ∑anxn সহগের একটি তালিকা; convergence লাগে না, আর a0 ≠ 0 হলেই 1/A(x) আছে।
- Convolution: [xn]A(x)B(x) = ∑akbn−k; গণনায় দুটি স্বাধীন অংশ, মোট আকার n. ফলে 1/(1 − x)n-এর সহগ C(n + k − 1, k).
- গোনা: প্রতিটি চলক বা কয়েনের জন্য একটি গুণনীয়ক, প্রতিটি অনুমোদিত মানের জন্য একটি পদ; ১, ২, ৫ টাকায় ১০ টাকা ১০ উপায়ে।
- Recurrence: xn গুণ করে যোগ, A(x) = P/Q, partial fraction, সহগ পড়া; Fibonacci = x/(1 − x − x2), Catalan = (1 − √(1 − 4x))/(2x).
- EGF আর partition: লেবেলযুক্ত বস্তুতে ∑anxn/n! (derangement e−x/(1 − x)); ∏(1 + xk) = ∏1/(1 − x2k−1) থেকে Euler-এর আলাদা = বিজোড় অংশ।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ৪৯ · Inclusion–exclusion আর derangementপরবর্তী পর্বযোগ-বিয়োগে গোনা, onto ফাংশন আর derangement-এর প্রমাণ।
- পর্ব ৩৫ · পুনরাবৃত্তিসহ বাছাই — stars and bars আর multinomialপুনরালোচনাC(n + k − 1, k)-এর bijection প্রমাণ, এই পর্বের উপপাদ্য ২.২-এর ভিত।
- পর্ব ৩৭ · গণনার কৌশল — lattice path, bijection আর double countingপুনরালোচনাCatalan সংখ্যার reflection প্রমাণ আর recurrence.
- ডিসক্রিট ম্যাথমেটিক্স · কোর্স হোম৮৩টি পর্বপুরো কোর্সের মানচিত্র আর ১৪টি মডিউল।
- DSA · পর্ব ৫৩ · DP-র ক্লাসিক সমস্যা ১ — knapsack, coin change আর LISকোডে প্রয়োগCoin change-এর DP, যা কয়েনের generating function-এর গুণফল।
- DSA · পর্ব ৪৯ · Divide and conquer — Strassen, closest pair আর Karatsubaদ্রুত গুণPolynomial গুণ দ্রুত করার কৌশল আর FFT-এর ধারণা।