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

Non-homogeneous recurrence আর particular solution

Non-homogeneous Recurrences and Particular Solutions — Undetermined Coefficients, the Colliding-Root Rule, Loan Amortisation and the Summation Factor

Taught in Bangla, this lesson defines non-homogeneous recurrences and their associated homogeneous part, and proves that every solution is a particular solution plus a homogeneous one. It gives trial forms for polynomial, exponential and polynomial-times-exponential terms and the n^m rule for colliding roots. Hanoi, the sum of squares and the monthly loan payment get closed forms, a summation factor solves the quicksort average recurrence, and in-page Python verifies each closed form exactly with Fraction.

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

  • Non-homogeneous recurrence আর তার associated homogeneous recurrence চেনা
  • “সব সমাধান = particular + homogeneous” উপপাদ্যের প্রমাণ, আর initial condition কোন ধাপে বসাতে হয়
  • Polynomial, exponential আর polynomial × exponential F(n)-এর trial form, আর মূলের সঙ্গে সংঘাতে nm নিয়মের কারণ
  • Hanoi, ∑k² আর ঋণ পরিশোধের closed form বের করা, আর summation factor দিয়ে quicksort-এর recurrence সমাধান
  • প্রতিটি closed form recurrence-এর সঙ্গে Python-এ Fraction দিয়ে নির্ভুলভাবে মেলানো

১ · বাড়তি পদওয়ালা recurrence — non-homogeneous কাকে বলে

পর্ব ৪৪ “Recurrence দিয়ে মডেল — Fibonacci, Hanoi আর bit string”-এ আপনি দেখেছেন, অনেক গণনার প্রশ্ন স্বাভাবিকভাবে একটি recurrence হয়ে আসে। পর্ব ৪৫ “Linear recurrence সমাধান — characteristic equation”-এ শিখেছেন an = an−1 + 2an−2 ধরনের recurrence সমাধানের পদ্ধতি: rn বসিয়ে মূল খোঁজা। কিন্তু বাস্তবের বহু recurrence-এ একটি বাড়তি পদ থাকে, যা আগের পদগুলোর ওপর নির্ভর করে না।

ধরুন বাজারঘরের একজন বিক্রেতা প্রতি মাসের শেষে একটি সঞ্চয় হিসাবে ৫,০০০ টাকা জমা দেন, আর তার আগে আগের জমার ওপর ১% মুনাফা যোগ হয় (হারটি শুধু উদাহরণ)। মাস শেষের জমা sn = 1.01 · sn−1 + 5000. প্রথম অংশ “আগের জমা বাড়ছে”, আর দ্বিতীয় অংশ “বাইরে থেকে নতুন টাকা আসছে”. দ্বিতীয় অংশ না থাকলে জমা শুধু গুণোত্তর ধারায় বাড়ত; সেটি পর্ব ৪৫-এর জগৎ। নতুন জমার পদটিই recurrence-কে non-homogeneous করে।

সংজ্ঞা ১.১ (non-homogeneous linear recurrence)

ধ্রুবক c1, …, ck (ck ≠ 0) আর n-এর একটি ফাংশন F(n) দিয়ে

an = c1an−1 + c2an−2 + … + ckan−k + F(n)

হলো ধ্রুবক coefficient-এর degree k-এর একটি linear recurrence. F(n) সব n-এ শূন্য হলে এটি homogeneous; নইলে এটি একটি non-homogeneous recurrence. F(n) বাদ দিলে যা থাকে, an = c1an−1 + … + ckan−k, তা এর associated homogeneous recurrence.

“Linear” মানে a-এর পদগুলো শুধু ধ্রুবক দিয়ে গুণ হয়ে যোগ হয়: an−12 বা an−1an−2 নেই। F(n) কিন্তু n-এর যেকোনো ফাংশন হতে পারে, যেমন 1, n2, 2n বা n · 3n. কয়েকটি উদাহরণ:

RecurrenceF(n)কোথা থেকে
H(n) = 2H(n − 1) + 11Tower of Hanoi-র চাল
an = an−1 + n2n212 + 22 + … + n2
bn = (1 + r)bn−1 − P−Pঋণের বাকি, মাসিক কিস্তি P
tk = 2tk−1 + 2k2kMerge sort, n = 2k বসিয়ে
an = 3an−1 + 2n2nএই পর্বের প্রথম stepper

প্রথম প্রশ্ন: সমাধান আদৌ একটিই কি না। পর্ব ৪৪-এ strong induction (পর্ব ১১ “Strong induction আর well-ordering”) দিয়ে দেখানো হয়েছে, degree k-এর recurrence-এ k-টি পরপর initial condition দিলে পুরো ধারাটি একটিই, কারণ প্রতিটি নতুন পদ আগের k-টি দিয়ে পুরোপুরি ঠিক হয়। বাড়তি F(n) এই যুক্তিতে কিছুই বদলায় না: সেটিও একটি জানা সংখ্যা। তাই প্রশ্নটি অস্তিত্বের নয়, সূত্র খোঁজার: n = 1000-এর মান লুপ না চালিয়ে কীভাবে লিখব? সেই সূত্রই closed form.

পর্ব ৪৪-এ closed form পাওয়ার একটি পথ দেখেছেন: unrolling, অর্থাৎ পেছনে গুনে যাওয়া। Hanoi-তে H(n) = 2H(n − 1) + 1 = 4H(n − 2) + 2 + 1 = … = 2nH(0) + (2n−1 + … + 2 + 1), আর শেষের অংশটি একটি geometric series, যোগফল 2n − 1. পথটি সুন্দর, কিন্তু প্রতিবার একটি নতুন যোগফল চেনার ওপর নির্ভর করে, আর degree 2 বা তার বেশি হলে দ্রুত জট পাকায়। এই পর্বের পদ্ধতি যান্ত্রিক: একই কয়েকটি ধাপ, যেকোনো degree-তে। দুটি পথ একে অপরকে যাচাইও করে।

২ · মূল উপপাদ্য — সব সমাধান = particular + homogeneous

পুরো পদ্ধতি একটি সরল পর্যবেক্ষণের ওপর দাঁড়িয়ে: একই non-homogeneous recurrence-এর দুটি সমাধান বিয়োগ করলে F(n) কাটা যায়। ধরুন কোনোভাবে একটি সমাধান হাতে পেলেন, যেটি initial condition মানে না, শুধু recurrence মানে। একে বলে particular solution. তাহলে বাকি সব সমাধান তার থেকে একটি homogeneous সমাধান দূরে।

উপপাদ্য ২.১ (সমাধানের গঠন)

(pn) যদি an = c1an−1 + … + ckan−k + F(n)-এর একটি সমাধান হয়, তাহলে এই recurrence-এর প্রতিটি সমাধানের আকার an = pn + hn, যেখানে (hn) associated homogeneous recurrence-এর একটি সমাধান। উল্টোভাবে, এমন প্রতিটি pn + hn মূল recurrence-এর সমাধান।

  1. (an) যেকোনো সমাধান ধরুন, আর hn = an − pn সংজ্ঞায়িত করুন। — সংজ্ঞা
  2. দুটি সমীকরণ লিখুন: an = ∑i cian−i + F(n) আর pn = ∑i cipn−i + F(n). প্রথমটি থেকে দ্বিতীয়টি বিয়োগ করলে hn = ∑i cihn−i, কারণ F(n) − F(n) = 0. — বিয়োগ, linearity
  3. অর্থাৎ (hn) homogeneous recurrence মানে, আর an = pn + hn. — ধাপ ১, ২
  4. উল্টো দিক: h homogeneous সমাধান হলে pn + hn = ∑i ci(pn−i + hn−i) + F(n), দুটি সমীকরণ যোগ করে। ∎ — যোগ

পর্ব ৪৫-এর ফলের সঙ্গে মেলালে একটি সম্পূর্ণ রেসিপি পাওয়া যায়। Homogeneous অংশের সাধারণ সমাধান k-টি স্বাধীন ধ্রুবক নিয়ে আসে, যেমন আলাদা মূল r1, …, rk হলে α1r1n + … + αkrkn. তাই মূল recurrence-এর general solution হলো pn + α1r1n + … + αkrkn, আর k-টি initial condition দিয়ে α-গুলো ঠিক হয়। Initial condition বসানোর সময় একটি অনিবার্য ক্রম আছে, যা নিচের ছবিতে দেখুন: আগে p যোগ, তারপর ধ্রুবক খোঁজা।

পদ্ধতি ২.২ (পাঁচ ধাপের রেসিপি)
  1. Associated homogeneous recurrence-এর characteristic equation-এর মূল আর গুণিতা বের করুন, আর hn লিখুন।
  2. F(n)-কে (polynomial) × sn আকারে লিখুন; একাধিক অংশ থাকলে আলাদা করুন।
  3. প্রতিটি অংশের trial বাছুন (§৪-এর নিয়ম), বসিয়ে coefficient মেলান।
  4. an = hn + pn লিখে initial condition দিয়ে ধ্রুবক বের করুন।
  5. ছোট n-এ (অন্তত তিনটি পদ) সূত্র আর recurrence মিলিয়ে দেখুন।

Non-homogeneous recurrence সমাধানের পথ

উদাহরণ an = 3an−1 + 2n, a0 = 1. বাঁ শাখা homogeneous অংশ, ডান শাখা particular অংশ; দুটি মিলিয়ে তবেই initial condition.

Solving a non-homogeneous recurrence: homogeneous part plus particular part, then initial condition aₙ = 3aₙ₋₁ + 2n a₀ = 1 homogeneous aₙ = 3aₙ₋₁ মূল r = 3 hₙ = α·3ⁿ particular F(n) = 2n অনুমান cn + d pₙ = −n − 3/2 aₙ = α·3ⁿ − n − 3/2 a₀ = 1 ⇒ α = 5/2 aₙ = (5·3ⁿ − 2n − 3)/2 initial condition সবশেষে, যোগফলের ওপর

Particular solution একটিমাত্র নয়। pn একটি particular solution হলে pn + 7 · 3n-ও একটি (an = 3an−1 + 2n-এর ক্ষেত্রে), কারণ 7 · 3n homogeneous সমাধান। তাই “particular” মানে “বিশেষ একটি”, “একমাত্র” নয়; আমরা সবচেয়ে সরলটি বাছি। উল্টো দিকে, শেষ উত্তরটি একটিই: initial condition বসানোর পর ধ্রুবকগুলো একটিমাত্র রৈখিক system-এর সমাধান। আলাদা মূলের degree 2-এর ক্ষেত্রে এই system-এর ম্যাট্রিক্স [1 1; r1 r2], যার determinant r2 − r1 ≠ 0, তাই সমাধান সবসময় আছে আর একটিই (পর্ব ৪৫-এর যুক্তি)। Particular অংশ এই ম্যাট্রিক্স বদলায় না, শুধু ডান পাশের সংখ্যাগুলো সরায়।

একটি তুলনা মনে রাখুন। দুটি জমা হিসাবের একই নিয়ম (একই মুনাফা, একই মাসিক জমা), কিন্তু শুরুর জমা আলাদা। তাদের পার্থক্য প্রতি মাসে শুধু ১% হারে বাড়ে, কারণ মাসিক জমা দুই হিসাবেই সমান আর বিয়োগে কাটা যায়। পার্থক্যটি তাই homogeneous ধারা sn = 1.01 · sn−1 মানে। উপপাদ্য ২.১ ঠিক এই কথাটিই সাধারণভাবে বলে।

