সরাসরি পর্বে যান
পর্ব ৫৯ · ৮৩-এর মধ্যে · মডিউল ১০

Connectivity — path, component, cut vertex আর Menger-এর ধারণা

Graph Connectivity — Walks, Paths, Components, Bridges, Cut Vertices, Whitney's Inequality and Menger's Theorem

Taught in Bangla, this lesson separates walks, trails and paths and proves every walk contains a path. It treats connected components as equivalence classes, proves the n − m lower bound on components, shows an edge is a bridge exactly when it lies on no cycle, and covers cut vertices, Whitney's inequality κ ≤ λ ≤ δ, Menger's theorem, strong components and distance. In-page Python finds components with BFS and union-find, tests bridges against cycles and checks Whitney and Menger on small graphs.

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

  • Walk, trail, path, circuit আর cycle-এর নির্ভুল সংজ্ঞা, আর walk থেকে path বের করার প্রমাণ
  • Connected component-কে equivalence class হিসেবে দেখা, আর edge-সংখ্যার দুটি সীমা (n − 1 আর C(n − 1, 2)) প্রমাণসহ
  • Bridge আর cut vertex চেনা, “bridge ⇔ কোনো cycle-এ নেই” উপপাদ্যের দুই দিকের প্রমাণ
  • κ ≤ λ ≤ δ-এর প্রমাণ, Menger-এর উপপাদ্যের দুই রূপ আর max-flow min-cut-এর সঙ্গে সম্পর্ক
  • Strongly connected component, distance, diameter, adjacency matrix-এর ঘাত আর BFS-এর সঠিকতা

১ · Walk, trail আর path — “পৌঁছানো যায়” কথার নির্ভুল ভাষা

বাজারঘরের একজন রাইডার সাভারের গুদাম থেকে কেরানীগঞ্জে একটি পার্সেল নিয়ে যাবেন। তিনি পথে কোনো মোড় দুবার পার হতে পারেন, একই রাস্তা দুবার ধরতে পারেন; তবু তিনি পৌঁছান। প্রশ্ন হলো: “পৌঁছানো যায়” বললে আমরা ঠিক কী দাবি করি, আর কখন বলতে পারি “সবচেয়ে ছোট রাস্তায় কোনো মোড় দুবার আসে না”?

এই পর্বে graph মানে সাধারণত undirected simple graph G = (V, E): vertex-এর একটি সসীম সেট V আর edge-এর সেট E, যেখানে প্রতিটি edge দুটি আলাদা vertex-এর একটি জোড়া {u, v}। Loop বা একই জোড়ার একাধিক edge (multigraph) যেখানে চলে, সেখানে আলাদা করে বলা আছে। সংজ্ঞাগুলোর বিস্তারিত পর্ব ৫৭ “গ্রাফ — সংজ্ঞা, degree আর handshake theorem”-এ। নিচের সংজ্ঞায় v0, v1, …, vk এমন vertex-ক্রম, যার পরপর প্রতিটি জোড়া {vi−1, vi} একটি edge; k হলো তার দৈর্ঘ্য (edge-এর সংখ্যা)।

নামvertex ফিরতে পারে?edge ফিরতে পারে?শুরু = শেষ?
walkহ্যাঁহ্যাঁযেকোনো (হলে closed walk)
trailহ্যাঁনাযেকোনো
pathনানানা (k ≥ 1 হলে)
circuit (closed trail)হ্যাঁনাহ্যাঁ, k ≥ 1
cycleশুধু শুরু = শেষনাহ্যাঁ, simple graph-এ k ≥ 3

সাবধান: বইভেদে নাম বদলায়। কোনো বইয়ে “path” মানে আমাদের walk, আর আমাদের path-কে বলে “simple path”. পরীক্ষায় উত্তর লেখার আগে কোন সংজ্ঞা ব্যবহার করছেন, তা এক লাইনে লিখে নিন। এখানে দৈর্ঘ্য ০-এর walk (শুধু একটি vertex v0) বৈধ, আর তা একটি path.

বাজারঘরের ডেলিভারি নেটওয়ার্ক (নামগুলো শুধু লেবেল)

৭টি হাব, ৮টি রাস্তা। লাল ড্যাশ রেখা bridge, হলুদ vertex cut vertex; দুটিই §৪-এ প্রমাণসহ বের হবে।

Delivery graph with seven hubs: two triangles joined through bridges S–M and G–T; cut vertices M, G and T SMU GTDK সাভারমিরপুরউত্তরা গুলশানমতিঝিলধানমন্ডিকেরানীগঞ্জ bridge cut vertex
উপপাদ্য ১.১ (walk-এর ভেতরে path)

যেকোনো graph-এ (multigraph-এও) u থেকে v-তে একটি walk W থাকলে u থেকে v-তে একটি path আছে, যার প্রতিটি edge W-এর edge. বিশেষ করে u–v-এর সবচেয়ে ছোট walk সবসময় একটি path, তাই তার দৈর্ঘ্য ≤ n − 1.

  1. W-এর edge দিয়ে গঠিত সব u–v walk-এর সংগ্রহ খালি নয় (W নিজেই আছে)। দৈর্ঘ্যগুলো অঋণাত্মক পূর্ণসংখ্যা, তাই সবচেয়ে ছোট দৈর্ঘ্যের একটি walk P = (u = v0, …, vk = v) আছে। — well-ordering, পর্ব ১১
  2. ধরুন P-তে কোনো vertex দুবার আছে: vi = vj, i < j. — বিরোধের জন্য অনুমান
  3. মাঝের অংশ vi+1, …, vj বাদ দিলে v0, …, vi, vj+1, …, vk আবার একটি u–v walk, কারণ vi = vj আর {vj, vj+1} একটি edge. এর edge-গুলো W-এর, আর দৈর্ঘ্য k − (j − i) < k. — লুপ কাটা
  4. এটি P-এর ন্যূনতমতার বিরোধী, তাই P-তে কোনো vertex ফেরে না: P একটি path. Path-এর vertex সব আলাদা, তাই k + 1 ≤ n. ∎ — বিরোধ

প্রমাণটি আসলে একটি algorithm-ও: প্রথম পুনরাবৃত্ত vertex খুঁজুন, মাঝের লুপ কাটুন, আবার করুন। প্রতিবার দৈর্ঘ্য কমে, তাই কাজটি থামে। নিচের stepper ডেলিভারি graph-এর একটি ১০-edge walk থেকে এভাবে path বের করে।

1W = S M U G M G T D K T D2প্রথম পুনরাবৃত্তি: M3M … M লুপ কাটা4পরের পুনরাবৃত্তি: T5T … T লুপ কাটা
সাভার S থেকে ধানমন্ডি D
ক্রম
দৈর্ঘ্য
ফেরে
  1. শুরু। রাইডারের walk S, M, U, G, M, G, T, D, K, T, D: পরপর প্রতিটি জোড়া একটি রাস্তা, মোট ১০টি edge. M, G, T আর D একাধিকবার এসেছে, আর G–M রাস্তাটি দুবার ব্যবহার হয়েছে, তাই এটি trail-ও নয়।
  2. প্রথম পুনরাবৃত্ত vertex. বাঁ থেকে পড়লে প্রথম যে vertex আগে দেখা গেছে, তা M: স্থান 1 আর 4. মাঝের অংশ U, G, M একটি closed walk, যা কোথাও এগোয় না।
  3. লুপ কাটা। স্থান 2 থেকে 4 বাদ দিলে S, M, G, T, D, K, T, D. M–G একটি edge, তাই এটি এখনো বৈধ walk; দৈর্ঘ্য 10 থেকে 7.
  4. পরের পুনরাবৃত্তি। নতুন ক্রমে প্রথম ফেরা vertex T: স্থান 3 আর 6. মাঝে D, K, T আরেকটি ঘোরা। (D-ও ফেরে, কিন্তু এই কাটায় সেটিও চলে যাবে।)
  5. Path. কাটার পর S, M, G, T, D: দৈর্ঘ্য 4, কোনো vertex দুবার নেই। প্রতিটি edge মূল walk-এরই edge. প্রতিটি কাটায় দৈর্ঘ্য অন্তত ১ কমে, তাই প্রক্রিয়া সবসময় থামে, ঠিক উপপাদ্য ১.১-এর যুক্তি।

২ · Connected graph আর component — একটি equivalence relation

G-এর vertex-এর ওপর সম্পর্ক সংজ্ঞায়িত করুন: u ~ v ⇔ G-তে u থেকে v-তে একটি walk আছে (উপপাদ্য ১.১ অনুযায়ী, সমতুল্যভাবে একটি path আছে)।

উপপাদ্য ২.১ (component = equivalence class)

~ একটি equivalence relation. এর প্রতিটি equivalence class-এর ওপর induced subgraph-কে বলে G-এর একটি connected component. G connected যদি এবং কেবল যদি component ঠিক একটি।

  1. Reflexive: দৈর্ঘ্য ০-এর walk (v) v থেকে v-তে যায়। — ০-দৈর্ঘ্যের walk বৈধ
  2. Symmetric: u থেকে v-এর walk উল্টো ক্রমে পড়লে v থেকে u-এর walk, কারণ edge-এর দিক নেই। — undirected
  3. Transitive: u থেকে v আর v থেকে w-এর walk পরপর জুড়লে u থেকে w-এর walk. ∎ — জোড়া লাগানো

ধাপ ৩-এ walk দরকার, path নয়: দুটি path জুড়লে vertex ফিরতে পারে, ফলে তা path না-ও হতে পারে। এই কারণেই সংজ্ঞায় walk নেওয়া সুবিধাজনক। পর্ব ৫৫ “Equivalence relation আর partition”-এর মৌলিক উপপাদ্য অনুযায়ী component-গুলো V-কে ভাগ করে, আর প্রতিটি component সবচেয়ে বড় connected subgraph: তাতে আরেকটি vertex যোগ করলে আর connected থাকে না। Relation-এর ভাষায় ~ হলো edge-relation-এর reflexive-transitive closure, যার connectivity relation R* আর Warshall-এর হিসাব পর্ব ৫৪-এ আছে।

হিসাবের দুটি সহজ পথ। এক, প্রতিটি না-দেখা vertex থেকে BFS চালানো, প্রতিবার যত vertex পৌঁছায় সেটাই একটি component. দুই, edge একটি একটি করে নিয়ে union-find দিয়ে দুই প্রান্তের দল জোড়া, পর্ব ৫৫-এর equivalence closure. নিচের ব্লক ৩০০টি এলোমেলো graph-এ দুই পদ্ধতির উত্তর মেলায়, আর পরের অংশের উপপাদ্য ৩.১-ও পরীক্ষা করে। প্রথমবার চালালে ব্রাউজারে Python (Pyodide) নামতে কয়েক সেকেন্ড লাগে।

import random; from collections import deque
def bfs_components(n, adj):            # comp[v] = number of v's component
    comp, c = [-1] * n, 0
    for s in range(n):
        if comp[s] == -1:
            comp[s] = c; q = deque([s])
            while q:
                x = q.popleft()
                for y in adj[x]:
                    if comp[y] == -1:
                        comp[y] = c; q.append(y)
            c += 1
    return comp, c
