Notes for 1/22/97 15-852 Randomized Algorithms
* the Minimum cut problem (Chapter 1.1, 10.2)
A simple, fast monte-carlo algorithm
===========================================================================
THE MINIMUM CUT PROBLEM
Given a graph G, a CUT is a set of edges whose removal splits the
graph into at least two connected components. The MINIMUM CUT is the
cut of minimum size. For instance, say this graph represents a
network, and we want to know how "robust" it is in the sense of the
the minimum number of links whose failure causes the network to become
disconnected. The minimum cut problem is to find a cut of minimum size.
Easy fact: the minimum cut has size at most the minimum degree of any node.
You're probably more familiar with the "s-t minimum cut" problem,
where you want a cut that separates to specific vertices s and t,
since this is the dual to the max flow problem. In fact, for a while,
the best algorithm for finding the global minimum cut was to solve the
s-t cut problem n times.
Here's a really simple randomized algorithm: [due to D. Karger]
THE SIMPLE ALGORITHM (view #1)
1. Pick an edge (x,y) at random in G.
2. CONTRACT the edge, keeping multi-edges, but removing self-loops.
(i.e., if there were edges (x,v) and (y,v), we keep both of them.)
3. If there are more than 2 nodes, go back to 1. Else, output the
edges remaining as your cut.
(Note: step 1 is NOT the same as picking two connected vertices x,y
at random. Why?)
Do example on graph: *-------*
/| |\
/ | | \
* | | *
\ | | /
\| |/
*-------*
Easy algorithm, want to show it has a reasonable (1/n^2) chance of working.
(So, run n^2 * log n times to get success w.h.p.)
EQUIVALENT FORMULATION:
1. Randomly rank the edges.
2. Use Kruskal to find minimum spanning tree (i.e., start with
lighted edge, then put in next lightest that connects two different
components, etc.)
3. remove the last edge. This gives you the two components.
ANALYSIS
--------
1) Say we fix some cut C. So long as none of edges in C have been
selected, C remains a cut. Reason: only contract edges, so things on
left side of C stay on left side, and things on right side stay on
right side.
2) in the course of the algorithm, does the min cut size go down or
up? Claim: any cut in the new graph is also a cut in the original
graph. Why? So, min cut size can't go down.
3) Say original graph has min cut of size k. Claim: when have n-i
nodes remaining (for some i>= 0), there are at least (n-i)k/2 edges in
the graph. Why?
The point of (3) is that we want to have lots of edges to reduce
the chance that we kill our favorite cut.
So,..... Fix some cut C of size k. What is the prob that C survives
the first round?
1 - k/(# edges) >= 1 - k/(nk/2) = 1 - 2/n.
Suppose it's survived so far, and there are now n-i vertices. Prov of
survival is at least:
1 - 2/(n-i).
So, prob that C survives overall is at least:
Prod_{i=0}^{n-3} (1 - 2/(n-i))
= (n-2)/n * (n-3)/(n-1) * (n-4)/(n-2) * ... * 1/3
= 2/(n(n-1))
Neat implication: How many minimum cuts are there? A: at most n(n-1)/2.
Running time: can implement in O(m log m) time, or O(n^2) time,
results in O(mn^2 log^2 n) overall if we run it O(n^2 log(n)) times.
Simple, but not all THAT fast. How can we speed all this up?
SPEEDING UP THE ALGORITHM [Due to D. Karger and C. Stein]
-------------------------
Claim: earlier steps are less risky than later steps. Why?
At what point is our chance of having lost C about 50/50?
Ans: when we have about n/sqrt(2) vertices left. By that time, our
success probability is about:
(n/sqrt(2))^2 / n^2 = 1/2.
So, this suggests a speedup:
Instead of repeating from the start, let's repeat from only
partway down. E.g., from when we had just n/sqrt(2) vertices left.
Idea: build a binary tree.
Depth is 2lg(n). # leaves is n^2.
Can think of as: each edge is independently destroyed with prob 1/2.
What's the probability some path to a leaf survives?
(can think of the strategy of doing n^2 repititions as a root
with n^2 branches leading, in depth 2lg(n) to n^2 leaves.)
First, what is running time:
T(n) = O(n^2) + 2T(n/sqrt(2)) = O(n^2 log n)
Now: want to show that a path survives with probability at least 1/log(n).
Proof:
For tree of depth d, let P_d be the probability a path survives.
Looking recursively, we get:
P_d = (1/2) P_{d-1} + (1/4)(1 - (1-P_{d-1})^2)
= (1/2) P_{d-1} + (1/4)(2P_{d-1} - (P_{d-1})^2)
= P_{d-1} - (1/4) (P_{d-1})^2.
We can now verify that P_d > 1/d, since:
1/(d-1) - 1/(4(d-1)^2) > 1/(d-1) - 1/(d(d-1)) = 1/d
So, we can just run our algorithm log^2(n) times to get good
probability of success.
One good way of looking at what we've shown is this: we have shown
that we can replace n^2 indepdendent runs of the algorithm by n^2
DEPENDENT runs of the algorithm in a way that drastically reduces
running time ((n^2 * cost-of-one-run) versus (log(n) * cost-of-one-run),
but only slightly reduces the chance of success (constant versus 1/log(n)).