৩ · Undetermined coefficients — F(n) যখন polynomial

এখন বাকি থাকে একটি particular solution খোঁজা। কৌশলটির নাম method of undetermined coefficients: F(n)-এর আকার দেখে একই আকারের একটি “trial” অনুমান করুন, অজানা coefficient রেখে। তারপর recurrence-এ বসিয়ে দুই পাশের n-এর একই ঘাতের coefficient মেলান। F(n) = 2n একটি degree 1-এর polynomial, তাই trial pn = cn + d. দুটি অজানা, দুটি সমীকরণ।

1homogeneous: r = 32trial pₙ = cn + d3বসানো আর সাজানো4c = −1, d = −3/25α·3ⁿ − n − 3/2; a₀ = 16a₁, a₂, a₃ মেলানো
aₙ = 3aₙ₋₁ + 2n, a₀ = 1
hₙ
pₙ
সমীকরণ
যাচাই
  1. Homogeneous অংশ। F(n) বাদ দিলে an = 3an−1; characteristic equation r − 3 = 0, মূল 3. তাই hn = α · 3n, α এখনো অজানা।
  2. Trial বাছাই। F(n) = 2n, degree 1-এর polynomial. 1 মূল নয় (মূল শুধু 3), তাই সংঘাত নেই: pn = cn + d. শুধু cn নিলে চলবে না; নিচের ঘাতের পদও রাখতে হয়।
  3. বসানো। cn + d = 3(c(n − 1) + d) + 2n = (3c + 2)n + (3d − 3c). বাঁ আর ডান পাশে n-এর coefficient সমান: c = 3c + 2. ধ্রুবক পদ সমান: d = 3d − 3c.
  4. সমাধান। প্রথমটি থেকে c = −1. দ্বিতীয়টি থেকে 2d = 3c = −3, তাই d = −3/2. যাচাই: p0 = −3/2, p1 = −5/2, আর 3p0 + 2 = −9/2 + 2 = −5/2 ✓.
  5. যোগ, তারপর initial condition. an = α · 3n − n − 3/2. n = 0 বসালে α − 3/2 = 1, তাই α = 5/2. ফল an = (5 · 3n − 2n − 3)/2.
  6. যাচাই। Recurrence থেকে a1 = 3 + 2 = 5, a2 = 15 + 4 = 19, a3 = 57 + 6 = 63. সূত্র থেকে (15 − 5)/2 = 5, (45 − 7)/2 = 19, (135 − 9)/2 = 63. মিলে গেল।

Hanoi আবার — এক লাইনে

পর্ব ৪৪-এ Tower of Hanoi-র চালের সংখ্যা H(n) = 2H(n − 1) + 1, H(0) = 0 পাওয়া গিয়েছিল, আর পেছনে গুনে গুনে (unrolling) 2n − 1 অনুমান করে induction-এ প্রমাণ করা হয়েছিল। এবার অনুমান ছাড়াই: homogeneous মূল 2, F(n) = 1 একটি ধ্রুবক, আর 1 মূল নয়। Trial pn = A: A = 2A + 1, তাই A = −1. সাধারণ সমাধান α · 2n − 1, আর H(0) = 0 থেকে α = 1. উত্তর H(n) = 2n − 1.

Particular solution −1-এর একটি সুন্দর মানে আছে: un = H(n) + 1 বসালে un = 2un−1, একটি নিখাদ homogeneous recurrence. ধ্রুবক F-এর ক্ষেত্রে particular solution মানে ধারার “ভারসাম্য বিন্দু”, যেখান থেকে সরে থাকা অংশটুকু শুধু গুণ হতে থাকে।

∑k² — যখন 1 নিজেই মূল

Sn = 12 + 22 + … + n2 লিখলে Sn = Sn−1 + n2, S0 = 0. পর্ব ১৭ “Sequence আর summation — closed form আর বিখ্যাত যোগফল”-এ এর সূত্র telescoping দিয়ে বের হয়েছে; এখানে একই সূত্র recurrence থেকে আসে। Homogeneous অংশ Sn = Sn−1-এর মূল 1, আর F(n) = n2 = n2 · 1n-এর s-ও 1. এখানেই প্রথম সংঘাত: সরল trial An2 + Bn + C কাজ করে না, কারণ ধ্রুবক C নিজেই homogeneous সমাধান, আর বসালে বাঁ পাশ থেকে ডান পাশ বিয়োগে n2-এর পদ কাটা যায়: An2 − A(n − 1)2 = 2An − A, যার degree মাত্র 1. সমাধান: trial-কে n দিয়ে গুণ করুন।

  1. Trial pn = n(An2 + Bn + C) = An3 + Bn2 + Cn. — নিয়ম ৪.১, m = 1
  2. pn − pn−1 = A(3n2 − 3n + 1) + B(2n − 1) + C = 3An2 + (2B − 3A)n + (A − B + C). — বিস্তার
  3. এটি n2-এর সমান হতে হবে: 3A = 1, 2B − 3A = 0, A − B + C = 0. তাই A = 1/3, B = 1/2, C = 1/6. — coefficient মেলানো
  4. pn = n3/3 + n2/2 + n/6 = n(n + 1)(2n + 1)/6, আর p0 = 0 = S0, তাই homogeneous অংশের ধ্রুবক 0. Sn = n(n + 1)(2n + 1)/6. ∎ — উপপাদ্য ২.১

যাচাই: S10 = 10 · 11 · 21/6 = 385, আর S20 = 2870; দুটিই পর্ব ১৭-এর মানের সঙ্গে মেলে, আর §৫-এর Python ব্লকেও আসে।

আরেকটি: n রেখায় সমতলের অঞ্চল

পর্ব ৪৪-এর আরেকটি মডেল: সমতলে n-টি রেখা, কোনো দুটি সমান্তরাল নয় আর কোনো তিনটি এক বিন্দুতে মেলে না। n-তম রেখা আগের n − 1টিকে n − 1টি আলাদা বিন্দুতে কাটে, তাই নিজে n-টি টুকরো হয়, আর প্রতিটি টুকরো একটি পুরোনো অঞ্চলকে দুই ভাগ করে। ফলে R(n) = R(n − 1) + n, R(0) = 1. মূল 1, আর F(n) = n · 1n: আবার সংঘাত, m = 1. Trial n(An + B): n(An + B) − (n − 1)(A(n − 1) + B) = 2An − A + B = n, তাই A = B = 1/2, আর pn = n(n + 1)/2. R(0) = 1 থেকে ধ্রুবক 1: R(n) = 1 + n(n + 1)/2. যাচাই: 2, 4, 7, 11, recurrence-এর সঙ্গে এক। বাজারঘরের ডেলিভারি-ম্যাপে n-টি সোজা রাস্তা শহরকে সর্বোচ্চ এতগুলো এলাকায় ভাগ করতে পারে।

৪ · Exponential F(n) আর সংঘাতের নিয়ম — কেন nm দিয়ে গুণ

F(n) = 2n হলে স্বাভাবিক trial A · 2n. বেশিরভাগ ক্ষেত্রে তা কাজ করে। কিন্তু homogeneous অংশের মূলও যদি 2 হয়, তাহলে A · 2n নিজেই homogeneous সমাধান: বসালে বাঁ আর ডান পাশের A-এর পদ হুবহু কাটা যায়, আর পড়ে থাকে 0 = 2n-এর মতো অসম্ভব সমীকরণ। নিচের stepper এই colliding (সংঘাতের) ক্ষেত্রটি ধাপে ধাপে দেখায়।

1homogeneous: r = 22trial c·2ⁿ ⇒ 0 = 1 ✗3কারণ: c·2ⁿ নিজেই hₙ4নতুন trial cn·2ⁿ ⇒ c = 15(α + n)2ⁿ; a₀ = 16aₙ = (n + 1)2ⁿ ✓
aₙ = 2aₙ₋₁ + 2ⁿ, a₀ = 1
trial
2ⁿ দিয়ে ভাগ
ফল
  1. Homogeneous অংশ। an = 2an−1-এর মূল 2, তাই hn = α · 2n. F(n) = 2n, অর্থাৎ s = 2, আর s মূলের সমান।
  2. সরল trial. pn = c · 2n বসালে c · 2n = 2 · c · 2n−1 + 2n. দুই পাশ 2n দিয়ে ভাগ করলে c = c + 1, অর্থাৎ 0 = 1. কোনো c কাজ করে না।
  3. কেন ভাঙল। c · 2n নিজেই homogeneous সমাধান, তাই “বাঁ − ডান” করলে c-এর সব পদ কাটা যায়, আর 2n মেলানোর মতো কিছু থাকে না। এটিই সংঘাত: s = 2 হলো characteristic equation-এর একগুণ মূল, m = 1.
  4. n দিয়ে গুণ। pn = cn · 2n: cn · 2n = 2c(n − 1)2n−1 + 2n. 2n দিয়ে ভাগ: cn = cn − c + 1, তাই c = 1. Particular solution pn = n · 2n.
  5. যোগ, তারপর a0. an = α · 2n + n · 2n. n = 0-তে α = 1, তাই an = (n + 1)2n.
  6. যাচাই। Recurrence: a1 = 2 + 2 = 4, a2 = 8 + 4 = 12, a3 = 24 + 8 = 32, a4 = 64 + 16 = 80. সূত্র: 2 · 2, 3 · 4, 4 · 8, 5 · 16, একই সংখ্যা।

এই উদাহরণটি algorithm বিশ্লেষণে বারবার আসে। Merge sort-এর recurrence T(n) = 2T(n/2) + n-এ n = 2k আর tk = T(2k) বসালে tk = 2tk−1 + 2k: ঠিক উপরের recurrence. T(1) = 1 হলে tk = (k + 1)2k, অর্থাৎ T(n) = n(log2 n + 1). Merge sort-এর বিখ্যাত log n গুণকটি আসলে এই সংঘাতের n-গুণকই! কোড থেকে এমন recurrence লেখা আর সংখ্যায় যাচাইয়ের অভ্যাস DSA কোর্সের পর্ব ০৮-এ আছে; এখানে আমরা দেখলাম log n কেন আসে, তার গাণিতিক কারণ। সাধারণ divide-and-conquer recurrence আর master theorem-এর প্রমাণ পর্ব ৪৭ “Divide-and-conquer recurrence আর master theorem-এর গণিত”-এ আসবে।

নিয়ম ৪.১ (trial form, সংঘাতসহ)

ধরুন F(n) = (btnt + … + b1n + b0) · sn, যেখানে s ≠ 0 একটি ধ্রুবক।

  • s যদি associated homogeneous recurrence-এর characteristic equation-এর মূল না হয়, তাহলে একটি particular solution আছে এই আকারে: (Atnt + … + A1n + A0) · sn.
  • s যদি m-গুণ মূল হয় (multiplicity m), তাহলে একটি particular solution আছে এই আকারে: nm(Atnt + … + A0) · sn.