def uf_roots(n, edges):                # union-find: root = class name
    parent = list(range(n))
    def find(x):
        while parent[x] != x:
            parent[x] = parent[parent[x]]; x = parent[x]
        return x
    for u, v in edges:
        parent[find(u)] = find(v)
    return [find(x) for x in range(n)]
random.seed(59); equal = 0
for trial in range(300):
    n = random.randint(1, 15)
    pairs = [(random.randrange(n), random.randrange(n)) for _ in range(n)]
    edges = [(u, v) for u, v in pairs if u != v]     # no loops
    adj = [[] for _ in range(n)]
    for u, v in edges: adj[u].append(v); adj[v].append(u)
    comp, c = bfs_components(n, adj); root = uf_roots(n, edges)
    assert all((comp[i] == comp[j]) == (root[i] == root[j])
               for i in range(n) for j in range(n))
    assert c >= n - len(edges)                       # theorem 3.1
    equal += (c == n - len(edges))
print("300 random graphs: BFS == union-find, c >= n - m; equality in", equal)

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

300 random graphs: BFS == union-find, c >= n - m; equality in 72

প্রতিটি graph-এ প্রতিটি জোড়া (i, j)-এর জন্য “একই component” প্রশ্নে দুই পদ্ধতি একমত; একটিও assert ব্যর্থ হয়নি। এলোমেলো জোড়ায় একই edge দুবার আসতে পারে, তাই এগুলো আসলে multigraph, আর উপপাদ্য ৩.১ সেখানেও খাটে। ৩০০টির মধ্যে ৭২টিতে সমতা c = n − m হয়েছে; §৩-এর প্রমাণ দেখায়, সমতা ঠিক তখন যখন graph-এ কোনো cycle নেই (একটি forest, মডিউল ১১-এর পর্ব ৬৫ “Tree — ধর্ম, rooted tree আর m-ary tree-এর হিসাব”-এর বিষয়)। কোডের বিস্তারিত DSA কোর্সের পর্ব ৪০ আর পর্ব ৩৩-এ।

৩ · কয়টি edge লাগে — n − 1 আর C(n − 1, 2)-এর সীমা

বাজারঘর নতুন ১০টি হাব খুলবে। সবগুলোকে জুড়তে কমপক্ষে কয়টি রাস্তা লাগবে? আর উল্টো প্রশ্ন: এলোমেলোভাবে কতগুলো রাস্তা বানালে connected হওয়া নিশ্চিত? দুটি প্রশ্নের উত্তর দুটি উপপাদ্য।

উপপাদ্য ৩.১ (component-এর নিম্নসীমা)

n vertex আর m edge-এর যেকোনো graph-এ (multigraph আর loop-সহ) component-এর সংখ্যা c(G) ≥ n − m. ফলে connected graph-এ m ≥ n − 1.

প্রমাণ (m-এর ওপর induction, পর্ব ১০):

  1. ভিত্তি m = 0: কোনো edge নেই, প্রতিটি vertex নিজেই একটি component, c = n = n − 0. — base case
  2. ধরুন m − 1টি edge-এর সব graph-এ দাবি সত্য (m ≥ 1). এখন m edge-এর যেকোনো graph G নিন, আর তার যেকোনো একটি edge e = {u, v} সরিয়ে G − e বানান। G − e-তে m − 1টি edge, তাই c(G − e) ≥ n − m + 1. — inductive hypothesis
  3. e ফিরিয়ে দিলে শুধু u আর v-এর component বদলাতে পারে: তারা G − e-তে একই component-এ থাকলে কিছু বদলায় না, আলাদা থাকলে দুটি component এক হয়। তাই c(G) ≥ c(G − e) − 1. — একটি edge দুটির বেশি component জোড়ে না
  4. মিলিয়ে c(G) ≥ n − m + 1 − 1 = n − m. Connected মানে c = 1, তাই 1 ≥ n − m, অর্থাৎ m ≥ n − 1. ∎

লক্ষ করুন ধাপ ২-এর দিক: আমরা m edge-এর একটি যেকোনো graph থেকে শুরু করে ছোট graph-এ নেমেছি। উল্টো পথে, অর্থাৎ m − 1 edge-এর graph-এ একটি edge “যোগ করে” সব m-edge graph পাওয়া গেছে ধরে নেওয়া graph-এর induction-এর সবচেয়ে পরিচিত ভুল; অনুশীলন ৪-এ এমন একটি ভুল প্রমাণ আছে। এখানে সমস্যা নেই, কারণ যেকোনো G-এর ক্ষেত্রেই G − e একটি বৈধ ছোট graph.

উপপাদ্য ৩.২ (connected হওয়া নিশ্চিত)

n ≥ 2 vertex-এর simple graph-এ m > C(n − 1, 2) হলে G connected. সীমাটি নিখুঁত: Kn−1-এর সঙ্গে একটি একা vertex, যাতে ঠিক C(n − 1, 2)টি edge, connected নয়।

  1. ধরুন G connected নয়। একটি component-এর vertex-সেট X নিন, |X| = k, আর Y = V − X; তাহলে 1 ≤ k ≤ n − 1, আর X ও Y-এর মধ্যে কোনো edge নেই। — বিরোধের জন্য অনুমান
  2. সব edge হয় X-এর ভেতরে, নয়তো Y-এর ভেতরে, আর simple graph-এ k vertex-এর ভেতরে সর্বোচ্চ C(k, 2)টি edge থাকে। তাই m ≤ C(k, 2) + C(n − k, 2). — simple graph-এ প্রতিটি জোড়ায় সর্বোচ্চ একটি edge
  3. বীজগণিত: C(n − 1, 2) − C(k, 2) − C(n − k, 2) = (k − 1)(n − k − 1) ≥ 0, কারণ 1 ≤ k ≤ n − 1. — দুই পাশ খুলে মেলানো
  4. তাই m ≤ C(n − 1, 2), যা অনুমান m > C(n − 1, 2)-এর বিরোধী। ∎

ধাপ ৩ একটি সুন্দর তথ্য দেয়: (k − 1)(n − k − 1) শূন্য হয় শুধু k = 1 বা k = n − 1-এ, অর্থাৎ disconnected graph-এ সবচেয়ে বেশি edge থাকে যখন একটি vertex একা আর বাকিরা পূর্ণ graph. ১০টি হাবে উত্তর তাই: connected হতে কমপক্ষে ৯টি রাস্তা লাগে, কিন্তু রাস্তার সংখ্যা ছাড়া আর কিছু না জানলে connected নিশ্চিত হতে চাই C(9, 2) + 1 = 37টি। দুই সংখ্যার বিশাল ফারাক দেখায়, edge-এর সংখ্যা একা connectivity-র দুর্বল নির্দেশক; কোথায় edge আছে সেটাই আসল কথা।

৪ · Bridge আর cut vertex — নেটওয়ার্কের দুর্বল জায়গা

ডেলিভারি নেটওয়ার্কে কোন একটি রাস্তা বন্ধ হলে কিছু হাব বিচ্ছিন্ন হয়ে যায়? কোন একটি হাব বন্ধ হলে? এই প্রশ্নগুলোর নাম:

সংজ্ঞা ৪.১ (bridge আর cut vertex)

G-এর একটি edge e bridge (cut edge), যদি G − e-তে component-এর সংখ্যা G-এর চেয়ে বেশি। একটি vertex v cut vertex (articulation point), যদি G − v-তে (v আর তার সব edge সরিয়ে) component-এর সংখ্যা G-এর চেয়ে বেশি।

সংজ্ঞা অনুযায়ী bridge খুঁজতে প্রতিটি edge সরিয়ে component গুনতে হয়। কিন্তু একটি পরিষ্কার চরিত্র-বর্ণনা আছে, যা হাতে-কলমে অনেক দ্রুত।

উপপাদ্য ৪.২ (bridge ⇔ কোনো cycle-এ নেই)

Simple graph G-এর একটি edge e = {u, v} bridge যদি এবং কেবল যদি e, G-এর কোনো cycle-এ না থাকে।

  1. Lemma: e bridge ⇔ G − e-তে কোনো u–v path নেই। G − e-তে u–v path P থাকলে G-এর যেকোনো walk-এ e-এর জায়গায় P বসানো যায়, তাই “একই component” সম্পর্ক বদলায় না আর e bridge নয়। আর P না থাকলে u, v G-তে একই component-এ কিন্তু G − e-তে আলাদা; G − e-এর component-গুলো G-এর component ভেঙে আসে, তাই সংখ্যা বাড়ে। — উপপাদ্য ২.১
  2. (⇐ দিক, contrapositive) ধরুন e কোনো cycle u, v, w1, …, wr, u-তে আছে। e বাদ দিলে v, w1, …, wr, u একটি u–v path যাতে e নেই। Lemma অনুযায়ী e bridge নয়। — cycle থেকে বিকল্প পথ
  3. (⇒ দিক, contrapositive) ধরুন e bridge নয়। Lemma অনুযায়ী G − e-তে একটি u–v walk, আর উপপাদ্য ১.১ অনুযায়ী একটি u–v path P = (u, …, v). P-তে e নেই, আর G simple বলে u–v-এর একমাত্র edge e, তাই P-এর দৈর্ঘ্য ≥ 2. P-এর শেষে e জুড়লে কোনো vertex না ফিরিয়ে u-তে ফেরা যায়: একটি cycle যাতে e আছে। ∎ — path + edge = cycle

ডেলিভারি graph-এ উপপাদ্যটি কীভাবে কাজ করে, তা নিচের stepper-এ দেখুন। প্রতিটি edge-এর জন্য প্রশ্ন একটাই: এটি কোনো ত্রিভুজ বা অন্য cycle-এ আছে কি?

1V = {S,M,U,G,T,D,K}, ৮টি edge2S–M: কোনো cycle-এ?3M–U, U–G, G–M4G–T: কোনো cycle-এ?5T–D, D–K, K–T6ফল: bridge আর cut vertex
G − e-তে component
পরীক্ষা
component
bridge
  1. Graph. ৭টি হাব আর ৮টি রাস্তা: S–M, M–U, U–G, G–M, G–T, T–D, D–K, K–T. graph connected, তাই component ১টি।
  2. S–M. deg(S) = 1, তাই S দিয়ে কোনো cycle যায় না (cycle-এর প্রতিটি vertex-এ দুটি edge লাগে)। উপপাদ্য ৪.২ অনুযায়ী bridge; সরালে {S} আলাদা হয়, component ২টি।
  3. প্রথম ত্রিভুজ। M–U, U–G আর G–M তিনটিই cycle M, U, G, M-এ আছে। যেকোনো একটি সরালে বাকি দুটি দিয়ে ঘুরে যাওয়া যায়: কোনোটিই bridge নয়।
  4. G–T. G থেকে T-তে G–T ছাড়া আর কোনো পথ নেই, কারণ বাঁ দিকের {S, M, U, G} আর ডান দিকের {T, D, K}-এর মধ্যে এটিই একমাত্র edge. তাই এটি কোনো cycle-এ নেই: bridge, সরালে দুই দল।
  5. দ্বিতীয় ত্রিভুজ। T–D, D–K, K–T সবাই cycle T, D, K, T-এ আছে, তাই bridge নয়।
  6. ফল। Bridge ঠিক দুটি: S–M আর G–T. Cut vertex: M (সরালে S একা), G আর T (সরালে দুই ত্রিভুজ আলাদা)। S cut vertex নয়: তার degree 1, তাকে সরালেও বাকিরা connected. বাস্তবে বাজারঘরের জন্য শিক্ষা: S–M আর G–T-এর পাশে একটি বিকল্প রাস্তা থাকলে একটি রাস্তা বন্ধ হলেও কোনো হাব বিচ্ছিন্ন হয় না।

