Eight routers, numbered to , and fourteen cables. Routers – are all wired to each other, and so are –. Router has two more cables, to and to :
Every router has at least three cables. Does that mean the network survives any two failures? No. If the two cables – and – fail, the left group can no longer reach the right group. Worse, one router failure is enough: if router fails, the same split happens.
So there are two different questions, with two different answers. How many routers must fail before the network splits (here, 1)? How many cables (here, 2)? And how do both compare with the smallest number of cables at any one router (here, 3)? This module defines the two numbers, proves how they are ordered, and shows that each comparison can be strict.
A computer can answer both questions by trying every set of routers, then every set of cables, smallest first, until one disconnects the network:
from itertools import combinations
from collections import deque
def network(edges):
g = {}
for u, v in edges:
g.setdefault(u, set()).add(v)
g.setdefault(v, set()).add(u)
return g
def connected(g, removed_vertices=(), removed_edges=()):
"""Is what remains of g connected? (One vertex or none counts as connected.)"""
gone = set(removed_vertices)
cut = {frozenset(e) for e in removed_edges}
left = [v for v in g if v not in gone]
if len(left) <= 1:
return True
seen, queue = {left[0]}, deque([left[0]])
while queue:
u = queue.popleft()
for w in g[u]:
if w not in gone and w not in seen and frozenset((u, w)) not in cut:
seen.add(w)
queue.append(w)
return len(seen) == len(left)
def edges_of(g):
return sorted({tuple(sorted((u, v))) for u in g for v in g[u]})
def kappa(g):
"""Fewest vertices whose removal disconnects g; n - 1 for a complete graph (by brute force)."""
n = len(g)
if all(len(g[v]) == n - 1 for v in g):
return n - 1
return next(k for k in range(n) for S in combinations(sorted(g), k) if not connected(g, S))
def kappa_edges(g):
"""Fewest edges whose removal disconnects g (by brute force over edge sets)."""
E = edges_of(g)
return next(k for k in range(len(E) + 1) for F in combinations(E, k) if not connected(g, (), F))
K4_left = list(combinations(range(4), 2))
K4_right = [(a + 4, b + 4) for a, b in K4_left]
N = network(K4_left + K4_right + [(3, 4), (3, 5)])
assert len(edges_of(N)) == 14 and min(len(N[v]) for v in N) == 3
assert kappa(N) == 1 and kappa_edges(N) == 2
That is fine for fourteen cables, but the number of cable sets grows like . And it proves nothing a reader can check without rerunning it. The rest of the module replaces "try everything" with definitions you can reason about and short evidence: a set of routers or cables whose removal visibly splits the network.
Let be a graph with vertices.
Two words are easy to blur, so this course keeps them apart: a disconnecting set is minimum if no disconnecting set has fewer edges, and minimal if no proper subset of it disconnects.
Both are 4. is the convention. For , isolating one vertex takes its 4 edges, and no 3 edges can split : Whitney's inequality below gives .
An edge cut always disconnects: in no edge joins to , and both are nonempty. The converse is the useful direction.
Lemma. In every graph, every disconnecting set contains an edge cut. If is a minimal disconnecting set, it is an edge cut.
Proof. is disconnected; let be the vertex set of one of its components. Then is nonempty, and is nonempty because has another component. An edge of from to cannot survive in , or its end in would belong to the component . So . If is minimal, then , being itself a disconnecting subset of , must equal .
So is the smallest over nonempty proper subsets : a search over sets of vertices instead of sets of edges. In the smallest edge cut is with , the two cables – and –.
Proposition. An edge of is a cut edge if and only if lies on no cycle of .
Proof. First, is a cut edge exactly when has no -path. If has a -path, every walk that used can detour along it, so no two vertices are separated and the number of components stays the same. If it has none, and , which were in one component of , lie in different components of , so the number of components grows. If lies on a cycle, the rest of the cycle is a -path in , so is not a cut edge. Conversely, if has a -path , then together with is a cycle through .
In every cable lies on a triangle, including – (on the triangle ), so has no cut edge, even though router is a cut vertex:
assert [e for e in edges_of(N) if not connected(N, (), [e])] == []
assert [v for v in N if not connected(N, [v])] == [3]
Whitney's inequality (1932)
For every graph , , where is the minimum degree.
The right half is one line: the edges at a vertex of minimum degree form a disconnecting set (when has another vertex), so . The left half needs an idea. Here it is on .
Start from the minimum edge cut with and . Pick and that are not adjacent: , . Now collect a set of vertices:
So , and deleting it separates from :
X, Y = {0, 1, 2, 3}, {4, 5, 6, 7}
F = [(u, v) for u in sorted(X) for v in sorted(N[u]) if v in Y]
T = {3} # the two rules above, applied by hand
assert F == [(3, 4), (3, 5)] and 4 not in N[0]
assert not connected(N, T) and len(T) <= len(F)
Proof of . If has one vertex, both sides are 0 by the conventions. Otherwise let be a minimum disconnecting set; by the lemma it is an edge cut , with .
Case 1: every vertex of is adjacent to every vertex of . Then
(The middle inequality is . And for every graph: for by the convention, and otherwise deleting all vertices but two non-adjacent ones separates them.)
Case 2: some and are not adjacent. Let consist of the neighbors of in together with the vertices of that have a neighbor in .
So is a separating set with , and .
Proof moves used here. The same moves recur all semester:
Both inequalities can be strict, separately or together. Computed with the brute-force helpers above:
| graph | |||
|---|---|---|---|
| two 's sharing one vertex | 1 | 3 | 3 |
| two 's joined by one edge | 1 | 1 | 3 |
| : two 's joined by two edges at one vertex | 1 | 2 | 3 |
| Petersen graph | 3 | 3 | 3 |
shared = network(K4_left + [(a + 3, b + 3) for a, b in K4_left]) # both contain vertex 3
bridge = network(K4_left + K4_right + [(3, 4)])
petersen = network([(i, (i + 1) % 5) for i in range(5)] + [(i, i + 5) for i in range(5)]
+ [(5, 7), (7, 9), (9, 6), (6, 8), (8, 5)])
def delta(g):
return min(len(g[v]) for v in g)
rows = [(kappa(g), kappa_edges(g), delta(g)) for g in (shared, bridge, N, petersen)]
assert rows == [(1, 3, 3), (1, 1, 3), (1, 2, 3), (3, 3, 3)]
For 3-regular graphs the first inequality is always an equality: if is 3-regular, then (West, Theorem 4.1.11). We state it without proof here. The Petersen graph is an instance: .
A separating set of size proves , and anyone can check it with one search over the remaining graph, in time. An edge cut proves the same way. The lemma above means a search for needs only the splits of the vertices, not the sets of edges. For that is 127 splits against 16,384 edge sets:
assert 2 ** (8 - 1) - 1 == 127 and 2 ** 14 == 16_384
Proving the lower bound, that no smaller cut exists, is a different matter. Short evidence for it exists too: for every two non-adjacent vertices, paths between them that share no internal vertex ( holds exactly when such paths exist for every non-adjacent pair, in a graph that is not complete). That is Menger's theorem, two modules from now.
A town wants to make every street one-way, and still let every resident drive from any corner to any other. For which street maps is that possible? If one street is the only link between two halves of town, it clearly fails. Is that the only obstacle? Nothing in the question mentions cuts. The lab's last exercise is a different problem that also hides its structure.
The lab runs in your browser. Your own code turns an edge cut into a separating set, one charged edge per frame, the way the proof does. Then you compute by searching splits of the vertices, and watch a tempting shortcut fail. Half of the lab is proofs. You assemble a proof about the ends of a cut edge, with decoys among the steps. You find the false step in a convincing argument and build a counterexample in code. And you finish with a growing network that does not say what it is, where you write the proof yourself and check it against explicit criteria.
node_connectivity and edge_connectivity compute
and by maximum-flow computations, not by subset search.After the lab, the tutor will ask you to defend your work out loud:
Topic list modeled on the public syllabus of UIUC Math 412 (Graph Theory), which follows D. B. West, Introduction to Graph Theory, 2nd ed., Chapters 1–7. All lessons, proofs, examples, code and exercises here are original. This course is independent and not affiliated with or endorsed by the University of Illinois.