ঋণাত্মক s-ও চলে। নিয়মটিতে s যেকোনো অশূন্য ধ্রুবক, তাই F(n) = (−1)n-এর মতো পর্যায়ক্রমে চিহ্ন-বদলানো পদও একই ছকে পড়ে। যেমন an = an−1 + 2an−2 + (−1)n: মূল 2 আর −1, আর s = −1 একগুণ মূল, তাই trial An(−1)n. বসিয়ে (−1)n দিয়ে ভাগ করলে An = −A(n − 1) + 2A(n − 2) + 1 = An − 3A + 1, তাই A = 1/3 আর pn = n(−1)n/3 (scratch-এ ৩০টি পদে মেলানো)। এক সপ্তাহ বেশি, পরের সপ্তাহ কম, এমন দোলানো চাহিদার মডেলে এই ধরনের পদ আসে।

m কীভাবে বের করবেন। χ(x) হলো characteristic polynomial (নিচের রূপরেখায় সংজ্ঞা)। s মূল কি না দেখতে χ(s) হিসাব করুন। শূন্য হলে অন্তত একগুণ মূল; তারপর অন্তরজ χ′(s)-ও শূন্য হলে অন্তত দ্বিগুণ, আর এভাবে চলতে থাকে। যেমন χ(x) = x2 − 4x + 4-এ χ(2) = 0 আর χ′(x) = 2x − 4, χ′(2) = 0, কিন্তু χ″(2) = 2 ≠ 0: তাই m = 2. পরীক্ষায় সাধারণত মূলগুলো সরাসরি factor করে দেখাই সহজ, কিন্তু বড় degree-তে এই পরীক্ষা কাজে লাগে।

প্রমাণের রূপরেখা। পর্ব ৪৫-এ degree k-এর সাধারণ ফলটি (পুনরাবৃত্ত মূল r-এর জন্য rn, nrn, …, nm−1rn) বলা হয়েছে; এখানে সেটি ব্যবহার করি। একটি ধারার ওপর “এক ধাপ সামনে সরাও” কাজটিকে E লিখুন: (Ea)n = an+1.

  1. Recurrence-টিকে এক জায়গায় আনলে লেখা যায় χ(E)a = G, যেখানে χ(x) = xk − c1xk−1 − … − ck হলো characteristic polynomial আর Gn = F(n + k). — সূচক সরানো
  2. q একটি degree j-এর polynomial হলে (E − s) প্রয়োগে q(n)sn হয় s(q(n + 1) − q(n))sn, যার polynomial অংশের degree j − 1. তাই (E − s)t+1 প্রয়োগে G পুরো মুছে যায়। এই (E − s)t+1-কে G-এর annihilator বলে। — পার্থক্যে degree কমে
  3. অতএব প্রতিটি সমাধান a একটি বড় homogeneous recurrence মানে: (E − s)t+1χ(E)a = 0, যার characteristic polynomial χ(x)(x − s)t+1. এতে s-এর গুণিতা m + t + 1. — E-এর polynomial গুণ বিনিময়যোগ্য
  4. পর্ব ৪৫-এর উপপাদ্য অনুযায়ী a = (χ-এর মূল থেকে আসা পদ) + nm(A0 + … + Atnt)sn; sn, …, nm−1sn-এর পদগুলো আগেই χ-এর অংশ, তাই প্রথম ভাগে ঢুকে যায়। — পুনরাবৃত্ত মূলের উপপাদ্য
  5. প্রথম ভাগ নিজে homogeneous সমাধান, তাই উপপাদ্য ২.১ অনুযায়ী তা বাদ দিলে যা থাকে, nm(A0 + … + Atnt)sn, সেটিও একটি সমাধান: এটিই চাওয়া particular solution. ∎ — উপপাদ্য ২.১

রূপরেখাটি দেখায় trial form-টি “আন্দাজ” নয়: সমাধানের আকার প্রমাণিতভাবে এটিই, আমরা শুধু coefficient-গুলো জানি না। পুরো বিস্তারিত (A-গুলো সত্যিই একটিমাত্র রৈখিক system-এর সমাধান) generating function দিয়ে আরও পরিষ্কার হয়, যা পর্ব ৪৮ “Generating function — গণনাকে বীজগণিতে রূপান্তর”-এ আসবে।

F(n)s মূল নয়s হলো m-গুণ মূল
ধ্রুবক d (s = 1)AA · nm
n2 বা যেকোনো degree 2 (s = 1)An2 + Bn + Cnm(An2 + Bn + C)
d · snA · snA · nmsn
n · sn(An + B)snnm(An + B)sn
F1(n) + F2(n)প্রতিটির trial আলাদা করে, তারপর যোগ

শেষ সারির নিয়মটির নাম superposition principle: p(1) যদি F1-এর আর p(2) যদি F2-এর particular solution হয়, তাহলে p(1) + p(2) হলো F1 + F2-এর particular solution; দুটি সমীকরণ যোগ করলেই প্রমাণ। একটি সতর্কতা: F(n) = n2 হলেও trial-এ নিচের সব ঘাত রাখতে হয় (An2 + Bn + C), কারণ বসানোর পর নিচের ঘাতগুলো আপনাআপনি তৈরি হয়। আর F(n) যদি এই ছকে না পড়ে, যেমন n! বা 1/n, তাহলে এই পদ্ধতি খাটে না; তখন §৭-এর summation factor বা generating function লাগে।

Superposition-এর একটি উদাহরণ। an = 2an−1 + n + 3n, a0 = 1. মূল 2; বাড়তি পদের দুই অংশের কোনোটিই সংঘাত করে না (s = 1 আর s = 3). প্রথম অংশ n-এর জন্য trial An + B: An + B = 2A(n − 1) + 2B + n থেকে A = −1, B = −2. দ্বিতীয় অংশ 3n-এর জন্য trial C · 3n: 3C = 2C + 3, তাই C = 3. যোগ করে an = α · 2n − n − 2 + 3n+1; a0 = 1 থেকে α − 2 + 3 = 1, তাই α = 0. উত্তর an = 3n+1 − n − 2: ধারা 1, 6, 23, 76, 237, recurrence থেকেও হুবহু তাই (scratch-এ ১২টি পদ মেলানো)। এখানে α = 0 হওয়া কাকতাল মাত্র; সাধারণত তা হয় না।

৫ · Python-এ একটি সাধারণ first-order সমাধানকারী

নিয়ম ৪.১-কে এবার কোডে বসাই। নিচের ফাংশন an = c · an−1 + p(n) · sn ধরনের যেকোনো recurrence নেয়, যেখানে p একটি polynomial (coefficient-এর তালিকা হিসেবে দেওয়া)। এটি নিজেই সংঘাত চেনে (s = c হলে m = 1), trial বসিয়ে coefficient-এর রৈখিক system বানায়, Fraction দিয়ে Gauss–Jordan পদ্ধতিতে সমাধান করে, আর সবশেষে initial condition থেকে α বের করে। তারপর ৪০টি পদ সরাসরি recurrence চালিয়ে closed form-এর সঙ্গে মেলায়। প্রথমবার চালালে ব্রাউজারে Python (Pyodide) নামতে কয়েক সেকেন্ড লাগে।

from fractions import Fraction as Fr

def solve(c, poly, s, a0):            # a_n = c a_(n-1) + poly(n) s^n
    t, m = len(poly) - 1, int(s == c)  # m = 1 when s collides with c
    def trial(q, n):                  # n^m (q0 + q1 n + ...) s^n
        return n**m * sum(x * n**i for i, x in enumerate(q)) * Fr(s)**n
    def F(n):
        return sum(b * n**i for i, b in enumerate(poly)) * Fr(s)**n
    unit = [[int(i == j) for i in range(t + 1)] for j in range(t + 1)]
    A = [[trial(u, n) - c * trial(u, n - 1) for u in unit] + [F(n)]
         for n in range(1, t + 2)]    # trial must satisfy the recurrence
    for i in range(t + 1):            # Gauss-Jordan with Fractions
        k = next(r for r in range(i, t + 1) if A[r][i] != 0)
        A[i], A[k] = A[k], A[i]
        A[i] = [x / A[i][i] for x in A[i]]
        for r in range(t + 1):
            if r != i:
                A[r] = [x - A[r][i] * y for x, y in zip(A[r], A[i])]
    q = [row[-1] for row in A]
    alpha = a0 - trial(q, 0)          # fit the initial value last
    return (lambda n: alpha * Fr(c)**n + trial(q, n)), q, m

cases = [("3a+2n", 3, [0, 2], 1, 1), ("2a+2^n", 2, [1], 2, 1),
         ("a+n^2", 1, [0, 0, 1], 1, 0), ("2a+1", 2, [1], 1, 0),
         ("2a+n2^n", 2, [0, 1], 2, 1)]
for name, c, poly, s, a0 in cases:
    f, q, m = solve(c, poly, s, a0)
    a, ok = Fr(a0), True
    for n in range(1, 41):            # iterate the recurrence itself
        a = c * a + sum(b * n**i for i, b in enumerate(poly)) * s**n
        ok = ok and a == f(n)
    print(f"{name:8} m={m} q={[str(x) for x in q]} a_10={f(10)} ok={ok}")

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

3a+2n    m=0 q=['-3/2', '-1'] a_10=147611 ok=True
2a+2^n   m=1 q=['1'] a_10=11264 ok=True
a+n^2    m=1 q=['1/6', '1/2', '1/3'] a_10=385 ok=True
2a+1     m=0 q=['-1'] a_10=1023 ok=True
2a+n2^n  m=1 q=['1/2', '1/2'] a_10=57344 ok=True

q হলো trial-এর coefficient, নিচের ঘাত থেকে ওপরে। প্রথম লাইনে q = (−3/2, −1), অর্থাৎ pn = −3/2 − n, প্রথম stepper-এর ফল; a10 = (5 · 310 − 23)/2 = 147611. দ্বিতীয় লাইনে কোড নিজেই সংঘাত ধরেছে (m = 1), আর a10 = 11 · 210 = 11264, দ্বিতীয় stepper-এর (n + 1)2n. তৃতীয় লাইনে ∑k²-এর trial n(1/6 + n/2 + n²/3), আর a10 = 385. চতুর্থটি Hanoi: p = −1, a10 = 210 − 1. শেষ লাইন polynomial × exponential, সংঘাতসহ: pn = n(1/2 + n/2)2n = n(n + 1)2n−1 (§৮-এর অঙ্ক ২)। প্রতিটি ক্ষেত্রে ৪০টি পদ হুবহু মিলেছে (ok=True), কারণ সব হিসাব ভগ্নাংশে, কোনো float নেই। ফাংশনটির সীমাও জেনে রাখুন: এটি শুধু first-order, ধ্রুবক c-এর জন্য। Degree k-তে একই কৌশল খাটে, তবে তখন s-এর গুণিতা m বের করতে characteristic polynomial-এর মূল লাগে, আর শেষে k-টি initial condition দিয়ে k-টি ধ্রুবকের একটি system সমাধান করতে হয়। §৮-এর অঙ্ক ১ সেই হিসাবটি হাতে দেখায়। একটি সূক্ষ্ম বিষয়: n = 1, …, t + 1-এ বসিয়ে পাওয়া system সবসময় একটিমাত্র সমাধান দেয়, কারণ নিয়ম ৪.১ বলে উপযুক্ত coefficient আছে, আর degree t-এর polynomial t + 1টি বিন্দুতে মান দিলেই পুরোপুরি ঠিক হয়।

৬ · ঋণ পরিশোধ — মাসিক কিস্তির closed form