Cut vertex-এর জন্যও একই ধাঁচের তথ্য আছে। দুটি দরকারি কথা, সংক্ষিপ্ত প্রমাণসহ:

  • Bridge-এর প্রান্ত: connected G-তে bridge {u, v}-এর প্রান্ত u-এর degree ≥ 2 হলে u একটি cut vertex. কারণ: u-এর আরেক প্রতিবেশী w নিন; w থেকে v-তে u এড়িয়ে কোনো path থাকলে তার সঙ্গে v–u–w জুড়ে e-যুক্ত একটি cycle হতো, যা উপপাদ্য ৪.২-এর বিরোধী। তাই G − u-তে w আর v আলাদা component-এ।
  • সবাই cut vertex হতে পারে না: অন্তত ২টি vertex-এর connected graph-এ অন্তত দুটি vertex cut vertex নয়। কারণ: সবচেয়ে লম্বা path v0, …, vk নিন। v0-এর সব প্রতিবেশী এই path-এর ওপর (নইলে path আরও লম্বা করা যেত)। তাই কোনো walk v0 দিয়ে গেলে ঢোকা আর বের হওয়ার দুই প্রতিবেশীকে path-এর বাকি অংশ দিয়েই জোড়া যায়, v0 বাদ দিয়ে। একই যুক্তি vk-এর জন্য।

নিচের ব্লক উপপাদ্য ৪.২ একেবারে আলাদা পথে পরীক্ষা করে। “Bridge” বের হয় সংজ্ঞা থেকে (edge সরিয়ে component গোনা), আর “কোনো cycle-এ আছে” বের হয় সব edge-সেট খুঁজে: একটি edge-সেট একটি cycle যদি তার প্রতিটি vertex-এর degree ঠিক ২ আর সেটটি connected.

import random
from itertools import combinations
def n_comps(V, E):                     # count components by search
    adj = {v: set() for v in V}
    for u, v in E:
        adj[u].add(v); adj[v].add(u)
    seen, c = set(), 0
    for s in V:
        if s not in seen:
            c += 1; stack = [s]; seen.add(s)
            while stack:
                for y in adj[stack.pop()] - seen:
                    seen.add(y); stack.append(y)
    return c
def is_cycle(F):                       # edge set = one cycle?
    deg = {}
    for u, v in F:
        deg[u] = deg.get(u, 0) + 1; deg[v] = deg.get(v, 0) + 1
    return all(d == 2 for d in deg.values()) and n_comps(list(deg), F) == 1
random.seed(59)
stats = [0, 0, 0]                      # edges, bridges, cut vertices
for trial in range(150):
    V = list(range(6))
    E = [e for e in combinations(V, 2) if random.random() < 0.4]
    c = n_comps(V, E); stats[0] += len(E)
    for e in E:                        # bridge <=> on no cycle
        bridge = n_comps(V, [f for f in E if f != e]) > c
        on_cycle = any(is_cycle(F) for k in range(3, 7)
                       for F in combinations(E, k) if e in F)
        assert bridge == (not on_cycle); stats[1] += bridge
    for v in V:                        # cut vertex: removal splits
        W = [x for x in V if x != v]
        stats[2] += n_comps(W, [f for f in E if v not in f]) > c
print("edges, bridges, cut vertices:", stats)
print("every bridge is on no cycle, every non-bridge on a cycle")

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

edges, bridges, cut vertices: [867, 290, 207]
every bridge is on no cycle, every non-bridge on a cycle

১৫০টি এলোমেলো ৬-vertex graph-এর মোট ৮৬৭টি edge-এর প্রতিটিতে দুই উত্তর মিলেছে: ২৯০টি bridge-এর কোনোটি কোনো cycle-এ নেই, আর বাকি ৫৭৭টির প্রতিটি অন্তত একটি cycle-এ আছে। ৬টি vertex-এ cycle-এর দৈর্ঘ্য ৩ থেকে ৬, তাই শুধু সেই আকারের edge-সেট দেখা যথেষ্ট। এই brute force প্রতিটি edge-এ প্রায় 2m কাজ করে; বড় graph-এ চলে না। DFS-ভিত্তিক “low-link” পদ্ধতি সব bridge আর cut vertex একবারে O(n + m) সময়ে দেয়, যার কোড DSA কোর্সের পর্ব ৪৬-এ।

৫ · কতটা মজবুত — κ, λ, δ আর Whitney-এর অসমতা

Bridge বা cut vertex থাকা মানে একটি ব্যর্থতাতেই নেটওয়ার্ক ভাঙে। কিন্তু দুটি রাস্তা একসঙ্গে বন্ধ হলে? “কতগুলো ব্যর্থতা সহ্য করা যায়” তা মাপার জন্য দুটি সংখ্যা।

সংজ্ঞা ৫.১ (connectivity-র মাপ)
  • Vertex connectivity κ(G): সবচেয়ে কম কয়টি vertex সরালে G disconnected হয় বা একটিমাত্র vertex থাকে। প্রথা: κ(Kn) = n − 1. এমন vertex-সেটকে বলে vertex cut.
  • Edge connectivity λ(G): সবচেয়ে কম কয়টি edge সরালে G disconnected হয় (একটি vertex-এর graph-এ λ = 0). এমন edge-সেট একটি edge cut.
  • Minimum degree δ(G): সবচেয়ে ছোট degree. G k-connected যদি κ(G) ≥ k, আর k-edge-connected যদি λ(G) ≥ k.

ডেলিভারি graph-এ κ = λ = δ = 1 (S-এর degree 1, M একটি cut vertex, S–M একটি bridge). Kn-এ তিনটিই n − 1. তিনটির সম্পর্ক সবসময় একই দিকে:

উপপাদ্য ৫.২ (Whitney-এর অসমতা)

অন্তত ২টি vertex-এর যেকোনো simple graph-এ κ(G) ≤ λ(G) ≤ δ(G).

  1. λ ≤ δ: সবচেয়ে ছোট degree-র vertex v-এর δটি edge সরালে v একা হয়ে যায়, আর বাকি অন্তত একটি vertex আছে, তাই graph disconnected. — একটি সরাসরি edge cut
  2. κ ≤ λ, সহজ ক্ষেত্র: G disconnected হলে দুটিই 0. এখন ধরুন G connected, আর F একটি সবচেয়ে ছোট edge cut, |F| = λ। G − F-এর vertex-গুলোকে দুই ভাগ X আর Y-তে সাজান, যাতে X থেকে Y-এ যাওয়া প্রতিটি edge F-এ থাকে। — সংজ্ঞা
  3. যদি X-এর প্রতিটি vertex Y-এর প্রতিটির সঙ্গে যুক্ত হয়, তবে |F| ≥ |X|·|Y| ≥ n − 1 (দুটি ধনাত্মক পূর্ণসংখ্যার যোগফল n হলে গুণফল ≥ n − 1). আর যেকোনো graph-এ κ ≤ n − 1, তাই κ ≤ λ। — পূর্ণ দ্বিভাগ
  4. নইলে x ∈ X আর y ∈ Y আছে যারা সংলগ্ন নয়। F-এর প্রতিটি edge থেকে একটি প্রান্ত বাছুন: edge-টি x-কে না ছুঁলে তার X-প্রান্ত, ছুঁলে তার Y-প্রান্ত। বাছাই করা vertex-গুলোর সেট S; |S| ≤ |F|, আর S-এ x নেই, y-ও নেই (x আর y সংলগ্ন নয় বলে x-এর কোনো edge y-তে যায় না)। — প্রতিটি cut edge থেকে একটি প্রান্ত
  5. যেকোনো x–y path-কে X থেকে Y-এ যেতে F-এর কোনো edge ধরতে হয়, আর সেই edge-এর বাছাই করা প্রান্ত path-এর ওপর আছে। তাই G − S-এ x থেকে y-তে path নেই, G − S disconnected, আর κ ≤ |S| ≤ λ। ∎ — প্রতিটি পথ আটকানো

অসমতা দুটি কঠোরও হতে পারে। দুটি আলাদা K4 নিন (a1–a4 আর b1–b4), আর a1–b1, a1–b2 দুটি edge জুড়ুন। a1 সরালে দুই দল আলাদা, তাই κ = 1; দুই দলের মধ্যে দুটি edge, তাই λ = 2; আর সবচেয়ে ছোট degree 3, তাই δ = 3. নিচের ব্লক এই উদাহরণ আর ২০০টি এলোমেলো graph-এ brute force দিয়ে তিনটি সংখ্যা বের করে।

import random
from itertools import combinations
def connected(V, E):
    seen, stack = {V[0]}, [V[0]]
    while stack:
        x = stack.pop()
        for u, v in E:
            for a, b in ((u, v), (v, u)):
                if a == x and b not in seen:
                    seen.add(b); stack.append(b)
    return len(seen) == len(V)
def kld(V, E):                         # brute force kappa, lambda, delta
    delta = min(sum(v in e for e in E) for v in V)
    lam = next(k for k in range(len(E) + 1) if any(not connected(V,
               [e for e in E if e not in S]) for S in combinations(E, k)))
    if len(E) == len(V) * (len(V) - 1) // 2:
        return len(V) - 1, lam, delta  # complete graph: kappa = n - 1
    kap = next(k for k in range(len(V)) if any(not connected(
               [v for v in V if v not in S],
               [e for e in E if not set(e) & set(S)])
               for S in combinations(V, k)))
    return kap, lam, delta
a, b = ["a1", "a2", "a3", "a4"], ["b1", "b2", "b3", "b4"]
E = list(combinations(a, 2)) + list(combinations(b, 2))
E += [("a1", "b1"), ("a1", "b2")]               # two edges join the K4s
print("two K4 + 2 edges:", kld(a + b, E))
random.seed(59); gaps = [0, 0]
for trial in range(200):
    V = list(range(random.randint(2, 7)))
    E = [e for e in combinations(V, 2) if random.random() < 0.6]
    k, l, d = kld(V, E)
    assert k <= l <= d                 # Whitney's inequality
    gaps[0] += k < l; gaps[1] += l < d
