এই পর্বে যা শিখবেন
- Matrix-এর গুণ, identity, ঘাত, transpose আর symmetric matrix-এর নিয়ম, প্রমাণসহ
- 0-1 matrix-এর join, meet আর Boolean product হাতে কষা, আর সাধারণ গুণের সঙ্গে তার সম্পর্ক
- Adjacency matrix-এর Boolean power দিয়ে “k ধাপে কোথায় পৌঁছানো যায়” প্রশ্নের উত্তর, induction দিয়ে প্রমাণ
- Matrix chain-এ বন্ধনীর জায়গা অনুযায়ী সংখ্যা-গুণের হিসাব, আর Strassen-এর ধারণা
- পরীক্ষার ধাঁচের অঙ্ক, আর matrix-এর একটি পরিচিত ভুল প্রমাণ ধরা
১ · Matrix — দ্রুত পুনরালোচনা, discrete চোখে
বাজারঘরের তিনটি গুদাম (G1, G2, G3) আর চারটি জেলা (ঢাকা, চট্টগ্রাম, খুলনা, রাজশাহী)। কোন গুদাম কোন জেলায় সরাসরি পার্সেল পাঠায়, তা একটি ছকে লিখলে সারি হয় গুদাম, কলাম হয় জেলা, আর প্রতিটি ঘরে “হ্যাঁ” হলে 1, “না” হলে 0. এই ছকটিই একটি matrix. Discrete math-এ matrix সাধারণত এভাবেই আসে: দুটি সসীম সেটের মধ্যে কোন জোড়া সম্পর্কিত, তার হিসাব। পর্ব ১৪ “সেট — সংজ্ঞা, subset, power set আর Cartesian product”-এ দেখেছেন, A × B-এর যেকোনো subset একটি relation; সসীম সেটে সেই relation-কে লেখার সবচেয়ে সরাসরি উপায় এই 0-1 ছক।
বাস্তব সংখ্যার matrix, তার জ্যামিতি আর linear algebra এই কোর্সে আবার শেখানো হবে না: তার জন্য Machine Learning কোর্সের পর্ব ০৬ আর পর্ব ০৭, আর NumPy-তে হাতে-কলমে AI Foundations কোর্সের পর্ব ১৭ দেখুন। এখানে আমরা শুধু সংজ্ঞাগুলো এক জায়গায় রাখব, তারপর এমন জিনিসে যাব যা ওই কোর্সগুলোতে নেই: 0-1 matrix, Boolean product আর গুণের খরচ গোনা।
m-টি সারি আর n-টি কলামে সাজানো সংখ্যার আয়তাকার ছক একটি m × n matrix. A = [aij] লিখলে aij হলো i-তম সারি আর j-তম কলামের ঘর। m = n হলে A একটি বর্গ (square) matrix. দুটি matrix সমান ঠিক তখন, যখন আকার এক আর প্রতিটি ঘর সমান।
একই আকারের A, B-এর যোগফল A + B = [aij + bij]. A যদি m × k আর B যদি k × n হয়, তবে গুণফল AB একটি m × n matrix, যার ঘর
(AB)ij = ai1b1j + ai2b2j + ⋯ + aikbkj = ∑t=1k aitbtj
অর্থাৎ A-এর i-তম সারি আর B-এর j-তম কলামের ঘরগুলো জোড়ায় জোড়ায় গুণ করে যোগ। A-এর কলাম-সংখ্যা আর B-এর সারি-সংখ্যা (ভেতরের মাপ k) না মিললে AB সংজ্ঞায়িত নয়।
এখানে ∑ হলো summation চিহ্ন: t = 1 থেকে k পর্যন্ত প্রতিটি পদের যোগফল। পর্ব ১৭ “Sequence আর summation — closed form আর বিখ্যাত যোগফল”-এ এর নিয়মগুলো (index বদল, double sum) আসছে; এখানে আমাদের শুধু এই একটি সংজ্ঞা লাগবে।
সারি-কলামের গুণ মনে রাখার ঘরোয়া উপায়: চায়ের দোকানের হিসাব। একজন ক্রেতা কোন জিনিস কয়টি নিলেন (একটি সারি), আর প্রতিটি জিনিসের দাম (একটি কলাম)। মোট বিল = প্রতিটি জিনিসের পরিমাণ × দাম, সব যোগ। কয়েকজন ক্রেতা (সারিগুলো) আর কয়েকটি দামের তালিকা (কলামগুলো) হলে প্রতিটি জোড়ার বিল মিলে একটি গুণফল matrix.
একটি ছোট উদাহরণ হাতে কষে দেখা যাক। M = [[1, 2, 0], [0, 1, 3]] (2 × 3) আর N = [[1, 0], [2, 1], [0, 4]] (3 × 2). MN-এর (1, 1) ঘর = 1·1 + 2·2 + 0·0 = 5; (1, 2) = 1·0 + 2·1 + 0·4 = 2; (2, 1) = 0·1 + 1·2 + 3·0 = 2; (2, 2) = 0·0 + 1·1 + 3·4 = 13. তাই MN = [[5, 2], [2, 13]], একটি 2 × 2 matrix. অথচ NM একটি 3 × 3 matrix: একই দুটি matrix, উল্টো ক্রমে গুণ করলে আকারই আলাদা। (এখানে [[…], […]] মানে সারিগুলোর তালিকা, Python-এর মতো করে লেখা।)
২ · গুণের নিয়ম — non-commutativity, identity, ঘাত আর transpose
সংখ্যার গুণে ab = ba. Matrix-এর গুণে এই নিয়ম ভাঙে, আর এটিই সবচেয়ে বেশি ভুলের উৎস। আকার না মিললে তো BA সংজ্ঞায়িতই না-ও হতে পারে; কিন্তু বর্গ matrix-এও সাধারণত AB ≠ BA. একটি counterexample-ই যথেষ্ট (পর্ব ০৯-এর counterexample দিয়ে খণ্ডন):
P = [[1, 1], [0, 1]], Q = [[1, 0], [1, 1]] ⇒ PQ = [[2, 1], [1, 1]], কিন্তু QP = [[1, 1], [1, 2]]
কারণটা পর্ব ১৬-এ দেখা composition-এর মতোই। Matrix গুণ আসলে দুটি রূপান্তর পরপর প্রয়োগ, আর composition সাধারণত বিনিময়যোগ্য নয়: আগে মোজা পরে জুতা, আর আগে জুতা পরে মোজা, এক জিনিস নয়।
n × n identity matrix In-এর কর্ণের (diagonal) ঘরগুলো 1, বাকি সব 0. যেকোনো m × n matrix A-এর জন্য AIn = ImA = A. বর্গ matrix A-এর ঘাত: A0 = In, আর Ar = Ar−1A (r ≥ 1), পর্ব ১২-এর মতো recursive সংজ্ঞা।
m × n matrix A-এর transpose AT হলো n × m matrix, যেখানে (AT)ij = aji: সারি হয়ে যায় কলাম। বর্গ matrix A symmetric, যদি AT = A, অর্থাৎ প্রতিটি i, j-তে aij = aji.
(ক) A m × k, B k × n, C n × p হলে (AB)C = A(BC). (খ) A m × k, B k × n হলে (AB)T = BTAT. (গ) যেকোনো A-এর জন্য AAT symmetric.
প্রমাণ:
- (ক) দুই পাশই m × p. সংজ্ঞা দুবার লাগিয়ে ((AB)C)ij = ∑s (AB)iscsj = ∑s ∑t aitbtscsj. — গুণের সংজ্ঞা, বণ্টন নিয়ম
- একইভাবে (A(BC))ij = ∑t ait(BC)tj = ∑t ∑s aitbtscsj. সসীম double sum-এ যোগের ক্রম বদলালে ফল বদলায় না, তাই দুটি সমান। — যোগের বিনিময় আর সংযোগ নিয়ম
- (খ) (AB)T আর BTAT দুটিই n × m. ((AB)T)ij = (AB)ji = ∑t ajtbti. — transpose আর গুণের সংজ্ঞা
- (BTAT)ij = ∑t (BT)it(AT)tj = ∑t btiajt. সংখ্যার গুণ বিনিময়যোগ্য, তাই প্রতিটি পদ ধাপ ৩-এর পদের সমান। — সংখ্যার commutativity
- (গ) (খ) থেকে (AAT)T = (AT)TAT = AAT, কারণ দুবার transpose নিলে আগের matrix ফেরে। ∎
লক্ষ করুন, (খ)-এর প্রমাণে সংখ্যার গুণের commutativity লেগেছে, matrix-এর নয়। আর ফলে ক্রম উল্টে গেছে, ঠিক পর্ব ১৬-এর (g∘f)−1 = f−1∘g−1-এর মতো। (A + B)2 খুললে পাওয়া যায় A2 + AB + BA + B2; AB = BA না হলে একে A2 + 2AB + B2 লেখা যায় না। নিচের ব্লক এই সব দাবি ছোট উদাহরণে পরীক্ষা করে। প্রথমবার চালালে ব্রাউজারে Python (Pyodide) নামতে কয়েক সেকেন্ড লাগে।
def mul(A, B): # ordinary product: row i of A times column j of B
assert len(A[0]) == len(B), "inner sizes differ"
return [[sum(A[i][t] * B[t][j] for t in range(len(B))) for j in range(len(B[0]))]
for i in range(len(A))]
def T(A): # transpose: rows become columns
return [list(col) for col in zip(*A)]
def size(A):
return f"{len(A)}x{len(A[0])}"
I = [[1, 0], [0, 1]]
P = [[1, 1], [0, 1]]
Q = [[1, 0], [1, 1]]
print("PQ =", mul(P, Q), " QP =", mul(Q, P))
print("IP == PI == P:", mul(I, P) == mul(P, I) == P)
print("P^2 =", mul(P, P), " P^3 =", mul(mul(P, P), P))
M = [[1, 2, 0], [0, 1, 3]] # 2x3
N = [[1, 0], [2, 1], [0, 4]] # 3x2
print("MN is", size(mul(M, N)), " NM is", size(mul(N, M)))
print("(MN)^T == N^T M^T:", T(mul(M, N)) == mul(T(N), T(M)))
print("M^T N^T is", size(mul(T(M), T(N))), "so it cannot equal (MN)^T")
S = mul(M, T(M))
print("M M^T =", S, " symmetric:", S == T(S))
S2 = [[P[i][j] + Q[i][j] for j in range(2)] for i in range(2)]
lhs = mul(S2, S2)
rhs = [[mul(P, P)[i][j] + 2 * mul(P, Q)[i][j] + mul(Q, Q)[i][j] for j in range(2)]
for i in range(2)]
print("(P+Q)^2 =", lhs, " P^2+2PQ+Q^2 =", rhs)আসল আউটপুট (ব্রাউজারের Python):
PQ = [[2, 1], [1, 1]] QP = [[1, 1], [1, 2]]
IP == PI == P: True
P^2 = [[1, 2], [0, 1]] P^3 = [[1, 3], [0, 1]]
MN is 2x2 NM is 3x3
(MN)^T == N^T M^T: True
M^T N^T is 3x3 so it cannot equal (MN)^T
M M^T = [[5, 2], [2, 10]] symmetric: True
(P+Q)^2 = [[5, 4], [4, 5]] P^2+2PQ+Q^2 = [[6, 4], [4, 4]]
প্রথম লাইনে PQ ≠ QP, অর্থাৎ commutativity-র counterexample. P-এর ঘাতে একটি প্যাটার্ন দেখা যাচ্ছে: Pr = [[1, r], [0, 1]], যা mathematical induction (পর্ব ১০) দিয়ে সহজে প্রমাণ করা যায়; এখানে শুধু r = 2, 3 দেখা হয়েছে, যা প্রমাণ নয়। চতুর্থ থেকে ষষ্ঠ লাইন উপপাদ্য ২.২(খ) দেখায়: সঠিক ক্রম NTMT, আর “ক্রম না উল্টানো” MTNT-এর তো আকারই আলাদা (3 × 3 বনাম 2 × 2). MMT symmetric, উপপাদ্যের (গ)। শেষ লাইনে (P + Q)2 আর P2 + 2PQ + Q2 আলাদা: পার্থক্য ঠিক QP − PQ = [[−1, 0], [0, 1]].
৩ · 0-1 matrix — join, meet আর Boolean product
এবার এমন matrix, যার প্রতিটি ঘর 0 বা 1: “সম্পর্ক আছে” বা “নেই”। এদের সঙ্গে সবচেয়ে স্বাভাবিক অপারেশন যোগ-গুণ নয়, বরং পর্ব ০২-এর ∨ (অথবা) আর ∧ (এবং), যেখানে 1 মানে সত্য আর 0 মানে মিথ্যা। কম্পিউটার আর্কিটেকচার কোর্সের পর্ব ০৭-এ এই অপারেশনগুলো logic gate হিসেবে এসেছে; এখানে তারা matrix-এর ঘরে বসবে।
যে matrix-এর প্রতিটি ঘর 0 বা 1, তা একটি 0-1 matrix (zero-one বা Boolean matrix). একই আকারের দুটি 0-1 matrix A, B-এর
join A ∨ B: (i, j) ঘর aij ∨ bij; meet A ∧ B: (i, j) ঘর aij ∧ bij.
A যদি m × k আর B যদি k × n 0-1 matrix হয়, তবে তাদের Boolean product A ⊙ B একটি m × n 0-1 matrix, যার ঘর
(A ⊙ B)ij = (ai1 ∧ b1j) ∨ (ai2 ∧ b2j) ∨ ⋯ ∨ (aik ∧ bkj)
সংজ্ঞাটি সাধারণ গুণের হুবহু ছক, শুধু “গুণ” হয়েছে ∧ আর “যোগ” হয়েছে ∨. কথায়: (A ⊙ B)ij = 1 ঠিক তখন, যখন অন্তত একটি t আছে যাতে ait = 1 এবং btj = 1. বাজারঘরের ভাষায়: W যদি বলে কোন গুদাম কোন hub-এ মাল পাঠায়, আর H বলে কোন hub কোন জেলায় পাঠায়, তবে W ⊙ H বলে কোন গুদাম অন্তত একটি hub হয়ে কোন জেলায় পৌঁছাতে পারে। মাঝের t হলো সেই hub. Join আর meet ঘরে ঘরে কাজ করে, পর্ব ১৫ “সেটের অপারেশন — union, intersection, Venn diagram আর identity”-এর union আর intersection-এর মতো, আর আসলে ঠিক তাই: matrix দুটি দুটি relation হলে join তাদের union, meet তাদের intersection.
1W: গুদাম × hub (H1 H2 H3)2G1: 1 0 13G2: 0 1 04H: hub × জেলা (KHL SYL)5H1: 0 1 H2: 1 0 H3: 1 16কলাম KHL = 0 1 17কলাম SYL = 1 0 1
| ঘর | |
| জোড়ায় ∧ | |
| ∨ ফল (সাধারণ গুণে) |
- আকার মেলানো। W 2 × 3 (দুটি গুদাম, তিনটি hub), H 3 × 2 (তিনটি hub, দুটি জেলা: খুলনা KHL আর সিলেট SYL). ভেতরের মাপ 3 = 3, তাই W ⊙ H সংজ্ঞায়িত, আর ফল 2 × 2.
- (G1, KHL). G1-এর সারি 1 0 1, KHL-এর কলাম 0 1 1. জোড়ায় ∧: 1∧0 = 0, 0∧1 = 0, 1∧1 = 1. অন্তত একটি 1 আছে, তাই ∨ ফল 1. অর্থ: G1 থেকে H3 হয়ে খুলনা। সাধারণ গুণেও এই ঘর 1.
- (G1, SYL). সারি 1 0 1, কলাম 1 0 1: ∧ দেয় 1, 0, 1. ফল 1. কিন্তু সাধারণ গুণে এই ঘর 2, কারণ দুটি আলাদা hub (H1 আর H3) দিয়ে পথ আছে। Boolean product শুধু বলে “আছে কি না”, কয়টি তা গোনে না।
- (G2, KHL). সারি 0 1 0, কলাম 0 1 1: ∧ দেয় 0, 1, 0. ফল 1, পথটি H2 দিয়ে।
- (G2, SYL). সারি 0 1 0, কলাম 1 0 1: তিনটি ∧-ই 0, তাই ফল 0. G2-এর একমাত্র hub H2 সিলেটে পাঠায় না। পূর্ণ ফল W ⊙ H = [[1, 1], [1, 0]], আর সাধারণ গুণফল WH = [[1, 2], [1, 0]]. ∎
শেষ ধাপের তুলনাটি একটি সাধারণ সত্য: সাধারণ গুণফলের যে ঘর 0-এর বেশি, Boolean product-এ ঠিক সেই ঘর 1. এটি প্রমাণ করে নেওয়া যাক, কারণ এর ওপর ভর করেই ⊙-এর বাকি নিয়মগুলো সহজে আসে।
A m × k আর B k × n 0-1 matrix হলে প্রতিটি i, j-তে (A ⊙ B)ij = 1 ⇔ (AB)ij > 0. অর্থাৎ A ⊙ B হলো সাধারণ গুণফল AB-এর প্রতিটি ধনাত্মক ঘরকে 1 করে পাওয়া matrix.
প্রমাণ:
- (AB)ij = ∑t aitbtj. প্রতিটি পদ 0·0, 0·1, 1·0 বা 1·1, অর্থাৎ 0 বা 1; আর aitbtj = 1 ⇔ ait = 1 এবং btj = 1 ⇔ ait ∧ btj = 1. — 0-1 সংখ্যার গুণ আর ∧-এর truth table একই
- অঋণাত্মক সংখ্যার যোগফল 0-এর বেশি ⇔ অন্তত একটি পদ 0-এর বেশি। — সব পদ ≥ 0
- তাই (AB)ij > 0 ⇔ কোনো t-তে ait ∧ btj = 1 ⇔ (A ⊙ B)ij = 1. ∎ — ∨-এর সংজ্ঞা: অন্তত একটি সত্য
উপযুক্ত আকারের 0-1 matrix A, B, C-এর জন্য (A ⊙ B) ⊙ C = A ⊙ (B ⊙ C). কিন্তু সাধারণভাবে A ⊙ B ≠ B ⊙ A.
প্রমাণ: অঋণাত্মক পূর্ণসংখ্যার যেকোনো matrix X-এর জন্য ⟦X⟧ লিখি সেই 0-1 matrix, যার ঘর 1 ঠিক যেখানে X-এর ঘর ধনাত্মক। উপপাদ্য ৩.২ বলে A ⊙ B = ⟦AB⟧.
- দাবি: X, Y অঋণাত্মক হলে ⟦⟦X⟧Y⟧ = ⟦XY⟧. কারণ (XY)ij = ∑t xitytj > 0 ⇔ কোনো t-তে xit > 0 আর ytj > 0 ⇔ কোনো t-তে ⟦X⟧it = 1 আর ytj > 0 ⇔ (⟦X⟧Y)ij > 0. একইভাবে ⟦X⟦Y⟧⟧ = ⟦XY⟧. — উপপাদ্য ৩.২-এর যুক্তি
- (A ⊙ B) ⊙ C = ⟦⟦AB⟧C⟧ = ⟦(AB)C⟧, আর A ⊙ (B ⊙ C) = ⟦A⟦BC⟧⟧ = ⟦A(BC)⟧. — ধাপ ১
- উপপাদ্য ২.২(ক) অনুযায়ী (AB)C = A(BC), তাই দুই পাশ সমান। — সাধারণ গুণের associativity
- অসমতার জন্য একটি counterexample: X = [[1, 0, 1], [0, 1, 1], [1, 0, 0]], Y = [[0, 1, 0], [1, 0, 1], [0, 1, 1]] নিলে X ⊙ Y-এর (2, 2) ঘর 1, কিন্তু Y ⊙ X-এর (2, 2) ঘর 0 (নিচের ব্লকে পুরো দুটি matrix). ∎
এই উপপাদ্যগুলোর একটি সুন্দর ব্যাখ্যা relation-এর ভাষায়। গুদাম থেকে hub-এর relation R-এর matrix যদি MR হয়, আর hub থেকে জেলার relation S-এর matrix MS, তবে “গুদাম থেকে কোনো hub হয়ে জেলা” relation-টি হলো R আর S-এর composition, আর তার matrix ঠিক MR ⊙ MS. ফাংশনের composition-এর মতোই এখানে ক্রম গুরুত্বপূর্ণ, আর associativity মানে তিনটি ধাপ জুড়তে কোন দুটি আগে জুড়লেন তাতে কিছু যায় আসে না। Relation-এর এই হিসাব প্রমাণসহ আসবে পর্ব ৫২ “Relation আর তার ধর্ম — reflexive, symmetric, transitive”-এ।
নিচের ব্লক ⊙ শূন্য থেকে লেখে (শুধু any আর and দিয়ে), stepper-এর উদাহরণ আর উপপাদ্য ৩.৩-এর counterexample ছাপে, তারপর নির্দিষ্ট seed-এ ২,০০০টি এলোমেলো আকার ও মানের matrix-এ উপপাদ্য ৩.২ আর ৩.৩ পরীক্ষা করে। মনে রাখবেন, এলোমেলো পরীক্ষা আস্থা দেয়, প্রমাণ দেয় উপপাদ্য।
import random
random.seed(19)
def bool_product(A, B): # (A ⊙ B)[i][j] = OR over t of (A[i][t] AND B[t][j])
assert len(A[0]) == len(B), "inner sizes differ"
return [[int(any(A[i][t] and B[t][j] for t in range(len(B))))
for j in range(len(B[0]))] for i in range(len(A))]
def int_product(A, B):
return [[sum(A[i][t] * B[t][j] for t in range(len(B)))
for j in range(len(B[0]))] for i in range(len(A))]
def join(A, B): return [[a | b for a, b in zip(r, s)] for r, s in zip(A, B)]
def meet(A, B): return [[a & b for a, b in zip(r, s)] for r, s in zip(A, B)]
W = [[1, 0, 1], [0, 1, 0]] # warehouse x hub
H = [[0, 1], [1, 0], [1, 1]] # hub x district
print("W ⊙ H =", bool_product(W, H), " W H =", int_product(W, H))
X = [[1, 0, 1], [0, 1, 1], [1, 0, 0]]
Y = [[0, 1, 0], [1, 0, 1], [0, 1, 1]]
print("X ∨ Y =", join(X, Y), " X ∧ Y =", meet(X, Y))
print("X ⊙ Y =", bool_product(X, Y), " Y ⊙ X =", bool_product(Y, X))
def rand01(r, c):
return [[random.randint(0, 1) for _ in range(c)] for _ in range(r)]
same = assoc = 0
for _ in range(2000):
n, k, m, p = (random.randint(1, 5) for _ in range(4))
A, B, C = rand01(n, k), rand01(k, m), rand01(m, p)
same += bool_product(A, B) == [[int(v > 0) for v in r] for r in int_product(A, B)]
assoc += bool_product(bool_product(A, B), C) == bool_product(A, bool_product(B, C))
print("A⊙B == (AB > 0):", same, "of 2000; (A⊙B)⊙C == A⊙(B⊙C):", assoc, "of 2000")আসল আউটপুট (ব্রাউজারের Python):
W ⊙ H = [[1, 1], [1, 0]] W H = [[1, 2], [1, 0]]
X ∨ Y = [[1, 1, 1], [1, 1, 1], [1, 1, 1]] X ∧ Y = [[0, 0, 0], [0, 0, 1], [0, 0, 0]]
X ⊙ Y = [[0, 1, 1], [1, 1, 1], [0, 1, 0]] Y ⊙ X = [[0, 1, 1], [1, 0, 1], [1, 1, 1]]
A⊙B == (AB > 0): 2000 of 2000; (A⊙B)⊙C == A⊙(B⊙C): 2000 of 2000
প্রথম লাইন stepper-এর ফল মেলায়: W ⊙ H-এর ঘরগুলো ঠিক WH-এর ধনাত্মক ঘরের জায়গায় 1, আর 2 হয়ে গেছে 1. দ্বিতীয় লাইনে join আর meet: এখানে X ∨ Y-এর সব ঘর 1, অথচ X ∧ Y-এ মাত্র একটি 1 (সারি 2, কলাম 3), কারণ X আর Y প্রায় কোথাও একসঙ্গে 1 নয়। তৃতীয় লাইনে X ⊙ Y আর Y ⊙ X তিনটি ঘরে আলাদা ((2, 2), (3, 1) আর (3, 3)), তাই ⊙ commutative নয়। শেষ লাইনে ২,০০০টি এলোমেলো ক্ষেত্রেই দুটি উপপাদ্য টিকেছে; একটিও ব্যর্থ হলে আমাদের প্রমাণে ভুল থাকত।
৪ · Adjacency matrix আর Boolean power — k ধাপে কোথায় পৌঁছানো যায়
বাজারঘরের ভ্যান কিছু জেলার মধ্যে একমুখী রুটে চলে: ঢাকা → চট্টগ্রাম, ঢাকা → রাজশাহী, চট্টগ্রাম → খুলনা, চট্টগ্রাম → সিলেট, রাজশাহী → খুলনা, খুলনা → ঢাকা. সিলেট থেকে কোনো ভ্যান ছাড়ে না। প্রশ্ন: ঠিক দুটি রুট পেরিয়ে ঢাকা থেকে কোথায় যাওয়া যায়? রাজশাহী থেকে সিলেটে পার্সেল পাঠাতে সবচেয়ে কম কয়টি রুট লাগে? এমন জেলা-জোড়া কি আছে, যেখানে কখনোই পৌঁছানো যায় না? ছোট নেটওয়ার্কে চোখে দেখা যায়, কিন্তু ৬৪টি জেলার নেটওয়ার্কে একটি পদ্ধতি লাগে। সেই পদ্ধতি Boolean power.
বাজারঘরের একমুখী ভ্যান-রুট আর তার adjacency matrix
প্রতিটি তীর একটি রুট; সারি = যেখান থেকে, কলাম = যেখানে
| থেকে \ পর্যন্ত | DHK | CTG | KHL | RAJ | SYL |
|---|---|---|---|---|---|
| DHK | 0 | 1 | 0 | 1 | 0 |
| CTG | 0 | 0 | 1 | 0 | 1 |
| KHL | 1 | 0 | 0 | 0 | 0 |
| RAJ | 0 | 0 | 1 | 0 | 0 |
| SYL | 0 | 0 | 0 | 0 | 0 |
একটি directed graph-এর শীর্ষবিন্দু v1, …, vn হলে তার adjacency matrix A একটি n × n 0-1 matrix: aij = 1 ⇔ vi থেকে vj-তে একটি তীর (edge) আছে। vi থেকে vj-তে দৈর্ঘ্য k-এর একটি walk হলো শীর্ষবিন্দুর একটি ক্রম vi = u0, u1, …, uk = vj, যেখানে প্রতিটি us−1 → us একটি তীর; শীর্ষবিন্দু পুনরাবৃত্ত হতে পারে।
বর্গ 0-1 matrix A-এর Boolean power: A[0] = In, আর A[r] = A[r−1] ⊙ A (r ≥ 1). উপপাদ্য ৩.৩-এর associativity-র জন্য বন্ধনীর জায়গা নিয়ে ভাবতে হয় না।
গ্রাফের পূর্ণ তত্ত্ব আসবে মডিউল ১০-এ (পর্ব ৫৭ “গ্রাফ — সংজ্ঞা, degree আর handshake theorem”), আর adjacency matrix বনাম adjacency list-এর তুলনা পর্ব ৫৮ “গ্রাফের representation আর isomorphism”-এ; প্রোগ্রামে তাদের উপস্থাপন DSA কোর্সের পর্ব ৩৯-এ। এখানে আমাদের শুধু তীর আর walk লাগবে।
1কলাম: DHK CTG KHL RAJ SYL2DHK সারি: 0 1 0 1 03CTG সারি: 0 0 1 0 14RAJ সারি: 0 0 1 0 05এক ধাপ বনাম ঠিক দুই ধাপ
| এই ধাপে | |
| পাওয়া সারি | |
| walk-এর সংখ্যা |
- কোন মধ্যবিন্দু? (A ⊙ A)DHK, j = 1 হতে হলে কোনো t লাগবে যাতে DHK → t আর t → j দুটিই রুট। ঢাকার সারি 0 1 0 1 0, তাই t শুধু CTG বা RAJ. বাকি তিনটি t-এর পদ শুরুতেই 0. Boolean product-এর একটি সারি তাই A-এর কয়েকটি সারির join.
- CTG হয়ে। চট্টগ্রামের সারি 0 0 1 0 1: চট্টগ্রাম থেকে খুলনা আর সিলেট। তাই ঢাকা → চট্টগ্রাম → খুলনা আর ঢাকা → চট্টগ্রাম → সিলেট, দুটি দুই-ধাপের walk.
- RAJ হয়ে। রাজশাহীর সারি 0 0 1 0 0: শুধু খুলনা। তাই ঢাকা → রাজশাহী → খুলনা, খুলনায় পৌঁছানোর দ্বিতীয় একটি walk.
- Join. দুই সারির ∨: 0 0 1 0 1. ঠিক দুই ধাপে ঢাকা থেকে শুধু খুলনা আর সিলেট। সাধারণ ঘাত A2-এ একই সারি 0 0 2 0 1: খুলনায় দুটি walk, সিলেটে একটি।
- “ঠিক k” বনাম “বড়জোর k”. ঢাকা → চট্টগ্রাম এক ধাপে যায়, তবু A[2]-এর (DHK, CTG) ঘর 0, কারণ ঠিক দুই ধাপের কোনো walk নেই। “দুই ধাপের মধ্যে কোথায়” জানতে A ∨ A[2] লাগবে: 0 1 1 1 1.
n শীর্ষবিন্দুর directed graph-এর adjacency matrix A হলে প্রতিটি k ≥ 1 আর প্রতিটি i, j-এর জন্য (ক) (A[k])ij = 1 ⇔ vi থেকে vj-তে দৈর্ঘ্য k-এর একটি walk আছে; (খ) সাধারণ ঘাতের ঘর (Ak)ij হলো সেই walk-গুলোর সংখ্যা।
প্রমাণ (k-এর ওপর mathematical induction, পর্ব ১০):
- ভিত্তি k = 1: A[1] = I ⊙ A = A, আর দৈর্ঘ্য 1-এর walk মানে একটি তীর; aij = 1 ঠিক তখন। (খ)-তেও aij হলো দৈর্ঘ্য 1-এর walk-এর সংখ্যা (0 বা 1). — adjacency matrix-এর সংজ্ঞা
- Inductive hypothesis: কোনো k ≥ 1-এর জন্য দাবি দুটি সব i, j-তে সত্য ধরি। — অনুমান
- দৈর্ঘ্য k + 1-এর প্রতিটি walk vi = u0, …, uk, uk+1 = vj-কে ঠিক একভাবে ভাঙা যায়: vi থেকে uk = vt-তে দৈর্ঘ্য k-এর একটি walk, তারপর vt → vj তীর। উল্টোভাবে এমন যেকোনো জোড়া জুড়লে দৈর্ঘ্য k + 1-এর walk হয়। — শেষ ধাপ আলাদা করা
- (ক) তাই দৈর্ঘ্য k + 1-এর walk আছে ⇔ কোনো t-তে (A[k])it = 1 আর atj = 1 ⇔ (A[k] ⊙ A)ij = (A[k+1])ij = 1. — hypothesis আর ⊙-এর সংজ্ঞা
- (খ) ধাপ ৩-এর ভাঙন এক-এক মিল, তাই walk-এর সংখ্যা = ∑t (vi থেকে vt-তে দৈর্ঘ্য k-এর walk-এর সংখ্যা) × atj = ∑t (Ak)itatj = (Ak+1)ij. ∎ — যোগ আর গুণের নিয়ম, hypothesis
এবার শেষ প্রশ্ন: কোন জোড়ায় কোনো দৈর্ঘ্যের walk আছে? অসীম সংখ্যক k দেখা সম্ভব নয়, কিন্তু দরকারও নেই।
n শীর্ষবিন্দুর graph-এ vi থেকে vj-তে কোনো walk থাকলে দৈর্ঘ্য বড়জোর n-এর একটি walk আছে। তাই reachability-র matrix A* = A ∨ A[2] ∨ ⋯ ∨ A[n]: (A*)ij = 1 ⇔ vi থেকে vj-তে দৈর্ঘ্য ≥ 1-এর কোনো walk আছে।
প্রমাণ:
- vi থেকে vj-তে walk-গুলোর মধ্যে সবচেয়ে ছোটটি নিই, দৈর্ঘ্য m; well-ordering নীতি (পর্ব ১১) বলে এমন একটি আছে। — well-ordering
- ধরি m > n. তাহলে walk-এর m + 1টি অবস্থানের মধ্যে u1, …, um এই m > n-টিতে মাত্র n-টি শীর্ষবিন্দু, তাই pigeonhole অনুযায়ী কোনো শীর্ষবিন্দু দুবার আসে: up = uq, 1 ≤ p < q ≤ m. — pigeonhole (পর্ব ১৬)
- up+1, …, uq অংশটি কেটে দিলে vi থেকে vj-তে দৈর্ঘ্য m − (q − p) < m-এর একটি walk পাই, আর তার দৈর্ঘ্য ≥ 1, কারণ u1 থেকে গোনা হয়েছে বলে প্রথম তীরটি থাকে। এটি সবচেয়ে ছোট হওয়ার বিরোধী। — proof by contradiction
- তাই m ≤ n, আর উপপাদ্য ৪.২(ক) অনুযায়ী (A[m])ij = 1, ফলে (A*)ij = 1. উল্টো দিক সরাসরি ৪.২ থেকে। ∎
A*-কে বলে A-এর relation-এর transitive closure. এটি বের করার দ্রুততর উপায় Warshall-এর algorithm, যা আসবে পর্ব ৫৪ “Relation-এর closure আর Warshall-এর algorithm”-এ; সেখানে এই উপপাদ্যই শুরুর বিন্দু। নিচের ব্লক আমাদের নেটওয়ার্কে k = 1 থেকে 5 পর্যন্ত Boolean power, “k ধাপের মধ্যে” কতগুলো জোড়া পৌঁছানো যায়, আর ঢাকা থেকে walk-এর সংখ্যা (সাধারণ ঘাত) ছাপে।
names = ["DHK", "CTG", "KHL", "RAJ", "SYL"]
routes = [("DHK", "CTG"), ("DHK", "RAJ"), ("CTG", "KHL"),
("CTG", "SYL"), ("RAJ", "KHL"), ("KHL", "DHK")]
n = len(names)
A = [[0] * n for _ in range(n)]
for u, v in routes:
A[names.index(u)][names.index(v)] = 1
def bprod(X, Y):
return [[int(any(X[i][t] and Y[t][j] for t in range(n))) for j in range(n)]
for i in range(n)]
def iprod(X, Y):
return [[sum(X[i][t] * Y[t][j] for t in range(n)) for j in range(n)]
for i in range(n)]
def rows(M):
return " ".join("".join(map(str, r)) for r in M)
P, C, R = A, A, A # Boolean power, integer power, "within k steps"
for k in range(1, 6):
if k > 1:
P, C = bprod(P, A), iprod(C, A)
R = [[R[i][j] | P[i][j] for j in range(n)] for i in range(n)]
print(f"k={k} A^[{k}] = {rows(P)} within {k}: {sum(map(sum, R))} pairs")
if k <= 3:
print(f" walks from DHK of length {k}:", dict(zip(names, C[0])))
never = [(names[i], names[j]) for i in range(n) for j in range(n) if not R[i][j]]
print("never reachable:", never)আসল আউটপুট (ব্রাউজারের Python):
k=1 A^[1] = 01010 00101 10000 00100 00000 within 1: 6 pairs
walks from DHK of length 1: {'DHK': 0, 'CTG': 1, 'KHL': 0, 'RAJ': 1, 'SYL': 0}
k=2 A^[2] = 00101 10000 01010 10000 00000 within 2: 12 pairs
walks from DHK of length 2: {'DHK': 0, 'CTG': 0, 'KHL': 2, 'RAJ': 0, 'SYL': 1}
k=3 A^[3] = 10000 01010 00101 01010 00000 within 3: 19 pairs
walks from DHK of length 3: {'DHK': 2, 'CTG': 0, 'KHL': 0, 'RAJ': 0, 'SYL': 0}
k=4 A^[4] = 01010 00101 10000 00101 00000 within 4: 20 pairs
k=5 A^[5] = 00101 10000 01010 10000 00000 within 5: 20 pairs
never reachable: [('SYL', 'DHK'), ('SYL', 'CTG'), ('SYL', 'KHL'), ('SYL', 'RAJ'), ('SYL', 'SYL')]
প্রতিটি matrix সারি ধরে লেখা (DHK, CTG, KHL, RAJ, SYL ক্রমে)। k = 2-এ ঢাকার সারি 00101, stepper-এর ফল, আর walk-এর সংখ্যা খুলনায় 2. k = 3-এ ঢাকা থেকে ঠিক তিন ধাপে শুধু ঢাকাতেই ফেরা যায়, দুটি চক্র দিয়ে, তাই সংখ্যা 2. “k ধাপের মধ্যে” জোড়ার সংখ্যা 6, 12, 19, 20, তারপর থেমে যায়: k = 3-এ একমাত্র বাকি ছিল রাজশাহী → সিলেট, যার সবচেয়ে ছোট walk রাজশাহী → খুলনা → ঢাকা → চট্টগ্রাম → সিলেট, চার ধাপের। n = 5, তাই উপপাদ্য ৪.৩ অনুযায়ী k = 5-এর পর আর কিছু যোগ হতে পারে না। কখনো পৌঁছানো যায় না শুধু সিলেট থেকে, কারণ সেখান থেকে কোনো রুট নেই। আরেকটি লক্ষণীয় বিষয়: A[5] = A[2], কারণ এই নেটওয়ার্কের চক্রগুলো তিন দৈর্ঘ্যের; সসীম 0-1 matrix-এর Boolean power-এর ক্রম একসময় পুনরাবৃত্ত হতে বাধ্য, কারণ n × n 0-1 matrix মোট 2n²টি।
৫ · গুণের খরচ — বন্ধনী কোথায় বসাবেন
উপপাদ্য ২.২(ক) বলে (AB)C = A(BC): ফল একই। কিন্তু কম্পিউটারের কাছে দুটি পথের খরচ একই নয়। একটি p × q matrix-কে q × r matrix দিয়ে সংজ্ঞা অনুযায়ী গুণ করলে ফলের pr-টি ঘরের প্রতিটিতে q-টি সংখ্যা-গুণ লাগে।
(ক) সংজ্ঞা অনুযায়ী p × q আর q × r matrix গুণ করতে ঠিক pqr-টি সংখ্যা-গুণ আর pr(q − 1)টি যোগ লাগে। (খ) A1A2⋯An গুণফলে বন্ধনী বসানোর ভিন্ন উপায়ের সংখ্যা P(1) = 1, আর n ≥ 2-এ P(n) = ∑k=1n−1 P(k)P(n − k).
প্রমাণ: (ক) ফলের প্রতিটি ঘর ∑t=1q aitbtj: q-টি গুণ আর q − 1টি যোগ; ঘর pr-টি, গুণের নিয়মে মোট pqr আর pr(q − 1). (খ) যেকোনো বন্ধনীতে শেষ গুণটি দুটি অংশের মধ্যে: (A1⋯Ak)(Ak+1⋯An), কোনো 1 ≤ k ≤ n − 1-এর জন্য। বাম অংশের P(k) আর ডান অংশের P(n − k) উপায় স্বাধীনভাবে মেলে, আর ভিন্ন k ভিন্ন বন্ধনী দেয়; তাই যোগ-গুণের নিয়মে সূত্রটি। ∎
P(n)-এর মানগুলো 1, 1, 2, 5, 14, 42, …: এগুলো বিখ্যাত Catalan সংখ্যা (n − 1-তম), যার closed form আর আরও অনেক রূপ আসবে পর্ব ৫০ “বিশেষ সংখ্যা — Catalan, Stirling আর partition”-এ। এরা প্রায় 4n হারে বাড়ে, তাই সব বন্ধনী একে একে দেখা বড় n-এ অবাস্তব।
1A: 10 × 302B: 30 × 53C: 5 × 604পথ ১: (AB)C5পথ ২: A(BC)
| এই গুণ | |
| এই ধাপে | |
| মধ্যবর্তী ফল |
- আকার। A 10 × 30, B 30 × 5, C 5 × 60. ভেতরের মাপগুলো মেলে, আর যেকোনো বন্ধনীতে ফল 10 × 60. প্রশ্ন শুধু খরচের।
- পথ ১, প্রথম গুণ। AB: (10 × 30)(30 × 5), খরচ 10 · 30 · 5 = 1500. ফল ছোট, মাত্র 10 × 5 = 50টি ঘর।
- পথ ১, দ্বিতীয় গুণ। (AB)C: (10 × 5)(5 × 60), খরচ 10 · 5 · 60 = 3000. মোট 4500টি সংখ্যা-গুণ।
- পথ ২, প্রথম গুণ। BC: (30 × 5)(5 × 60), খরচ 30 · 5 · 60 = 9000. মধ্যবর্তী ফল বড়: 30 × 60 = 1800টি ঘর।
- পথ ২, দ্বিতীয় গুণ। A(BC): (10 × 30)(30 × 60), খরচ 10 · 30 · 60 = 18000. মোট 27000, পথ ১-এর ছয় গুণ। ভালো বন্ধনী মধ্যবর্তী ফল ছোট রাখে। ∎
চারটি matrix হলে বন্ধনী পাঁচভাবে বসে, আর তাদের খরচের পার্থক্য আরও বড় হতে পারে। সবচেয়ে সস্তা বন্ধনী খোঁজার সমস্যাকে বলে matrix chain multiplication. উপপাদ্য ৫.১(খ)-এর যুক্তি থেকেই সমাধান আসে: শেষ গুণ কোথায় হবে (k), প্রতিটি সম্ভাবনায় দুই অংশের সবচেয়ে কম খরচ আর শেষ গুণের খরচ যোগ করে সর্বনিম্নটি নিন। একই উপসমস্যা বারবার আসে বলে উত্তরগুলো মনে রেখে কাজ করার এই কৌশলের নাম dynamic programming; এর algorithm আর টেবিল DSA কোর্সের পর্ব ৫৪-এ। নিচের ব্লক stepper-এর হিসাব, চারটি matrix-এর পাঁচটি বন্ধনীর খরচ, DP-র উত্তর আর P(n)-এর মান ছাপে।
from functools import lru_cache
from math import comb
def cost(p, q, r): # (p x q) times (q x r) needs p*q*r scalar multiplications
return p * q * r
print("A 10x30, B 30x5, C 5x60")
print(" (AB)C:", cost(10, 30, 5) + cost(10, 5, 60),
" A(BC):", cost(30, 5, 60) + cost(10, 30, 60))
dims = [20, 2, 30, 12, 8] # M1 20x2, M2 2x30, M3 30x12, M4 12x8
def orders(i, j): # every bracketing of Mi..Mj with its cost
if i == j:
return [(f"M{i + 1}", 0)]
out = []
for k in range(i, j):
for ls, lc in orders(i, k):
for rs, rc in orders(k + 1, j):
out.append((f"({ls}{rs})", lc + rc + dims[i] * dims[k + 1] * dims[j + 1]))
return out
for s, c in sorted(orders(0, 3), key=lambda x: x[1]):
print(f" {s:16} {c:6}")
@lru_cache(maxsize=None)
def best(i, j): # dynamic programming over sub-chains Mi..Mj
if i == j:
return 0
return min(best(i, k) + best(k + 1, j) + dims[i] * dims[k + 1] * dims[j + 1]
for k in range(i, j))
print("DP minimum:", best(0, 3))
print("bracketings for n = 1..10 matrices:",
[comb(2 * (n - 1), n - 1) // n for n in range(1, 11)])আসল আউটপুট (ব্রাউজারের Python):
A 10x30, B 30x5, C 5x60
(AB)C: 4500 A(BC): 27000
(M1((M2M3)M4)) 1232
((M1(M2M3))M4) 3120
(M1(M2(M3M4))) 3680
((M1M2)(M3M4)) 8880
(((M1M2)M3)M4) 10320
DP minimum: 1232
bracketings for n = 1..10 matrices: [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862]
প্রথম দুই লাইন stepper-এর 4500 আর 27000. চারটি matrix-এ (20 × 2, 2 × 30, 30 × 12, 12 × 8) সবচেয়ে সস্তা M1((M2M3)M4), 1232টি গুণ; বাম থেকে ডানে সরল ক্রম (((M1M2)M3)M4) লাগে 10320টি, আট গুণের বেশি। কারণ M1M2 প্রথমেই একটি বড় 20 × 30 matrix বানায়, অথচ M2-এর ছোট মাপ 2-কে ধরে রাখলে সব মধ্যবর্তী ফল ছোট থাকে। DP সব বন্ধনী না দেখেই 1232 পেয়েছে। শেষ লাইনে P(n) = C(2(n − 1), n − 1)/n সূত্রে হিসাব করা মান; দশটি matrix-এ 4862টি বন্ধনী। সূত্রটি এখানে প্রমাণ ছাড়া ব্যবহার করা হলো, তবে প্রথম চারটি মান উপপাদ্য ৫.১(খ)-এর recurrence-এ হাতে মিলিয়ে দেখতে পারেন (1, 1·1 = 1, 1·1 + 1·1 = 2, 1·2 + 1·1 + 2·1 = 5).
Strassen — আটের বদলে সাত
উপপাদ্য ৫.১(ক) সংজ্ঞা অনুযায়ী গুণের খরচ; প্রশ্ন হলো সংজ্ঞাটি কি একমাত্র উপায়? দুটি n × n matrix-এ সংজ্ঞা লাগে n3টি গুণ। Volker Strassen ১৯৬৯ সালে দেখান, দুটি 2 × 2 matrix (বা block) সাতটি গুণে (আটটির বদলে, কিছু বাড়তি যোগ-বিয়োগের বিনিময়ে) গুণ করা যায়; এটি বারবার অর্ধেক আকারে প্রয়োগ করলে মোট খরচ মোটামুটি nlog2 7 ≈ n2.81. এই Strassen-এর algorithm-এর বিস্তারিত আর recurrence DSA কোর্সের পর্ব ৪৯-এ। বাস্তবে বড় matrix ছাড়া সাধারণ পদ্ধতিই প্রায়ই দ্রুত, আর দশমিক সংখ্যায় Strassen-এর গোলমাল (rounding error) একটু বেশি হতে পারে, তাই লাইব্রেরিগুলো সাধারণত সংজ্ঞার পদ্ধতিই খুব যত্নে সাজিয়ে ব্যবহার করে। উপপাদ্য ৩.২-এর জন্য 0-1 matrix-এর Boolean product-ও যেকোনো দ্রুত পূর্ণসংখ্যা-গুণ দিয়ে করা যায়: সাধারণ গুণফল বের করে ধনাত্মক ঘরকে 1 করলেই হলো।
৬ · পরীক্ষার অঙ্ক আর একটি ভুল প্রমাণ
বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর লিখিত পরীক্ষায় এই বিষয়ের যে ধাঁচের অঙ্ক আসে, তার তিনটি পূর্ণ সমাধান। প্রতিটি সংখ্যা উপরের ব্লক বা scratch-এ Python দিয়ে মেলানো।
অঙ্ক ১: X = [[1, 0, 1], [0, 1, 1], [1, 0, 0]], Y = [[0, 1, 0], [1, 0, 1], [0, 1, 1]]. X ∨ Y, X ∧ Y, X ⊙ Y আর Y ⊙ X বের করুন
- Join আর meet ঘরে ঘরে: X ∨ Y-এর প্রতিটি ঘর 1 (প্রতিটি অবস্থানে X বা Y-এর অন্তত একটি 1). X ∧ Y-এ শুধু (2, 3) ঘর 1, কারণ একমাত্র সেখানেই দুটিই 1.
- X ⊙ Y, সারি ধরে: X-এর সারি 1 = 1 0 1, তাই Y-এর সারি 1 আর 3-এর join: 010 ∨ 011 = 011. সারি 2 = 0 1 1: Y-এর সারি 2 আর 3: 101 ∨ 011 = 111. সারি 3 = 1 0 0: শুধু Y-এর সারি 1: 010. তাই X ⊙ Y = [[0, 1, 1], [1, 1, 1], [0, 1, 0]].
- Y ⊙ X: Y-এর সারি 1 = 0 1 0: X-এর সারি 2 = 011. সারি 2 = 1 0 1: X-এর সারি 1 আর 3: 101 ∨ 100 = 101. সারি 3 = 0 1 1: X-এর সারি 2 আর 3: 011 ∨ 100 = 111. তাই Y ⊙ X = [[0, 1, 1], [1, 0, 1], [1, 1, 1]] ≠ X ⊙ Y.
কৌশলটি মনে রাখুন: (A ⊙ B)-এর i-তম সারি = A-এর i-তম সারিতে যেখানে যেখানে 1, B-এর সেই সারিগুলোর join. ঘরে ঘরে হিসাবের চেয়ে দ্রুত, আর ভুল কম।
অঙ্ক ২: M1 20 × 2, M2 2 × 30, M3 30 × 12, M4 12 × 8. সবচেয়ে কম সংখ্যা-গুণের বন্ধনী কোনটি?
- বন্ধনী P(4) = 5টি। প্রতিটির খরচ: (((M1M2)M3)M4) = 1200 + 7200 + 1920 = 10320; ((M1M2)(M3M4)) = 1200 + 2880 + 4800 = 8880; ((M1(M2M3))M4) = 720 + 480 + 1920 = 3120; (M1((M2M3)M4)) = 720 + 192 + 320 = 1232; (M1(M2(M3M4))) = 2880 + 480 + 320 = 3680.
- উত্তর: M1((M2M3)M4), 1232টি গুণ। §৫-এর ব্লকের তালিকার সঙ্গে প্রতিটি সংখ্যা মেলে।
অঙ্ক ৩: §৪-এর ভ্যান-নেটওয়ার্কে রাজশাহী থেকে সিলেটে সবচেয়ে কম কয় ধাপে যাওয়া যায়?
সবচেয়ে ছোট k বের করতে হবে যাতে (A[k])RAJ, SYL = 1. রাজশাহীর সারি: A-তে 00100 (শুধু খুলনা), A[2]-এ 10000 (ঢাকা), A[3]-এ 01010 (চট্টগ্রাম, রাজশাহী), A[4]-এ 00101 (খুলনা, সিলেট)। উত্তর 4: রাজশাহী → খুলনা → ঢাকা → চট্টগ্রাম → সিলেট. প্রতিটি সারি এক ধাপ আগের সারিতে যেখানে 1, A-এর সেই সারিগুলোর join; অঙ্ক ১-এর কৌশলই।
প্রমাণের ভুল ধরুন: “A[2] হলো দুই ধাপের মধ্যে reachability”
একজন লিখলেন: “দাবি: যেকোনো directed graph-এ (A[2])ij = 1 ⇔ vi থেকে vj-তে বড়জোর দুই ধাপে যাওয়া যায়। প্রমাণ: উপপাদ্য ৪.২ বলে A[2] দুই ধাপের walk চিনে নেয়; আর এক ধাপের রুট থাকলে তার পরে আরেকটি রুট নিলে দুই ধাপ হয়। ∎” পড়ে ভুলটি নিজে খুঁজুন।
ভুল কোথায়: “তার পরে আরেকটি রুট” সবসময় থাকে না। §৪-এর নেটওয়ার্কে ঢাকা → চট্টগ্রাম এক ধাপে যায়, কিন্তু (A[2])DHK, CTG = 0: ঠিক দুই ধাপে চট্টগ্রামে পৌঁছানোর কোনো walk নেই। প্রমাণটি এমন একটি ধাপ নিঃশব্দে ধরে নিয়েছে, যা প্রতিটি শীর্ষবিন্দুতে একটি loop (নিজের দিকে তীর) থাকলে তবেই সত্য। সঠিক দাবি: “বড়জোর দুই ধাপ” ⇔ (A ∨ A[2])ij = 1, বা সমতুল্যভাবে ((A ∨ I)[2])ij = 1 (i ≠ j-এর জন্য)। শিক্ষা: “ঠিক k” আর “বড়জোর k” আলাদা quantifier, আর একটি ছোট counterexample-ই এমন প্রমাণ বাতিল করে।
আরও গভীরে: সাধারণ গুণের ছকে (+, ×)-এর জায়গায় (∨, ∧) বসালে reachability আসে; (min, +) বসালে একই ছক সবচেয়ে ছোট পথের দৈর্ঘ্য দেয়, যা Floyd–Warshall algorithm-এর ভিত্তি (DSA কোর্সের পর্ব ৪৪)। যে অপারেশন-জোড়ায় এই ছক কাজ করে, গণিতে তাকে semiring বলে। আর দুটি n × n matrix গুণের সবচেয়ে কম খরচের সূচক ω-এর (matrix multiplication exponent) সঠিক মান আজও অজানা: জানা আছে 2 ≤ ω, আর গবেষণায় ওপরের সীমা ধাপে ধাপে কমে প্রায় ২.৩৭-এ নেমেছে; ω = 2 কি না, তা একটি খোলা প্রশ্ন।
পরীক্ষা ও ইন্টারভিউতে: বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় এই ধরনের প্রশ্ন প্রায়ই আসে:
- A 3 × 4, B 4 × 2 হলে AB আর BA-এর আকার? AB 3 × 2; BA সংজ্ঞায়িত নয় (2 ≠ 3).
- Matrix গুণ কি commutative? না; [[1, 1], [0, 1]] আর [[1, 0], [1, 1]]-এ PQ ≠ QP. তবে associative.
- Adjacency matrix-এর A2-এর (i, j) ঘর 3 মানে কী? i থেকে j-তে ঠিক দুই ধাপের ৩টি walk.
- (10 × 30)(30 × 5)(5 × 60)-এর সবচেয়ে সস্তা বন্ধনী? (AB)C, 4500টি গুণ; A(BC)-তে 27000.
- (AB)T = ? BTAT; Boolean product-এও (A ⊙ B)T = BT ⊙ AT.
৭ · AI-এর যুগে — matrix-এর হিসাব আর প্রমাণ যাচাই
AI সহকারীকে একটি Boolean product বা matrix chain-এর খরচ জিজ্ঞেস করলে উত্তর সাধারণত দ্রুত আর পরিপাটি আসে। কিন্তু এখানে ছোট ভুলই বড় ফল বদলায়, আর AI-এর কিছু ভুল নিয়মিত:
| AI-এর ভুল | কীভাবে ধরবেন |
|---|---|
| Boolean product-এ ∨-এর বদলে সাধারণ যোগ: ঘরে 2 লিখে ফেলা, বা ⊙ আর ঘরে ঘরে meet গুলিয়ে ফেলা | ফলের প্রতিটি ঘর 0 বা 1 কি না দেখুন; উপপাদ্য ৩.২ দিয়ে সাধারণ গুণফলের সঙ্গে মেলান |
| AB = BA ধরে নেওয়া: (A + B)2 = A2 + 2AB + B2, বা (AB)T = ATBT | প্রতিটি ধাপে কোন নিয়ম লাগল জিজ্ঞেস করুন; 2 × 2-এর একটি counterexample চালিয়ে দেখুন |
| “ঠিক k ধাপ” আর “বড়জোর k ধাপ” গুলিয়ে ফেলা; walk আর path (পুনরাবৃত্তিহীন) এক ধরে নেওয়া | একটি ছোট graph-এ A, A[2] আর A ∨ A[2] নিজে বের করে মেলান |
| সারি আর কলাম উল্টে adjacency matrix লেখা (তীরের দিক উল্টো) | একটি নির্দিষ্ট তীর ধরে তার ঘরটি খুঁজুন; directed graph-এ A সাধারণত symmetric নয় |
| গুণের খরচে off-by-one: pqr-এর বদলে pr(q + 1), বা বন্ধনীর সংখ্যা ভুল | ছোট chain-এ সব বন্ধনী brute force করে DP-র উত্তরের সঙ্গে মেলান (§৫-এর ব্লক) |
| Strassen বা ω নিয়ে বানানো সংখ্যা, সাল বা গবেষকের নাম | বিশ্বস্ত পাঠ্যবই বা মূল গবেষণাপত্রে মিলিয়ে নিন; নিশ্চিত না হলে সংখ্যাটি বাদ দিন |
AI-এর কাছে matrix-সংক্রান্ত হিসাব বা প্রমাণ চাইলে এমন কাঠামো দিন, যাতে প্রতিটি ধাপ আলাদা করে যাচাই করা যায়:
AI-এর উত্তর হাতে পেলে — যাচাইয়ের চেকলিস্ট
সবচেয়ে সস্তা প্রথম পরীক্ষা: AI যে matrix ফল দিল, সেটি §৩-এর bool_product বা §২-এর mul দিয়ে নিজে চালিয়ে মেলান। একটি ঘরের অমিলই পুরো উত্তরকে সন্দেহজনক করে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।
প্র ০১Matrix-এর গুণ এমন অদ্ভুতভাবে (সারি × কলাম) সংজ্ঞায়িত কেন, ঘরে ঘরে গুণ নয় কেন? ইতিহাসে এই সংজ্ঞা কীভাবে এল?
ঘরে ঘরে গুণও একটি বৈধ অপারেশন (একে Hadamard product বলা হয়), কিন্তু গণিতের ইতিহাসে matrix এসেছে রূপান্তর বা প্রতিস্থাপন বর্ণনা করতে, আর সারি × কলাম গুণ হলো দুটি প্রতিস্থাপন পরপর প্রয়োগের হিসাব। ধরুন x আর y থেকে নতুন চলক u = 2x + y, v = x + 3y পাওয়া গেল, তারপর u, v থেকে আবার নতুন চলক। দ্বিতীয় ধাপের সূত্রে u, v বসিয়ে সরল করলে যে সহগগুলো আসে, সেগুলো ঠিক দুটি সহগ-ছকের সারি × কলাম গুণফল। অর্থাৎ গুণের সংজ্ঞা composition থেকে জন্মেছে, পর্ব ১৬-এর g∘f-এর মতো, আর তাই composition-এর মতোই এটি associative কিন্তু commutative নয়।
রৈখিক সমীকরণের সহগ ছকে সাজিয়ে সমাধানের পদ্ধতি অনেক পুরোনো; প্রাচীন চীনা গ্রন্থ “নয় অধ্যায়ে গণিতশিল্প” (Nine Chapters on the Mathematical Art, সাধারণত খ্রিস্টপূর্ব শেষ শতাব্দীগুলো থেকে খ্রিস্টীয় প্রথম শতাব্দীর মধ্যে সংকলিত বলে ধরা হয়) এমন ছক-ভিত্তিক পদ্ধতির উদাহরণ হিসেবে প্রায়ই উল্লেখিত হয়। তবে “matrix” নামটি James Joseph Sylvester ১৮৫০ সালে ব্যবহার করেন বলে সাধারণভাবে উল্লেখ করা হয়, determinant-এর উৎস হিসেবে একটি ছককে বোঝাতে। Arthur Cayley ১৮৫৮ সালে “A Memoir on the Theory of Matrices” লেখায় matrix-কে নিজস্ব বীজগণিতের বস্তু হিসেবে দেখেন: যোগ, গুণ, identity আর inverse সংজ্ঞায়িত করেন, আর লক্ষ করেন যে গুণ সাধারণত বিনিময়যোগ্য নয়।
এই দৃষ্টিভঙ্গিই আধুনিক: matrix একটি রৈখিক রূপান্তরের নাম-ঠিকানা, আর গুণ মানে রূপান্তর জোড়া দেওয়া। Discrete math-এ একই ছবি অন্য রূপে আসে। 0-1 matrix একটি relation, আর Boolean product দুটি relation-এর composition: “গুদাম থেকে hub” আর “hub থেকে জেলা” জুড়ে “গুদাম থেকে জেলা”। এখানেও ক্রম বদলালে অর্থ বদলায়, ঠিক যেমন “বাবার ভাই” (চাচা) আর “ভাইয়ের বাবা” (নিজের বাবা) এক নয়। ঘরে ঘরে গুণের (meet) নিজস্ব অর্থ আছে, দুটি relation-এর intersection, কিন্তু সেটি জোড়া দেওয়া নয়।
মূল উপলব্ধি: সারি × কলাম গুণ হলো রূপান্তর বা relation পরপর জোড়া দেওয়ার হিসাব; তাই এটি composition-এর সব ধর্ম পায়, associativity আর non-commutativity দুটিই।
প্র ০২Boolean power দিয়ে transitive closure পেতে প্রায় n-টি Boolean product লাগে। এর চেয়ে দ্রুত উপায় কী, আর সেগুলো কবে এল?
উপপাদ্য ৪.৩-এর সরল পদ্ধতিতে A, A[2], …, A[n] বের করতে n − 1টি Boolean product লাগে, আর প্রতিটি সংজ্ঞা অনুযায়ী প্রায় n3টি ∧ নেয়। মোট খরচ তাই n4-এর মাপে: ১,০০০ শীর্ষবিন্দুর নেটওয়ার্কে প্রায় এক লক্ষ কোটি অপারেশন। প্রথম উন্নতি সহজ: বারবার বর্গ করা। B = A ∨ I নিলে B[k] মানে “বড়জোর k ধাপ”, আর B, B[2], B[4], … এভাবে log2 n বার বর্গ করলেই n ছাড়িয়ে যায়, পর্ব ১৩-এর দ্রুত ঘাতের মতো। খরচ নামে প্রায় n3 log n-এ।
দ্বিতীয় উন্নতি Warshall-এর algorithm, যা Stephen Warshall ১৯৬২ সালে প্রকাশ করেন বলে উল্লেখিত; প্রায় একই ধারণা Bernard Roy-এর ১৯৫৯ সালের কাজেও ছিল বলে অনেক বইয়ে বলা হয়। এর কৌশল ধাপ গোনা নয়, মধ্যবিন্দু গোনা: k-তম ধাপে প্রশ্ন “শুধু প্রথম k-টি শীর্ষবিন্দুকে মধ্যবিন্দু হিসেবে ব্যবহার করে i থেকে j-তে যাওয়া যায় কি?”। প্রতিটি ধাপ n2টি ঘর একবার হালনাগাদ করে, মোট n3. এটি পর্ব ৫৪-এ প্রমাণসহ আসবে।
তৃতীয় দিক হলো দ্রুত matrix গুণ ব্যবহার। উপপাদ্য ৩.২-এর কারণে Boolean product একটি সাধারণ পূর্ণসংখ্যা গুণফল থেকে পাওয়া যায়, তাই Strassen-ধাঁচের যেকোনো দ্রুত গুণ এখানে খাটে; আর জানা ফল হলো transitive closure বের করা মোটামুটি matrix গুণের মতোই কঠিন, এর বেশি নয় (সঠিক বক্তব্যের জন্য algorithm-এর পাঠ্যবই দেখুন)। Boolean matrix-এর জন্য আলাদা একটি কৌশলও আছে, যা চারজন সোভিয়েত গবেষকের (Arlazarov, Dinic, Kronrod, Faradzev) ১৯৭০ সালের দিকের কাজ থেকে “Four Russians” পদ্ধতি নামে পরিচিত: সারিগুলোকে ছোট খণ্ডে ভাগ করে সব সম্ভাব্য খণ্ডের join আগে থেকে হিসাব করে রাখা, ফলে প্রায় log n গুণ সাশ্রয়।
বাস্তবে আরেকটি সরল কৌশল খুব কার্যকর: একটি 0-1 সারিকে একটি পূর্ণসংখ্যার bit হিসেবে রাখা (পর্ব ১৫-এর bit string), যাতে দুটি সারির join একটি bitwise OR-এ হয়। 64-bit যন্ত্রে এতে একবারে 64টি ঘর হালনাগাদ হয়।
মূল উপলব্ধি: একই গাণিতিক বস্তু (A*) বের করার খরচ পদ্ধতিভেদে n4 থেকে n3-এর নিচে নামে; ধারণা আসে বীজগণিত থেকে (associativity, বারবার বর্গ), আর গতি আসে প্রতিনিধিত্ব থেকে (bit string).
প্র ০৩Matrix chain-এর DP কেন কাজ করে, আর একই ধারণা বাস্তবে কোথায় দেখা যায়?
DP কাজ করে কারণ সমস্যাটির একটি “সর্বোত্তম উপকাঠামো” আছে: যদি M1⋯M4-এর সবচেয়ে সস্তা বন্ধনীতে শেষ গুণটি (M1)(M2M3M4) হয়, তবে ডান অংশ M2M3M4-এর ভেতরের বন্ধনীও নিজে সবচেয়ে সস্তা হতে বাধ্য; নইলে সেটি বদলে মোট খরচ কমানো যেত। এটি একটি exchange বা contradiction যুক্তি, পর্ব ০৮-এর ধাঁচের। আর উপসমস্যা মাত্র n(n + 1)/2টি (প্রতিটি অবিচ্ছিন্ন অংশ Mi⋯Mj), যদিও বন্ধনীর সংখ্যা Catalan হারে বিস্ফোরিত হয়। প্রতিটি উপসমস্যায় বড়জোর n-টি বিভাজন দেখতে হয়, তাই মোট কাজ n3-এর মাপে।
Dynamic programming শব্দটি Richard Bellman ১৯৫০-এর দশকে চালু করেন বলে সাধারণভাবে উল্লেখিত। Matrix chain সমস্যার DP সমাধান প্রায়ই ১৯৭০-এর দশকের শুরুর একটি কাজের (S. Godbole, ১৯৭৩) সঙ্গে যুক্ত করা হয়, আর পরে T. C. Hu ও M. T. Shing ১৯৮০-এর দশকের শুরুতে n log n সময়ের একটি অনেক জটিল algorithm দেন বলে জানা যায়। পাঠ্যবইয়ে n3-এর সরল DP-ই শেখানো হয়, কারণ এটি DP-র ধারণা পরিষ্কার দেখায়।
একই ধারণার বাস্তব আত্মীয় হলো relational database-এ join-এর ক্রম বাছাই। কয়েকটি টেবিল join করার ফল ক্রম বদলালেও এক (join associative আর commutative), কিন্তু মধ্যবর্তী টেবিলের আকার, তাই খরচ, বিশালভাবে বদলায়। ১৯৭০-এর দশকের শেষে একটি গবেষণা-ডেটাবেস প্রকল্পে (System R) Patricia Selinger ও সহকর্মীরা ছোট উপসমস্যা থেকে DP দিয়ে join-এর ক্রম বাছাইয়ের পদ্ধতি দেন বলে উল্লেখিত, যার ধারণা আজও query optimizer-গুলোতে দেখা যায়। ডেটাবেসের দিকটি DBMS কোর্সে আর এই কোর্সের পর্ব ৫৩ “n-ary relation আর relational database-এর গণিত”-এ আসবে। Machine learning-এ automatic differentiation-এর forward আর reverse mode-এর তুলনাও আসলে একটি matrix chain (Jacobian-এর গুণফল) কোন দিক থেকে গুণ করা সস্তা, সেই প্রশ্ন।
মূল উপলব্ধি: associativity ফল এক রাখে, কিন্তু খরচ এক রাখে না; সবচেয়ে সস্তা ক্রম খুঁজতে সর্বোত্তম উপকাঠামোর প্রমাণ আর উপসমস্যার সংখ্যা ছোট হওয়া, এই দুটিই DP-কে সম্ভব করে।
প্র ০৪Strassen-এর পর matrix গুণের সূচক ω নিয়ে কী জানা গেছে? তত্ত্বের দ্রুত algorithm বাস্তবে ব্যবহার হয় না কেন?
১৯৬৯ সালের আগে অনেকে ধরে নিয়েছিলেন n3-ই matrix গুণের স্বাভাবিক সীমা। Volker Strassen-এর ফল সেই ধারণা ভাঙে: 2 × 2-এ আটের বদলে সাতটি গুণ, যা বারবার প্রয়োগে n2.81-এর কাছাকাছি খরচ দেয়। এর পর একটি দীর্ঘ গবেষণা-ধারা শুরু হয়, যার লক্ষ্য সবচেয়ে ছোট ω, যাতে দুটি n × n matrix প্রায় nω ধাপে গুণ করা যায়। ১৯৭০ আর ১৯৮০-এর দশকে কয়েকজন গবেষক সীমাটি ধাপে ধাপে নামান; Don Coppersmith আর Shmuel Winograd ১৯৯০ সালে প্রায় ২.৩৮-এ নিয়ে আসেন বলে উল্লেখিত, আর তার পর থেকে উন্নতি এসেছে খুব ছোট ছোট ধাপে, দশমিকের তৃতীয় ঘরে, ২০২০-এর দশকের সাম্প্রতিক কাজগুলোতে প্রায় ২.৩৭-এ। নিচের সীমা হিসেবে শুধু ω ≥ 2 জানা, কারণ ফলের n2টি ঘর লিখতেই অন্তত ততটা কাজ লাগে।
তবু বাস্তবের গণনা লাইব্রেরিগুলো সাধারণত এই algorithm ব্যবহার করে না, কয়েকটি কারণে। প্রথমত, সূচকের সঙ্গে একটি ধ্রুবক গুণক থাকে; Coppersmith–Winograd ধাঁচের পদ্ধতিতে এটি এত বড় যে সুবিধা পেতে অবাস্তব রকম বড় matrix লাগে, তাই এদের কখনো কখনো “galactic algorithm” বলা হয়। দ্বিতীয়ত, আধুনিক প্রসেসরে খরচ শুধু গুণ গুনে মাপা যায় না: memory থেকে ডেটা আনার খরচ, cache-এর ব্যবহার আর একসঙ্গে অনেক গুণ (vector instruction, GPU) প্রায়ই বেশি গুরুত্বপূর্ণ, আর সংজ্ঞার পদ্ধতিকে block করে সাজালে এগুলো চমৎকারভাবে কাজে লাগানো যায়। তৃতীয়ত, দশমিক সংখ্যায় Strassen-এর বাড়তি যোগ-বিয়োগ rounding error একটু বাড়াতে পারে। তবু খুব বড় matrix-এ Strassen-এর এক-দুই স্তর কিছু ক্ষেত্রে ব্যবহার হয় বলে জানা যায়।
তত্ত্বের দিকে ω-এর গুরুত্ব অনেক: transitive closure, কিছু graph সমস্যা আর linear equation সমাধানের খরচ ω-এর সঙ্গে বাঁধা, তাই ω কমলে সেগুলোর তাত্ত্বিক সীমাও কমে।
মূল উপলব্ধি: গুণ গোনার তত্ত্ব (ω) আর বাস্তবের গতি এক জিনিস নয়; তত্ত্ব বলে কী সম্ভব, আর যন্ত্রের memory ও ধ্রুবক গুণক বলে কোনটি আসলে দ্রুত।
প্র ০৫বড় নেটওয়ার্কে adjacency matrix কেন প্রায়ই ভালো পছন্দ নয়? তবু matrix-এর দৃষ্টিভঙ্গি কোথায় অপরিহার্য?
n শীর্ষবিন্দুর adjacency matrix-এ n2টি ঘর, তীর যতই কম হোক। বাংলাদেশের সব ইউনিয়নকে শীর্ষবিন্দু ধরে একটি সড়ক-নেটওয়ার্ক ভাবুন: কয়েক হাজার শীর্ষবিন্দু, কিন্তু প্রতিটি থেকে হাতে গোনা কয়েকটি রাস্তা। matrix-এর প্রায় সব ঘর 0, অথচ সবগুলোর জন্য জায়গা লাগে, আর একটি শীর্ষবিন্দুর প্রতিবেশী খুঁজতে পুরো সারি (n-টি ঘর) পড়তে হয়। এমন sparse (বিরল) graph-এ adjacency list, অর্থাৎ প্রতিটি শীর্ষবিন্দুর প্রতিবেশীর তালিকা, জায়গা আর সময় দুটিই বাঁচায়; BFS, DFS, Dijkstra-র মতো algorithm তাই সাধারণত list নিয়ে লেখা হয় (DSA কোর্সের পর্ব ৩৯)। ঘন (dense) graph-এ, বা যেখানে “i আর j কি যুক্ত?” প্রশ্নটি খুব ঘনঘন আসে, matrix ভালো।
তবু matrix-এর দৃষ্টিভঙ্গি বহু জায়গায় অপরিহার্য, কারণ এটি graph-এর প্রশ্নকে বীজগণিতে নিয়ে আসে। উপপাদ্য ৪.২ তার প্রথম উদাহরণ: walk গোনা মানে ঘাত নেওয়া। এর পরের ধাপে matrix-এর eigenvalue graph-এর গঠন সম্পর্কে তথ্য দেয় (spectral graph theory); Kirchhoff-এর matrix-tree theorem একটি determinant দিয়ে spanning tree গোনে, যা পর্ব ৬৭ “Spanning tree — DFS/BFS, minimum spanning tree আর Kirchhoff-এর গণনা”-এ আসবে। Web পাতার গুরুত্ব নির্ধারণের কিছু পুরোনো ও সুপরিচিত পদ্ধতি, আর Markov chain-এর দীর্ঘমেয়াদি আচরণ, একটি বিশেষ matrix-এর ঘাত বা eigenvector-এর ওপর দাঁড়িয়ে।
আর matrix ভাষায় লিখলে গণনাটিও প্রায়ই দ্রুত হয়: GPU আর বিশেষ লাইব্রেরি ঘন matrix গুণে অত্যন্ত দক্ষ, তাই কখনো কখনো একটি graph algorithm-কে sparse matrix-এর গুণ হিসেবে লেখা হয়, যাতে সেই যন্ত্রগুলো কাজে লাগে। সংক্ষেপে, সংরক্ষণের জন্য প্রায়ই list, চিন্তা আর প্রমাণের জন্য প্রায়ই matrix.
মূল উপলব্ধি: adjacency matrix জায়গার দিক থেকে ব্যয়বহুল হলেও graph-কে বীজগণিতের ভাষা দেয়; কখন কোন প্রতিনিধিত্ব, তা নির্ভর করে graph কতটা ঘন আর কোন প্রশ্ন করা হচ্ছে তার ওপর।
অনুশীলন
আগে খাতায় করুন, তারপর উত্তর খুলে মেলান।
-
প্রমাণ: A একটি m × k আর B একটি k × n 0-1 matrix. প্রমাণ করুন (A ⊙ B)T = BT ⊙ AT. তারপর দেখান, A একটি symmetric বর্গ 0-1 matrix হলে প্রতিটি k ≥ 1-এ A[k]-ও symmetric.
- দুই পাশই n × m. ((A ⊙ B)T)ij = (A ⊙ B)ji = ∨t (ajt ∧ bti). — transpose আর ⊙-এর সংজ্ঞা
- (BT ⊙ AT)ij = ∨t ((BT)it ∧ (AT)tj) = ∨t (bti ∧ ajt). ∧ commutative, তাই প্রতিটি পদ ধাপ ১-এর পদের সমান। ∎ — ∧-এর commutativity
- দ্বিতীয় দাবি, k-এর ওপর induction. ভিত্তি: A[1] = A, symmetric. ধাপ: A[k] symmetric ধরে (A[k+1])T = (A[k] ⊙ A)T = AT ⊙ (A[k])T = A ⊙ A[k].
- শেষ রাশিটি A[k+1], কারণ উপপাদ্য ৩.৩-এর associativity-তে A ⊙ A ⊙ ⋯ ⊙ A-তে বন্ধনী যেখানেই বসুক ফল এক। তাই A[k+1] symmetric. ∎
অর্থ: undirected graph-এ (যেখানে প্রতিটি রাস্তা দুই দিকে চলে, তাই A symmetric) i থেকে j-তে k ধাপের walk থাকলে j থেকে i-তেও থাকে, যা walk-টি উল্টো দিকে হাঁটলেই দেখা যায়।
-
হিসাব: (ক) A 5 × 10, B 10 × 3, C 3 × 12. (AB)C আর A(BC)-তে কয়টি করে সংখ্যা-গুণ? (খ) পাঁচটি আর ছয়টি matrix-এর গুণফলে বন্ধনী কতভাবে বসানো যায়? (গ) A = [[1, 1], [0, 1]] হলে A[2], A[3] আর সাধারণ A2 বের করুন।
(ক) (AB)C = 5·10·3 + 5·3·12 = 150 + 180 = 330; A(BC) = 10·3·12 + 5·10·12 = 360 + 600 = 960. (AB)C প্রায় তিন গুণ সস্তা।
(খ) উপপাদ্য ৫.১(খ)-এর recurrence: P(5) = P(1)P(4) + P(2)P(3) + P(3)P(2) + P(4)P(1) = 5 + 2 + 2 + 5 = 14; P(6) = 14 + 5 + 4 + 5 + 14 = 42. §৫-এর ব্লকের তালিকার সঙ্গে মেলে।
(গ) A[2]: সারি 1 = 1 1, তাই A-এর দুই সারির join 11 ∨ 01 = 11; সারি 2 = 0 1, তাই A-এর সারি 2 = 01. ফল [[1, 1], [0, 1]] = A, আর তাই A[3] = A[2] ⊙ A = A-ও। সাধারণ ঘাত A2 = [[1, 2], [0, 1]]: শীর্ষবিন্দু 1 থেকে 2-তে দুই ধাপের দুটি walk (1→1→2 আর 1→2→2), কারণ দুটি শীর্ষবিন্দুতেই loop আছে। সব সংখ্যা scratch-এ Python দিয়ে যাচাই করা।
-
আউটপুট অনুমান: কোড না চালিয়ে বলুন কী ছাপা হবে। তারপর যেকোনো Python-এ চালিয়ে মেলান।
A = [[1, 1], [0, 1]] B = [[0, 1], [1, 1]] def bp(X, Y): return [[int(any(X[i][t] and Y[t][j] for t in range(2))) for j in range(2)] for i in range(2)] print(bp(A, B), bp(B, A)) print([[sum(A[i][t] * B[t][j] for t in range(2)) for j in range(2)] for i in range(2)])[[1, 1], [1, 1]] [[0, 1], [1, 1]] [[1, 2], [1, 1]]A ⊙ B: A-এর সারি 1 = 1 1, তাই B-এর দুই সারির join 01 ∨ 11 = 11; সারি 2 = 0 1, তাই B-এর সারি 2 = 11. B ⊙ A: B-এর সারি 1 = 0 1, তাই A-এর সারি 2 = 01; সারি 2 = 1 1, তাই 11 ∨ 01 = 11. দুটি আলাদা, ⊙ commutative নয়। শেষ লাইন সাধারণ গুণফল AB: তার (1, 2) ঘর 2, আর A ⊙ B-তে সেই ঘর 1, উপপাদ্য ৩.২-এর মতো।
-
প্রমাণের ভুল ধরুন: একজন লিখলেন: “দাবি: যেকোনো দুটি n × n matrix A, B-এর জন্য (A + B)2 = A2 + 2AB + B2. প্রমাণ: (A + B)2 = (A + B)(A + B) = A2 + AB + BA + B2 = A2 + 2AB + B2. ∎” ভুল কোথায়, আর সঠিক দাবি কী?
- ভুল: শেষ সমতায় AB + BA-কে 2AB লেখা হয়েছে, যা AB = BA ধরে নেয়। Matrix গুণ commutative নয়। Counterexample: P = [[1, 1], [0, 1]], Q = [[1, 0], [1, 1]]; (P + Q)2 = [[5, 4], [4, 5]], কিন্তু P2 + 2PQ + Q2 = [[6, 4], [4, 4]] (§২-এর ব্লকের শেষ লাইন)।
- সঠিক দাবি: সবসময় (A + B)2 = A2 + AB + BA + B2; আর (A + B)2 = A2 + 2AB + B2 ⇔ AB = BA. প্রমাণ: দুই পাশের পার্থক্য BA − AB, যা শূন্য ঠিক তখন, যখন AB = BA. ∎
- শিক্ষা: স্কুলের বীজগণিতের প্রতিটি সূত্র কোন নিয়মের ওপর দাঁড়িয়ে, তা জিজ্ঞেস করুন; commutativity সবচেয়ে বেশি নিঃশব্দে ঢুকে পড়ে।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমদুটি 0-1 matrix-এর Boolean product A ⊙ B-এর (i, j) ঘর বের করার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- A-এর কলাম-সংখ্যা আর B-এর সারি-সংখ্যা মেলে কি না দেখা
- A-এর i-তম সারি আর B-এর j-তম কলাম আলাদা করে লেখা
- একই অবস্থানের ঘরগুলোর জোড়ায় জোড়ায় ∧ নেওয়া
- সব ∧-ফলের ∨ নেওয়া: অন্তত একটি 1 হলে ঘরটি 1
- সাধারণ গুণফলের সেই ঘর 0-এর বেশি কি না দেখে ফল মিলিয়ে নেওয়া
A একটি 3 × 4 আর B একটি 4 × 2 matrix. কোনটি সঠিক?
- AB একটি 3 × 2 matrix, আর BA সংজ্ঞায়িত নয়
- AB একটি 4 × 4 matrix
- AB আর BA দুটিই সংজ্ঞায়িত
- AB একটি 2 × 3 matrix
A = [[1, 0], [1, 1]] আর B = [[0, 1], [1, 0]] দুটি 0-1 matrix. Boolean product A ⊙ B কত?
- [[1, 1], [1, 0]]
- [[0, 1], [1, 1]]
- [[0, 0], [1, 0]]
- [[1, 0], [1, 1]]
একটি directed graph-এর adjacency matrix A. Boolean power A[3]-এর (i, j) ঘর 1 হওয়ার অর্থ কী?
- i থেকে j-তে বড়জোর তিন ধাপে যাওয়া যায়
- i থেকে j-তে ঠিক তিনটি walk আছে
- i থেকে j-তে ঠিক তিন ধাপের অন্তত একটি walk আছে
- i থেকে j-তে সবচেয়ে ছোট পথের দৈর্ঘ্য তিন
A 4 × 10, B 10 × 3, C 3 × 20. ABC গুণফলে সবচেয়ে কম কয়টি সংখ্যা-গুণ লাগে?
- 1400
- 360
- 120
- 2400
উপযুক্ত আকারের যেকোনো 0-1 matrix A আর B-এর জন্য কোনটি সবসময় সত্য?
- A ⊙ B = B ⊙ A
- A ⊙ A = A
- (A ⊙ B)T = AT ⊙ BT
- (A ⊙ B)T = BT ⊙ AT
একটি directed graph-এর adjacency matrix A-এর সাধারণ বর্গ A2-এর (i, j) ঘরে 3 আছে। এর অর্থ কী?
- i থেকে j-তে তিনটি সরাসরি তীর আছে
- i থেকে j-তে তিন ধাপের একটি walk আছে
- i থেকে j-তে ঠিক দুই ধাপের তিনটি walk আছে
- এটি অসম্ভব, কারণ A একটি 0-1 matrix
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- গুণ: (m × k)(k × n) = m × n, ঘর ∑t aitbtj. Associative, commutative নয়; AI = IA = A; (AB)T = BTAT; AAT symmetric.
- 0-1 matrix: join ∨ আর meet ∧ ঘরে ঘরে; Boolean product-এ যোগের বদলে ∨, গুণের বদলে ∧. A ⊙ B = সাধারণ গুণফলের ধনাত্মক ঘরগুলো।
- দ্রুত কৌশল: (A ⊙ B)-এর i-তম সারি = A-এর i-তম সারিতে যেখানে 1, B-এর সেই সারিগুলোর join.
- Walk: A[k]-এর ঘর 1 ⇔ ঠিক k ধাপের walk আছে; Ak সেগুলো গোনে; A ∨ A[2] ∨ ⋯ ∨ A[n] হলো reachability (transitive closure).
- খরচ: (p × q)(q × r)-তে pqr গুণ; বন্ধনী ফল বদলায় না, খরচ বদলায়; সবচেয়ে সস্তা বন্ধনী DP দিয়ে, আর Strassen 2 × 2-এ সাতটি গুণে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ২০ · বিভাজ্যতা আর মৌলিক সংখ্যা — division algorithm আর unique factorizationপরবর্তী পর্ববিভাজ্যতা, মৌলিক সংখ্যা আর উৎপাদকে ভাঙার একক পথ।
- পর্ব ১৬ · ফাংশন — one-to-one, onto, inverse আর compositionপুনরালোচনাcomposition, যার হিসাবই matrix গুণ।
- ডিসক্রিট ম্যাথমেটিক্স · কোর্স হোম৮৩টি পর্বপুরো কোর্সের মানচিত্র আর ১৪টি মডিউল।
- Machine Learning · পর্ব ০৭ · Matrix-এর জ্যামিতি — projection, rotation আর least squaresবাস্তব সংখ্যার matrixmatrix গুণের জ্যামিতিক অর্থ আর ML-এ তার ব্যবহার।
- AI Foundations · পর্ব ১৭ · NumPy-তে linear algebra — vector, matrix, dot product আর normহাতে-কলমেNumPy-তে @, shape-এর নিয়ম আর transpose.
- DSA · পর্ব ৫৪ · DP-র ক্লাসিক সমস্যা ২ — LCS, edit distance আর matrix chainmatrix chain DPসবচেয়ে সস্তা বন্ধনী খোঁজার algorithm আর কোড।