পর্ব ৪৪-এ বাজারঘরের একটি কাল্পনিক ব্যবসায়িক ঋণের মডেল বানানো হয়েছিল। ধরুন ঋণ L টাকা, মাসিক সুদের হার r (যেমন r = 0.01, অর্থাৎ মাসে ১%; এটি শুধু উদাহরণের সংখ্যা, কোনো আসল ব্যাংকের হার নয়), আর প্রতি মাসের শেষে একই কিস্তি P দেওয়া হয়। n মাস পরে বাকি bn হলে

bn = (1 + r) · bn−1 − P, b0 = L

এটি এক ধরনের compound interest: সুদ বাকির ওপর বসে, আর বাকিতে আগের সুদও আছে। প্রশ্ন: N মাসে পুরো ঋণ শোধ করতে P কত হবে? লুপ চালিয়ে চেষ্টা-ভুল করা যায়, কিন্তু closed form সরাসরি উত্তর দেয়। এই হিসাবের নাম loan amortization.

উপপাদ্য ৬.১ (ঋণের বাকি আর কিস্তি)

r > 0 হলে bn = (L − P/r)(1 + r)n + P/r. বিশেষত bN = 0 হয় ঠিক তখন, যখন

P = L · r(1 + r)N / ((1 + r)N − 1)

  1. Homogeneous অংশ bn = (1 + r)bn−1-এর মূল 1 + r, তাই hn = α(1 + r)n. — পর্ব ৪৫
  2. F(n) = −P একটি ধ্রুবক (s = 1), আর r > 0 বলে 1 ≠ 1 + r: সংঘাত নেই। Trial pn = A: A = (1 + r)A − P, তাই A = P/r. — নিয়ম ৪.১
  3. উপপাদ্য ২.১: bn = α(1 + r)n + P/r; n = 0-তে α = L − P/r. — initial condition সবশেষে
  4. bN = 0 মানে (L − P/r)(1 + r)N = −P/r. দুই পাশ r দিয়ে গুণ করে সাজালে P((1 + r)N − 1) = Lr(1 + r)N; (1 + r)N > 1, তাই ভাগ বৈধ। ∎ — বীজগণিত

কিস্তির কতটা মূল ঋণে যায়? n-তম কিস্তিতে সুদ r · bn−1, আর বাকিটুকু মূল ঋণ কমায়: bn−1 − bn. Closed form থেকে bn−1 − bn = −(L − P/r)(1 + r)n−1 · r = (P − rL)(1 + r)n−1. অর্থাৎ মূল ঋণে যাওয়া অংশ প্রতি মাসে (1 + r) গুণ বাড়ে, আর সুদের অংশ সেই হারেই কমে, কারণ দুটির যোগফল সবসময় P. প্রথম মাসে এটি P − rL, যা নিচের ব্লকের উদাহরণে প্রায় ৯,৪৬২ টাকা।

একই সূত্র, অন্য দিক থেকে। কিস্তির সূত্রটি উল্টে লিখলে L = P(1 − (1 + r)−N)/r = P/(1 + r) + P/(1 + r)2 + … + P/(1 + r)N, একটি সসীম geometric series (পর্ব ১৭)। মানেটি সুন্দর: k মাস পরের P টাকার “আজকের মূল্য” P/(1 + r)k, কারণ আজ সেই পরিমাণ রাখলে k মাসে সুদে-আসলে P হতো। ঋণদাতা আজ যে L দেন, তা ঠিক ভবিষ্যতের সব কিস্তির আজকের মূল্যের যোগফল। Recurrence-এর পথ আর এই যোগফলের পথ একই উত্তরে পৌঁছায়, যা দুটি স্বাধীন যাচাইয়ের কাজ করে।

P/r সংখ্যাটির একটি পরিষ্কার মানে আছে: বাকি ঠিক P/r হলে মাসের সুদ r · P/r = P, কিস্তির সমান, তাই বাকি কখনো বদলায় না। এটিই ভারসাম্য বিন্দু (Hanoi-র −1-এর মতো)। L < P/r হলে ভারসাম্য থেকে দূরত্ব L − P/r ঋণাত্মক, আর তা প্রতি মাসে (1 + r) গুণ বাড়তে বাড়তে বাকিকে শূন্যে নামায়। P ≤ Lr হলে কিস্তি সুদও ঢাকে না, আর ঋণ কখনো শোধ হয় না।

উদাহরণ: L = 1,20,000 টাকা, r = 1/100, N = 12. নিচের ব্লক কিস্তি নির্ভুলভাবে বের করে, প্রতি মাসের খাতা (ledger) closed form-এর সঙ্গে মেলায়, আর দেখায় পয়সায় গোল করলে কী হয়। এটি শুধু গণিতের উদাহরণ, কোনো আর্থিক পরামর্শ নয়; বাস্তব ঋণে ফি, সুদ হিসাবের নিয়ম আর দিন গোনার রীতি আলাদা হতে পারে।

from fractions import Fraction as Fr

L, r, N = Fr(120000), Fr(1, 100), 12  # loan, example monthly rate, months
g = (1 + r) ** N
P = L * r * g / (g - 1)               # the payment that makes b_N = 0
print("exact monthly payment P ~", round(float(P), 4))

def closed(n, pay):                   # b_n = (L - pay/r)(1+r)^n + pay/r
    return (L - pay / r) * (1 + r) ** n + pay / r

b = L
for n in range(1, N + 1):             # month-by-month ledger
    b = (1 + r) * b - P
    if n in (1, 2, 6, 12):
        print(f"month {n:2}: ledger {float(b):10.2f}"
              f"   formula {float(closed(n, P)):10.2f}")
print("ledger == formula, and b_12 == 0:", b == closed(N, P) == 0)

P2 = Fr(round(P * 100), 100)          # paid in whole paisa
print("rounded payment", float(P2), "-> left after 12 months:",
      round(float(closed(N, P2)), 4))
print("total paid", float(P2 * N), "  of which interest", float(P2 * N - L))

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

exact monthly payment P ~ 10661.8546
month  1: ledger  110538.15   formula  110538.15
month  2: ledger  100981.67   formula  100981.67
month  6: ledger   61790.53   formula   61790.53
month 12: ledger       0.00   formula       0.00
ledger == formula, and b_12 == 0: True
rounded payment 10661.85 -> left after 12 months: 0.0589
total paid 127942.2   of which interest 7942.2

নির্ভুল কিস্তি একটি ভগ্নাংশ, প্রায় ১০,৬৬১.৮৫৪৬ টাকা; Fraction-এ রাখায় মাসে মাসে খাতা আর closed form হুবহু এক, আর ১২ মাস পরে বাকি ঠিক শূন্য। প্রথম মাসে ১,২০,০০০-এর ১% = ১,২০০ টাকা সুদ, তাই কিস্তির মাত্র প্রায় ৯,৪৬২ টাকা মূল ঋণ কমায় (বাকি ১,১০,৫৩৮.১৫)। পরের মাসগুলোতে সুদের অংশ কমে আর মূলের অংশ বাড়ে। বাস্তবে কিস্তি পয়সায় গোল হয় (১০,৬৬১.৮৫), আর তাতে ১২ মাস শেষে প্রায় ৬ পয়সা বাকি থাকে, যা সাধারণত শেষ কিস্তিতে সমন্বয় করা হয়। গোল করার এই ছোট ভুলও closed form-এর (L − P/r)(1 + r)n পদ দিয়ে ব্যাখ্যা হয়: P-এর ছোট পরিবর্তন প্রতি মাসে (1 + r) গুণে বাড়ে।

উল্টো দিক: সঞ্চয়ের লক্ষ্য

§১-এর সঞ্চয় হিসাবেও একই পদ্ধতি। sn = 1.01 · sn−1 + 5000, s0 = 0. মূল 1.01, trial A: A = 1.01A + 5000, তাই A = −5,00,000. sn = α(1.01)n − 500000, আর s0 = 0 থেকে α = 500000: sn = 500000((1.01)n − 1). এক বছরে s12 ≈ ৬৩,৪১২.৫২ টাকা, যার ৬০,০০০ নিজের জমা আর বাকিটা মুনাফা। প্রশ্ন: কত মাসে জমা ১,০০,০০০ টাকা ছাড়াবে? Closed form থাকায় লুপ লাগে না: (1.01)n ≥ 1.2, অর্থাৎ n ≥ ln 1.2/ln 1.01 ≈ 18.3, তাই ১৯ মাস (scratch-এ লুপ চালিয়েও ১৯)। Particular solution এখানে ঋণাত্মক, −5,00,000: গণিতের দিক থেকে এটি সেই “ভারসাম্য বিন্দু”, যেখানে থাকলে মুনাফার বিয়োগ আর জমা পরস্পর কাটত; বাস্তবে এর কোনো মানে নেই, তবু সূত্রে এটি অপরিহার্য।

৭ · চলমান coefficient আর summation factor — quicksort-এর recurrence

এতক্ষণ coefficient c ছিল ধ্রুবক। কিন্তু algorithm-এর বিশ্লেষণে প্রায়ই আসে an = gn · an−1 + hn, যেখানে gn নিজেই n-এর ফাংশন, যেমন (n + 1)/n. তখন characteristic equation কাজ করে না, কারণ rn বসালে n বাদ যায় না। এর জন্য একটি পুরোনো, সরল কৌশল আছে।

উপপাদ্য ৭.১ (summation factor)

an = gnan−1 + hn (n ≥ 1), যেখানে প্রতিটি gn ≠ 0. G0 = 1 আর Gn = g1g2⋯gn ধরলে

an = Gn(a0 + ∑k=1n hk/Gk)

  1. Recurrence-কে Gn দিয়ে ভাগ করুন: an/Gn = gnan−1/Gn + hn/Gn = an−1/Gn−1 + hn/Gn, কারণ Gn = gnGn−1. — Gn ≠ 0
  2. un = an/Gn ধরলে un − un−1 = hn/Gn. — নতুন চলক
  3. k = 1 থেকে n পর্যন্ত যোগ করলে বাঁ পাশ কাটাকাটি হয়ে un − u0 থাকে (telescoping sum, পর্ব ১৭)। u0 = a0, তাই Gn দিয়ে গুণ করলে সূত্রটি আসে। ∎ — telescoping

1/Gn-কে বলে summation factor: এই গুণকে গুণ করলে recurrence একটি সাধারণ যোগফলে পরিণত হয়। ধ্রুবক gn = c-এ Gn = cn, আর সূত্রটি §৫-এর মতোই ফল দেয়, তবে যোগফলটি নিজে বের করতে হয়।

ছোট উদাহরণ। an = n · an−1 + n!, a0 = 1. এখানে F(n) = n! কোনো trial-এর ছকে পড়ে না, আর coefficient n-ও চলমান। gn = n, তাই Gn = n!, আর hk/Gk = k!/k! = 1. সূত্র থেকে an = n!(1 + n) = (n + 1)!. যাচাই: a1 = 1 + 1 = 2, a2 = 4 + 2 = 6, a3 = 18 + 6 = 24, ঠিক 2!, 3!, 4!.

Quicksort-এর গড় তুলনা

পর্ব ৪০ “Random variable আর প্রত্যাশা — linearity-র জাদু”-এ randomized quicksort-এর প্রত্যাশিত তুলনা 2(n + 1)Hn − 4n দেখানো হয়েছিল indicator আর linearity দিয়ে, যেখানে harmonic number Hn = 1 + 1/2 + … + 1/n. এবার একই উত্তর recurrence থেকে আসে। n-টি আলাদা key-এ pivot সমান সম্ভাবনায় k-তম ছোট (k = 1, …, n). Pivot-এর সঙ্গে বাকি n − 1টির তুলনা হয়, তারপর k − 1 আর n − k আকারের দুটি অংশ। শর্তসাপেক্ষ প্রত্যাশার গড় (total expectation) নিলে, C(n) = প্রত্যাশিত তুলনা হলে