print("200 random graphs: kappa <= lambda <= delta; kappa < lambda in",
      gaps[0], "graphs, lambda < delta in", gaps[1])

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

two K4 + 2 edges: (1, 2, 3)
200 random graphs: kappa <= lambda <= delta; kappa < lambda in 5 graphs, lambda < delta in 1

প্রথম লাইন হাতের হিসাব (κ, λ, δ) = (1, 2, 3) মিলিয়েছে। দ্বিতীয় লাইনে ২০০টি graph-এর একটিতেও অসমতা ভাঙেনি; তবে এলোমেলো ছোট graph-এ তিনটি সংখ্যা প্রায় সবসময় সমান, κ < λ মাত্র ৫টিতে আর λ < δ মাত্র ১টিতে। অর্থাৎ পাল্টা-উদাহরণ এলোমেলোভাবে খুঁজলে প্রায় পাওয়া যায় না, পরিকল্পনা করে বানাতে হয়। কোডটি সব vertex-সেট আর edge-সেট দেখে, তাই ২০-৩০টি edge-এর ওপরে অচল; বাস্তবে κ আর λ বের হয় max-flow দিয়ে (পরের অংশ)।

৬ · Menger-এর উপপাদ্য — আলাদা পথ গোনা আর পথ কাটা একই সংখ্যা

দুটি নির্দিষ্ট vertex s আর t-এর কথা ভাবুন: সাভারের গুদাম থেকে একটি গ্রাহক-এলাকা। “কতটা মজবুত সংযোগ” দুইভাবে মাপা যায়। এক, এমন কয়টি পথ আছে যারা মাঝপথে কোনো vertex ভাগ করে না, যাতে একটি হাব বন্ধ হলে বড়জোর একটি পথ নষ্ট হয়? দুই, s থেকে t আলাদা করতে সবচেয়ে কম কয়টি হাব বন্ধ করতে হয়?

সংজ্ঞা ৬.১

s–t path-গুলো internally disjoint, যদি s আর t ছাড়া কোনো দুটি path-এর মধ্যে কোনো সাধারণ vertex না থাকে। s আর t সংলগ্ন না হলে একটি s–t separator হলো এমন vertex-সেট S (s, t বাদে), যা সরালে s থেকে t-তে কোনো path থাকে না।

উপপাদ্য ৬.২ (Menger, দুই রূপ)

Vertex রূপ: G-এর দুটি আলাদা, অসংলগ্ন vertex s আর t-এর জন্য internally disjoint s–t path-এর সর্বোচ্চ সংখ্যা = সবচেয়ে ছোট s–t separator-এর আকার।
Edge রূপ: যেকোনো দুটি আলাদা vertex s আর t-এর জন্য edge-disjoint s–t path-এর সর্বোচ্চ সংখ্যা = s থেকে t আলাদা করার সবচেয়ে ছোট edge-সেটের আকার।

সহজ দিকের প্রমাণ (সর্বোচ্চ ≤ সর্বনিম্ন):

  1. k-টি internally disjoint s–t path আর যেকোনো s–t separator S নিন। S সরালে কোনো path থাকে না, তাই প্রতিটি path-এর মাঝখানের (s, t নয় এমন) অন্তত একটি vertex S-এ আছে। — separator-এর সংজ্ঞা
  2. Path-গুলোর মাঝখানের vertex পরস্পর আলাদা, তাই এই k-টি vertex-ও আলাদা, আর |S| ≥ k. সব path-সংগ্রহ আর সব separator-এ এটি খাটে, তাই সর্বোচ্চ ≤ সর্বনিম্ন। ∎ — প্রতিটি পথে একটি আলাদা প্রতিনিধি

কঠিন দিক (সবচেয়ে ছোট separator-এর আকারের সমান সংখ্যক path সত্যিই পাওয়া যায়) এখানে প্রমাণ করা হলো না। একটি পথ হলো edge-গুলোকে capacity 1 দিয়ে একটি flow network বানিয়ে max-flow min-cut theorem প্রয়োগ করা (vertex রূপে প্রতিটি vertex-কে “ঢোকা” আর “বের হওয়া” দুই ভাগে ভেঙে মাঝে capacity 1-এর edge), যার algorithm আর প্রমাণ DSA কোর্সের পর্ব ৪৭-এ। Menger-এর উপপাদ্য ১৯২৭ সালের বলে সাধারণত উল্লেখ করা হয়, max-flow min-cut-এর প্রায় তিন দশক আগে; সরাসরি induction-ভিত্তিক প্রমাণ প্রায় সব graph theory পাঠ্যবইয়ে আছে।

Menger যাচাইয়ের graph: s থেকে t

s আর t সংলগ্ন নয়। হলুদ vertex d আর e একটি সবচেয়ে ছোট separator.

Menger example: s joined to a, b, c; a–b, a–d, b–d, c–e, d–t, e–t; separator {d, e} sabc det
1সব s–t path তালিকা2প্রথম পথ বাছাই3দ্বিতীয় পথ, d আর a এড়িয়ে4তৃতীয় পথ সম্ভব?5separator খোঁজা
s থেকে t, s আর t অসংলগ্ন
পথ
separator
সংখ্যা
  1. সব path. Edge: s–a, s–b, s–c, a–b, a–d, b–d, c–e, d–t, e–t. s থেকে t-এর simple path ঠিক ৫টি: s-a-d-t, s-b-d-t, s-a-b-d-t, s-b-a-d-t আর s-c-e-t.
  2. প্রথম পথ। s-a-d-t নিন; এর মাঝের vertex a আর d. এখন অন্য কোনো পথ a বা d ব্যবহার করতে পারবে না।
  3. দ্বিতীয় পথ। s-c-e-t-এর মাঝের vertex c আর e, প্রথম পথের সঙ্গে কোনো মিল নেই। এখন ২টি internally disjoint পথ।
  4. তৃতীয় পথ নেই। s-c-e-t ছাড়া বাকি চারটি পথের প্রত্যেকটি d দিয়ে যায়, তাই যেকোনো দুটি “d-পথ” একে অন্যের সঙ্গে মেলে। ফলে একসঙ্গে বড়জোর একটি d-পথ আর s-c-e-t: সর্বোচ্চ ২।
  5. Separator. S = {d, e} সরালে t-এর কোনো প্রতিবেশী থাকে না, তাই s থেকে t-এ পথ নেই; |S| = 2. একটি vertex যথেষ্ট নয়: d সরালে s-c-e-t থাকে, e সরালে s-a-d-t থাকে, আর a, b বা c সরালে অন্তত একটি পথ থাকে। সবচেয়ে ছোট separator ২ = সর্বোচ্চ disjoint পথ ২। ({c, d}-ও একটি ২-আকারের separator.)

Menger থেকে একটি সামগ্রিক রূপ আসে, যা Hassler Whitney-এর ১৯৩২ সালের কাজের সঙ্গে যুক্ত বলে উল্লেখ করা হয়: অন্তত k + 1 vertex-এর G k-connected যদি এবং কেবল যদি প্রতিটি জোড়া আলাদা vertex-এর মধ্যে k-টি internally disjoint path থাকে; একইভাবে k-edge-connected ⇔ প্রতিটি জোড়ার মধ্যে k-টি edge-disjoint path. পুরো graph-এর λ(G) আসলে সবচেয়ে ছোট global minimum cut, যা পর্ব ৪৩ “Probabilistic method আর randomized algorithm”-এর Karger-এর algorithm এলোমেলো edge contraction দিয়ে খোঁজে। নিচের ব্লক vertex রূপটি ছোট এলোমেলো graph-এ দুই দিক থেকেই brute force দিয়ে মেলায়।

import random
from itertools import combinations
def paths(adj, s, t, p=None):          # every simple s-t path
    p = p or [s]
    if p[-1] == t:
        yield p; return
    for y in adj[p[-1]]:
        if y not in p:
            yield from paths(adj, s, t, p + [y])
def most_disjoint(inner):              # largest set of disjoint interiors
    if not inner: return 0
    first, rest = inner[0], inner[1:]
    return max(most_disjoint(rest),
               1 + most_disjoint([q for q in rest if not q & first]))
def min_separator(V, P, s, t):         # smallest vertex set hitting all
    others = [v for v in V if v not in (s, t)]
    return next(k for k in range(len(others) + 1)
                for S in combinations(others, k)
                if all(set(S) & p for p in P))
random.seed(59); checked = 0
for trial in range(120):
    V = list(range(7))
    adj = {v: set() for v in V}
    for u, v in combinations(V, 2):
        if random.random() < 0.45:
            adj[u].add(v); adj[v].add(u)
    s, t = 0, 6
    if t in adj[s]: continue           # vertex form needs s, t non-adjacent
    P = [set(p[1:-1]) for p in paths(adj, s, t)]
    assert most_disjoint(P) == min_separator(V, P, s, t)
    checked += 1
print(checked, "non-adjacent pairs: max disjoint paths == min separator")

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

59 non-adjacent pairs: max disjoint paths == min separator

১২০টি এলোমেলো ৭-vertex graph-এর যেগুলোতে 0 আর 6 অসংলগ্ন, এমন ৫৯টিতে দুই সংখ্যা হুবহু মিলেছে; s–t path না থাকলে দুটিই 0. প্রতিটি path-কে তার মাঝের vertex-সেট দিয়ে রাখা হয়েছে, কারণ disjoint কি না আর separator ছোঁয় কি না, দুটিই শুধু মাঝের vertex-এর ওপর নির্ভর করে। Separator যে প্রতিটি path ছোঁয়, এটি “S সরালে পথ নেই”-এর সমান কথা। s আর t সংলগ্ন হলে কোনো separator নেই (edge s–t কোনো vertex সরিয়ে কাটা যায় না), তাই vertex রূপে শর্তটি লাগে।

৭ · Directed graph — strongly আর weakly connected

শহরে একমুখী রাস্তা থাকলে “পৌঁছানো যায়” আর দুই দিকে সমান থাকে না: মতিঝিল থেকে গুলশান যাওয়া গেলেও উল্টোটা না-ও যেতে পারে। Directed graph-এ walk মানে তীরের দিক মেনে চলা, আর reachability সাধারণত symmetric নয়।

সংজ্ঞা ৭.১ আর উপপাদ্য ৭.২

Directed graph D strongly connected, যদি প্রতিটি ক্রমজোড়া (u, v)-এর জন্য u থেকে v-তে directed path থাকে; আর weakly connected, যদি তীরের দিক ভুলে গেলে পাওয়া undirected graph connected. u ↔ v (u থেকে v আর v থেকে u দুই দিকেই directed walk আছে) একটি equivalence relation; এর class-গুলোকে বলে strongly connected component (SCC).

  1. Reflexive: দৈর্ঘ্য ০-এর walk. Symmetric: সংজ্ঞাটি u আর v-তে প্রতিসম। — সংজ্ঞা
  2. Transitive: u ↔ v আর v ↔ w হলে u → v → w-এর walk জুড়ে u থেকে w, আর w → v → u জুড়ে w থেকে u. ∎ — walk জোড়া

