MIT 6.1220 — Lecture 5

Randomized Algorithms

Definition. There are two types of randomized algorithms.

Problem. (Matrix Product) Given n×nn \times n matrices AA and BB, compute ABAB.

You could just compute Θ(n2)\Theta(n^2) dot products, each of which takes Θ(n)\Theta(n) time, yielding Θ(n3)\Theta(n^3) runtime.

Remark. If you're smarter about it, you might discover Strassen's divide-and-conquer algorithm, with recursion T(n)=7T(n2)+Θ(n2)T(n) = 7T\left(\frac{n}{2}\right) + \Theta(n^2), yielding a runtime of T(n)=nlog2(7)n2.81T(n) = n^{\log_2(7)} \approx n^{2.81}.

The best algorithm we've achieved so far is Θ(n2.371339)\Theta(n^{2.371339\dots}).

Problem. (Matrix Product Verification) Given n×nn \times n matrices A,B,CF2n×nA, B, C \in \mathbb{F}_2^{n \times n}, verify whether AB=CAB = C.

Solution. (Randomized Solution #1) Pick a random nonzero vF2nv \in \mathbb{F}_2^n. Check whether Cv=A(Bv)Cv = A(Bv) in Θ(n2)\Theta(n^2) time.

This is a guaranteed success if det(CAB)0\det(C - AB) \neq 0, and performs worse the lower the nonzero rank of CABC - AB is. Notably, if CABC \neq AB, the algorithm succeeds with probability at least 12\frac{1}{2}.

Thus, we could run this algorithm multiple times to decrease the false positive rate.

Problem. (Rank Finding) Let AA be an unsorted array of NN numbers, and let r[1,N]r \in [1, N] be a rank.

Output the rthr^{\text{th}} smallest number (i.e. the unique number with rank rr).

Recall the following solution outline, altered slightly to integrate randomness:

Solution. (Quick Select) Pick a random pivot xAx \in A, with L(x):={yAy<x}L(x) := \{ y \in A \mid y < x\} and G(x):={yAy>x}G(x) := \{ y \in A \mid y > x \}. Then recurse either on L(x)L(x) or G(x)G(x), depending on whether L(x)r|L(x)| \geq r.

We can sacrifice a little time complexity to make the analysis simpler, too.

Solution. (Paranoid Select) Randomly try pivots xAx \in A until xx is 34\frac{3}{4}-balanced, that is, 14ARank(x)34A\frac{1}{4}|A| \leq \textsc{Rank}(x) \leq \frac{3}{4}|A|.

In expectation, Paranoid Select requires two tries to pick a good xx, yielding Θ(N)\Theta(N) runtime in expectation.

Remark. Though the analysis of Paranoid Select is simpler, it turns out Quick Select is just better in practice.

Problem. (Sorting) Just sort an array AA.

Solution. (Paranoid Quick Sort) Pick a random pivot xAx \in A, and compute L(x)L(x) and G(x)G(x). Then write QS(L)+{x}+QS(G)\textsc{QS}(L) + \{x\} + \textsc{QS}(G). Pick xx by randomly trying pivots until a 34\frac{3}{4}-balance is achieved.

This yields the following recurrence:

T(n)maxn4i3n4{T(i)+T(ni)}+Θ(n)T(n4)+T(3n4)+Θ(n),T(n) \leq \max_{\frac{n}{4} \leq i \leq \frac{3n}{4}} \{ T(i) + T(n - i) \} + \Theta(n) \leq T\left(\dfrac{n}{4}\right) + T\left(\dfrac{3n}{4}\right) + \Theta(n),

which solves to T(n)=Θ(nlogn)T(n) = \Theta(n \log n). (We skipped over the step of showing i=n4i = \frac{n}{4} is worst-case.)

To finish, we'll analyze the non-paranoid version of quick sort: what happens if we allow randomly-chosen unbalanced pivots?

Chernoff Bound. For a binomial random variable Y=B(n,p)Y = B(n, p) and β[0,1]\beta \in [0, 1]:

E[Y]=np   and   P[Y(1+β)np]e13β2np.\mathbb{E}[Y] = np ~~ \text{ and } ~~ \mathbb{P}[Y \geq (1 + \beta) \cdot np] \leq e^{-\frac{1}{3} \beta^2 np}.

For example, when β=0.2\beta = 0.2, this upper-bounds the probability
that a binomial variable exceeds its expected value by 20%20\%.

Claim. With high probability (e.g., at least 11n1 - \frac{1}{n}), Quick Sort runs in O(nlogn)O(n \log n) time.

Proof: Call a choice of pivot good if it is 34\frac{3}{4}-balanced, and bad otherwise.

Suppose a run of Quick Sort goes to depth LL. We'd like to show that for any aiAa_i \in A, if we follow aia_i down LL steps of the recursion tree, then with high probability aia_i encounters sufficiently many good pivots.

To be precise, let's define for every index ii a set of indicator variables (Yi,1, Yi,2, , Yi,L)(Y_{i, 1}, \ Y_{i, 2}, \ \dots, \ Y_{i, L}).

Yi,k:={1if ai is involved in a bad pivot at depth k0if ai is involved in a good pivot at depth kY_{i, k} := \begin{cases} 1 & \text{if } a_i \text{ is involved in a bad pivot at depth } k \\ 0 & \text{if } a_i \text{ is involved in a good pivot at depth } k \end{cases}

We want aia_i to encounter good pivots, so we want Yi=k=1LYi,kY_i = \sum_{k = 1}^L Y_{i, k} to (probably) be small. Well, Yi=B(L,0.5)Y_i = B(L, 0.5), so:

P[Yi0.6L]e13(0.2)2L(0.5)=e1150L      P[Yi0.6L]1e1150L.\mathbb{P}[Y_i \geq 0.6L] \leq e^{-\frac{1}{3} (0.2)^2 L (0.5)} = e^{-\frac{1}{150}L} ~ \implies ~ \mathbb{P}[Y_i \leq 0.6L] \geq 1 - e^{-\frac{1}{150}L}.

We must declare a logarithmic depth LL for which the following hold:

  1. If Yi0.6LY_i \leq 0.6L for all ii, then Quick Sort has succeeded (i.e. no aia_i is still in a subset with >1>1 size).

  2. The probability that Yi0.6LY_i \leq 0.6L for all ii is high.

We claim L=300lnnL = 300 \cdot \ln n works. For part 1, the condition Yi0.6LY_i \leq 0.6L (i.e. at least 0.4L0.4L good pivots) tells us:

size of the subset containing ai at depth Ln(34)0.4L=nnln(34)×0.4×300n33<1.\text{size of the subset containing } a_i \text{ at depth } L \leq n \cdot \left(\dfrac{3}{4}\right)^{0.4L} = n \cdot n^{\ln \left(\frac{3}{4}\right) \times 0.4 \times 300} \approx n^{-33} < 1.

For part 2, we can use the union bound:

P[Yi0.6L]e1150L=1n2      P[Yi0.6L for some i]n1n2=1n.\mathbb{P}[Y_i \geq 0.6L] \leq e^{-\frac{1}{150}L} = \dfrac{1}{n^2} ~ \implies ~ \mathbb{P}[Y_i \geq 0.6L \text{ for some } i] \leq n \cdot \dfrac{1}{n^2} = \dfrac{1}{n}.

So with probability at least 11n1 - \frac{1}{n}, every aia_i is “done with quick sort” by depth L=300lnnL = 300 \cdot \ln n. Since the depth LL is logarithmic in nn, this means Quick Sort has run in O(nlogn)O(n \log n) time, as desired.   \blacksquare

Remark. We could have set L=15000lnnL = 15000 \cdot \ln n to show that Quick Sort runs in O(nlogn)O(n \log n) time with probability at least 11n991 - \frac{1}{n^{99}}. This sounds even better, but the cost of this improvement is hidden in the big-OO.

In the very likely case that Quick Sort finishes with depth at most L=15000lnnL = 15000 \cdot \ln n, the coefficient of the bound on the time complexity is very large. So it'd be a pretty bad O(nlogn)O(n \log n).

Thus, we care about achieving “high probability”, but not how high that “high probability” is.