C(n) = n − 1 + (1/n)∑k=1n (C(k − 1) + C(n − k)) = n − 1 + (2/n)∑j=0n−1 C(j), C(0) = 0

যুক্তিটি ধাপে ধাপে: (১) pivot-এর rank k হওয়ার সম্ভাবনা 1/n, প্রতিটি k-এর জন্য; (২) rank k ধরে নিলে বাকি কাজ দুটি স্বাধীন ছোট সমস্যা, আর ছোট অংশের ভেতরের ক্রমও এলোমেলো থাকে, তাই তাদের প্রত্যাশিত তুলনা C(k − 1) আর C(n − k); (৩) total expectation-এর নিয়মে (পর্ব ৪০-এর linearity আর পর্ব ৩৯-এর শর্তসাপেক্ষ ভাগ মিলিয়ে) মোট প্রত্যাশা = প্রতিটি k-এর শর্তসাপেক্ষ প্রত্যাশার গড়। দুটি যোগফল একই পদগুলো উল্টো ক্রমে গোনে, তাই 2 গুণ। এখানে C(n) আগের সব পদের ওপর নির্ভর করে: এমন recurrence-কে বলে full-history recurrence. প্রথম কাজ একে first-order বানানো।

1C(n) = n−1 + (2/n)∑C(j)2n দিয়ে গুণ3n−1-এর রূপ বিয়োগ4n(n+1) দিয়ে ভাগ5telescoping যোগ6C(n) = 2(n+1)Hₙ − 4n
সাধারণ ধাপ আর n = 4-এ মান
সূত্র
n = 4
  1. শুরু। C(n) = n − 1 + (2/n)(C(0) + … + C(n − 1)), C(0) = 0. ছোট মান: C(1) = 0, C(2) = 1, C(3) = 2 + (2/3)(0 + 0 + 1) = 8/3. n = 4-এ C(4) = 3 + (2/4)(0 + 0 + 1 + 8/3) = 3 + 11/6 = 29/6.
  2. n দিয়ে গুণ। nC(n) = n(n − 1) + 2∑j=0n−1 C(j). n = 4-এ বাঁ পাশ 4 · 29/6 = 58/3, ডান পাশ 12 + 2 · 11/3 = 58/3.
  3. পরপর দুটি বিয়োগ। একই সমীকরণ n − 1-এর জন্য লিখে বিয়োগ করলে যোগফলের শুধু শেষ পদ 2C(n − 1) থাকে: nC(n) − (n − 1)C(n − 1) = 2(n − 1) + 2C(n − 1), অর্থাৎ nC(n) = (n + 1)C(n − 1) + 2(n − 1). n = 4: 5 · 8/3 + 6 = 58/3 ✓.
  4. Summation factor. এখানে gn = (n + 1)/n, তাই Gn = (2/1)(3/2)⋯((n + 1)/n) = n + 1. পুরো সমীকরণ n(n + 1) দিয়ে ভাগ করলে C(n)/(n + 1) = C(n − 1)/n + 2(n − 1)/(n(n + 1)). n = 4: 29/30 = 2/3 + 3/10 ✓.
  5. Telescoping. C(0)/1 = 0 থেকে যোগ করলে C(n)/(n + 1) = ∑k=1n 2(k − 1)/(k(k + 1)). আংশিক ভগ্নাংশে 2(k − 1)/(k(k + 1)) = 4/(k + 1) − 2/k, তাই যোগফল 4(Hn+1 − 1) − 2Hn = 2Hn + 4/(n + 1) − 4. n = 4: 25/6 + 4/5 − 4 = 29/30 ✓.
  6. ফল। (n + 1) দিয়ে গুণ করলে C(n) = 2(n + 1)Hn + 4 − 4(n + 1) = 2(n + 1)Hn − 4n. n = 4: 10 · 25/12 − 16 = 125/6 − 16 = 29/6, ধাপ ১-এর মান। পর্ব ৪০-এর indicator পদ্ধতির হুবহু একই উত্তর।

নিচের ব্লক তিনটি জিনিস মেলায়: (১) recurrence-টি নিজে ঠিক কি না, সব n! ইনপুট-ক্রমে প্রথম উপাদানকে pivot ধরে গড় তুলনা গুনে (এলোমেলো ইনপুটে প্রথম উপাদান pivot আর যেকোনো ইনপুটে এলোমেলো pivot, দুটির বণ্টন একই); (২) recurrence আর closed form n ≤ 30-এ হুবহু এক কি না; (৩) stepper-এর ধাপ ৩-এর first-order রূপটি।

from fractions import Fraction as Fr
from itertools import permutations

def comparisons(lst):                 # quicksort, first element as pivot
    if len(lst) <= 1:
        return 0
    p = lst[0]
    small = [x for x in lst[1:] if x < p]
    big = [x for x in lst[1:] if x > p]
    return len(lst) - 1 + comparisons(small) + comparisons(big)

C = [Fr(0)]                           # C(n) = n-1 + (2/n)(C(0)+...+C(n-1))
for n in range(1, 31):
    C.append(n - 1 + Fr(2, n) * sum(C))
H = [Fr(0)]
for k in range(1, 31):
    H.append(H[-1] + Fr(1, k))
closed = [2 * (n + 1) * H[n] - 4 * n for n in range(31)]

for n in range(1, 7):                 # average over all n! input orders
    perms = list(permutations(range(n)))
    avg = Fr(sum(comparisons(list(p)) for p in perms), len(perms))
    print(f"n = {n}: brute force {str(avg):>6}   recurrence {str(C[n]):>6}")
print("recurrence == 2(n+1)H_n - 4n for all n <= 30:", C == closed)
ok = all(n * C[n] == (n + 1) * C[n - 1] + 2 * (n - 1) for n in range(1, 31))
print("n C(n) == (n+1) C(n-1) + 2(n-1) for all n <= 30:", ok)
print("C(30) ~", round(float(C[30]), 3), "  C(10) ~", round(float(C[10]), 3))

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

n = 1: brute force      0   recurrence      0
n = 2: brute force      1   recurrence      1
n = 3: brute force    8/3   recurrence    8/3
n = 4: brute force   29/6   recurrence   29/6
n = 5: brute force   37/5   recurrence   37/5
n = 6: brute force 103/10   recurrence 103/10
recurrence == 2(n+1)H_n - 4n for all n <= 30: True
n C(n) == (n+1) C(n-1) + 2(n-1) for all n <= 30: True
C(30) ~ 127.689   C(10) ~ 24.437

প্রথম ছয় লাইনে n = 6 পর্যন্ত সব ক্রম (৬! = ৭২০টি পর্যন্ত) গুনে পাওয়া গড় recurrence-এর মানের সঙ্গে হুবহু এক: 8/3, 29/6, 37/5, 103/10. অর্থাৎ recurrence-এর মডেলটিই ঠিক। পরের দুই লাইন দেখায়, ৩০টি পর্যন্ত প্রতিটি n-এ closed form আর ধাপ ৩-এর রূপ নির্ভুলভাবে সত্য। ১০টি key-তে গড়ে প্রায় ২৪.৪টি তুলনা, ৩০টিতে প্রায় ১২৭.৭টি। Brute force এখানেই থামে: n = 12-তে ক্রম প্রায় ৪৮ কোটি, অথচ recurrence n = 30-এ মুহূর্তে চলে। Partition-এর কোড আর বাস্তব দিক DSA কোর্সের পর্ব ২২-এ।

একই recurrence আরেকটি প্রশ্নের উত্তরও দেয়। এলোমেলো ক্রমে n-টি আলাদা key একটি binary search tree-তে ঢোকালে প্রথম key-টি root হয়, আর সেটি সমান সম্ভাবনায় যেকোনো rank-এর; বাঁ আর ডান subtree আবার এলোমেলো ক্রমের ছোট গাছ। প্রতিটি key ঢোকানোর সময় যতগুলো তুলনা হয়, তার মোট যোগফল ঠিক quicksort-এর তুলনার মতো একই recurrence মানে, কারণ root-এর সঙ্গে বাকি n − 1টির তুলনা হয়, তারপর দুই ভাগ। তাই এলোমেলো BST বানাতে গড়ে 2(n + 1)Hn − 4n তুলনা, আর একটি key-এর গড় গভীরতা প্রায় 2 ln n. এক recurrence, দুটি algorithm: গণিতের এই পুনর্ব্যবহারই recurrence শেখার বড় লাভ।

৮ · পরীক্ষার অঙ্ক আর সাধারণ ভুল

অঙ্ক ১: দ্বিতীয় ক্রম, সংঘাত ছাড়া

an = 5an−1 − 6an−2 + 7n, a0 = a1 = 0. সমাধান করুন।

  1. Characteristic equation r2 − 5r + 6 = 0, মূল 2 আর 3. hn = α2n + β3n.
  2. s = 7 মূল নয়: trial A · 7n. বসিয়ে 7n−2 দিয়ে ভাগ: 49A = 35A − 6A + 49, তাই 20A = 49, A = 49/20.
  3. an = α2n + β3n + (49/20)7n. a0 = 0: α + β = −49/20. a1 = 0: 2α + 3β = −343/20. সমাধানে α = 49/5, β = −49/4.
  4. উত্তর: an = (49/20)(7n − 5 · 3n + 4 · 2n). যাচাই: a2 = (49/20)(49 − 45 + 16) = 49 = 5 · 0 − 6 · 0 + 49 ✓, আর a3 = 588 (scratch-এ মেলানো)।

অঙ্ক ২: polynomial × exponential, সংঘাতসহ

an = 2an−1 + n · 2n, a0 = 1.

  1. মূল 2, আর s = 2: m = 1. F-এর polynomial অংশ n, degree 1, তাই trial n(An + B)2n.
  2. বসিয়ে 2n দিয়ে ভাগ: An2 + Bn = A(n − 1)2 + B(n − 1) + n, অর্থাৎ 0 = (1 − 2A)n + (A − B). তাই A = B = 1/2.
  3. an = α2n + n(n + 1)2n−1; a0 = 1 থেকে α = 1. উত্তর: an = 2n−1(n2 + n + 2). যাচাই: 1, 4, 16, 56, 176, recurrence-এর মানের সঙ্গে এক।

অঙ্ক ৩: ঋণের কিস্তি

৫০,০০০ টাকার একটি কাল্পনিক ঋণ, মাসিক হার ২% (উদাহরণমাত্র), ৬ মাসে সমান কিস্তিতে শোধ। মাসিক কিস্তি আর মোট সুদ কত?

  1. উপপাদ্য ৬.১: P = 50000 · 0.02 · (1.02)6/((1.02)6 − 1). (1.02)6 ≈ 1.126162.
  2. P ≈ 1000 × 1.126162/0.126162 ≈ ৮,৯২৬.২৯ টাকা।
  3. মোট পরিশোধ ≈ 6 × 8926.29 ≈ ৫৩,৫৫৭.৭৪, তাই মোট সুদ প্রায় ৩,৫৫৭.৭৪ টাকা (scratch-এ Fraction দিয়ে মেলানো, আর ৬ মাস পরে বাকি ঠিক শূন্য)।