এটি পর্ব ৫৪-এর reachability relation R* আর তার উল্টো (R*)−1-এর intersection (Δ-সহ), আর পর্ব ৫৫-এর উপপাদ্য অনুযায়ী intersection-এ equivalence টিকে থাকে। প্রতিটি SCC-কে একটি বিন্দুতে গুটিয়ে নিলে যে directed graph পাওয়া যায়, তাকে বলে condensation; এটি সবসময় একটি DAG (directed acyclic graph). কারণ: দুই বা ততোধিক SCC-এর মধ্যে একটি directed cycle থাকলে cycle-এর সব vertex পরস্পরের কাছে দুই দিকে পৌঁছাতে পারত, তাই তারা একই SCC-তে থাকত, বিরোধ। ফলে যেকোনো directed graph হলো “SCC-গুলোর একটি topological ক্রম”, যার গণিত পর্ব ৫৬-এ। একটি DAG-এ প্রতিটি SCC একটি মাত্র vertex, তাই n-vertex DAG-এ SCC ঠিক nটি। SCC বের করার Kosaraju আর Tarjan-এর algorithm DSA কোর্সের পর্ব ৪৬-এ আছে।

উদাহরণ: হাব A → B → C → A আর C → D → E → D. SCC: {A, B, C}, {D, E}; D থেকে C-তে ফেরা যায় না, তাই graph weakly connected কিন্তু strongly connected নয়; condensation হলো দুটি বিন্দু আর একটি তীর।

৮ · দূরত্ব, diameter, matrix-এর ঘাত আর BFS-এর প্রমাণ

Connected graph-এ distance d(u, v) = u থেকে v-এর সবচেয়ে ছোট path-এর দৈর্ঘ্য (edge-এর সংখ্যা); path না থাকলে d = ∞। উপপাদ্য ১.১ অনুযায়ী এটি সবচেয়ে ছোট walk-এর দৈর্ঘ্যও। d একটি metric: d(u, v) = 0 ⇔ u = v; d(u, v) = d(v, u) (path উল্টানো); আর ত্রিভুজ অসমতা d(u, w) ≤ d(u, v) + d(v, w), কারণ দুটি সবচেয়ে ছোট path জুড়লে d(u, v) + d(v, w) দৈর্ঘ্যের একটি u–w walk পাওয়া যায়, আর সবচেয়ে ছোট u–w walk তার চেয়ে লম্বা নয়। Diameter হলো সব জোড়ার মধ্যে সর্বোচ্চ distance.

ডেলিভারি graph-এ (scratch-এ BFS দিয়ে গুনে মেলানো) সাভার থেকে দূরত্ব: M 1; U আর G 2; T 3; D আর K 4. Diameter 4 (যেমন S থেকে K: S, M, G, T, K). G থেকে প্রতিটি হাব বড়জোর ২ দূরে, তাই গুদাম বসানোর সেরা জায়গা গুলশান: “সবচেয়ে দূরের হাব কত দূরে” প্রশ্নে G-এর উত্তর ২, যা সব vertex-এর মধ্যে সবচেয়ে কম।

Adjacency matrix-এর ঘাত। পর্ব ১৯-এ প্রমাণ হয়েছে, Ak-এর (u, v) ঘর = u থেকে v-এর দৈর্ঘ্য-k walk-এর সংখ্যা। উপপাদ্য ১.১-এর সঙ্গে মিলিয়ে: d(u, v) = সবচেয়ে ছোট k, যার জন্য (Ak)uv > 0. ডেলিভারি graph-এ S থেকে K-এর ঘর A, A2, A3-এ 0 আর A4-এ 1, তাই d(S, K) = 4. আর M থেকে T: A2-এ 1 (M, G, T), A4-এ 7, কারণ লম্বা walk-এ ত্রিভুজের চারপাশে ঘোরা যায়। (A3-এর কর্ণের যোগফল ÷ 6 = ত্রিভুজের সংখ্যা; এখানে 12 ÷ 6 = 2.)

উপপাদ্য ৮.১ (BFS সবচেয়ে ছোট পথ দেয়)

Unweighted graph-এ s থেকে BFS চালালে প্রতিটি vertex v যে স্তর L(v)-এ প্রথম আবিষ্কৃত হয় (s-এর স্তর 0, x-এর প্রতিবেশী নতুন হলে স্তর L(x) + 1), সেটিই d(s, v).

  1. দাবি P(k): স্তর k-এর vertex-গুলো ঠিক {v : d(s, v) = k}। k = 0-তে দুই পাশেই শুধু s. — base case
  2. BFS-এর queue FIFO, তাই স্তর 0-এর সব vertex, তারপর স্তর 1-এর সব, এভাবে ক্রমে প্রক্রিয়া হয়; স্তর k + 1-এর vertex শুধু স্তর k-এর vertex থেকে আবিষ্কৃত হয়। — queue-এর ধর্ম
  3. ধরুন P(0), …, P(k) সত্য। v স্তর k + 1-এ থাকলে তার একটি প্রতিবেশী x স্তর k-এ, তাই d(s, v) ≤ k + 1; আর v আগের কোনো স্তরে নেই, তাই inductive hypothesis অনুযায়ী d(s, v) > k. অতএব d(s, v) = k + 1. — strong induction, পর্ব ১১
  4. উল্টো দিকে d(s, v) = k + 1 হলে একটি সবচেয়ে ছোট path-এ v-এর আগের vertex x-এর d(s, x) = k, তাই x স্তর k-এ। x প্রক্রিয়ার সময় v আগে না দেখা হলে স্তর k + 1-এ আবিষ্কৃত হয়; আর আগে দেখা হতে পারে না, কারণ স্তর ≤ k-তে শুধু দূরত্ব ≤ k-এর vertex. ∎ — দুই দিকের অন্তর্ভুক্তি

প্রমাণে edge-এর “ওজন নেই” কথাটি ধাপ ৩-এ লেগেছে: প্রতিটি edge ঠিক ১ দূরত্ব যোগ করে। রাস্তায় সময় বা দূরত্বের ওজন থাকলে BFS ভুল উত্তর দিতে পারে, তখন Dijkstra লাগে, যার প্রমাণ পর্ব ৬১ “Shortest path-এর গণিত — Dijkstra-র প্রমাণ আর traveling salesperson”-এ।

৯ · পরীক্ষার অঙ্ক আর একটি ভুল প্রমাণ

অঙ্ক ১: Edge গুনে সিদ্ধান্ত

(ক) ১০ vertex-এর একটি simple graph-এ ৩৭টি edge. এটি কি অবশ্যই connected? (খ) ৩৬টি হলে? (গ) ১২ vertex আর ৮ edge-এর graph-এ অন্তত কয়টি component?

  1. (ক) C(9, 2) = 36 < 37, তাই উপপাদ্য ৩.২ অনুযায়ী হ্যাঁ।
  2. (খ) না, অবশ্যই নয়: K9 আর একটি একা vertex, ঠিক ৩৬টি edge, connected নয়।
  3. (গ) উপপাদ্য ৩.১: c ≥ 12 − 8 = 4; সমতা হয় যেমন ৮টি edge-এর একটি path আর ৩টি একা vertex নিলে (9 + 3 = 12 vertex, component 4).

অঙ্ক ২: κ, λ, δ

দুটি K4, {a1, a2, a3, a4} আর {b1, b2, b3, b4}, তার সঙ্গে a1–b1 আর a1–b2. κ, λ, δ বের করুন।

  1. δ: b3, b4, a2, a3, a4-এর degree 3; a1-এর 5; b1, b2-এর 4. তাই δ = 3.
  2. λ: দুই দলের মধ্যে ঠিক দুটি edge, সরালে graph ভাঙে, তাই λ ≤ 2. একটি edge সরালে ভাঙে না: দুই দলের মধ্যে আরেকটি edge থাকে, আর K4-এর ভেতর থেকে একটি edge সরালেও K4 connected (λ(K4) = 3). তাই λ = 2.
  3. κ: a1 সরালে দুই দলের মধ্যে কোনো edge থাকে না, তাই κ = 1. (১ < ২ < ৩, তৃতীয় Python ব্লকে মেলানো।)

অঙ্ক ৩: দূরত্ব matrix থেকে

ডেলিভারি graph-এ (A3)SK = 0 আর (A4)SK = 1. d(S, K) কত, আর দৈর্ঘ্য-৪ walk-টি কোনটি? উত্তর: d(S, K) = 4 (§৮-এর সূত্র), আর একমাত্র walk S, M, G, T, K (S-এর একমাত্র প্রতিবেশী M, আর G–T bridge পেরোতেই হয়)।

প্রমাণের ভুল ধরুন: “সব degree ≥ 2 হলে bridge নেই”

একজন লিখলেন: “e = {u, v} যেকোনো edge নিন। deg(u) ≥ 2, তাই u-এর আরেকটি প্রতিবেশী w আছে; একইভাবে v-এর আরেকটি প্রতিবেশী x. e সরালেও u আর v দুজনেই অন্যদের সঙ্গে যুক্ত থাকে, তাই graph connected থাকে। সুতরাং কোনো edge bridge নয়।”

ভুল কোথায়: “u আর v দুজনেই কারও সঙ্গে যুক্ত” থেকে “u থেকে v-তে e ছাড়া পথ আছে” আসে না; §৪-এর lemma অনুযায়ী দরকার ঠিক দ্বিতীয়টি। পাল্টা-উদাহরণ: দুটি ত্রিভুজ {1, 2, 3} আর {4, 5, 6}, মাঝে edge 3–4. সব degree ≥ 2, অথচ 3–4 কোনো cycle-এ নেই, তাই উপপাদ্য ৪.২ অনুযায়ী bridge (scratch-এ component গুনে মেলানো)। সঠিক কথা: δ ≥ 2 হলে graph-এ অন্তত একটি cycle আছে (সবচেয়ে লম্বা path-এর শেষ vertex-এর যুক্তি), কিন্তু প্রতিটি edge cycle-এ থাকবে, এমন কোনো নিশ্চয়তা নেই।

আরও গভীরে: κ আর λ দুটিই polynomial সময়ে বের হয়, কয়েকটি max-flow হিসাব দিয়ে; ২০২২ সালে Chen, Kyng, Liu, Peng, Probst Gutenberg আর Sachdeva প্রায়-রৈখিক (almost-linear) সময়ের max-flow algorithm ঘোষণা করেন বলে জানা যায়, যা এই হিসাবগুলোও দ্রুত করে। 2-connected graph-এর একটি সুন্দর গঠন আছে: প্রতিটি 2-connected graph একটি cycle থেকে শুরু করে বারবার “ear” (দুই প্রান্ত পুরোনো অংশে, মাঝখান নতুন এমন path) জুড়ে পাওয়া যায় (Whitney-এর ear decomposition). আর expander graph হলো কম edge-এর অথচ খুব মজবুত connectivity-র graph, যা network নকশা, error-correcting code আর pseudorandomness-এ ব্যবহার হয়।

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

  • n vertex-এর connected graph-এ কমপক্ষে কয়টি edge? n − 1 (উপপাদ্য ৩.১)।
  • ১০ vertex-এর simple graph connected নিশ্চিত করতে কয়টি edge যথেষ্ট? C(9, 2) + 1 = 37.
  • একটি edge কখন bridge? যখন সেটি কোনো cycle-এ নেই।
  • κ, λ, δ-এর সম্পর্ক? κ ≤ λ ≤ δ, আর দুটি অসমতাই কঠোর হতে পারে।
  • n vertex-এর DAG-এ কয়টি strongly connected component? nটি, প্রতিটি vertex নিজেই একটি।

