এই পর্বে যা শিখবেন
- Matching, maximal, maximum আর perfect matching-এর নির্ভুল সংজ্ঞা আর পার্থক্য
- Augmenting path দিয়ে matching বড় করা, আর Berge-এর উপপাদ্যের দুই দিকের প্রমাণ
- Hall-এর উপপাদ্য (induction-এ পূর্ণ প্রমাণ), König-এর উপপাদ্য, আর তা থেকে Dilworth-এর প্রমাণ
- Regular bipartite graph-এ perfect matching, আর Hungarian পদ্ধতির ধারণা একটি ছোট উদাহরণে
- Gale–Shapley algorithm, তার থামা, stability আর প্রস্তাবদাতার জন্য সর্বোত্তমতার প্রমাণ
১ · Matching কী — maximal, maximum আর perfect
সন্ধ্যায় বাজারঘরের চারটি অর্ডার এসেছে, আর চারজন রাইডার হাতে আছেন। প্রত্যেক রাইডার শুধু কাছের কয়েকটি অর্ডার নিতে পারেন, আর একজন রাইডার একবারে একটি অর্ডারই নেবেন। প্রশ্ন: একসঙ্গে সবচেয়ে বেশি কয়টি অর্ডার পাঠানো যায়? পরীক্ষার হলে পরীক্ষার্থী আর আসনের মিলও একই কাঠামো।
এই পর্বে graph মানে সসীম undirected simple graph G = (V, E), যদি না অন্য কিছু বলা থাকে। Vertex v-এর প্রতিবেশী-সেট N(v); একটি সেট X-এর জন্য N(X) মানে X-এর অন্তত একজনের প্রতিবেশী এমন সব vertex. সংজ্ঞাগুলোর বিস্তারিত পর্ব ৫৭ “গ্রাফ — সংজ্ঞা, degree আর handshake theorem”-এ।
G-এর matching হলো edge-এর একটি সেট M ⊆ E, যার কোনো দুটি edge-এর একটিও সাধারণ প্রান্ত নেই। M-এর কোনো edge যে vertex ছোঁয়, তা M-এ saturated (জোড়া পাওয়া); বাকিরা M-free. M maximal, যদি তাতে আর কোনো edge যোগ করলে matching থাকে না; M maximum, যদি G-এর কোনো matching-এ M-এর চেয়ে বেশি edge না থাকে। সবচেয়ে বড় matching-এর আকারকে ν(G) লেখা হয় (ν গ্রিক “নিউ”)। M perfect, যদি প্রতিটি vertex saturated, অর্থাৎ |M| = |V|/2.
নিচের ছবিটি একটি bipartite graph: vertex দুই দলে ভাগ, বাঁয়ে L (রাইডার a, b, c, d), ডানে R (অর্ডার 1, 2, 3, 4), আর প্রতিটি edge দুই দলের মধ্যে। মোটা সবুজ রেখা একটি matching M = {a–1, c–2, d–3}.
রাইডার আর অর্ডারের bipartite graph
সবুজ মোটা রেখা matching M, ধূসর রেখা বাকি edge. M maximal, কিন্তু maximum নয়: b আর 4 এখনো একা।
এই M-এ আর কোনো edge যোগ করা যায় না: b-এর একমাত্র প্রতিবেশী 1 আগেই ব্যস্ত, আর 4-এর একমাত্র প্রতিবেশী d-ও ব্যস্ত। তাই M maximal. অথচ {b–1, a–2, c–3, d–4} চারটি edge-এর একটি perfect matching, তাই M maximum নয়। “লোভী” পদ্ধতি (যেকোনো খালি edge নিয়ে যাওয়া) ঠিক এমন maximal matching-এ আটকে যায়। তবু এর একটি নিশ্চয়তা আছে।
যেকোনো graph-এ M maximal আর M* maximum হলে |M*| ≤ 2|M|.
- M*-এর প্রতিটি edge e-এর অন্তত একটি প্রান্ত M-এ saturated; নইলে e-কে M-এ যোগ করা যেত। — maximal-এর সংজ্ঞা
- প্রতিটি e ∈ M*-এর জন্য এমন একটি প্রান্ত বেছে নিন। M* matching বলে আলাদা edge-এর বাছাই করা প্রান্ত আলাদা। — matching-এ প্রান্ত ভাগ হয় না
- বাছাই করা সব প্রান্ত M-এর edge-গুলোর 2|M|টি প্রান্তের মধ্যে, তাই |M*| ≤ 2|M|. ∎ — পর্ব ৩২-এর গণনা
সীমাটি নিখুঁত: চার vertex-এর path 1–2–3–4-এ শুধু মাঝের edge {2–3} একটি maximal matching (আকার 1), অথচ {1–2, 3–4} আকার 2. দুটি সহজ গণনাও মনে রাখুন। Complete graph K2n-এ perfect matching (2n − 1)(2n − 3)⋯3·1টি: vertex 1-এর সঙ্গী বাছার 2n − 1 উপায়, তারপর বাকি সবচেয়ে ছোট vertex-এর 2n − 3 উপায়, এভাবে (পর্ব ৩১-এর গুণের নিয়ম)। আর Kn,n-এ perfect matching মানে L থেকে R-এ একটি bijection, তাই n!টি। Perfect matching থাকতে vertex-সংখ্যা জোড় হতেই হবে, তবে তা যথেষ্ট নয়।
২ · Augmenting path আর Berge-এর উপপাদ্য
ছবির M থেকে perfect matching-এ কীভাবে যাওয়া যায়? b থেকে শুরু করে পালা করে “M-এর বাইরের edge, M-এর edge” ধরে হাঁটুন: b–1 (বাইরে), 1–a (M-এ), a–2 (বাইরে), 2–c (M-এ), c–3 (বাইরে), 3–d (M-এ), d–4 (বাইরে)। দুই প্রান্ত b আর 4 দুজনেই free. এখন এই পথের প্রতিটি edge-এর অবস্থা উল্টে দিন: M-এর তিনটি edge বাদ, বাইরের চারটি ঢুকে যায়। Matching এক বড় হয়।
M-এর সাপেক্ষে একটি alternating path এমন একটি path, যার edge পালা করে M-এর বাইরে আর M-এর ভেতরে। যে alternating path-এর দুই প্রান্তই M-free, তা M-augmenting path. দুই প্রান্ত free বলে এর প্রথম আর শেষ edge দুটিই M-এর বাইরে, তাই দৈর্ঘ্য বিজোড়, আর বাইরের edge ভেতরের চেয়ে একটি বেশি।
“উল্টে দেওয়া” কাজটির গাণিতিক নাম symmetric difference: A ⊕ B = (A − B) ∪ (B − A), অর্থাৎ ঠিক একটিতে আছে এমন উপাদান (পর্ব ১৫)। P-কে তার edge-সেট ধরলে নতুন matching M ⊕ P.
1M = {a–1, c–2, d–3}2b থেকে: b–1, তারপর 1–a3a থেকে: a–2, তারপর 2–c4c থেকে: c–3, তারপর 3–d5d থেকে: d–4, 4 free!6M ← M ⊕ P
| পথ P | |
| M | |
| |M| |
- শুরু। M = {a–1, c–2, d–3}, আকার 3. M-free vertex: L-এ b, R-এ 4. খোঁজ শুরু হয় L-এর free vertex b থেকে।
- প্রথম জোড়া ধাপ। b থেকে M-এর বাইরের edge b–1. 1 free নয়, তার M-সঙ্গী a; তাই M-এর edge 1–a ধরে a-তে পৌঁছাই। পথ এখন b, 1, a.
- দ্বিতীয় জোড়া ধাপ। a থেকে বাইরের edge a–2 (a–1 আগেই পথে আছে)। 2-এর সঙ্গী c, তাই 2–c ধরে c-তে। পথ b, 1, a, 2, c.
- তৃতীয় জোড়া ধাপ। c থেকে বাইরের edge c–3; 3-এর সঙ্গী d, তাই 3–d ধরে d-তে। পথ b, 1, a, 2, c, 3, d.
- Free vertex পাওয়া গেল। d থেকে বাইরের edge d–4, আর 4 M-free. দুই প্রান্ত free, edge পালা করে বাইরে-ভেতরে: ৭টি edge-এর একটি M-augmenting path P, যার ৪টি বাইরে আর ৩টি M-এ।
- উল্টে দেওয়া। M ⊕ P = {b–1, a–2, c–3, d–4}: M-এর তিনটি edge বাদ, বাইরের চারটি যোগ। আকার 4 = |V|/2, তাই এটি perfect matching, আর Berge-এর উপপাদ্য অনুযায়ী maximum (scratch-এ সব edge-সেট পরীক্ষা করে ν = 4 মেলানো)।
যেকোনো graph G-তে (bipartite হওয়া জরুরি নয়) একটি matching M maximum যদি এবং কেবল যদি G-তে কোনো M-augmenting path নেই।
(⇒ দিক, contrapositive) ধরুন P একটি M-augmenting path, যার k + 1টি edge M-এর বাইরে আর kটি M-এ।
- M ⊕ P-তে P-এর ভেতরের প্রতিটি vertex ঠিক একটি edge পায়: আগে তার M-edge ছিল P-তে, এখন P-এর অন্য edge-টি। — পালা করে আসা edge
- P-এর দুই প্রান্ত আগে free ছিল, এখন ঠিক একটি edge পায়; P-এর বাইরের vertex-এর কিছুই বদলায় না। তাই M ⊕ P একটি matching. — প্রান্ত free
- |M ⊕ P| = |M| − k + (k + 1) = |M| + 1, তাই M maximum নয়। — গণনা
(⇐ দিক, contrapositive) ধরুন M maximum নয়: একটি matching M* আছে যার |M*| > |M|.
- H = M ⊕ M* নিন (edge-সেট, সঙ্গে সব vertex). প্রতিটি vertex M-এর বড়জোর একটি আর M*-এর বড়জোর একটি edge ছোঁয়, তাই H-এ প্রতিটি degree ≤ 2. — দুটিই matching
- যে graph-এর সব degree ≤ 2, তার প্রতিটি component একটি path বা একটি cycle (একা vertex-ও দৈর্ঘ্য ০-এর path). H-এ একই vertex-এ মেলা দুটি edge একই matching-এর হতে পারে না, তাই প্রতিটি path ও cycle-এ M আর M*-এর edge পালা করে আসে। — degree ≤ 2-এর গঠন
- পালা করে আসায় প্রতিটি cycle-এর দৈর্ঘ্য জোড়, আর তাতে M আর M*-এর edge সমান। H-এ M*-এর edge বেশি (|M* − M| > |M − M*|, কারণ সাধারণ অংশ দুই দিক থেকেই বাদ), তাই কোনো একটি path-এ M*-এর edge M-এর চেয়ে বেশি: ঠিক একটি বেশি, আর তার প্রথম ও শেষ edge M*-এর। — pigeonhole
- সেই path-এর একটি প্রান্ত u নিন। u যদি M-এ saturated হতো একটি edge f দিয়ে, তবে f ∉ M* (u-এর M*-edge তো H-এ আছে, তাই M-এ নেই), ফলে f ∈ H, আর H-এ deg(u) = 2 হতো; কিন্তু u প্রান্ত, তার degree 1. তাই u M-free, অন্য প্রান্তও তাই। — বিরোধ
- অতএব path-টি একটি M-augmenting path. ∎
উপপাদ্যটি একটি algorithm-এর নকশা দেয়: খালি matching থেকে শুরু করুন, augmenting path পেলে উল্টে দিন, আর না পাওয়া পর্যন্ত চালিয়ে যান। প্রতিবার আকার ১ বাড়ে, তাই বড়জোর |V|/2 বার। কঠিন অংশ হলো দ্রুত augmenting path খোঁজা; bipartite graph-এ তা সরল DFS (§৪-এর কোড), সাধারণ graph-এ odd cycle সমস্যা বাধায় (§৮)।
৩ · Hall-এর বিয়ের উপপাদ্য — কখন সবাই জোড়া পায়
বাজারঘরের গুদামে পাঁচজন কর্মী আর পাঁচটি শিফট। কে কোন শিফট করতে পারেন, তালিকা আছে। প্রত্যেককে আলাদা একটি শিফট দেওয়া কি সম্ভব? প্রতিটি সম্ভাব্য ভাগ (5! = 120টি) পরীক্ষা করা যায়, কিন্তু ৫০ জন হলে 50! অসম্ভব। Hall-এর উপপাদ্য বলে, উত্তর “না” হলে তার একটি ছোট, যাচাইযোগ্য কারণ সবসময় থাকে।
একটি স্পষ্ট বাধা: যদি তিনজন কর্মী মিলে মাত্র দুটি শিফট করতে পারেন, তবে তিনজনকে আলাদা শিফট দেওয়া অসম্ভব (pigeonhole). তাই প্রয়োজনীয় শর্ত: L-এর প্রতিটি উপসেট X-এর জন্য |N(X)| ≥ |X|. বিস্ময়কর কথা হলো, শর্তটি যথেষ্টও।
G একটি bipartite graph, দুই দল L আর R. G-তে L-এর সব vertex saturated করে এমন matching আছে যদি এবং কেবল যদি প্রতিটি X ⊆ L-এর জন্য |N(X)| ≥ |X| (Hall-এর শর্ত)।
(⇒) সহজ: matching X-এর প্রতিটি সদস্যকে N(X)-এর আলাদা একজন সঙ্গী দেয়, তাই |N(X)| ≥ |X|. (⇐) দিকের প্রমাণ |L|-এর ওপর strong induction দিয়ে (Halmos আর Vaughan-এর ধাঁচ বলে পরিচিত)।
- ভিত্তি |L| = 1: L = {u}, শর্ত অনুযায়ী |N(u)| ≥ 1, তাই u-এর একটি প্রতিবেশী v আছে; {u–v} কাজ করে। — base case
- ধরুন |L| ≥ 2, আর |L|-এর চেয়ে ছোট L-ওয়ালা সব bipartite graph-এ দাবি সত্য। দুটি ক্ষেত্র। — inductive hypothesis
- ক্ষেত্র ক: প্রতিটি অশূন্য X ⊊ L-এ |N(X)| ≥ |X| + 1 (শর্তে এক “বাড়তি”)। যেকোনো u ∈ L আর তার একটি প্রতিবেশী v নিন; G′ = G − u − v. G′-এ যেকোনো অশূন্য X ⊆ L − {u}-এর প্রতিবেশী বড়জোর একজন (v) কমেছে: |N′(X)| ≥ |X| + 1 − 1 = |X|. Hypothesis অনুযায়ী G′-এ L − {u} saturate করা matching আছে; তাতে u–v যোগ করুন। — বাড়তি একজন খরচ করা
- ক্ষেত্র খ: কোনো অশূন্য X0 ⊊ L-এ |N(X0)| = |X0| (শর্ত ঠিক টায়-টায়)। G1 = X0 ∪ N(X0)-এর ওপর induced subgraph. X ⊆ X0-এর প্রতিবেশী সবাই N(X0)-এ, তাই G1-এ Hall-এর শর্ত বহাল; |X0| < |L| বলে hypothesis X0 saturate করা matching M1 দেয়। — টাইট দলকে আলাদা করে মেলানো
- G2 = (L − X0) ∪ (R − N(X0))-এর ওপর induced subgraph. যেকোনো Y ⊆ L − X0-এর G2-তে প্রতিবেশী N2(Y) = N(Y) − N(X0), আর N(Y ∪ X0) হলো N2(Y) আর N(X0)-এর disjoint union. তাই |N2(Y)| = |N(Y ∪ X0)| − |X0| ≥ |Y| + |X0| − |X0| = |Y|. — G-তে Y ∪ X0-এর জন্য শর্ত
- |L − X0| < |L|, তাই hypothesis G2-তে matching M2 দেয়। M1 আর M2-এর vertex আলাদা, তাই M1 ∪ M2 একটি matching যা পুরো L saturate করে। ∎ — জোড়া লাগানো
ক্ষেত্র খ-এর কৌশলটি লক্ষ করুন: যে দলের শর্ত “টায়-টায়”, তাদের প্রতিবেশীদের তাদের জন্যই রেখে দিতে হয়, নইলে তারা জায়গা পায় না। “বিয়ের উপপাদ্য” নামটি এসেছে পাত্র-পাত্রীর পছন্দ-তালিকার পুরোনো রূপ থেকে। আরেকটি পুরোনো রূপ system of distinct representatives: সেটের একটি পরিবার A1, …, An থেকে প্রতিটি সেটের জন্য আলাদা একটি প্রতিনিধি বাছা যায় ঠিক তখন, যখন যেকোনো kটি সেটের union-এ অন্তত kটি উপাদান।
উপপাদ্যটির ব্যবহারিক মূল্য হলো certificate বা প্রমাণপত্র: matching না থাকলে একটি X দেখালেই চলে যার |N(X)| < |X|; যে কেউ তা এক নজরে যাচাই করতে পারেন। নিচের stepper কর্মী–শিফট তালিকায় সেই X খোঁজে।
1A:{1,2} B:{2} C:{1,2} D:{3,4,5} E:{4}2|X| = 1: প্রত্যেকের N3|X| = 2: ১০টি জোড়া4|X| = 3: X = {A, B, C}5ফল: ν = 4, cover, সমাধান
| X | |
| |N(X)| | |
| শর্ত |
- তালিকা। কর্মী A, B, C, D, E; শিফট 1 (ভোর), 2 (সকাল), 3 (দুপুর), 4 (বিকাল), 5 (রাত)। A পারেন 1, 2; B শুধু 2; C পারেন 1, 2; D পারেন 3, 4, 5; E শুধু 4.
- একক দল। প্রত্যেকের অন্তত একটি শিফট আছে, তাই |X| = 1-এ শর্ত মানে। শুধু এটুকু দেখে “সম্ভব” বলা একটি সাধারণ ভুল।
- জোড়া। C(5, 2) = 10টি জোড়ার প্রতিটির মিলিত তালিকায় অন্তত দুটি শিফট; সবচেয়ে ছোট, যেমন {A, B} → {1, 2} বা {B, E} → {2, 4}, ঠিক দুটি। এখানেও শর্ত মানে।
- তিনজনের দল। X = {A, B, C}: N(X) = {1, 2}, মাত্র দুটি শিফট তিনজনের জন্য। |N(X)| = 2 < 3 = |X|: Hall-এর শর্ত ভাঙল। এই একটি X-ই প্রমাণ যে সবাইকে শিফট দেওয়া অসম্ভব।
- ফল। বড়জোর চারজন কাজ পান, আর চারজনের একটি matching আছে: A–1, B–2, D–3, E–4. সবচেয়ে ছোট vertex cover {1, 2, D, 4}-এর আকারও 4 (§৪-এর König). সমাধান: C যদি দুপুরের শিফট 3-ও শেখেন, তবে A–1, B–2, C–3, D–5, E–4 একটি perfect matching (scratch-এ সব উপসেট গুনে মেলানো)।
নিচের ব্লকটি ঠিক এই কাজ করে: ছোট থেকে বড় সব X পরীক্ষা করে প্রথম ভাঙা X ফেরত দেয়। তারপর ৫০০টি এলোমেলো bipartite graph-এ মেলায় যে Hall-এর শর্ত মানা আর brute force-এর উত্তর একই। প্রথমবার চালালে ব্রাউজারে Python (Pyodide) নামতে কয়েক সেকেন্ড লাগে।
import random
from itertools import combinations, permutations
def hall_violation(adj): # smallest X with |N(X)| < |X|
L = sorted(adj)
for k in range(1, len(L) + 1):
for X in combinations(L, k):
N = set().union(*(adj[x] for x in X))
if len(N) < k:
return X, sorted(N)
return None
def saturates_L(adj, R): # brute force: try every injection
L = sorted(adj)
return any(all(r in adj[u] for u, r in zip(L, p))
for p in permutations(R, len(L)))
staff = {"A": {1, 2}, "B": {2}, "C": {1, 2}, "D": {3, 4, 5}, "E": {4}}
print("staff-shift:", hall_violation(staff))
staff["C"].add(3) # C can also take shift 3
print("after C learns shift 3:", hall_violation(staff))
random.seed(35); agree = with_pm = 0
for trial in range(500):
nL, nR = random.randint(1, 5), random.randint(1, 6)
R = list(range(nR))
adj = {u: {r for r in R if random.random() < 0.35} for u in range(nL)}
hall_ok = hall_violation(adj) is None
assert hall_ok == (nL <= nR and saturates_L(adj, R))
agree += 1; with_pm += hall_ok
print(agree, "random graphs: Hall's condition <=> L-saturating matching;",
with_pm, "had one")আসল আউটপুট (ব্রাউজারের Python):
staff-shift: (('A', 'B', 'C'), [1, 2])
after C learns shift 3: None
500 random graphs: Hall's condition <=> L-saturating matching; 204 had one
প্রথম লাইন stepper-এর X = {A, B, C} আর N(X) = {1, 2} হুবহু দেয়। C-কে শিফট 3 শেখালে কোনো ভাঙা X থাকে না (None), আর উপপাদ্য অনুযায়ী তখন perfect matching আছে। ৫০০টি এলোমেলো graph-এ দুই পদ্ধতি একমত, যার ২০৪টিতে L saturate করা matching ছিল। সতর্কতা: hall_violation সব 2|L| উপসেট দেখতে পারে, তাই এটি শুধু ছোট graph-এর যাচাই-যন্ত্র; বড় graph-এ ভাঙা X বের হয় §৪-এর König-এর নির্মাণ থেকে, polynomial সময়ে।
৪ · König-এর উপপাদ্য — matching আর vertex cover একই সংখ্যা
বাজারঘর প্রতিটি সম্ভাব্য রাইডার–অর্ডার জোড়া পর্যবেক্ষণ করতে চায়, কিন্তু খরচ বাঁচাতে যত কম সম্ভব মানুষ বা অর্ডারে নজরদার বসাবে, যাতে প্রতিটি edge-এর অন্তত এক প্রান্তে নজরদার থাকে। এই সেটের নাম vertex cover: এমন vertex-সেট C, যা প্রতিটি edge-এর অন্তত একটি প্রান্ত ধারণ করে। সবচেয়ে ছোট cover-এর আকার τ(G) (গ্রিক “টাউ”)।
সহজ দিক যেকোনো graph-এ: ν(G) ≤ τ(G). কারণ maximum matching-এর প্রতিটি edge ঢাকতে cover-এর একটি vertex লাগে, আর matching-এর edge প্রান্ত ভাগ করে না বলে একই vertex দুটি edge ঢাকে না। ত্রিভুজে ν = 1 কিন্তু τ = 2, তাই সাধারণ graph-এ সমতা নাও থাকতে পারে। Bipartite graph-এ থাকে।
Bipartite graph G-তে ν(G) = τ(G): maximum matching-এর আকার = minimum vertex cover-এর আকার।
প্রমাণ (augmenting path দিয়ে, নির্মাণসহ): M একটি maximum matching, U = L-এর M-free vertex-গুলো। Z = যেসব vertex U থেকে কোনো M-alternating path দিয়ে পৌঁছানো যায় (U নিজেও Z-এ), ZL = Z ∩ L, ZR = Z ∩ R. সংজ্ঞা দিন C = (L − ZL) ∪ ZR.
- U থেকে alternating path L থেকে R-এ যায় M-এর বাইরের edge দিয়ে, আর R থেকে L-এ ফেরে M-এর edge দিয়ে। ZR-এর প্রতিটি vertex M-এ saturated: নইলে সেই alternating path একটি augmenting path হতো, যা Berge-এর উপপাদ্য অনুযায়ী অসম্ভব। আর তার M-সঙ্গী ZL-এ। — উপপাদ্য ২.২
- C প্রতিটি edge uv (u ∈ L, v ∈ R) ঢাকে: u ∉ ZL হলে u ∈ C. u ∈ ZL আর uv ∉ M হলে u পর্যন্ত alternating path-এর শেষে uv যোগ করলে v-তে পৌঁছানো যায়, তাই v ∈ ZR ⊆ C. u ∈ ZL আর uv ∈ M হলে u free নয়, তাই u-তে পৌঁছানো হয়েছে তার সঙ্গী v থেকেই, ফলে v ∈ ZR. — cover-এর শর্ত
- C-এর প্রতিটি vertex saturated: L − ZL-এ কোনো free vertex নেই (free-রা সবাই U ⊆ ZL), আর ZR-এর জন্য ধাপ ১. — সংজ্ঞা
- M-এর কোনো edge-এর দুই প্রান্তই C-তে নেই: uv ∈ M আর v ∈ ZR হলে ধাপ ১ অনুযায়ী u ∈ ZL, তাই u ∉ C. ফলে C-এর প্রতিটি vertex-কে তার M-edge-এ পাঠানোর নিয়মটি one-to-one, আর |C| ≤ |M|. — injection
- C একটি cover, তাই |C| ≥ τ(G) ≥ ν(G) = |M|. মিলিয়ে |C| = |M|, অর্থাৎ τ(G) = ν(G). ∎
প্রমাণটি দুটি জিনিস একসঙ্গে দেয়: একটি matching আর সমান আকারের একটি cover. দুটি হাতে পেলে যে কেউ সহজে নিশ্চিত হতে পারেন যে দুটিই সর্বোত্তম, কারণ ν ≤ τ সবসময় সত্য। এটিই “duality”-র ধরন, যা পর্ব ৫৯ Connectivity-এর Menger-এর উপপাদ্যেও দেখেছেন। Hall-এর উপপাদ্যও König থেকে আসে: L saturate করা matching না থাকলে |C| = ν < |L|, আর X = L − C নিলে N(X) ⊆ C ∩ R (C cover), তাই |N(X)| ≤ |C| − |C ∩ L| < |L| − |C ∩ L| = |X|.
নিচের ব্লক augmenting-path (DFS) পদ্ধতিতে maximum matching বের করে, প্রমাণের Z থেকে cover বানায়, আর ২০০টি এলোমেলো bipartite graph-এ তিনটি সংখ্যা মেলায়: algorithm-এর matching, brute force-এর ν, আর cover-এর আকার। Cover সত্যিই প্রতিটি edge ঢাকে কি না, তাও পরীক্ষা হয়।
import random
from itertools import combinations
def max_matching(L, adj): # augmenting paths (DFS)
mate = {} # right vertex -> left vertex
def augment(u, seen):
for v in adj[u]:
if v not in seen:
seen.add(v)
if v not in mate or augment(mate[v], seen):
mate[v] = u; return True
return False
for u in L: augment(u, set())
return mate
def konig_cover(L, adj, mate): # alternating reach from free left
zL = {u for u in L if u not in mate.values()}; zR = set(); todo = list(zL)
while todo:
for v in adj[todo.pop()]:
if v not in zR:
zR.add(v)
if mate[v] not in zL: zL.add(mate[v]); todo.append(mate[v])
return (set(L) - zL) | zR
def brute_nu(E, top): # largest k with k disjoint edges
return next(k for k in range(top, -1, -1) if any(
len({x for e in S for x in e}) == 2 * k for S in combinations(E, k)))
random.seed(64); ok = 0
for trial in range(200):
L = [f"L{i}" for i in range(random.randint(1, 5))]
R = [f"R{j}" for j in range(random.randint(1, 5))]
adj = {u: [v for v in R if random.random() < 0.4] for u in L}
E = [(u, v) for u in L for v in adj[u]]
mate = max_matching(L, adj); C = konig_cover(L, adj, mate)
assert len(mate) == brute_nu(E, min(len(L), len(R))) == len(C)
assert all(u in C or v in C for u, v in E); ok += 1
print(ok, "random bipartite graphs: augmenting = brute force = |cover|")আসল আউটপুট (ব্রাউজারের Python):
200 random bipartite graphs: augmenting = brute force = |cover|
একটিও assert ব্যর্থ হয়নি: প্রতিটি graph-এ DFS-এর matching-এর আকার brute force-এর ν-এর সমান (Berge: augmenting path না থাকলে maximum), আর প্রমাণের নির্মাণ থেকে আসা C প্রতিটি edge ঢাকে, আকারও ঠিক ν (König). লক্ষ করুন konig_cover-এ mate[v] কখনো KeyError দেয় না: ZR-এর প্রতিটি vertex saturated, ঠিক প্রমাণের ধাপ ১। augment ফাংশনটি একটি free u থেকে alternating path খোঁজে, আর পেলে ফেরার পথে প্রতিটি সঙ্গী বদলে দেয়, অর্থাৎ M ⊕ P. এই সরল পদ্ধতি (প্রায়ই Kuhn-এর algorithm বলা হয়) O(|V|·|E|) সময় নেয়; দ্রুততর Hopcroft–Karp আর flow-ভিত্তিক কোড DSA কোর্সের পর্ব ৪৭-এ।
৫ · Dilworth-এর উপপাদ্যের প্রমাণ — König থেকে
পর্ব ৫৬-এ Dilworth-এর উপপাদ্য প্রমাণ ছাড়া বলা হয়েছিল: সসীম poset-এর width w (সবচেয়ে বড় antichain-এর আকার) হলে উপাদানগুলো ঠিক wটি chain-এ ভাগ করা যায়, এর কম chain-এ নয়। “কম নয়” অংশ সহজ ছিল। এখন বাকি অংশ, D. R. Fulkerson-এর ১৯৫৬ সালের ধারণা বলে পরিচিত পথে।
সসীম poset (P, ≼)-এ সবচেয়ে কম কয়টি chain-এ P ভাগ করা যায় = সবচেয়ে বড় antichain-এর আকার।
নির্মাণ: |P| = n. প্রতিটি x ∈ P-এর দুটি কপি নিন: বাঁয়ে x−, ডানে x+. Bipartite graph B-তে x−–y+ edge থাকবে ঠিক যখন x ≺ y (x ≼ y আর x ≠ y). x−–y+ edge মানে “কোনো chain-এ x-এর ঠিক পরে y বসতে পারে”।
- Matching থেকে chain: B-এর একটি matching M নিন, আর প্রতিটি x−–y+ ∈ M-কে “x → y” তীর ধরুন। প্রতিটি x-এর বড়জোর একটি পরের তীর (x− একবার) আর বড়জোর একটি আগের তীর (x+ একবার)। তীর সবসময় কঠোরভাবে ওপরে যায়, তাই কোনো চক্র হয় না: তীরগুলো P-কে কয়েকটি শৃঙ্খলে ভাগ করে, আর transitivity অনুযায়ী প্রতিটি শৃঙ্খল একটি chain. kটি উপাদানের chain-এ k − 1টি তীর, তাই chain-এর সংখ্যা n − |M|. — প্রতিটি তীর দুটি টুকরো জোড়ে
- ফলে maximum matching দিয়ে n − ν(B)টি chain-এ ভাগ পাওয়া যায়। — ধাপ ১, M maximum
- Cover থেকে antichain: König অনুযায়ী B-এর একটি vertex cover C আছে যার |C| = ν(B). A = {x ∈ P : x− ∉ C আর x+ ∉ C} নিন। C-এর প্রতিটি vertex বড়জোর একটি x-কে বাদ দেয়, তাই |A| ≥ n − |C| = n − ν(B). — উপপাদ্য ৪.১
- A একটি antichain: x, y ∈ A আর x ≺ y হলে x−–y+ একটি edge, যার কোনো প্রান্ত C-তে নেই, অথচ C cover. বিরোধ। — cover-এর সংজ্ঞা
- তাই width ≥ |A| ≥ n − ν(B) = (ধাপ ২-এর chain-সংখ্যা) ≥ সবচেয়ে কম chain-সংখ্যা ≥ width, শেষটি সহজ দিক। সব অসমতা সমতা। ∎
হাতে একটি ছোট উদাহরণ: 12-এর উৎপাদক {1, 2, 3, 4, 6, 12}, সম্পর্ক “ভাগ করে” (∣)। Matching 1→2, 2→4, 4→12, 3→6 (আকার 4) দুটি chain দেয়: 1 ∣ 2 ∣ 4 ∣ 12 আর 3 ∣ 6. Antichain {4, 6} (4 ∤ 6, 6 ∤ 4). দুই সংখ্যাই 2, তাই width = 2 (scratch-এ সব উপসেট পরীক্ষা করে মেলানো)। নিচের ব্লক একই কাজ 60-এর ১২টি উৎপাদকে করে, যেখানে পর্ব ৫৬ চারটি chain দেখিয়েছিল।
from itertools import combinations
X = [d for d in range(1, 61) if 60 % d == 0] # poset: divisors, a | b
up = {x: [y for y in X if y != x and y % x == 0] for x in X} # x- -> y+
nxt = {} # matching: x- matched to y+
def augment(x, seen):
for y in up[x]:
if y not in seen:
seen.add(y)
owner = next((a for a in nxt if nxt[a] == y), None)
if owner is None or augment(owner, seen):
nxt[x] = y; return True
return False
for x in X: augment(x, set())
starts = [x for x in X if x not in nxt.values()] # nobody points to x
chains = []
for s in starts:
c = [s]
while c[-1] in nxt: c.append(nxt[c[-1]])
chains.append(c)
print("matching size", len(nxt), "-> chains", len(X) - len(nxt), chains)
zL = {x for x in X if x not in nxt}; zR = set(); todo = list(zL) # Konig
while todo:
for y in up[todo.pop()]:
if y not in zR:
zR.add(y)
owner = next(a for a in nxt if nxt[a] == y)
if owner not in zL: zL.add(owner); todo.append(owner)
cover = {("-", x) for x in X if x not in zL} | {("+", y) for y in zR}
anti = [x for x in X if ("-", x) not in cover and ("+", x) not in cover]
print("cover size", len(cover), "-> antichain", anti)
assert all(a % b and b % a for a, b in combinations(anti, 2))
print("width = min number of chains =", len(anti))আসল আউটপুট (ব্রাউজারের Python):
matching size 8 -> chains 4 [[1, 2, 4, 12, 60], [3, 6, 30], [5, 10, 20], [15]]
cover size 8 -> antichain [4, 6, 10, 15]
width = min number of chains = 4
১২টি উপাদান, maximum matching 8, তাই 12 − 8 = 4টি chain: প্রতিটি তালিকায় আগেরটি পরেরটিকে ভাগ করে। König-এর cover-এর আকারও 8, আর যাদের কোনো কপি cover-এ নেই তারা {4, 6, 10, 15}: কোনো দুটি একে অন্যকে ভাগ করে না (assert পাস)। চারটি chain আর চার আকারের antichain একসঙ্গে প্রমাণ করে width = 4.
৬ · Regular bipartite graph আর ওজনসহ assignment
বাজারঘর ঠিক করেছে, প্রতিটি রাইডার ঠিক তিনটি এলাকায় কাজ জানবেন আর প্রতিটি এলাকা ঠিক তিনজন রাইডার জানবেন। এমন ব্যবস্থায় কি প্রতিদিন প্রত্যেক রাইডারকে আলাদা একটি এলাকা দেওয়া যায়? Hall-এর উপপাদ্য এক লাইনে উত্তর দেয়। (k-regular মানে প্রতিটি vertex-এর degree ঠিক k.)
k ≥ 1 হলে প্রতিটি k-regular bipartite graph-এ (multigraph হলেও) একটি perfect matching আছে। আরও: তার edge-গুলো kটি আলাদা perfect matching-এ ভাগ করা যায়।
- Edge গুনুন দুইভাবে: প্রতিটি edge-এর ঠিক একটি প্রান্ত L-এ, তাই |E| = k|L|; একইভাবে |E| = k|R|. তাই |L| = |R|. — পর্ব ৩৭-এর double counting
- যেকোনো X ⊆ L নিন। X থেকে বের হওয়া edge ঠিক k|X|টি, আর সবাই N(X)-এ পড়ে। N(X)-এর প্রতিটি vertex মোট kটি edge পায়, তাই এই edge-গুলো বড়জোর k|N(X)|টি। ফলে k|X| ≤ k|N(X)|, অর্থাৎ |N(X)| ≥ |X|. — double counting
- Hall অনুযায়ী L saturate করা matching আছে; |L| = |R| বলে এটি perfect. — উপপাদ্য ৩.১
- এই matching সরালে graph (k − 1)-regular bipartite থাকে; k-এর ওপর induction-এ kটি perfect matching পাওয়া যায়। ∎ — পর্ব ১০-এর induction
শেষ অংশটি König-এর ১৯১৬ সালের একটি ফলের সঙ্গে যুক্ত বলে উল্লেখ করা হয়: bipartite graph-এর edge-গুলো Δ রঙে (Δ = সর্বোচ্চ degree) রাঙানো যায়, যাতে একই vertex-এ দুটি edge একই রঙ না পায়। রাইডারের উদাহরণে অর্থ: তিন দিনের একটি পালা বানানো যায়, যাতে প্রতিদিন প্রত্যেকে আলাদা এলাকায় যান আর তিন দিনে নিজের তিনটি এলাকাই ঘোরা হয়। Graph coloring-এর বিস্তারিত পর্ব ৬৩ “Graph coloring — chromatic number, scheduling আর চার রঙের উপপাদ্য”-এ।
ওজনসহ matching: assignment problem আর Hungarian পদ্ধতির ধারণা
এবার প্রতিটি রাইডার–অর্ডার জোড়ার একটি খরচ আছে (মিনিটে যাতায়াত সময়, সংখ্যাগুলো কাল্পনিক)। মোট খরচ সবচেয়ে কম রেখে একটি perfect matching চাই: এর নাম assignment problem. n জনের জন্য n!টি সম্ভাবনা, তাই brute force দ্রুত অচল। Hungarian পদ্ধতি (Harold Kuhn, ১৯৫৫; König আর Egerváry-র কাজের ওপর ভিত্তি করে, তাই এই নাম) polynomial সময়ে সমাধান দেয়। এর মূল ধারণা একটি “নিম্নসীমার প্রমাণপত্র”:
- প্রতিটি রাইডার i-কে একটি সংখ্যা ui আর প্রতিটি অর্ডার j-কে vj দিন, যাতে সব জোড়ায় ui + vj ≤ cij (cij = খরচ)।
- তাহলে যেকোনো perfect matching-এর খরচ ≥ ∑ui + ∑vj, কারণ প্রতিটি i আর প্রতিটি j ঠিক একবার আসে।
- যেখানে সমতা ui + vj = cij, সেই “টাইট” edge-গুলো দিয়ে perfect matching পাওয়া গেলে সেটিই সর্বোত্তম। না পেলে König-এর cover বলে দেয় কোন u, v কতটা বদলালে নতুন টাইট edge আসে; পদ্ধতিটি তা বারবার করে।
উদাহরণ: তিন রাইডার, তিন অর্ডার, খরচ-matrix-এর সারি (9, 2, 7), (6, 4, 3), (5, 8, 1). প্রতিটি সারির সবচেয়ে ছোট সংখ্যা u = (2, 3, 1); বাদ দিলে প্রতিটি কলামের সবচেয়ে ছোট বাকি v = (3, 0, 0). টাইট ঘর: (১, ২), (২, ১), (২, ৩), (৩, ৩). এদের মধ্যে perfect matching: রাইডার ১ → অর্ডার ২, ২ → ১, ৩ → ৩, খরচ 2 + 6 + 1 = 9. নিম্নসীমা ∑u + ∑v = 6 + 3 = 9. দুই সংখ্যা সমান, তাই 9-ই সর্বনিম্ন, আর কোনো ৬টি assignment গোনা লাগেনি (scratch-এ ৬টিই গুনে মেলানো: পরের সেরাটি 10). এই “দুই দিকের প্রমাণপত্র” হলো linear programming duality-র একটি রূপ। Algorithm-এর পূর্ণ কোড DSA কোর্সের পর্ব ৪৭-এ।
৭ · Stable matching — Gale–Shapley-এর প্রস্তাব আর প্রত্যাখ্যান
বাজারঘরের চারজন শিক্ষানবিশ A, B, C, D চারটি গুদামে (গাজীপুর G, নারায়ণগঞ্জ N, সাভার S, টঙ্গী T) প্রশিক্ষণ নেবেন। প্রত্যেক শিক্ষানবিশের গুদামের একটি পছন্দ-তালিকা আছে, আর প্রতিটি গুদামেরও শিক্ষানবিশদের একটি তালিকা। এবার শুধু “সবাই জোড়া পেল” যথেষ্ট নয়; বিপদ হলো এমন একটি জোড়া, যারা দুজনেই বর্তমান সঙ্গীর চেয়ে একে অন্যকে বেশি চান। তারা নিয়ম ভেঙে নিজেরা চুক্তি করে ফেলবেন।
সমান আকারের দুই দল (প্রস্তাবদাতা আর গ্রহীতা), প্রত্যেকের অপর দলের সবার একটি কঠোর পছন্দ-ক্রম। একটি perfect matching M-এ (p, w) একটি blocking pair, যদি p আর w M-এ জোড়া নন, অথচ p তাঁর M-সঙ্গীর চেয়ে w-কে বেশি পছন্দ করেন আর w তাঁর M-সঙ্গীর চেয়ে p-কে। কোনো blocking pair না থাকলে M stable.
Gale–Shapley algorithm (David Gale আর Lloyd Shapley, ১৯৬২; “deferred acceptance” নামেও পরিচিত): যতক্ষণ কোনো প্রস্তাবদাতা p একা আছেন, p তাঁর তালিকার পরের গ্রহীতা w-কে প্রস্তাব দেন, যাঁকে আগে দেননি। w একা হলে প্রস্তাবটি “ধরে রাখেন”; কাউকে ধরে রাখলে দুজনের মধ্যে যাঁকে বেশি পছন্দ তাঁকে রাখেন, অন্যজনকে ফিরিয়ে দেন, আর ফেরত পাওয়া জন আবার একা। কেউ একা না থাকলে ধরে রাখা জোড়াগুলোই উত্তর। নিচে সব একা প্রস্তাবদাতা একসঙ্গে প্রস্তাব দেন, রাউন্ডে রাউন্ডে।
1A: T S N G G: A C D B2B: G N T S N: B C D A3C: T G S N S: C D B A4D: G S N T T: B D A C5রাউন্ড ১6রাউন্ড ২7রাউন্ড ৩8stability যাচাই
| প্রস্তাব | |
| ধরে রাখা | |
| ফেরত |
- পছন্দ-তালিকা। প্রতিটি সারিতে বাঁয়ে শিক্ষানবিশের তালিকা (সবচেয়ে পছন্দ আগে), ডানে গুদামের। যেমন A সবচেয়ে চান T, তারপর S, N, G; আর গুদাম T সবচেয়ে চায় B, তারপর D, A, C.
- রাউন্ড ১। সবাই প্রথম পছন্দে প্রস্তাব দেন: A আর C যান T-তে, B আর D যান G-তে। T-এর তালিকায় A (তৃতীয়) C-এর (চতুর্থ) আগে, তাই T ধরে রাখে A. G-এর তালিকায় D (তৃতীয়) B-এর (চতুর্থ) আগে, তাই G ধরে রাখে D. B আর C ফেরত।
- রাউন্ড ২। B দ্বিতীয় পছন্দ N-এ, C দ্বিতীয় পছন্দ G-তে। N খালি ছিল, B-কে রাখে। G-এর হাতে D, কিন্তু G-এর তালিকায় C (দ্বিতীয়) D-এর (তৃতীয়) আগে: G আরও ভালো জনকে নেয়, D ফেরত।
- রাউন্ড ৩। D-এর তালিকায় G-এর পরে S; S খালি, D-কে রাখে। আর কেউ একা নন। ফল: A–T, B–N, C–G, D–S, মোট প্রস্তাব 4 + 2 + 1 = 7.
- যাচাই। কোনো blocking pair নেই: যেমন D চান G-কে বেশি, কিন্তু G-এর কাছে C, যিনি D-এর আগে। ২৪টি perfect matching-এর মধ্যে stable ঠিক দুটি: এটি আর A–G, B–N, C–S, D–T. দ্বিতীয়টিতে A, C, D সবাই খারাপ সঙ্গী পান, B একই: শিক্ষানবিশদের জন্য Gale–Shapley-এর উত্তর সেরা (পরের Python ব্লকে মেলানো)।
n জন প্রস্তাবদাতা আর n জন গ্রহীতা, সম্পূর্ণ কঠোর তালিকা। Gale–Shapley বড়জোর n2টি প্রস্তাবের পর থামে, আর ফল একটি stable perfect matching.
- থামা: প্রত্যেক প্রস্তাবদাতা একজন গ্রহীতাকে বড়জোর একবার প্রস্তাব দেন, তাই মোট প্রস্তাব ≤ n · n. প্রতিটি ধাপে একটি প্রস্তাব হয়, তাই algorithm থামে। — সসীম গণনা
- গ্রহীতার দিক: একবার প্রস্তাব পেলে w সবসময় কাউকে ধরে রাখেন, আর ধরে রাখা জন শুধু তাঁর তালিকায় ওপরে ওঠেন। — নিয়ম থেকে, ধাপে ধাপে induction
- সবাই জোড়া পান: ধরুন শেষে p একা। তাহলে p সব nজনকে প্রস্তাব দিয়ে ফেরত পেয়েছেন, তাই ধাপ ২ অনুযায়ী nজন গ্রহীতাই কাউকে ধরে রাখছেন, আর তাঁরা সবাই p নন: n − 1 জন প্রস্তাবদাতা nজনের হাতে, যা অসম্ভব (pigeonhole). — বিরোধ
- Stable: ধরুন (p, w) blocking: p তাঁর সঙ্গী M(p)-এর চেয়ে w-কে বেশি চান। p তালিকা ধরে নিচে নামেন, তাই M(p)-এর আগে w-কে প্রস্তাব দিয়েছিলেন, আর কোনো এক সময় w তাঁকে ফেরত দিয়েছেন বা নেননি, কারণ তখন হাতে p-এর চেয়ে পছন্দের কেউ ছিলেন। ধাপ ২ অনুযায়ী w-এর শেষ সঙ্গী M(w) তাঁর কাছে অন্তত তত ভালো, তাই w, p-এর চেয়ে M(w)-কে বেশি চান। এটি blocking-এর বিরোধী। ∎ — বিরোধ
p-এর জন্য w “সম্ভব”, যদি কোনো stable matching-এ p–w জোড়া। Gale–Shapley-এ প্রত্যেক p পান তাঁর সবচেয়ে পছন্দের সম্ভব সঙ্গী; প্রস্তাবের ক্রম যা-ই হোক, ফল একই।
- দাবি: কোনো প্রস্তাবদাতা কখনো একজন সম্ভব সঙ্গীর কাছ থেকে প্রত্যাখ্যাত হন না। বিপরীতে, এমন প্রথম ঘটনাটি নিন: w, p-কে ফেরাল p′-এর জন্য, যেখানে w p-এর সম্ভব সঙ্গী, অর্থাৎ কোনো stable S-এ S(p) = w. — সময়ে প্রথম ঘটনা, well-ordering
- w-এর কাছে p′ > p. আর p′ তালিকা ধরে নামতে নামতে w-তে পৌঁছেছেন, তাই w-এর আগের সবাই তাঁকে ফিরিয়েছেন; এটি প্রথম “সম্ভব-প্রত্যাখ্যান” বলে তাঁদের কেউ p′-এর সম্ভব সঙ্গী নন। S(p′) p′-এর একজন সম্ভব সঙ্গী আর S(p′) ≠ w, তাই p′ তালিকায় w-কে S(p′)-এর চেয়ে ওপরে রাখেন। — ধাপে ধাপে নামা
- তাহলে S-এ (p′, w) blocking: p′ নিজের S-সঙ্গীর চেয়ে w চান, আর w নিজের S-সঙ্গী p-এর চেয়ে p′ চান। কিন্তু S stable, বিরোধ। — সংজ্ঞা ৭.১
- তাই প্রত্যেক p তাঁর সব সম্ভব সঙ্গীর ওপরের কারও কাছ থেকেই ফেরত পান, আর ফল (যা stable, তাই p-এর সঙ্গী সম্ভব) ঠিক সেরা সম্ভব সঙ্গী। এই বর্ণনা প্রস্তাবের ক্রমের ওপর নির্ভর করে না। ∎
উল্টো দিকটিও জানা যায় (McVitie আর Wilson, ১৯৭১ বলে উল্লেখ করা হয়): একই matching-এ প্রত্যেক গ্রহীতা পান তাঁর সবচেয়ে অপছন্দের সম্ভব সঙ্গী। তাই কে প্রস্তাব দেয়, সেই নকশা-সিদ্ধান্তের ফল বাস্তবে বড়। নিচের ব্লক উদাহরণটি পুরো যাচাই করে।
from itertools import permutations
P = {"A": "TSNG", "B": "GNTS", "C": "TGSN", "D": "GSNT"} # trainees' lists
W = {"G": "ACDB", "N": "BCDA", "S": "CDBA", "T": "BDAC"} # warehouses' lists
def gale_shapley(P, W):
nxt = {p: 0 for p in P}; held = {}; free = sorted(P); proposals = 0
while free:
p = free.pop(0); w = P[p][nxt[p]]; nxt[p] += 1; proposals += 1
if w not in held:
held[w] = p
elif W[w].index(p) < W[w].index(held[w]): # w trades up
free.append(held[w]); held[w] = p
else:
free.append(p) # w rejects p
return {p: w for w, p in held.items()}, proposals
def blocking_pairs(M, P, W):
owner = {w: p for p, w in M.items()}
return [(p, w) for p in P for w in W
if P[p].index(w) < P[p].index(M[p])
and W[w].index(p) < W[w].index(owner[w])]
M, k = gale_shapley(P, W)
print("trainees propose:", dict(sorted(M.items())), "proposals:", k)
print("blocking pairs:", blocking_pairs(M, P, W))
stable = [dict(zip(P, perm)) for perm in permutations(W)
if not blocking_pairs(dict(zip(P, perm)), P, W)]
print("stable among all 24:", [''.join(s.values()) for s in stable])
for p in P: # proposer-optimal check
assert all(P[p].index(M[p]) <= P[p].index(s[p]) for s in stable)
R, _ = gale_shapley(W, P)
print("warehouses propose:", dict(sorted((p, w) for w, p in R.items())))আসল আউটপুট (ব্রাউজারের Python):
trainees propose: {'A': 'T', 'B': 'N', 'C': 'G', 'D': 'S'} proposals: 7
blocking pairs: []
stable among all 24: ['GNST', 'TNGS']
warehouses propose: {'A': 'G', 'B': 'N', 'C': 'S', 'D': 'T'}
এই কোড এক এক করে প্রস্তাব দেয় (রাউন্ডে নয়), তবু ফল stepper-এর মতোই, আর প্রস্তাবও ৭টি: উপপাদ্য ৭.৩ বলে ক্রম বদলালেও ফল বদলায় না। সব ২৪টি matching পরীক্ষা করে stable ঠিক দুটি: “GNST” মানে A–G, B–N, C–S, D–T, আর “TNGS” মানে Gale–Shapley-এর উত্তর। assert দেখায় প্রত্যেক শিক্ষানবিশ সব stable matching-এর চেয়ে ভালো বা সমান সঙ্গী পেয়েছেন। গুদামগুলো প্রস্তাব দিলে উত্তর হয় অন্য stable matching-টি, যা গুদামদের জন্য সেরা আর শিক্ষানবিশদের জন্য সবচেয়ে খারাপ।
৮ · সাধারণ graph-এ matching — odd cycle, Tutte আর Edmonds
Berge-এর উপপাদ্য যেকোনো graph-এ সত্য, কিন্তু Hall আর König শুধু bipartite graph-এ। সাধারণ graph-এ বাধা আসে odd cycle থেকে: ত্রিভুজে প্রতিটি vertex-এর প্রতিবেশী দুজন, তবু perfect matching নেই (vertex বিজোড়), আর ν = 1 < 2 = τ. Bipartite হওয়া মানেই odd cycle না থাকা (পর্ব ৫৭ “গ্রাফ — সংজ্ঞা, degree আর handshake theorem”), আর এই কারণেই সেখানে সব এত পরিষ্কার।
G-তে perfect matching আছে যদি এবং কেবল যদি প্রতিটি S ⊆ V-এর জন্য G − S-এর বিজোড়-আকারের component-এর সংখ্যা ≤ |S|.
প্রয়োজনীয়তার দিকটি সহজ: G − S-এর প্রতিটি বিজোড় component-এর অন্তত একটি vertex-কে বাইরে, অর্থাৎ S-এ, সঙ্গী খুঁজতে হয়, আর S-এর প্রতিটি vertex একজনকেই নিতে পারে। উদাহরণ: তারকা K1,3-এ (একটি কেন্দ্র, তিনটি পাতা) S = {কেন্দ্র} সরালে তিনটি একা vertex, তিনটি বিজোড় component > 1 = |S|, তাই perfect matching নেই। যথেষ্টতার প্রমাণ দীর্ঘতর, তাই এখানে বাদ। একটি পরিচিত ফল (Petersen, ১৮৯১ বলে উল্লেখ করা হয়): প্রতিটি 3-regular graph যাতে কোনো bridge নেই, তাতে perfect matching আছে; Petersen graph-এ এমন matching ঠিক ৬টি (scratch-এ গুনে মেলানো)।
Algorithm-এর দিকে সমস্যাটি এমন: alternating path খুঁজতে গিয়ে একটি odd cycle-এ ঘুরে এলে একই vertex-এ “জোড়” আর “বিজোড়” দুই অবস্থায় পৌঁছানো যায়, আর সরল DFS ভুল পথে আটকে যায়। Jack Edmonds ১৯৬৫ সালে দেখান, এমন odd cycle (তাঁর ভাষায় “blossom” বা ফুল) পেলে সেটিকে একটি vertex-এ সংকুচিত করে খোঁজ চালিয়ে যাওয়া যায়, আর augmenting path পেলে ফুল খুলে আসল path বের করা যায়। এই blossom algorithm সাধারণ graph-এ maximum matching polynomial সময়ে দেয়। ওজনসহ সাধারণ matching-এরও polynomial সমাধান আছে, Edmonds-এরই আরেকটি কাজ বলে উল্লেখ করা হয়। তুলনায়, একটি 3-uniform hypergraph-এ (প্রতিটি “edge” তিনটি vertex জোড়ে) perfect matching আছে কি না, সেই প্রশ্ন NP-complete; DSA কোর্সের পর্ব ৬৪ দেখুন।
৯ · পরীক্ষার অঙ্ক আর একটি ভুল প্রমাণ
অঙ্ক ১: Maximal বনাম maximum
৬ vertex-এর path P6: 0–1–2–3–4–5. (ক) ν কত? (খ) সবচেয়ে ছোট maximal matching কত বড়? (গ) উপপাদ্য ১.২-এর সীমা মেলে কি?
- (ক) {0–1, 2–3, 4–5} perfect, তাই ν = 3.
- (খ) {1–2, 3–4}: বাকি edge 0–1, 2–3, 4–5-এর প্রত্যেকটির একটি প্রান্ত ব্যস্ত, তাই maximal; আকার 2. একটি edge বড়জোর ৩টি edge ছোঁয়, তাই একটিতে ৫টি edge আটকানো যায় না।
- (গ) 3 ≤ 2 · 2, মেলে (scratch-এ সব edge-সেট পরীক্ষা করে মেলানো)।
অঙ্ক ২: Perfect matching গোনা
K6-এ আর K3,3-এ কয়টি perfect matching? উত্তর: K6-এ 5 · 3 · 1 = 15 (§১-এর যুক্তি), K3,3-এ 3! = 6 (L থেকে R-এ bijection). দুটিই scratch-এ প্রতিটি matching গুনে মেলানো।
অঙ্ক ৩: König দিয়ে প্রমাণপত্র
§৩-এর কর্মী–শিফট graph-এ দেখান যে ৪-এর বেশি কর্মী একসঙ্গে কাজ পাবেন না, Hall ব্যবহার না করে। উত্তর: {1, 2, D, 4} একটি vertex cover (A, B, C-এর সব edge 1 বা 2-এ, D-এর সব edge D-তে, E–4 ঢাকে 4), আকার 4. ν ≤ τ, তাই ν ≤ 4; আর A–1, B–2, D–3, E–4 আকার 4-এর matching, তাই ν = 4.
প্রমাণের ভুল ধরুন: “লোভী matching-ই maximum”
একজন লিখলেন: “লোভী পদ্ধতি একটি maximal matching M দেয়। ধরুন M*-এ আরও বেশি edge আছে। তাহলে M*-এর একটি edge e আছে যা M-এ নেই। e-কে M-এ যোগ করলে বড় matching হয়, যা M-এর maximal হওয়ার বিরোধী। তাই M maximum.”
ভুল কোথায়: “e ∉ M” থেকে “M ∪ {e} একটি matching” আসে না; e-এর একটি প্রান্ত M-এর অন্য কোনো edge-এ ব্যস্ত থাকতে পারে, আর maximal-এর সংজ্ঞা ঠিক সেটাই বলে। পাল্টা-উদাহরণ: path 1–2–3–4-এ M = {2–3} maximal, অথচ M* = {1–2, 3–4} বড়, আর M*-এর কোনো edge M-এ যোগ করা যায় না। সঠিক কথা উপপাদ্য ১.২ (|M| ≥ ν/2) আর Berge: M থেকে M*-এ যেতে edge “যোগ” নয়, একটি augmenting path ধরে “বদল” লাগে, এখানে 1–2–3–4 নিজেই।
আরও গভীরে: Bipartite matching-এর দ্রুততম ক্লাসিক্যাল পদ্ধতি Hopcroft–Karp (১৯৭৩), O(|E|√|V|) সময়ে; ২০২২ সালে ঘোষিত প্রায়-রৈখিক সময়ের max-flow algorithm (Chen, Kyng, Liu, Peng, Probst Gutenberg, Sachdeva) bipartite matching-ও প্রায়-রৈখিক সময়ে নামায় বলে জানা যায়। Matching-এর সংখ্যা গোনা (bipartite graph-এ matrix-এর permanent) Valiant-এর ১৯৭৯ সালের ফল অনুযায়ী #P-complete, অথচ planar graph-এ Kasteleyn-এর পদ্ধতিতে তা polynomial সময়ে গোনা যায়। আর প্রত্যেকের নিজের দলেই সঙ্গী খোঁজার “stable roommates” সমস্যায় stable matching না-ও থাকতে পারে; থাকলে খুঁজে বের করার একটি algorithm Irving ১৯৮৫ সালে দেন বলে উল্লেখ করা হয়।
পরীক্ষা ও ইন্টারভিউতে: বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় এই ধরনের প্রশ্ন প্রায়ই আসে:
- Maximal আর maximum matching-এর পার্থক্য? আর edge যোগ করা যায় না বনাম সবচেয়ে বড়; maximal ≥ maximum-এর অর্ধেক।
- Berge-এর উপপাদ্য? Matching maximum ⇔ কোনো augmenting path নেই; প্রমাণ M ⊕ M* দিয়ে।
- Hall-এর শর্ত? Bipartite graph-এ প্রতিটি X ⊆ L-এ |N(X)| ≥ |X| ⇔ L saturate করা matching.
- Kn,n আর K2n-এ কয়টি perfect matching? n! আর (2n − 1)(2n − 3)⋯1.
- Gale–Shapley কার জন্য সেরা? প্রস্তাবদাতাদের জন্য; গ্রহীতারা পান সবচেয়ে খারাপ stable সঙ্গী।
১০ · AI-এর যুগে — matching-এর প্রমাণ আর হিসাব যাচাই
Matching-এর প্রশ্নে AI সহকারী নাম আর সংজ্ঞা সাধারণত ঠিক বলে, কিন্তু শর্ত বাদ দেয়, দুই দিক গুলিয়ে ফেলে, আর হাতের হিসাবে ভুল করে। কয়েকটি নিয়মিত ভুল আর ধরার উপায়:
| AI-এর ভুল | কীভাবে ধরবেন |
|---|---|
| Hall বা König-কে যেকোনো graph-এ প্রয়োগ, “bipartite” শর্ত বাদ | ত্রিভুজ: ν = 1 অথচ τ = 2; K3 2-regular অথচ perfect matching নেই |
| “লোভী পদ্ধতিই সবচেয়ে বড় matching দেয়” | Path 1–2–3–4-এ মাঝের edge আগে নিলে আকার 1, অথচ ν = 2 |
| Gale–Shapley-কে “সবার জন্য সেরা” বলা, বা গ্রহীতার জন্য সেরা বলা | সব perfect matching গুনে stable-গুলো তালিকা করুন, কে কোথায় কী পান দেখুন |
| Hall-এর শর্ত শুধু একক vertex বা জোড়ায় পরীক্ষা করে “সম্ভব” বলা | §৩-এর তালিকা: একক আর জোড়ায় ঠিক, তিনজনে ভাঙে |
| Perfect matching গোনায় ক্রম গুলিয়ে ফেলা (K6-এ 6!/2 ধরনের উত্তর) | ছোট n-এ সব matching গুনে সূত্রের সঙ্গে মেলান |
AI-এর কাছে matching-এর প্রমাণ বা হিসাব চাইলে এমন কাঠামো দিন, যাতে প্রতিটি ধাপ আলাদা করে যাচাই করা যায়:
AI-এর উত্তর হাতে পেলে — যাচাইয়ের চেকলিস্ট
Matching-এর উত্তরের সঙ্গে প্রমাণপত্রও চাইবেন: matching, cover, ভাঙা X বা blocking pair-এর তালিকা, যা কয়েক লাইনের কোডে মেলানো যায়।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।
প্র ০১Gale আর Shapley-এর ১৯৬২ সালের ছোট প্রবন্ধ কীভাবে ডাক্তারদের নিয়োগ, স্কুল ভর্তি আর শেষে অর্থনীতির নোবেল পর্যন্ত গেল?
David Gale আর Lloyd Shapley ১৯৬২ সালে American Mathematical Monthly-তে “College Admissions and the Stability of Marriage” নামে একটি প্রবন্ধ প্রকাশ করেন। প্রবন্ধটি প্রায় গণিতের ধাঁধার মতো: কলেজ আর আবেদনকারীদের পছন্দ জানা থাকলে কীভাবে এমন ভর্তি করা যায়, যাতে কোনো কলেজ আর আবেদনকারী মিলে নিয়ম ভাঙতে না চান। তাঁরা stable matching-এর সংজ্ঞা, deferred acceptance পদ্ধতি আর তার সঠিকতার প্রমাণ দেন, আর দেখান যে প্রস্তাবদাতাদের জন্য ফলটি সেরা stable matching.
পরে জানা যায়, যুক্তরাষ্ট্রে নতুন ডাক্তারদের হাসপাতালে নিয়োগের একটি কেন্দ্রীয় ব্যবস্থা (আজ National Resident Matching Program নামে পরিচিত) ১৯৫০-এর দশক থেকে এমন একটি পদ্ধতি চালাচ্ছিল, যা গাণিতিকভাবে হাসপাতাল-প্রস্তাবিত deferred acceptance-এর সমতুল্য বলে Alvin Roth তাঁর ১৯৮৪ সালের গবেষণায় দেখান বলে উল্লেখ করা হয়।
১৯৯০-এর দশকে Roth আর Elliott Peranson এই ব্যবস্থা নতুন করে নকশা করেন (আবেদনকারী-প্রস্তাবিত রূপে, দম্পতিদের মতো জটিলতা সামলে), আর তা প্রায় ১৯৯৮ সাল থেকে চালু বলে জানা যায়। একই ধারণা পরে কয়েকটি শহরের স্কুল ভর্তিতেও ব্যবহার হয়েছে বলে বর্ণনা পাওয়া যায়। Gale ২০০৮ সালে মারা যান; ২০১২ সালে Roth আর Shapley অর্থনীতিতে Nobel স্মারক পুরস্কার পান “stable allocation-এর তত্ত্ব আর market design-এর চর্চার জন্য”।
একটি সূক্ষ্ম তথ্য নকশায় খুব গুরুত্বপূর্ণ: প্রস্তাবদাতাদের জন্য সত্যি পছন্দ জানানোই সবচেয়ে ভালো কৌশল (Dubins–Freedman আর Roth-এর আশির দশকের শুরুর ফল বলে উল্লেখ করা হয়), কিন্তু গ্রহীতাদের জন্য তা সবসময় নয়। তাই কারা প্রস্তাব দেবেন, সেই সিদ্ধান্ত শুধু গণিত নয়, ন্যায্যতারও প্রশ্ন।
মূল উপলব্ধি: একটি সরল প্রস্তাব-প্রত্যাখ্যান পদ্ধতি আর তার তিনটি প্রমাণ (থামে, stable, প্রস্তাবদাতার জন্য সেরা) বাস্তবের বড় নিয়োগ ও ভর্তি ব্যবস্থার ভিত্তি হয়েছে; কে প্রস্তাব দেয়, সেই নকশা-সিদ্ধান্ত কার লাভ তা ঠিক করে।
প্র ০২Hungarian পদ্ধতির নাম “Hungarian” কেন? König, Egerváry আর Kuhn-এর গল্পে duality কীভাবে এল?
Dénes Kőnig ছিলেন বুদাপেস্টের গণিতবিদ। তাঁর ১৯৩১ সালের প্রবন্ধে bipartite graph-এ matching আর vertex cover-এর সমতা আসে (প্রায়ই 0-1 matrix-এর ভাষায়: সব 1 ঢাকতে সবচেয়ে কম কয়টি সারি বা কলাম লাগে = কোনো দুটি এক সারি বা কলামে নেই এমন সবচেয়ে বেশি কয়টি 1). একই বছর Jenő Egerváry এর ওজনসহ রূপ প্রকাশ করেন: খরচের matrix-এ সারি আর কলামে সংখ্যা বসিয়ে কীভাবে সর্বোত্তম assignment-এর সমান একটি নিম্নসীমা পাওয়া যায়। Kőnig-এর ১৯৩৬ সালের বইকে graph theory-র প্রথম পাঠ্যবই ধরা হয়।
প্রায় দুই দশক পর, ১৯৫৫ সালে, মার্কিন গণিতবিদ Harold Kuhn একটি algorithm প্রকাশ করেন, যা ঠিক এই দুই হাঙ্গেরীয়র ধারণা দিয়ে গঠিত; সম্মান জানিয়ে তিনি নাম দেন “Hungarian method”. §৬-এর উদাহরণে যা দেখেছেন, পদ্ধতিটি তা-ই: সারি আর কলামের সংখ্যা (u, v) রাখা, টাইট ঘরে maximum matching খোঁজা, আর না মিললে König-এর cover দেখে u, v সামঞ্জস্য করা। ১৯৫৭ সালে James Munkres পদ্ধতিটির polynomial সময়ের বিশ্লেষণ দেন বলে উল্লেখ করা হয়, আর পরে O(n3) সংস্করণও পাওয়া যায়।
একই সময়ে linear programming-এর duality তত্ত্ব (John von Neumann, George Dantzig প্রমুখের কাজ) গড়ে উঠছিল। পরে বোঝা যায়, König–Egerváry, Menger আর max-flow min-cut সবাই একটি সাধারণ সত্যের বিশেষ রূপ: একটি সর্বোচ্চকরণ সমস্যা আর তার “dual” সর্বনিম্নকরণ সমস্যার সর্বোত্তম মান সমান, আর bipartite graph-এর বিশেষ গঠনের জন্য উত্তর পূর্ণসংখ্যায় পাওয়া যায়। Dilworth-এর উপপাদ্যের Fulkerson-ধাঁচের প্রমাণ (§৫) এই পরিবারেরই আরেক সদস্য।
ব্যবহারিক শিক্ষা: সর্বোত্তম উত্তরের সঙ্গে একটি dual প্রমাণপত্র (cover, বা u, v) থাকলে উত্তর যাচাই এক লাইনের কাজ।
মূল উপলব্ধি: Hungarian পদ্ধতি König আর Egerváry-র ১৯৩১ সালের duality-কে algorithm-এ রূপ দেয়; সর্বোত্তমতার প্রমাণ আসে একটি dual নিম্নসীমা থেকে, যা linear programming duality-র একটি বিশেষ রূপ।
প্র ০৩Edmonds-এর ১৯৬৫ সালের “Paths, Trees, and Flowers” কেন শুধু matching নয়, “দক্ষ algorithm” ধারণার ইতিহাসেও গুরুত্বপূর্ণ?
১৯৫০-এর দশকের শেষে Berge-এর উপপাদ্য জানা ছিল: augmenting path না থাকলেই matching maximum. কিন্তু সাধারণ graph-এ augmenting path খোঁজার স্পষ্ট দ্রুত পদ্ধতি ছিল না। সমস্যা §৮-এর odd cycle: alternating খোঁজ একটি বিজোড় চক্র ঘুরে একই vertex-এ দুই পরিচয়ে ফেরে, আর কোন পথ ধরলে augmenting path মিলবে তা বোঝা যায় না। সব path পরীক্ষা করলে সময় exponential হয়ে যায়।
Jack Edmonds ১৯৬৫ সালে Canadian Journal of Mathematics-এ “Paths, Trees, and Flowers” প্রকাশ করেন। তাঁর সমাধান: খোঁজের সময় একটি odd cycle (blossom) পেলে তাকে একটি vertex-এ সংকুচিত করুন। তিনি প্রমাণ করেন, সংকুচিত graph-এ augmenting path থাকে ঠিক তখন, যখন মূল graph-এ থাকে, আর সংকুচিত path থেকে মূল path ফিরিয়ে আনা যায়। ফলে সব কাজ polynomial সময়ে হয়।
প্রবন্ধটির আরেকটি অংশ সমান বিখ্যাত। Edmonds সেখানে যুক্তি দেন যে একটি algorithm-কে “ভালো” বলা উচিত যদি তার ধাপ ইনপুটের আকারের একটি polynomial দিয়ে সীমিত হয়, আর এমন algorithm-যোগ্য সমস্যার একটি শ্রেণি থাকা উচিত। এই ধারণা, Alan Cobham-এর প্রায় একই সময়ের কাজের সঙ্গে মিলে, পরে P শ্রেণির সংজ্ঞার ভিত্তি হয় বলে ইতিহাসে উল্লেখ করা হয়। Edmonds আরও লক্ষ করেন, কিছু সমস্যার উত্তর যাচাই সহজ কিন্তু খুঁজে পাওয়া কঠিন মনে হয়; সেটিই পরে NP-এর ধারণার সঙ্গে যুক্ত। P বনাম NP প্রশ্নের বিস্তারিত DSA কোর্সের পর্ব ৬৪-এ।
এখানে Tutte-এর উপপাদ্যের ভূমিকাও লক্ষ করুন: perfect matching না থাকলে একটি S দেখালেই চলে যার বিজোড় component |S|-এর বেশি; থাকলে matching নিজেই প্রমাণ। দুই দিকেই ছোট প্রমাণপত্র, যা Edmonds-এর ভাষায় “ভালো চরিত্র-বর্ণনা” (good characterization). এমন সমস্যা প্রায়ই polynomial algorithm পায়, matching তার প্রথম বড় উদাহরণ।
মূল উপলব্ধি: Blossom সংকোচন সাধারণ graph-এ maximum matching polynomial সময়ে আনে; আর একই প্রবন্ধে “দক্ষ = polynomial সময়” ধারণাটি স্পষ্ট রূপ পায়, যা জটিলতা তত্ত্বের ভিত্তি।
প্র ০৪অর্ডার যদি একটি একটি করে আসে আর সঙ্গে সঙ্গে রাইডার ঠিক করতে হয়, তখন matching কতটা ভালো হতে পারে?
এ পর্যন্ত আমরা পুরো graph হাতে নিয়ে সর্বোত্তম matching খুঁজেছি। বাস্তবে বাজারঘরের অর্ডার আসে একটির পর একটি, আর প্রতিটি অর্ডার আসামাত্র কোন রাইডার নেবেন তা ঠিক করতে হয়, ভবিষ্যৎ না জেনে, আর সিদ্ধান্ত পরে বদলানো যায় না। একে “online bipartite matching” বলে। এখানে প্রশ্ন সর্বোত্তম নয়, বরং সবচেয়ে খারাপ ক্ষেত্রেও সর্বোত্তমের কত অংশ নিশ্চিত করা যায় (competitive ratio).
সবচেয়ে সরল নিয়ম: আসা অর্ডারকে যেকোনো খালি উপযুক্ত রাইডার দিন। এর ফল সবসময় একটি maximal matching, তাই উপপাদ্য ১.২ অনুযায়ী সর্বোত্তমের অন্তত অর্ধেক। আর কোনো নির্ধারিত (deterministic) নিয়ম অর্ধেকের চেয়ে ভালো নিশ্চয়তা দিতে পারে না: প্রতিপক্ষ সবসময় পরের অর্ডারটি এমনভাবে সাজাতে পারে যে আপনার বেছে নেওয়া রাইডারই একমাত্র উপযুক্ত ছিলেন।
১৯৯০ সালে Richard Karp, Umesh Vazirani আর Vijay Vazirani একটি এলোমেলো নিয়ম দেন, যার নাম RANKING: শুরুতে রাইডারদের একটি এলোমেলো ক্রম ঠিক করুন, আর প্রতিটি অর্ডারকে সেই ক্রমে প্রথম খালি উপযুক্ত রাইডার দিন। তাঁরা দেখান, প্রত্যাশিত ফল সর্বোত্তমের অন্তত 1 − 1/e ≈ 0.632 অংশ, আর কোনো এলোমেলো নিয়মও এর চেয়ে ভালো নিশ্চয়তা দিতে পারে না। মূল প্রমাণে একটি ফাঁক ছিল যা পরে কয়েকজন গবেষক সংশোধন ও সরল করেন বলে উল্লেখ করা হয়। এটি পর্ব ৪৩-এর মতো সম্ভাবনা-যুক্তির একটি সুন্দর প্রয়োগ।
বাস্তবের ডেলিভারি ব্যবস্থায় ব্যবহারিক সমাধান প্রায়ই মাঝামাঝি: কয়েক সেকেন্ডের অর্ডার জমিয়ে একসঙ্গে offline matching (Hungarian বা flow দিয়ে) চালানো, যাতে অপেক্ষার খরচ আর ভালো জোড়ার লাভ ভারসাম্যে থাকে।
মূল উপলব্ধি: ভবিষ্যৎ না জেনে matching করলে লোভী নিয়ম সর্বোত্তমের অর্ধেক নিশ্চিত করে, আর এলোমেলো RANKING 1 − 1/e; offline-এর সর্বোত্তমতা আর online-এর নিশ্চয়তা দুটি আলাদা প্রশ্ন।
প্র ০৫Perfect matching খোঁজা সহজ, কিন্তু গোনা কঠিন কেন? ৮ × ৮ দাবাবোর্ডে domino বসানোর সংখ্যা এর সঙ্গে কীভাবে যুক্ত?
৮ × ৮ বোর্ডকে ৩২টি domino (প্রতিটি পাশাপাশি দুটি ঘর ঢাকে) দিয়ে ঢাকার প্রতিটি উপায় হলো একটি graph-এর perfect matching: ঘরগুলো vertex, পাশাপাশি দুটি ঘর edge. দাবার রঙ অনুযায়ী graph-টি bipartite (প্রতিটি domino একটি সাদা আর একটি কালো ঘর ঢাকে)। এমন ঢাকার সংখ্যা 12,988,816, যা scratch-এ একটি সরল গণনায় মেলানো হয়েছে। ১৯৬১ সালে Pieter Kasteleyn আর স্বাধীনভাবে Temperley ও Fisher এই ধরনের গণনার সূত্র দেন বলে উল্লেখ করা হয়, পদার্থবিদ্যার “dimer” সমস্যার প্রসঙ্গে।
সাধারণ bipartite graph-এ perfect matching-এর সংখ্যা হলো তার 0-1 matrix-এর permanent: determinant-এর মতোই সব permutation-এর গুণফলের যোগ, শুধু চিহ্ন (±) ছাড়া। অদ্ভুত বিষয়, determinant Gaussian elimination-এ polynomial সময়ে আসে, কিন্তু permanent-এর জন্য এমন কিছু জানা নেই। ১৯৭৯ সালে Leslie Valiant দেখান, permanent গোনা #P-complete: এটি দ্রুত করা গেলে বিপুল সংখ্যক কঠিন গণনা-সমস্যাও দ্রুত হতো। তিনি এই প্রসঙ্গেই #P শ্রেণি সংজ্ঞায়িত করেন। অথচ “অন্তত একটি perfect matching আছে কি?” প্রশ্নটি §৪-এর পদ্ধতিতে polynomial সময়ে উত্তর পায়। অস্তিত্ব আর গণনার এই বিশাল ফারাক জটিলতা তত্ত্বের একটি মৌলিক শিক্ষা।
Kasteleyn-এর কৌশল হলো planar graph-এ edge-এর চিহ্ন এমনভাবে বসানো, যাতে determinant-ই permanent-এর সমান হয়ে যায়; তাই planar graph-এ (যেমন দাবাবোর্ড) গোনা দ্রুত। Planar graph-এর বিস্তারিত পর্ব ৬২ “Planar graph — Euler-এর সূত্র আর Kuratowski”-এ।
আমাদের ছোট উদাহরণগুলো এই ছবিতে বসে: Kn,n-এর সব-1 matrix-এর permanent n!, আর 3-cube Q3-এ perfect matching ৯টি (অনুশীলন ২)। ছোট graph-এ brute force চলে, কিন্তু vertex বাড়লে সংখ্যা বিস্ফোরিত হয়।
মূল উপলব্ধি: Perfect matching আছে কি না তা polynomial সময়ে জানা যায়, কিন্তু কয়টি আছে তা গোনা সাধারণভাবে #P-complete; planar graph-এর মতো বিশেষ গঠনে determinant-এর কৌশল গণনাকে আবার সহজ করে।
অনুশীলন
আগে খাতায় করুন, তারপর উত্তর খুলে মেলান।
-
প্রমাণ: Bipartite graph G-তে (দল L আর R) একটি d ≥ 1 আছে, যাতে L-এর প্রতিটি vertex-এর degree ≥ d আর R-এর প্রতিটি vertex-এর degree ≤ d. প্রমাণ করুন G-তে L saturate করা matching আছে।
- যেকোনো X ⊆ L নিন, আর X আর N(X)-এর মধ্যের edge-সংখ্যা e(X) গুনুন দুইভাবে। — double counting
- X-এর প্রতিটি vertex থেকে অন্তত dটি edge, আর সবাই N(X)-এ যায়: e(X) ≥ d|X|. — L-এর degree
- N(X)-এর প্রতিটি vertex বড়জোর dটি edge পায়: e(X) ≤ d|N(X)|. — R-এর degree
- d|X| ≤ d|N(X)| আর d ≥ 1, তাই |N(X)| ≥ |X|; Hall অনুযায়ী L saturate করা matching আছে। ∎
উপপাদ্য ৬.১ এর বিশেষ ক্ষেত্র (সব degree = k). scratch-এ শর্ত মানা ১০২১টি এলোমেলো ছোট graph-এ দাবিটি brute force-এ মেলানো।
-
গণনা: কয়টি perfect matching আছে (ক) K4,4-এ, (খ) K6-এ, (গ) ৮ vertex-এর cycle C8-এ, (ঘ) 3-cube Q3-এ (vertex 000…111, এক bit আলাদা হলে edge)?
(ক) 4! = 24: L থেকে R-এ bijection. (খ) 5 · 3 · 1 = 15. (গ) 2: প্রথম edge {0, 1} নিলে বাকি সব পালা করে বাঁধা হয়ে যায় ({2, 3}, {4, 5}, {6, 7}), আর না নিলে vertex 0-কে {7, 0} নিতে হয়, তখনও সব বাঁধা। (ঘ) 9: তিনটি “দিক”-এর যেকোনো একটি দিকের সব ৪টি edge নিলে ৩টি matching; বাকিগুলোতে দুই দিক মেশে। Q3-কে দুটি বর্গ (C4) আর তাদের মধ্যের ৪টি “খাড়া” edge ভাবুন: খাড়া edge 0টি নিলে প্রতিটি বর্গে 2টি করে, 2 · 2 = 4; ৪টি নিলে 1; ঠিক ২টি নিলে তারা একটি বর্গের একই পাশের, আর বাকি দুই জোড়া বাধ্যতামূলক: ৪টি পাশ, 4. মোট 4 + 1 + 4 = 9. (ক) থেকে (ঘ) চারটিই scratch-এ সব matching গুনে মেলানো।
-
আউটপুট অনুমান: কোড না চালিয়ে বলুন কী ছাপা হবে, আর matching-টি maximum কি না। তারপর যেকোনো Python-এ চালিয়ে মেলান।
E = [(1, 2), (0, 1), (2, 3), (3, 4), (4, 5)] used, M = set(), [] for a, b in E: if a not in used and b not in used: M.append((a, b)); used |= {a, b} print(len(M), M, sorted(set(range(6)) - used))2 [(1, 2), (3, 4)] [0, 5]Graph-টি path 0–1–2–3–4–5, কিন্তু edge-গুলো এলোমেলো ক্রমে। লোভী কোড (1, 2) নেয়; (0, 1) আর (2, 3) বাদ, কারণ 1 আর 2 ব্যস্ত; (3, 4) নেয়; (4, 5) বাদ। ফল আকার 2-এর maximal matching, free vertex 0 আর 5. এটি maximum নয়: 0–1–2–3–4–5 নিজেই একটি augmenting path (দুই প্রান্ত free, edge পালা করে বাইরে-ভেতরে), উল্টালে {0–1, 2–3, 4–5}, আকার 3 (CPython 3.14-এ চালিয়ে মেলানো)।
-
প্রমাণের ভুল ধরুন: দাবি: “k ≥ 1 হলে প্রতিটি k-regular graph-এ perfect matching আছে।” প্রমাণ: “যেকোনো vertex-সেট X নিন। X থেকে k|X|টি edge বের হয়, আর N(X)-এর প্রতিটি vertex বড়জোর kটি পায়, তাই |N(X)| ≥ |X|. Hall-এর উপপাদ্য অনুযায়ী perfect matching আছে। ∎” ভুল কোথায়? একটি পাল্টা-উদাহরণ দিন।
- পাল্টা-উদাহরণ: ত্রিভুজ K3 2-regular, কিন্তু vertex ৩টি (বিজোড়), তাই perfect matching অসম্ভব। একটি 3-regular উদাহরণও আছে: তিনটি bridge-এ একটি কেন্দ্রে ঝোলানো তিন টুকরোর ১৬-vertex graph, যেখানে কেন্দ্র সরালে তিনটি বিজোড় component (Tutte-এর শর্ত ভাঙে)।
- ভুল ধাপ: Hall-এর উপপাদ্য শুধু bipartite graph-এ, দুই দল L আর R সহ। সাধারণ graph-এ “X থেকে বের হওয়া edge” X-এর ভেতরেও পড়তে পারে (ত্রিভুজে X = সব vertex হলে N(X) = X), আর |N(X)| ≥ |X| থেকে matching আসে না। উপপাদ্যের শর্ত বাদ দেওয়াই ভুল।
- সঠিক কথা: উপপাদ্য ৬.১, যেখানে graph bipartite. সাধারণ graph-এ প্রশ্নটির উত্তর দেয় Tutte-এর উপপাদ্য (§৮), আর bridge-হীন 3-regular graph-এ Petersen-এর ফল।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রম“Augmenting path না থাকলে matching M maximum” প্রমাণের (contrapositive) ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- ধরুন M-এর চেয়ে বড় একটি matching M* আছে
- H = M ⊕ M* নিন; H-এ প্রতিটি vertex-এর degree বড়জোর 2
- তাই H-এর component-গুলো alternating path আর জোড় দৈর্ঘ্যের cycle
- M*-এর edge বেশি বলে একটি path-এ M*-এর edge একটি বেশি
- সেই path-এর দুই প্রান্ত M-free, তাই এটি একটি M-augmenting path
Complete bipartite graph K4,4-এ কয়টি perfect matching আছে?
- 16
- 24
- 8
- 70
Berge-এর উপপাদ্য অনুযায়ী যেকোনো graph-এ একটি matching M কখন maximum?
- যখন M-এ আর কোনো edge যোগ করা যায় না
- যখন প্রতিটি vertex M-এ saturated
- যখন কোনো M-alternating cycle নেই
- যখন কোনো M-augmenting path নেই
Bipartite graph-এ বাঁ দল {A, B, C}, ডান দল {1, 2, 3}; N(A) = {1}, N(B) = {1}, N(C) = {1, 2, 3}. বাঁ দলের সবাইকে আলাদা সঙ্গী দেওয়া যায় কি?
- না, কারণ {A, B}-এর মিলিত প্রতিবেশী মাত্র একজন
- হ্যাঁ, কারণ প্রত্যেকের অন্তত একজন প্রতিবেশী আছে
- হ্যাঁ, কারণ দুই দলের আকার সমান
- হ্যাঁ, কারণ C-এর তিনজন প্রতিবেশী
একটি bipartite graph-এর maximum matching-এ ৫টি edge. তার সবচেয়ে ছোট vertex cover-এ কয়টি vertex?
- 4
- 10
- 5
- graph না জেনে বলা যায় না
n জন প্রস্তাবদাতা আর n জন গ্রহীতার Gale–Shapley algorithm-এর ফল সম্পর্কে কোনটি সত্য?
- প্রত্যেকে, দুই দলেরই, নিজের সবচেয়ে পছন্দের সঙ্গী পান
- প্রত্যেক প্রস্তাবদাতা পান তাঁর সবচেয়ে পছন্দের সম্ভব (কোনো stable matching-এ পাওয়া যায় এমন) সঙ্গী
- প্রস্তাবের ক্রম বদলালে ফল বদলে যায়
- কিছু তালিকায় algorithm কখনো থামে না
কোনো graph-এ একটি maximal matching-এ ৩টি edge. ওই graph-এর maximum matching-এ সর্বোচ্চ কয়টি edge থাকতে পারে?
- 3
- 4
- 9
- 6
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- তিন রকম matching: maximal (আর যোগ হয় না), maximum (সবচেয়ে বড়, আকার ν), perfect (সবাই জোড়া পায়); maximal ≥ ν/2.
- Berge: matching maximum ⇔ কোনো augmenting path নেই; M ⊕ P এক বড়, আর M ⊕ M* ভাঙলে path আর জোড় cycle.
- Hall আর König: bipartite graph-এ |N(X)| ≥ |X| সব X-এ ⇔ L saturate করা matching; ν = τ, আর এ থেকে Dilworth-এর প্রমাণ।
- Regular আর ওজন: k-regular bipartite graph-এ perfect matching আছে, edge kটি perfect matching-এ ভাগ হয়; assignment-এর সর্বোত্তমতা dual নিম্নসীমা দিয়ে প্রমাণ হয়।
- Stable matching: Gale–Shapley থামে, stable, প্রস্তাবদাতার জন্য সেরা; সাধারণ graph-এ Tutte-এর শর্ত আর Edmonds-এর blossom.
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ৬৫ · Tree — ধর্ম, rooted tree আর m-ary tree-এর হিসাবপরবর্তী পর্বমডিউল ১১-এর শুরু: tree-এর ধর্ম আর গণনা।
- পর্ব ৫৬ · Partial order, Hasse diagram, topological sort আর latticeপুনরালোচনাChain, antichain আর Dilworth-এর উপপাদ্যের বক্তব্য।
- পর্ব ৫৯ · Connectivity — path, component, cut vertex আর Menger-এর ধারণাপুনরালোচনাMenger-এর উপপাদ্য, König-এর মতো আরেকটি duality.
- ডিসক্রিট ম্যাথমেটিক্স · কোর্স হোম৮৩টি পর্বপুরো কোর্সের মানচিত্র আর ১৪টি মডিউল।
- DSA · পর্ব ৪৭ · Network flow, min cut আর bipartite matchingকোডে প্রয়োগFlow দিয়ে matching, Hopcroft–Karp আর Hungarian algorithm.
- DSA · পর্ব ৬৪ · P বনাম NP — NP-complete আর reductionকোডে প্রয়োগকোন matching-ধাঁচের সমস্যা সহজ, কোনটি NP-complete.