অঙ্ক ৪: শুধু trial form

an = 6an−1 − 9an−2 + F(n)-এ (characteristic equation (r − 3)2 = 0, মূল 3 দ্বিগুণ) নিচের প্রতিটি F-এর trial লিখুন।

F(n)s, mTrial
n21, m = 0An2 + Bn + C
3n3, m = 2An23n (আসলে A = 1/2)
n · 3n3, m = 2n2(An + B)3n
2n + n2 আর 1, দুটিই m = 0A2n + Bn + C

যুক্তির ভুল ধরুন: “আগে ধ্রুবক, পরে particular”

একজন an = 3an−1 + 2n, a0 = 1 এভাবে সমাধান করলেন: “hn = α · 3n; a0 = 1 বসিয়ে α = 1. Particular pn = −n − 3/2. তাই an = 3n − n − 3/2.”

ভুল কোথায়: initial condition বসানো হয়েছে শুধু homogeneous অংশে। কিন্তু a0 = 1 শর্তটি আসল ধারার, h-এর নয়। ফলে তাঁর সূত্রে a0 = 1 − 0 − 3/2 = −1/2, যা 1 নয়, আর a1 = 3 − 1 − 3/2 = 1/2, যেখানে আসল মান 5. উপপাদ্য ২.১-এর ক্রম মানুন: আগে an = α · 3n + pn লিখুন, তারপর পুরো যোগফলে a0 বসান: α = 5/2. একটি সহজ অভ্যাস এই ধরনের ভুল সঙ্গে সঙ্গে ধরে: শেষ সূত্রে n = 0, 1, 2 বসিয়ে recurrence-এর মানের সঙ্গে মেলানো।

আরও গভীরে: চলমান coefficient-এর উচ্চতর ক্রমের recurrence, যেমন (n + 1)an+1 = (2n + 1)an + n an−1, এক বড় পরিবারের অংশ; যে ধারাগুলো polynomial coefficient-এর linear recurrence মানে, তাদের বলে P-recursive বা holonomic. Marko Petkovšek ১৯৯২ সালের কাছাকাছি এমন recurrence-এর সব “hypergeometric” সমাধান খোঁজার একটি algorithm (Hyper) দেন বলে জানা যায়, আর Petkovšek, Herbert Wilf ও Doron Zeilberger-এর ১৯৯৬ সালের বই “A = B” দেখায়, বহু combinatorial যোগফলের সূত্র কম্পিউটার নিজেই খুঁজে আর প্রমাণ করে দিতে পারে। এই পর্বের annihilator ভাবনাই সেই তত্ত্বের সরলতম রূপ।

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

  • an = 2an−1 + 1, a0 = 0-এর closed form? 2n − 1 (particular −1).
  • an = 6an−1 − 9an−2 + 3n-এর trial? An23n, কারণ 3 দ্বিগুণ মূল।
  • দুটি সমাধানের বিয়োগফল কোন recurrence মানে? Associated homogeneous recurrence.
  • 12 মাসে L টাকার ঋণ, মাসিক হার r: কিস্তি? Lr(1 + r)12/((1 + r)12 − 1).
  • Quicksort-এর গড় তুলনা? 2(n + 1)Hn − 4n ≈ 2n ln n, summation factor 1/(n(n + 1)) দিয়ে।

৯ · AI-এর যুগে — particular solution যাচাই

AI সহকারী recurrence সমাধানে খুব দ্রুত, আর উত্তরটি দেখতে প্রায় সবসময় পরিপাটি। কিন্তু এই বিষয়ের ভুলগুলো প্রায়ই ছোট একটি সিদ্ধান্তে থাকে: কোন trial, কোন ক্রমে initial condition. সুখবর হলো, এখানে যাচাই সবচেয়ে সহজ: সূত্রে n = 0, 1, 2, 3 বসিয়ে recurrence-এর মানের সঙ্গে মেলালেই হয়। কয়েকটি নিয়মিত ভুল:

AI-এর ভুলকীভাবে ধরবেন
সংঘাতের ক্ষেত্রে সরল trial, তারপর “0 = 1, তাই সমাধান নেই” বা হিসাবে একটি ভুল cs characteristic equation-এর মূল কি না নিজে পরীক্ষা করুন; m গুণিতা হলে nm
Initial condition শুধু homogeneous অংশে বসানোশেষ সূত্রে n = 0, 1 বসিয়ে দেখুন
F(n) = n2-এ trial An2, নিচের ঘাত বাদCoefficient মেলালে সমীকরণ বেশি, অজানা কম: অসংগতি দেখা দেয়
চলমান coefficient-এ (যেমন (n + 1)/n) characteristic equation খাটানোজিজ্ঞেস করুন: coefficient কি সত্যিই ধ্রুবক?
ঋণের সূত্রে বার্ষিক আর মাসিক হার মিশিয়ে ফেলাr আর N একই একক (মাস) কি না দেখুন; খাতা লুপে চালিয়ে মেলান
বড় n-এ float দিয়ে “যাচাই”, ছোট পার্থক্যকে rounding বলে উড়িয়ে দেওয়াFraction বা পূর্ণসংখ্যায় হুবহু মেলান

একটি নমুনা ভুল। ধরুন একটি সহকারী an = 2an−1 + 2n, a0 = 1-এর উত্তর দিল “an = 2n+1 − 1”, সঙ্গে কয়েক লাইনের আত্মবিশ্বাসী ব্যাখ্যা। দেখতে Hanoi-র মতো, তাই বিশ্বাসযোগ্য মনে হয়। n = 0-তে 2 − 1 = 1, মিলে গেল। কিন্তু n = 1-এ সূত্র দেয় 3, আর recurrence দেয় 2 · 1 + 2 = 4. একটি মাত্র পদ বসিয়েই ভুল ধরা পড়ল। সঠিক উত্তর (n + 1)2n, সংঘাতের ক্ষেত্র, যা §৪-এর stepper-এ আছে। শিক্ষা: n = 0-এ মেলা যথেষ্ট নয়, কারণ ধ্রুবক ঠিক ওই বিন্দুতেই মেলানো হয়; অন্তত আরও দুটি পদ মেলাতে হয়।

AI-এর কাছে recurrence-এর সমাধান চাইলে এমন কাঠামো দিন, যাতে প্রতিটি সিদ্ধান্ত আলাদা করে দেখা যায়:

নিচের non-homogeneous recurrence ধাপে ধাপে সমাধান করো: recurrence: [যেমন a(n) = 4a(n−1) − 4a(n−2) + 2^n, a(0) = 0, a(1) = 1] ১. Associated homogeneous recurrence আর characteristic equation-এর মূল, গুণিতাসহ, লেখো। ২. F(n)-কে (polynomial) × s^n আকারে লেখো, আর s মূল কি না, গুণিতা m কত, তা বলো। ৩. Trial form লেখো আর কেন সেটি, তা নিয়মসহ ব্যাখ্যা করো। ৪. Coefficient মেলানোর প্রতিটি সমীকরণ দেখাও। ৫. Initial condition বসাও শুধু পূর্ণ সমাধানে, অর্থাৎ homogeneous + particular-এর যোগফলে। ৬. শেষে fractions.Fraction দিয়ে প্রথম ৩০টি পদ recurrence আর সূত্রে মেলানোর Python কোড দাও।

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

আরেকটি ভালো অভ্যাস হলো AI-কে দুটি আলাদা পথে একই উত্তর বের করতে বলা: একবার undetermined coefficients দিয়ে, আরেকবার unrolling বা summation factor দিয়ে। দুই পথের উত্তর মিললে আস্থা বাড়ে; না মিললে অন্তত একটি পথে ভুল আছে, আর ছোট n-এ সংখ্যা বসিয়ে দেখলেই বোঝা যায় কোনটিতে। মনে রাখবেন, AI যদি কোনো পাঠ্যবইয়ের নাম বা পৃষ্ঠা উদ্ধৃত করে, সেটিও নিজে মিলিয়ে দেখতে হবে; বানানো উৎস এই বিষয়েও দেখা যায়।

এই পর্বের প্রতিটি সমাধান তিনটি সিদ্ধান্তে দাঁড়ায়: homogeneous মূল, trial form, আর initial condition-এর ক্রম। AI-এর উত্তর পড়ার সময় এই তিনটিই আলাদা করে প্রশ্ন করুন; বাকিটা সাধারণ বীজগণিত, যা Python এক মুহূর্তে মিলিয়ে দেয়।

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

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

প্র ০১Tower of Hanoi ধাঁধাটি কে, কবে বানালেন? মন্দিরের ৬৪ চাকতির গল্পটি কতটা সত্য, আর 264 − 1 চালে কত সময় লাগে?

ধাঁধাটি ফরাসি গণিতবিদ Édouard Lucas ১৮৮৩ সালে বাজারে আনেন বলে সাধারণত বলা হয়। তিনি এটি “N. Claus de Siam” ছদ্মনামে প্রকাশ করেন, যা “Lucas d'Amiens” নামের অক্ষর উল্টেপাল্টে বানানো; Lucas Amiens শহরে জন্মেছিলেন। Lucas নিজে সংখ্যাতত্ত্বে বিখ্যাত: Fibonacci-র মতো একটি ধারা, যাকে এখন Lucas সংখ্যা বলে, আর বড় মৌলিক সংখ্যা পরীক্ষার একটি পদ্ধতি তাঁর নামে।

ধাঁধার সঙ্গে একটি গল্প প্রচারিত হয়: একটি প্রাচীন মন্দিরে পুরোহিতরা ৬৪টি সোনার চাকতি নিয়মমতো সরাচ্ছেন, আর কাজ শেষ হলে পৃথিবী ধ্বংস হবে। ইতিহাসবিদদের মতে গল্পটি সম্ভবত ধাঁধার সঙ্গেই, বিক্রির সুবিধার জন্য, বানানো; এর পেছনে কোনো প্রাচীন উৎস পাওয়া যায় না। তবে গল্পটির গণিত সত্য। H(64) = 264 − 1 = 18,446,744,073,709,551,615টি চাল। প্রতি সেকেন্ডে একটি চাল হলে সময় প্রায় 5.8 × 1011 বছর, অর্থাৎ প্রায় ৫৮,০০০ কোটি বছর, মহাবিশ্বের আনুমানিক বয়সের (প্রায় ১,৪০০ কোটি বছর) চল্লিশ গুণেরও বেশি।

এই পর্বের দৃষ্টিতে Hanoi-র সবচেয়ে শিক্ষণীয় দিক হলো particular solution −1-এর মানে। H(n) + 1 প্রতি ধাপে ঠিক দ্বিগুণ হয়। অর্থাৎ “এক বাড়িয়ে নিলে” ধাঁধাটি একটি নিখাদ গুণোত্তর ধারা। এই কৌশল, বাড়তি ধ্রুবক F থাকলে ভারসাম্য বিন্দু বিয়োগ করে homogeneous বানানো, ঋণের হিসাবেও একই: সেখানে ভারসাম্য বিন্দু P/r. Algorithm-এর দিক থেকে 2n − 1 শুধু একটি উপরের সীমা নয়, নিচের সীমাও: সবচেয়ে বড় চাকতি সরানোর আগে বাকি n − 1টিকে একটি খুঁটিতে জড়ো করতেই হয়, এই যুক্তি পর্ব ৪৪-এ। তাই H(n) = 2H(n − 1) + 1 আসলে সর্বনিম্ন চালের সমীকরণ, আর এর সমাধান দেখায় সূচকীয় বৃদ্ধি কতটা নির্মম।