১০ · AI-এর যুগে — graph-এর প্রমাণ আর হিসাব যাচাই

Connectivity-র প্রশ্নে AI সহকারী সংজ্ঞা সাধারণত ঠিক বলে, কিন্তু প্রমাণে আর সংখ্যায় আত্মবিশ্বাসী ভুল করে। কয়েকটি নিয়মিত ভুল আর ধরার উপায়:

AI-এর ভুলকীভাবে ধরবেন
উল্টো কথা প্রমাণ: “n − 1টি edge থাকলেই connected”ত্রিভুজ আর একটি একা vertex: n = 4, ৩টি edge, connected নয়
Graph-এর induction-এ n vertex-এর graph-এ একটি vertex “যোগ করে” সব n + 1 vertex-এর graph পাওয়া ধরে নেওয়াদেখুন ধাপটি যেকোনো (n + 1)-vertex graph থেকে শুরু হয়েছে কি না
Menger-এর vertex রূপ “s আর t অসংলগ্ন” শর্ত ছাড়া বলা, বা κ = λ ধরে নেওয়াK2 বা দুই K4-এর উদাহরণে সংখ্যা মেলান
Walk, trail আর path গুলিয়ে ফেলা, বা ওজনযুক্ত graph-এ BFS-কে সবচেয়ে ছোট পথ বলাসংজ্ঞা লিখে নিন; ওজন থাকলে ছোট পাল্টা-উদাহরণ খুঁজুন
Bridge আর cut vertex-এর তালিকায় ভুল গণনাপ্রতিটি edge বা vertex সরিয়ে component গুনুন (ছোট graph-এ brute force)

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

নিচের graph-এর দাবিটি ধাপে ধাপে প্রমাণ করো বা খণ্ডন করো: দাবি: [যেমন "n vertex-এর simple graph-এ δ ≥ (n − 1)/2 হলে graph connected"] ১. শুরুতেই লেখো তুমি walk, path আর cycle-এর কোন সংজ্ঞা ব্যবহার করছ, আর graph simple না multigraph. ২. প্রতিটি ধাপের পাশে কোন সংজ্ঞা বা উপপাদ্য লাগল তা লেখো; উপপাদ্যের শর্তগুলো (যেমন s, t অসংলগ্ন) আলাদা করে উল্লেখ করো। ৩. Induction করলে স্পষ্ট দেখাও যে inductive step যেকোনো (n + 1)-vertex graph থেকে শুরু হয়েছে। ৪. দাবি মিথ্যা হলে সবচেয়ে ছোট পাল্টা-উদাহরণ edge-তালিকা আকারে দাও। ৫. ছোট n-এ (n ≤ 6) সব graph-এ দাবিটি পরীক্ষা করার একটি Python কোড দাও (শুধু itertools), যাতে আমি নিজে চালাতে পারি। ৬. কোনো উপপাদ্যের নাম, সাল বা উৎস নিয়ে নিশ্চিত না হলে তা স্পষ্ট বলো।

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

Graph-এর দাবি যাচাইয়ের বড় সুবিধা: ৬টি vertex-এ মাত্র 215 = 32768টি labelled simple graph, যা এক মুহূর্তে সব পরীক্ষা করা যায়। ভুল প্রমাণ সাধারণত এত ছোট graph-এই ধরা পড়ে; তাই আগে পাল্টা-উদাহরণ খুঁজুন, তারপর প্রমাণে ভরসা করুন।

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

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

প্র ০১Menger-এর উপপাদ্য আর max-flow min-cut theorem কীভাবে একই সত্যের দুই রূপ? কে কখন কী প্রমাণ করেন?

Karl Menger ১৯২৭ সালে তাঁর উপপাদ্য প্রকাশ করেন বলে সাধারণত উল্লেখ করা হয়; তিনি এটি একটি topology-র প্রশ্নের (curve-এর মাত্রা) প্রসঙ্গে পেয়েছিলেন। পরে Dénes Kőnig-এর ১৯৩৬ সালের বইকে প্রথম graph theory পাঠ্যবই ধরা হয়, আর সেখানে Menger-এর মূল প্রমাণের একটি ফাঁক নিয়ে আলোচনা আছে বলে ইতিহাসবিদেরা লেখেন। ফলে উপপাদ্যটি সম্পূর্ণ গ্রহণযোগ্য রূপ পেতে কিছু সময় লেগেছিল।

প্রায় তিন দশক পরে, ১৯৫৬ সালে, L. R. Ford Jr. আর D. R. Fulkerson একটি সম্পূর্ণ ভিন্ন প্রশ্ন থেকে একই কাঠামো পান: রেলপথের নেটওয়ার্কে এক জায়গা থেকে আরেক জায়গায় সর্বোচ্চ কত মাল পাঠানো যায়। একই বছর Elias, Feinstein আর Shannon-ও স্বাধীনভাবে একই ফল প্রকাশ করেন বলে জানা যায়। তাদের উপপাদ্য: সর্বোচ্চ flow = সবচেয়ে ছোট cut-এর capacity. সব capacity 1 হলে integer flow আসলে edge-disjoint path-এর সংগ্রহ (প্রতিটি একক flow একটি পথ ধরে চলে), আর cut মানে s থেকে t আলাদা করা edge-সেট। ঠিক Menger-এর edge রূপ।

দুটির মধ্যে একটি গভীর ধারণা কাজ করে, যাকে আজ “duality” বলে: একটি সর্বোচ্চকরণ সমস্যা (কতগুলো পথ) আর একটি সর্বনিম্নকরণ সমস্যা (কতগুলো vertex বা edge কাটা) একই সংখ্যা দেয়। সহজ দিকটি (সর্বোচ্চ ≤ সর্বনিম্ন) প্রায় সবসময় তুচ্ছ, যেমন §৬-এ দুই লাইনে প্রমাণ হলো। কঠিন দিকটিই আসল উপপাদ্য, আর তার প্রমাণ একটি certificate দেয়: পথ আর cut দুটোই হাতে দিলে যে কেউ সহজে মিলিয়ে দেখতে পারেন যে দুটিই সর্বোত্তম। পর্ব ৬৪ “Matching — bipartite graph, Hall-এর উপপাদ্য আর stable matching”-এর Kőnig-এর উপপাদ্যও একই পরিবারের, আর linear programming-এর duality তত্ত্ব এদের সবাইকে এক ছাতার নিচে আনে।

ব্যবহারিক দিক থেকে এর অর্থ: আপনি যদি s–t-এর মধ্যে k-টি disjoint পথ খুঁজে পান আর k-আকারের একটি separator-ও দেখাতে পারেন, তবে আর কোনো হিসাব লাগবে না, উত্তর নিশ্চিত।

মূল উপলব্ধি: Menger (১৯২৭) আর max-flow min-cut (১৯৫৬) একই duality-র দুই রূপ: আলাদা পথের সর্বোচ্চ সংখ্যা = পথ কাটার সর্বনিম্ন খরচ, আর দুই দিকের উত্তর একে অন্যের প্রমাণপত্র।

প্র ০২যোগাযোগ বা বিদ্যুৎ নেটওয়ার্ক নকশায় κ আর λ কেন গুরুত্বপূর্ণ? “একটি ব্যর্থতায় ভাঙবে না” কথাটি গাণিতিকভাবে কী?

১৯৬০-এর দশকের শুরুতে RAND Corporation-এ Paul Baran একটি প্রশ্ন নিয়ে কাজ করেন: যোগাযোগ নেটওয়ার্কের অনেক node বা লিংক নষ্ট হলেও বাকিরা কীভাবে যোগাযোগ রাখবে। তাঁর প্রতিবেদনগুলো (১৯৬৪ সালের “On Distributed Communications” সিরিজ বলে উল্লেখ করা হয়) কেন্দ্রীভূত (একটি hub-এর চারপাশে তারা-আকৃতি), বিকেন্দ্রীভূত আর বিতরিত (জালের মতো) নেটওয়ার্কের তুলনা করে। Graph-এর ভাষায় তারা-আকৃতির নেটওয়ার্কের কেন্দ্র একটি cut vertex, κ = 1: কেন্দ্র নষ্ট হলে সব শেষ। জালের মতো নেটওয়ার্কে প্রতিটি node-এর কয়েকটি প্রতিবেশী, κ আর λ বড়, তাই অনেক ব্যর্থতা সহ্য হয়।

“একটি লিংক নষ্ট হলেও নেটওয়ার্ক চলবে” মানে λ ≥ 2, অর্থাৎ কোনো bridge নেই; উপপাদ্য ৪.২ অনুযায়ী, প্রতিটি লিংক কোনো একটি ঘূর্ণি পথে (cycle) আছে। এজন্য অনেক শহরের fibre বা বিদ্যুৎ বিতরণ নকশায় “ring” কাঠামো দেখা যায়: একটি ring-এ একটি কাটা পড়লে উল্টো দিক দিয়ে সংযোগ চলে। “একটি যন্ত্র (router, substation) নষ্ট হলেও চলবে” মানে κ ≥ 2, অর্থাৎ কোনো cut vertex নেই। Whitney-এর অসমতা κ ≤ λ বলে, যন্ত্রের ব্যর্থতা সহ্য করা লিংকের ব্যর্থতা সহ্য করার চেয়ে কঠিন বা সমান কঠিন শর্ত।

Menger-এর উপপাদ্য ব্যবহারিক রূপ দেয়: κ ≥ 2 হলে প্রতিটি জোড়ার মধ্যে দুটি internally disjoint পথ আছে, তাই একটি “প্রধান” আর একটি “বিকল্প” রুট আগে থেকেই ঠিক করে রাখা যায়, যাদের কোনো যন্ত্র ভাগাভাগি নেই। তবে দাম আছে: Whitney-এর অসমতা অনুযায়ী κ ≥ k হলে δ ≥ k, তাই handshake theorem অনুযায়ী edge অন্তত nk/2টি; বেশি মজবুত মানে বেশি লিংক, বেশি খরচ। বাস্তবের ব্যর্থতা আবার স্বাধীন নয়: একই খাদ দিয়ে যাওয়া দুটি “আলাদা” fibre একসঙ্গে কাটা পড়তে পারে, তাই প্রকৌশলীরা ভৌগোলিকভাবে আলাদা পথও খোঁজেন, যা শুধু graph-এর মডেলে ধরা পড়ে না।