মূল উপলব্ধি: গল্পটি বানানো, কিন্তু সংখ্যাটি নয়; আর particular solution প্রায়ই একটি ভারসাম্য বিন্দু, যা বিয়োগ করলে সমস্যাটি সরল গুণোত্তর ধারা হয়ে যায়।

প্র ০২Recurrence বা difference equation-এর এই তত্ত্ব কোথা থেকে এল? Differential equation-এর সঙ্গে এর মিল এত বেশি কেন?

ধ্রুবক coefficient-এর linear recurrence-এর তত্ত্ব আঠারো শতকে গড়ে ওঠে। Abraham de Moivre ১৭২০-১৭৩০-এর দশকে “recurring series” নিয়ে কাজ করেন, যেখানে একটি ধারার প্রতিটি পদ আগের কয়েকটি পদের নির্দিষ্ট রৈখিক যোগফল; তিনি দেখান এমন ধারার generating function একটি ভগ্নাংশ-আকারের রাশি, আর আংশিক ভগ্নাংশে ভেঙে সাধারণ পদ বের করা যায়। পরে Euler, Lagrange আর Laplace এই কাজকে সম্ভাবনা আর জ্যোতির্বিদ্যার হিসাবে বিস্তৃত করেন বলে জানা যায়। উনিশ শতকে George Boole ১৮৬০ সালে “A Treatise on the Calculus of Finite Differences” নামে একটি পূর্ণ বই লেখেন, যেখানে E আর Δ-এর মতো operator-এর বীজগণিত ব্যবহার করা হয়; এই পর্বের annihilator যুক্তি সেই ধারারই সরল রূপ। Boole-এর বইয়ে differential আর difference সমীকরণকে পাশাপাশি রেখে দেখানো হয় যে একই operator-বীজগণিত দুই জায়গায় খাটে, যদিও আজকের কঠোর প্রমাণের মান সেখানে সবসময় ছিল না।

Differential equation-এর সঙ্গে মিলটি কাকতালীয় নয়। y'' − 5y' + 6y = e7t-এর মতো সমীকরণে y = eλt বসালে λ2 − 5λ + 6 = 0 আসে, ঠিক যেমন recurrence-এ rn বসালে আসে। সেখানেও সাধারণ সমাধান = particular + homogeneous, আর ডান পাশের est যদি নিজেই homogeneous সমাধান হয়, তাহলে trial-কে t দিয়ে গুণ করতে হয়: “tm” নিয়ম। কারণটিও একই: দুটিই রৈখিক operator (একটিতে সরানো E, অন্যটিতে অন্তরকলন D), আর রৈখিক operator-এর সমীকরণের সমাধান-সেট সবসময় “একটি সমাধান + kernel”. এই গঠনটি linear algebra-র: Ax = b-এর সব সমাধান = একটি বিশেষ সমাধান + Ax = 0-এর সমাধান-স্থান, যা একটি সমান্তরালভাবে সরানো subspace.

কম্পিউটারের যুগে difference equation আরও গুরুত্বপূর্ণ হয়েছে, কারণ কম্পিউটার সবকিছু ধাপে ধাপে, অর্থাৎ বিচ্ছিন্নভাবে, হিসাব করে। Differential equation-এর সংখ্যাগত সমাধানও শেষ পর্যন্ত একটি recurrence, আর digital filter-ও একটি linear recurrence.

মূল উপলব্ধি: “Particular + homogeneous” কোনো আলাদা কৌশল নয়; এটি রৈখিক যেকোনো সমীকরণের সাধারণ গঠন, যা ম্যাট্রিক্স, differential equation আর recurrence-এ একই চেহারায় আসে।

প্র ০৩সংঘাতের ক্ষেত্রে সমাধান হঠাৎ n গুণ বড় হয় কেন? পদার্থবিদ্যার resonance-এর সঙ্গে এর কী সম্পর্ক, আর কোন জনপ্রিয় ভুল ধারণা এড়াতে হয়?

an = 2an−1 + 2n-এ ধারাটি নিজে প্রতি ধাপে দ্বিগুণ হতে চায়, আর বাইরের ধাক্কা 2n-ও ঠিক একই হারে বাড়ে। প্রতি ধাপের ধাক্কা আগের সব ধাক্কার সঙ্গে “একই তালে” জমা হয়: n ধাপ পরে প্রতিটি পুরোনো ধাক্কা দ্বিগুণ হতে হতে ঠিক 2n হয়েছে, তাই মোট n · 2n. ধাক্কার হার আলাদা হলে, যেমন 3n, পুরোনো ধাক্কাগুলো ভিন্ন হারে বাড়ত আর যোগফল একটি গুণোত্তর ধারা হতো, যা একটি ধ্রুবক গুণকে থেমে যায়।

পদার্থবিদ্যায় একই ঘটনার নাম resonance. একটি দোলককে তার নিজস্ব কম্পাঙ্কে ধাক্কা দিলে (স্প্রিংয়ের সমীকরণ y'' + ω2y = cos ωt) ঘর্ষণ না থাকলে সমাধানে t · sin ωt আসে: বিস্তার সময়ের সঙ্গে সীমাহীনভাবে বাড়ে। গাণিতিকভাবে এটি হুবহু এই পর্বের nm নিয়ম। দোলনায় ঠিক তালে ধাক্কা দিলে দোলনা উঁচুতে ওঠে, এটি সবার চেনা অভিজ্ঞতা।

একটি জনপ্রিয় ভুল এখানে এড়াতে হয়। ১৯৪০ সালে আমেরিকার Tacoma Narrows সেতুর ভেঙে পড়াকে বহু পাঠ্যবই আর ভিডিও “বাতাসের resonance”-এর উদাহরণ বলে দেখায়। প্রকৌশলীদের বিশ্লেষণে আসল কারণটি aeroelastic flutter বলে ব্যাখ্যা করা হয়: বাতাস একটি নির্দিষ্ট তালে ধাক্কা দিচ্ছিল না; সেতুর নিজের নড়াচড়াই বাতাসের বলকে এমনভাবে বদলাচ্ছিল যে শক্তি জমতে থাকে, যা self-excited দোলন। অর্থাৎ বাইরের নির্দিষ্ট F(n) নয়, সমীকরণের নিজের গঠনই অস্থির হয়েছিল। এই পার্থক্য এই পর্বের ভাষায়ও স্পষ্ট: resonance মানে F(n)-এর সঙ্গে মূলের সংঘাত, আর অস্থিরতা মানে homogeneous অংশের মূলই 1-এর চেয়ে বড় (বা দোলনের ক্ষেত্রে ধনাত্মক বৃদ্ধির হার)।

Algorithm-এ resonance-এর সবচেয়ে বিখ্যাত চিহ্ন হলো merge sort-এর log n: প্রতিটি স্তরের কাজ (n) আর উপসমস্যার মোট বৃদ্ধি একই হারে চলে, তাই স্তরের সংখ্যা log n একটি গুণক হয়ে বসে। পর্ব ৪৭-এ master theorem-এর “সমান” case-টি ঠিক এই সংঘাত।

মূল উপলব্ধি: সংঘাত মানে বাইরের ধাক্কা ধারার নিজস্ব হারের সঙ্গে তাল মেলায়, আর প্রতিটি পুরোনো ধাক্কা সমান ওজনে জমে n গুণক তৈরি করে; তবে প্রতিটি বড় দোলন resonance নয়।

প্র ০৪Quicksort কীভাবে জন্মাল, আর তার গড় বিশ্লেষণ কেন একটি full-history recurrence? 2n ln n কি সর্বোত্তমের কাছাকাছি?

Tony Hoare (C. A. R. Hoare) ১৯৫৯-৬০ সালের দিকে quicksort-এর ধারণা পান বলে নিজে বর্ণনা করেছেন, যখন তিনি মস্কোতে যন্ত্রানুবাদের একটি প্রকল্পে শব্দের তালিকা সাজানোর উপায় খুঁজছিলেন। Algorithm-টি ১৯৬১ সালে Communications of the ACM-এ “Algorithm 64” হিসেবে আর ১৯৬২ সালে The Computer Journal-এ একটি পূর্ণ প্রবন্ধে প্রকাশিত হয়, যেখানে তিনি গড় তুলনার বিশ্লেষণও দেন বলে জানা যায়। পরে Robert Sedgewick ১৯৭৫ সালের ডক্টরাল গবেষণায় quicksort-এর নানা রূপ খুঁটিয়ে বিশ্লেষণ করেন, আর Donald Knuth-এর “The Art of Computer Programming”-এর sorting খণ্ডে এই recurrence-গুলোর বিস্তারিত সমাধান আছে।

Recurrence-টি full-history কারণ pivot যেকোনো জায়গায় পড়তে পারে: দুটি অংশের আকার 0 থেকে n − 1-এর যেকোনো কিছু, তাই C(n) আগের সব C(j)-এর ওপর নির্ভর করে। “পরপর দুটি সমীকরণ বিয়োগ” কৌশলটি যোগফলকে একটি পদে নামিয়ে আনে, তারপর summation factor কাজ শেষ করে। একই কৌশল binary search tree-তে এলোমেলো ক্রমে key ঢোকালে গড় গভীরতা, বা randomized quickselect-এর নির্ভুল প্রত্যাশা বের করতেও কাজে লাগে।

2(n + 1)Hn − 4n ≈ 2n ln n ≈ 1.39 n log2 n. যেকোনো তুলনা-ভিত্তিক sorting-এর সবচেয়ে খারাপ ক্ষেত্রে, আর গড়েও, অন্তত log2(n!) ≈ n log2 n − 1.44n তুলনা লাগে, কারণ n!টি সম্ভাব্য ক্রমের প্রতিটি আলাদা করতে হয়, আর প্রতিটি তুলনা দুই ভাগে ভাগ করে (decision tree যুক্তি)। তাই quicksort গড়ে সর্বোত্তমের মাত্র প্রায় ৩৯% বেশি তুলনা করে। Pivot হিসেবে তিনটি উপাদানের median নিলে গুণকটি আরও কমে, প্রায় 1.19 n log2 n বলে বিশ্লেষণে দেখা যায়। বাস্তবে quicksort জনপ্রিয় তার তুলনার সংখ্যার জন্য ততটা নয়, যতটা memory-তে পাশাপাশি থাকা উপাদান নিয়ে কাজ করার দক্ষতার জন্য।

মূল উপলব্ধি: Quicksort-এর গড় বিশ্লেষণ একটি full-history recurrence থেকে summation factor দিয়ে আসে, আর ফলটি তুলনা-ভিত্তিক sorting-এর তাত্ত্বিক নিচের সীমার একটি ছোট ধ্রুবক গুণের মধ্যে।

প্র ০৫চক্রবৃদ্ধি সুদ আর কিস্তির হিসাব কত পুরোনো? Closed form থাকতে ব্যাংকের খাতা কেন মাসে মাসে হিসাব করে, আর float কেন বিপজ্জনক?