বাজারঘরের ক্ষেত্রেও একই: §৪-এর graph-এ G–T একটি bridge, তাই গুলশান-মতিঝিল রাস্তা বন্ধ হলে পূর্ব দিকের তিনটি হাব বিচ্ছিন্ন। একটি নতুন রাস্তা U–D যোগ করলে দুই ত্রিভুজ একটি বড় cycle-এর অংশ হয়, আর G–T আর bridge থাকে না।

মূল উপলব্ধি: λ ≥ 2 মানে কোনো bridge নেই, κ ≥ 2 মানে কোনো cut vertex নেই; Menger এই সংখ্যাগুলোকে আগে থেকে ঠিক করা বিকল্প রুটে রূপ দেয়, আর মজবুতির দাম হলো অন্তত nk/2টি লিংক।

প্র ০৩Brute force-এ bridge খুঁজতে প্রতিটি edge সরিয়ে দেখতে হয়। DFS কীভাবে একবারে সব bridge আর cut vertex দেয়, আর এর ইতিহাস কী?

সংজ্ঞা থেকে সরাসরি হিসাবে প্রতিটি edge সরিয়ে একবার BFS চালাতে হয়: m-টি edge, প্রতিবার O(n + m) কাজ, মোট O(m(n + m)). ১০ লাখ edge-এর একটি রাস্তার নেটওয়ার্কে এটি প্রায় ১০12 ধাপ, কার্যত অসম্ভব। ১৯৭০-এর দশকের শুরুতে Robert Tarjan আর John Hopcroft দেখান যে depth-first search (DFS) একবার চালিয়েই সব cut vertex আর 2-connected অংশ (biconnected component) রৈখিক সময়ে বের করা যায়; Tarjan-এর ১৯৭২ সালের DFS-বিষয়ক প্রবন্ধ আর Hopcroft–Tarjan-এর ১৯৭৩ সালের প্রবন্ধকে এর সূত্র বলে উল্লেখ করা হয়। এই কাজগুলো পরে তাঁদের ১৯৮৬ সালের Turing Award-এর উল্লেখের অংশ ছিল বলে জানা যায়।

মূল ধারণাটি উপপাদ্য ৪.২ থেকেই আসে। DFS একটি tree বানায়; বাকি প্রতিটি edge (undirected graph-এ) একটি vertex-কে তার কোনো পূর্বপুরুষের সঙ্গে জোড়ে, যাকে back edge বলে, আর প্রতিটি back edge ঠিক একটি cycle তৈরি করে। একটি tree edge (u, v), যেখানে v হলো u-এর সন্তান, bridge যদি এবং কেবল যদি v-এর subtree থেকে কোনো back edge u বা তার ওপরে না পৌঁছায়: পৌঁছালে edge-টি একটি cycle-এ আছে, না পৌঁছালে কোনো cycle-এ নেই। প্রতিটি vertex-এর জন্য “low” মান (subtree থেকে সবচেয়ে ওপরে কোথায় পৌঁছানো যায়) DFS ফেরার পথে এক ধাপে হিসাব হয়, তাই পুরো কাজ O(n + m).

Cut vertex-এর নিয়ম প্রায় একই, একটি ব্যতিক্রমসহ: DFS-এর root একটি cut vertex যদি এবং কেবল যদি তার অন্তত দুটি সন্তান থাকে। ভুল করা খুব সহজ (“low[v] ≥ disc[u]” আর “>”-এর পার্থক্য bridge আর cut vertex আলাদা করে), তাই ছোট graph-এ brute force দিয়ে মেলানো, যেমন দ্বিতীয় Python ব্লকে, একটি ভালো অভ্যাস।

এখানে একটি শিক্ষা আছে: একটি গাণিতিক চরিত্র-বর্ণনা (“bridge ⇔ কোনো cycle-এ নেই”) প্রায়ই দ্রুত algorithm-এর চাবি। সংজ্ঞাটি যা জিজ্ঞেস করে (সরিয়ে দেখা), চরিত্র-বর্ণনা তা অন্য প্রশ্নে বদলে দেয় (back edge দিয়ে ঢাকা আছে কি না), যার উত্তর একবারের হাঁটায় পাওয়া যায়। কোড আর পূর্ণ প্রমাণ DSA কোর্সের পর্ব ৪৬-এ।

মূল উপলব্ধি: “bridge ⇔ কোনো cycle-এ নেই” উপপাদ্যকে DFS-এর back edge-এর ভাষায় লিখলে O(m(n + m))-এর brute force O(n + m)-এ নামে; গণিতের চরিত্র-বর্ণনাই দ্রুত algorithm-এর চাবি।

প্র ০৪“ছয় ধাপের দূরত্ব” কী? বড় social network-এর diameter বা গড় দূরত্ব এত ছোট কেন?

১৯৬৭ সালে মনোবিজ্ঞানী Stanley Milgram একটি পরীক্ষা চালান: যুক্তরাষ্ট্রের এক অঞ্চলের মানুষদের একটি চিঠি দেওয়া হয়, যা পরিচিতদের হাত ঘুরে দূরের একজন নির্দিষ্ট ব্যক্তির কাছে পৌঁছাতে হবে। যে চিঠিগুলো পৌঁছেছিল, সেগুলোর গড় হাতবদল প্রায় ৬-এর কাছাকাছি ছিল বলে প্রায়ই বলা হয়, আর সেখান থেকে “six degrees of separation” কথাটি জনপ্রিয় হয়। তবে অনেক চিঠি পৌঁছায়ইনি, আর নমুনা ছোট ছিল, তাই সংখ্যাটি সতর্কভাবে পড়তে হয়।

Graph-এর ভাষায় প্রশ্নটি distance আর diameter নিয়ে: মানুষ vertex, পরিচয় edge. বড় অনলাইন social network-এ গবেষকেরা সব জোড়ার গড় distance মেপে চার-পাঁচের কাছাকাছি সংখ্যা পেয়েছেন বলে জানা যায়। Diameter (সবচেয়ে দূরের জোড়া) এর চেয়ে বড়, কারণ প্রান্তিক কিছু vertex লম্বা শৃঙ্খলে যুক্ত থাকে; তাই “গড় distance” আর “diameter” আলাদা মাপ, গুলিয়ে ফেলা চলবে না।

দূরত্ব এত ছোট কেন? ১৯৯৮ সালে Duncan Watts আর Steven Strogatz একটি মডেল দেন: একটি নিয়মিত বলয় (প্রত্যেকে কাছের কয়েকজনের সঙ্গে যুক্ত, যেখানে diameter বড়) থেকে শুরু করে অল্প কয়েকটি edge এলোমেলোভাবে দূরে জুড়ে দিলে গড় দূরত্ব হঠাৎ অনেক কমে যায়, অথচ স্থানীয় “বন্ধুর বন্ধু” কাঠামো প্রায় অক্ষত থাকে। কারণটি সহজ গণনা: প্রত্যেকের d-জন পরিচিত হলে k ধাপে মোটামুটি dk পর্যন্ত মানুষ পৌঁছানো যায় (যদি ওভারল্যাপ কম হয়), তাই n মানুষে পৌঁছাতে প্রায় log n / log d ধাপ। d = 100 আর n = 800 কোটি হলে log n / log d প্রায় ৫।

গণিতবিদদের নিজস্ব সংস্করণ হলো Erdős number: Paul Erdős-এর সঙ্গে যৌথ প্রবন্ধের graph-এ Erdős থেকে দূরত্ব। এই distance BFS দিয়েই হিসাব হয় (উপপাদ্য ৮.১)। বাজারঘরের ক্ষেত্রে একই ধারণা: রাইডার নেটওয়ার্কে কয়েকটি দূরপাল্লার সরাসরি রুট যোগ করলে diameter অনেক কমে যেতে পারে।

মূল উপলব্ধি: বড় নেটওয়ার্কে অল্প কিছু “দূরের” edge থাকলেই গড় distance লগারিদমিক হারে ছোট হয়; distance আর diameter BFS দিয়ে নির্ভুল মাপা যায়, কিন্তু গড় আর সর্বোচ্চ আলাদা মাপ।

প্র ০৫এলোমেলো graph কখন connected হয়? Erdős–Rényi-এর threshold কী বলে?

১৯৫৯-৬০ সালে Paul Erdős আর Alfréd Rényi একটি প্রশ্ন নিয়ে কাজ করেন: n vertex-এ প্রতিটি সম্ভাব্য edge স্বাধীনভাবে সম্ভাবনা p দিয়ে রাখলে (আজ যাকে G(n, p) বলে) graph-টি কখন connected হয়? তাঁদের ফল একটি তীক্ষ্ণ সীমা (threshold) দেখায়: p মোটামুটি (ln n)/n-এর চেয়ে স্পষ্টভাবে কম হলে graph প্রায় নিশ্চিতভাবে disconnected, আর স্পষ্টভাবে বেশি হলে প্রায় নিশ্চিতভাবে connected (n বড় হতে থাকলে সম্ভাবনা 0 বা 1-এর দিকে যায়)।

সীমাটি ঠিক এখানে কেন, তার মূল কারণ একা vertex. একটি নির্দিষ্ট vertex একা থাকার সম্ভাবনা (1 − p)n−1 ≈ e−pn, তাই একা vertex-এর প্রত্যাশিত সংখ্যা প্রায় n · e−pn. p = (ln n)/n হলে এটি প্রায় 1; p একটু কম হলে অনেক বড়, একটু বেশি হলে প্রায় 0. দেখা যায়, এই সীমার কাছে graph connected না হওয়ার প্রধান কারণই একা vertex, বড় দুই টুকরো নয়। এটি পর্ব ৪৩-এর ধাঁচের প্রত্যাশা-যুক্তি, আর লক্ষ করুন, এর সঙ্গে §৫-এর Whitney-এর λ ≤ δ মিলে যায়: এলোমেলো graph-এ connectivity প্রায়ই minimum degree দিয়েই নির্ধারিত হয়।

আরও আগে, p ≈ 1/n-এর কাছে আরেকটি নাটকীয় পরিবর্তন: তার নিচে সব component ছোট (প্রায় log n আকারের), আর ওপরে হঠাৎ একটি “giant component” দেখা দেয়, যাতে vertex-এর একটি স্থির ভগ্নাংশ থাকে। Physics-এর phase transition-এর সঙ্গে এর মিল রয়েছে, আর এটি রোগ ছড়ানো বা গুজব ছড়ানোর মডেলে ব্যবহার হয়।

একটি তুলনা দেখুন: উপপাদ্য ৩.২ বলে, connected নিশ্চিত হতে প্রায় n2/2টি edge লাগে, কারণ সবচেয়ে খারাপ ক্ষেত্র ধরতে হয়। কিন্তু এলোমেলো graph-এ প্রায় (n ln n)/2টি edge-ই সাধারণত যথেষ্ট। “সবচেয়ে খারাপ ক্ষেত্র” আর “সাধারণ ক্ষেত্র”-এর এই বিশাল ফারাক algorithm বিশ্লেষণেও বারবার দেখা যায়।

মূল উপলব্ধি: G(n, p) প্রায় p = (ln n)/n-এ হঠাৎ connected হয়, মূলত একা vertex মিলিয়ে যাওয়ার কারণে; সবচেয়ে খারাপ ক্ষেত্রের C(n − 1, 2) সীমার তুলনায় এলোমেলো graph-এ অনেক কম edge যথেষ্ট।

অনুশীলন

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

  1. প্রমাণ: n ≥ 2 vertex-এর একটি simple graph G-তে প্রতিটি vertex-এর degree ≥ (n − 1)/2. প্রমাণ করুন G connected, আর আসলে diameter ≤ 2.
    1. যেকোনো দুটি আলাদা vertex u, v নিন। সংলগ্ন হলে d(u, v) = 1, কাজ শেষ। ধরুন সংলগ্ন নয়। — ক্ষেত্র ভাগ
    2. u আর v-এর প্রতিবেশীরা বাকি n − 2টি vertex-এর মধ্যে (u, v নিজেরা নয়, আর তারা পরস্পরের প্রতিবেশী নয়)। — simple graph, loop নেই
    3. |N(u)| + |N(v)| ≥ (n − 1)/2 + (n − 1)/2 = n − 1 > n − 2, তাই pigeonhole অনুযায়ী অন্তত একটি সাধারণ প্রতিবেশী w আছে। — পর্ব ৩২-এর pigeonhole
    4. u, w, v একটি path, তাই d(u, v) = 2. সব জোড়ায় d ≤ 2, তাই G connected আর diameter ≤ 2. ∎

    সীমাটি নিখুঁত: n জোড় হলে দুটি আলাদা Kn/2-এ প্রতিটি degree n/2 − 1 = (n − 2)/2, যা (n − 1)/2-এর চেয়ে সামান্য কম, আর graph connected নয় (scratch-এ n ≤ 7-এর সব graph-এ দাবিটি পরীক্ষা করে মেলানো)।

  2. হিসাব: (ক) ১৫ vertex আর ১০ edge-এর একটি graph-এ অন্তত কয়টি component? (খ) ১০ vertex-এর একটি simple graph-এ ঠিক ৩টি component; সর্বোচ্চ কয়টি edge থাকতে পারে? (গ) ৮ vertex-এর simple graph connected নিশ্চিত করতে কয়টি edge যথেষ্ট, আর তার একটি কম হলে কেন যথেষ্ট নয়?

    (ক) উপপাদ্য ৩.১: c ≥ 15 − 10 = 5.

    (খ) উপপাদ্য ৩.২-এর ধাপ ৩-এর যুক্তি বারবার প্রয়োগ করলে, নির্দিষ্ট সংখ্যক component-এ edge সবচেয়ে বেশি হয় যখন একটি component বড় আর পূর্ণ, বাকিগুলো একা vertex: K8 আর দুটি একা vertex, C(8, 2) = 28টি edge. সাধারণভাবে n vertex আর k component-এ সর্বোচ্চ C(n − k + 1, 2) (scratch-এ n ≤ 7-এর সব graph গুনে মেলানো)।

    (গ) C(7, 2) + 1 = 22টি। ২১টি যথেষ্ট নয়: K7 আর একটি একা vertex-এ ঠিক ২১টি edge, অথচ connected নয়।

  3. আউটপুট অনুমান: কোড না চালিয়ে বলুন কী ছাপা হবে, আর কেন। তারপর যেকোনো Python-এ চালিয়ে মেলান।
    E = {(0, 1), (1, 2), (2, 0), (2, 3), (3, 4)}
    def comps(E, n=5):
        root = list(range(n))
        def find(x):
            while root[x] != x: x = root[x]
            return x
        for u, v in E: root[find(u)] = find(v)
        return len({find(x) for x in range(n)})
    print(comps(E), [e for e in sorted(E) if comps(E - {e}) > comps(E)])
    1 [(2, 3), (3, 4)]

    Graph-টি একটি ত্রিভুজ 0, 1, 2 আর তার সঙ্গে ঝুলে থাকা path 2–3–4: connected, তাই প্রথম সংখ্যা 1. দ্বিতীয় অংশ সংজ্ঞা অনুযায়ী bridge খোঁজে: প্রতিটি edge সরিয়ে component গোনে। ত্রিভুজের তিনটি edge cycle-এ আছে, তাই bridge নয়; 2–3 আর 3–4 কোনো cycle-এ নেই, তাই দুটিই bridge (উপপাদ্য ৪.২)। sorted() tuple-কে অভিধান-ক্রমে সাজায়, তাই (2, 3) আগে। কোডের union-find ঠিক পর্ব ৫৫-এর মতো, শুধু path compression নেই (CPython 3.14-এ চালিয়ে মেলানো)।

  4. প্রমাণের ভুল ধরুন: দাবি: “n ≥ 2 vertex-এর যে graph-এ প্রতিটি vertex-এর degree ≥ 1, তা connected.” প্রমাণ: “n = 2-এ দুটি vertex-এর degree ≥ 1 মানে তাদের মধ্যে edge আছে, connected. ধরুন n vertex-এ সত্য। n vertex-এর এমন একটি graph নিন, যা inductive hypothesis অনুযায়ী connected; তাতে একটি নতুন vertex v যোগ করুন যার degree ≥ 1, অর্থাৎ v পুরোনো কোনো vertex-এর সঙ্গে যুক্ত। নতুন graph connected. ∎” ভুল কোথায়? একটি পাল্টা-উদাহরণ দিন।
    • পাল্টা-উদাহরণ: ৪টি vertex, দুটি আলাদা edge 1–2 আর 3–4. প্রতিটি degree 1, অথচ component ২টি (scratch-এ গুনে মেলানো)। তাই দাবিটি মিথ্যা, আর প্রমাণে ভুল আছেই।
    • ভুল ধাপ: inductive step দেখিয়েছে, শর্ত মানা n-vertex graph-এ একটি vertex যোগ করে যেসব (n + 1)-vertex graph পাওয়া যায়, সেগুলো connected. কিন্তু শর্ত মানা প্রতিটি (n + 1)-vertex graph এভাবে পাওয়া যায় না। উপরের উদাহরণ থেকে যেকোনো vertex সরালে একটি degree-0 vertex থাকে, তাই এটি কোনো শর্ত-মানা ৩-vertex graph থেকে “বানানো” নয়। ফলে n = 3 থেকে n = 4-এর ধাপটি এই graph-কে ছোঁয়ই না।
    • সঠিক পদ্ধতি: inductive step শুরু করুন শর্ত-মানা একটি যেকোনো (n + 1)-vertex graph থেকে, একটি vertex বা edge সরান, আর দেখান ছোট graph-টিও শর্ত মানে (উপপাদ্য ৩.১-এর মতো)। এখানে ঠিক সেই জায়গায় প্রমাণ আটকে যায়, যা দেখায় দাবিটিই ভুল।

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

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

ক্রম“n vertex আর m edge-এর graph-এ component অন্তত n − m” প্রমাণের ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. ভিত্তি: m = 0 হলে প্রতিটি vertex নিজেই একটি component, c = n
  2. m edge-এর যেকোনো graph G নিন আর তার যেকোনো একটি edge e সরান
  3. Inductive hypothesis অনুযায়ী G − e-তে component অন্তত n − m + 1
  4. e ফিরিয়ে দিলে বড়জোর দুটি component এক হয়, তাই component বড়জোর ১ কমে
  5. সিদ্ধান্ত: c(G) ≥ n − m, আর connected graph-এ m ≥ n − 1

১০ vertex-এর একটি simple graph-এ কমপক্ষে কয়টি edge থাকলে graph-টি অবশ্যই connected, যেভাবেই edge বসানো হোক?

  • 9
  • 36
  • 37
  • 45

Simple graph G-এর একটি edge e = {u, v} কখন bridge (সরালে component বাড়ে)?

  • যদি এবং কেবল যদি u বা v-এর degree 1
  • যদি এবং কেবল যদি e কোনো cycle-এ নেই
  • যদি এবং কেবল যদি u বা v একটি cut vertex
  • যদি G connected হয়

একটি simple graph-এর (vertex connectivity κ, edge connectivity λ, minimum degree δ) নিচের কোনটি হতে পারে?

  • (1, 2, 3)
  • (2, 1, 3)
  • (2, 3, 2)
  • (3, 3, 2)

১৫ vertex আর ১০ edge-এর একটি graph-এ connected component-এর সংখ্যা কমপক্ষে কত?

  • 1
  • 3
  • 4
  • 5

Menger-এর উপপাদ্যের vertex রূপ দুটি আলাদা vertex s আর t-এর জন্য কী বলে?

  • s আর t-এর distance = s আর t-এর সাধারণ প্রতিবেশীর সংখ্যা
  • s, t অসংলগ্ন হলে internally disjoint s–t path-এর সর্বোচ্চ সংখ্যা = সবচেয়ে ছোট s–t separator-এর আকার
  • s থেকে t-এর সব path-এর সংখ্যা = সবচেয়ে ছোট separator-এর আকার
  • সবচেয়ে ছোট s–t separator-এর আকার = deg(s)

৬টি vertex-এর একটি directed acyclic graph (DAG)-এ কয়টি strongly connected component আছে?

  • 1
  • edge-এর সংখ্যার ওপর নির্ভর করে
  • 6
  • 12

শব্দকোষ

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

মনে রাখুন

  1. Walk থেকে path: প্রতিটি u–v walk-এ একটি u–v path আছে; সবচেয়ে ছোট walk সবসময় path, দৈর্ঘ্য ≤ n − 1.
  2. Component: “walk আছে” সম্পর্ক equivalence, তার class-ই component; c ≥ n − m, তাই connected হতে m ≥ n − 1, আর m > C(n − 1, 2) হলে connected নিশ্চিত।
  3. Bridge আর cut vertex: একটি edge bridge ⇔ কোনো cycle-এ নেই; connected graph-এ অন্তত দুটি vertex cut vertex নয়।
  4. Whitney আর Menger: κ ≤ λ ≤ δ; disjoint পথের সর্বোচ্চ সংখ্যা = পথ কাটার সর্বনিম্ন সংখ্যা (vertex রূপে s, t অসংলগ্ন)।
  5. দিক আর দূরত্ব: SCC = দুই দিকের reachability-র class, condensation একটি DAG; d(u, v) একটি metric, Ak-এর প্রথম অশূন্য ঘর আর BFS-এর স্তর দুটিই d দেয়।

পরের পর্বে: পর্ব ৬০ “Euler আর Hamilton path — Königsberg থেকে NP-কঠিনতা”: প্রতিটি রাস্তা ঠিক একবার ধরে ঘোরা কখন সম্ভব, আর প্রতিটি হাবে ঠিক একবার যাওয়া কেন এত কঠিন প্রশ্ন, সেই আলোচনা শুরু হবে।

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

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