সুদের হিসাব গণিতের সবচেয়ে পুরোনো প্রয়োগগুলোর একটি। প্রাচীন মেসোপটেমিয়ার মাটির ফলকে সুদ দ্বিগুণ হতে কত সময় লাগে, এমন প্রশ্নের হিসাব পাওয়া যায় বলে গবেষকেরা জানান। ১২০২ সালে Leonardo of Pisa (Fibonacci)-র Liber Abaci-তে ব্যবসায়ীদের জন্য সুদ আর অংশীদারির বহু অঙ্ক ছিল। সতেরো শতকের শুরুতে, ১৬১৩ সালে, ইংল্যান্ডে Richard Witt চক্রবৃদ্ধি সুদের ছাপা তালিকাসহ একটি বই প্রকাশ করেন বলে ইতিহাসে উল্লেখ আছে। উপপাদ্য ৬.১-এর কিস্তির সূত্রটি আজ প্রতিটি spreadsheet-এর PMT জাতীয় ফাংশনের পেছনে আছে।

তবু ব্যাংকের খাতা closed form দিয়ে চলে না, মাসে মাসে recurrence চালিয়েই চলে। কারণ প্রতিটি মাসের সুদ আর বাকি পয়সায় গোল করে লেখা হয়, আর সেই গোল করা মানগুলোই আইনগত হিসাব। গোল করার পর recurrence আর রৈখিক থাকে না (round একটি অরৈখিক ফাংশন), তাই closed form শুধু খুব কাছাকাছি একটি মান দেয়; এই পর্বের ব্লকে তা মাত্র প্রায় ৬ পয়সা পার্থক্য দেখিয়েছে। এজন্য সাধারণত শেষ কিস্তিতে সামান্য সমন্বয় করা হয়।

Float-এর বিপদ আলাদা। কম্পিউটারের binary float-এ 0.1 বা 0.01 হুবহু রাখা যায় না, যেমন দশমিকে 1/3 হুবহু লেখা যায় না। হাজার হাজার লেনদেনে এই ক্ষুদ্র ভুল জমে, আর দুটি হিসাব একই হওয়ার কথা হলেও == পরীক্ষায় অমিল দেখায়। তাই আর্থিক সফটওয়্যারে টাকা সাধারণত পূর্ণসংখ্যায় (পয়সায়) রাখা হয়, অথবা Python-এর decimal-এর মতো দশমিক-ভিত্তিক সংখ্যা ব্যবহার করা হয়। গণিত যাচাইয়ে এই পর্ব Fraction ব্যবহার করেছে, যা কোনো গোল করা ছাড়াই নির্ভুল। একটি গুরুত্বপূর্ণ সতর্কতা: এই উদাহরণগুলো শুধু recurrence শেখার জন্য; কোনো ঋণ নেওয়ার সিদ্ধান্তে বাস্তব শর্ত, ফি আর হিসাবের নিয়ম প্রতিষ্ঠান থেকে লিখিতভাবে জেনে নিতে হয়।

মূল উপলব্ধি: Closed form বোঝায় আর পরিকল্পনা করায়, কিন্তু আসল খাতা গোল করা recurrence; দুটিকে নির্ভুল সংখ্যায় মিলিয়ে দেখাই ভুল ধরার সবচেয়ে নিরাপদ পথ।

অনুশীলন

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

  1. প্রমাণ: c ≠ 1 আর d ধ্রুবক হলে an = c · an−1 + d (n ≥ 1)-এর সমাধান an = cn(a0 − e) + e, যেখানে e = d/(1 − c). Mathematical induction দিয়ে প্রমাণ করুন, আর c = 1 হলে কী হয় বলুন।
    1. লক্ষ্য করুন: e = ce + d, কারণ e − ce = e(1 − c) = d. অর্থাৎ e একটি ধ্রুবক particular solution. — বীজগণিত
    2. ভিত্তি n = 0: c0(a0 − e) + e = a0 ✓. — সরাসরি
    3. অনুমান: কোনো n − 1 ≥ 0-এর জন্য an−1 = cn−1(a0 − e) + e. — inductive hypothesis
    4. ধাপ: an = c · an−1 + d = cn(a0 − e) + ce + d = cn(a0 − e) + e, ধাপ ১ থেকে। ∎ — induction (পর্ব ১০)

    c = 1 হলে e-এর হর শূন্য: এটিই সংঘাত (s = 1 মূল)। তখন trial An, আর an = a0 + nd, একটি সমান্তর ধারা। Hanoi (c = 2, d = 1) বসালে e = −1 আর H(n) = 2n(0 + 1) − 1 = 2n − 1.

  2. হিসাব: an = an−1 + 2an−2 + 2n, a0 = 0, a1 = 1 সমাধান করুন, আর a6 বের করে recurrence দিয়ে মেলান।
    1. r2 − r − 2 = 0, মূল 2 আর −1. s = 2 একগুণ মূল, তাই trial A · n · 2n.
    2. বসিয়ে 2n−2 দিয়ে ভাগ: 4An = 2A(n − 1) + 2A(n − 2) + 4 = 4An − 6A + 4, তাই A = 2/3.
    3. an = α2n + β(−1)n + (2/3)n2n. a0 = 0: α + β = 0. a1 = 1: 2α − β + 4/3 = 1, তাই α = −1/9, β = 1/9.
    4. উত্তর: an = (6n · 2n − 2n + (−1)n)/9. ধারা: 0, 1, 5, 15, 41, 103, 249. a6 = (2304 − 64 + 1)/9 = 2241/9 = 249, আর recurrence-এ 103 + 2 · 41 + 64 = 249 ✓ (scratch-এ ১২টি পদ মেলানো)।
  3. আউটপুট অনুমান: কোড না চালিয়ে বলুন কী ছাপা হবে। তারপর যেকোনো Python-এ চালিয়ে মেলান।
    a = 1
    for n in range(1, 6):
        a = 2 * a + 2 ** n
    print(a, (5 + 1) * 2 ** 5, 5 * 2 ** 5)
    h = 0
    for n in range(1, 11):
        h = 2 * h + 1
    print(h, 2 ** 10 - 1)
    192 192 160
    1023 1023

    প্রথম লুপ an = 2an−1 + 2n, a0 = 1 চালায়: 4, 12, 32, 80, 192. সঠিক সূত্র (n + 1)2n = 6 · 32 = 192; তৃতীয় সংখ্যাটি শুধু particular অংশ n2n = 160, যাতে homogeneous অংশ 25 = 32 বাদ পড়েছে। দ্বিতীয় লুপ Hanoi: H(10) = 1023 = 210 − 1. আউটপুট CPython-এ চালিয়ে মেলানো।

  4. প্রমাণের ভুল ধরুন: একজন লিখলেন: “an = 4an−1 − 4an−2 + 2n. মূল 2 (দ্বিগুণ)। 2n মূলের সঙ্গে সংঘাত করে, তাই trial cn · 2n. বসালে cn = 2c(n − 1) − c(n − 2) + 1, অর্থাৎ cn = cn + 1, তাই 0 = 1. সুতরাং এই recurrence-এর কোনো particular solution নেই, আর তাই কোনো সমাধানও নেই। ∎” ভুলগুলো কোথায়?
    • ভুল ১, গুণিতা: 2 এখানে দ্বিগুণ মূল (r2 − 4r + 4 = (r − 2)2), তাই m = 2, আর trial হওয়া উচিত cn2 · 2n. cn · 2n নিজেই homogeneous সমাধান (পুনরাবৃত্ত মূলের n · rn পদ), তাই বসালে সব কাটা যায়।
    • সঠিক হিসাব: cn2 = 2c(n − 1)2 − c(n − 2)2 + 1 = cn2 − 2c + 1, তাই c = 1/2, আর pn = n22n−1 (scratch-এ n ≤ 20-এ মেলানো)।
    • ভুল ২, সিদ্ধান্ত: “trial কাজ করেনি, তাই সমাধান নেই” যুক্তিটিই ভুল। পর্ব ৪৪-এর উপপাদ্য অনুযায়ী দুটি initial condition দিলে সমাধান সবসময় আছে আর একটিই; একটি ভুল আকারের অনুমান ব্যর্থ হলে প্রমাণ হয় শুধু সেই আকারটি ভুল।

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

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

ক্রমএকটি non-homogeneous linear recurrence সমাধানের ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. Associated homogeneous recurrence-এর characteristic equation-এর মূল আর গুণিতা বের করা
  2. F(n)-এর s মূলের সঙ্গে সংঘাত করে কি না দেখে trial form বাছা
  3. Trial বসিয়ে coefficient মিলিয়ে particular solution পাওয়া
  4. General solution = particular + homogeneous লেখা
  5. Initial condition বসিয়ে ধ্রুবক বের করা আর ছোট n-এ মেলানো

an = 3an−1 + 4n-এর particular solution-এর জন্য সঠিক trial form কোনটি?

  • A · 4n
  • An · 4n
  • A · 3n
  • An + B

an = 6an−1 − 9an−2 + 3n-এ characteristic equation (r − 3)2 = 0. Particular solution-এর trial কোনটি?

  • A · 3n
  • An · 3n
  • An2 · 3n
  • (An + B) · 3n

an = 2an−1 + 1, a0 = 0 হলে a5 কত?

  • 32
  • 31
  • 63
  • 11

(an) আর (bn) দুটিই an = 5an−1 − 6an−2 + n2-এর সমাধান, কিন্তু initial condition আলাদা। dn = an − bn কোন recurrence মানে?

  • dn = 5dn−1 − 6dn−2 + n2
  • dn = 5dn−1 − 6dn−2 + 2n2
  • dn = dn−1 − dn−2
  • dn = 5dn−1 − 6dn−2

an = an−1 + 2n, a0 = 0-এর closed form কোনটি?

  • n(n + 1)
  • n2
  • 2n − 1
  • n(n − 1)

nC(n) = (n + 1)C(n − 1) + 2(n − 1)-কে telescoping যোগফলে রূপ দিতে পুরো সমীকরণ কী দিয়ে ভাগ করতে হয়?

  • n
  • n + 1
  • n(n + 1)
  • n!

শব্দকোষ

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

মনে রাখুন

  1. গঠন: non-homogeneous recurrence-এর প্রতিটি সমাধান = একটি particular solution + associated homogeneous recurrence-এর একটি সমাধান; প্রমাণ এক লাইনের বিয়োগ।
  2. Trial: F(n) = (degree t polynomial) · sn হলে trial একই আকারের, সব নিচের ঘাতসহ; s যদি m-গুণ মূল হয়, nm দিয়ে গুণ।
  3. ক্রম: initial condition বসান সবশেষে, homogeneous + particular-এর পুরো যোগফলে; তারপর n = 0, 1, 2-এ মেলান।
  4. প্রয়োগ: H(n) = 2n − 1, ∑k² = n(n + 1)(2n + 1)/6, bn = (L − P/r)(1 + r)n + P/r আর P = Lr(1 + r)N/((1 + r)N − 1).
  5. Summation factor: an = gnan−1 + hn-কে g1⋯gn দিয়ে ভাগ করলে telescoping; quicksort-এ C(n) = 2(n + 1)Hn − 4n.

পরের পর্বে: পর্ব ৪৭ “Divide-and-conquer recurrence আর master theorem-এর গণিত”: T(n) = aT(n/b) + f(n) ধরনের recurrence, recursion tree আর master theorem-এর তিনটি case-এর পূর্ণ প্রমাণ, যেখানে এই পর্বের সংঘাতই log n গুণক হয়ে ফিরে আসে।

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

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