Algorithm Search⌘K

Proofs: Hunt-Szymanski algorithm

These are the human proofs of Hunt-Szymanski algorithm, at full length.

The Hunt-Szymanski thresholds give the LCS length and the links give an LCS full

This proof shows: correctness.

We use the pseudocode of the page. A match is a pair (i,j)(i, j) with xi=yjx_i = y_j. A chain of length kk is a list of matches (i1,j1),…,(ik,jk)(i_1, j_1), \ldots, (i_k, j_k) with i1<⋯<iki_1 < \cdots < i_k and j1<⋯<jkj_1 < \cdots < j_k. The common subsequences of XX and YY with a fixed embedding are exactly the chains: the chain spells xi1⋯xikx_{i_1} \cdots x_{i_k}. For 0≤i≤m0 \le i \le m define

Ti[k]=min⁡{jk:(i1,j1),…,(ik,jk) is a chain with ik≤i},T_i[k] = \min\{ j_k : (i_1, j_1), \ldots, (i_k, j_k) \text{ is a chain with } i_k \le i \},

with Ti[0]=0T_i[0] = 0 (the empty chain) and Ti[k]=∞T_i[k] = \infty if no chain of length kk has all rows at most ii. So Ti[k]T_i[k] is the smallest jj such that X[1…i]X[1 \ldots i] and Y[1…j]Y[1 \ldots j] have a common subsequence of length kk.

Lemma 1 (monotone). If Ti[k]<∞T_i[k] < \infty for some k≥1k \ge 1, then Ti[k−1]<Ti[k]T_i[k - 1] < T_i[k].

Proof. Drop the last match of a chain of length kk that ends in column Ti[k]T_i[k]. This gives a chain of length k−1k - 1 with all rows at most ii that ends in a column below Ti[k]T_i[k] (or the empty chain, with end 0). □\square

Lemma 2 (row update). For i≥1i \ge 1 and k≥1k \ge 1,

Ti[k]=min⁡(Ti−1[k], min⁡{j:(i,j) is a match and Ti−1[k−1]<j}).T_i[k] = \min\big( T_{i-1}[k],\ \min\{ j : (i, j) \text{ is a match and } T_{i-1}[k - 1] < j \} \big).

Proof. A chain with rows at most ii either has all rows at most i−1i - 1, or its last match is in row ii; then it has only one match in row ii, since rows strictly increase, and the rest is a chain of length k−1k - 1 with rows at most i−1i - 1 that ends in a column below jj. Such a rest exists if and only if Ti−1[k−1]<jT_{i-1}[k - 1] < j. Conversely, each such rest followed by (i,j)(i, j) is a chain. Taking the smallest last column over both kinds gives the formula. □\square

Lemma 3 (one row of the loop). Suppose that before row ii, T[k]=Ti−1[k]T[k] = T_{i-1}[k] for all kk. Then after the loop of line L4 for row ii, T[k]=Ti[k]T[k] = T_i[k] for all kk.

Proof. Let the matches of row ii be (i,j1),…,(i,js)(i, j_1), \ldots, (i, j_s) with j1>⋯>jsj_1 > \cdots > j_s, the order of line L4, and let ktk_t be the index that line L5 returns for jtj_t. Writes of line L7 only lower an entry, and each value written in this row is some jt′j_{t'}.

Claim. When (i,jt)(i, j_t) is handled, each entry changed earlier in this row holds a value greater than jtj_t, and each other entry kk holds Ti−1[k]T_{i-1}[k]. This holds because the values written before are j1,…,jt−1j_1, \ldots, j_{t-1}, all greater than jtj_t.

The index ktk_t. For k<ktk < k_t, T[k]<jtT[k] < j_t, so by the claim T[k]T[k] is unchanged and Ti−1[k]=T[k]<jtT_{i-1}[k] = T[k] < j_t. At ktk_t, Ti−1[kt]≥jtT_{i-1}[k_t] \ge j_t: if T[kt]T[k_t] is unchanged, Ti−1[kt]=T[kt]≥jtT_{i-1}[k_t] = T[k_t] \ge j_t; if it was changed, then Ti−1[kt]T_{i-1}[k_t] is larger than each value written at ktk_t, and these are larger than jtj_t. With Lemma 1, ktk_t is the smallest kk with Ti−1[k]≥jtT_{i-1}[k] \ge j_t.

The update. By Lemma 2, jtj_t is a candidate for Ti[k]T_i[k] exactly when Ti−1[k−1]<jtT_{i-1}[k - 1] < j_t, that is, when k≤ktk \le k_t. For k<ktk < k_t the candidate does not matter, because Ti−1[k]<jtT_{i-1}[k] < j_t. So Ti[k]=min⁡(Ti−1[k],min⁡{jt:kt=k})T_i[k] = \min(T_{i-1}[k], \min\{ j_t : k_t = k \}). Lines L6 and L7 lower T[kt]T[k_t] to jtj_t if jtj_t is smaller, so after the row each T[k]T[k] is this minimum, which is Ti[k]T_i[k]. □\square

Lemma 4 (links). Whenever line L7 sets T[k]=jT[k] = j in row ii, link[k]\mathrm{link}[k] is a chain of length kk whose last match is (i,j)(i, j).

Proof. By induction over the writes. link[0]=nil\mathrm{link}[0] = \mathrm{nil} is the empty chain, which ends in column T[0]=0T[0] = 0. At a write of line L7 in row ii, the entry k−1k - 1 has not been changed in row ii (by the claim in the proof of Lemma 3, since T[k−1]<jT[k - 1] < j), so link[k−1]\mathrm{link}[k - 1] was set in an earlier row, or is the empty chain, and by induction it is a chain whose last match has row below ii and column T[k−1]<jT[k - 1] < j. Appending (i,j)(i, j) gives a chain of length kk. □\square

Theorem. HUNT-SZYMANSKI returns a longest common subsequence of XX and YY.

Proof. Before row 1, T=T0T = T_0: T0[0]=0T_0[0] = 0 and T0[k]=∞T_0[k] = \infty for k≥1k \ge 1, which is line L2. By Lemma 3 and induction on ii, after the loop T=TmT = T_m. A common subsequence of length kk exists if and only if Tm[k]<∞T_m[k] < \infty, and no chain is longer than min⁡(m,n)\min(m, n), so ℓ\ell of line L8 is lcs(X,Y)\mathrm{lcs}(X, Y). By Lemma 4, link[ℓ]\mathrm{link}[\ell] is a chain of length ℓ\ell, and lines L9 and L10 output its items in the order of the chain, which is a common subsequence of length lcs(X,Y)\mathrm{lcs}(X, Y). ■\blacksquare

Cost. Each match is handled once in line L4, with one binary search over at most min⁡(m,n)+1\min(m, n) + 1 entries in line L5 and O(1)O(1) other work, so the loop takes O(rlog⁡n+m)O(r \log n + m) time, and at most rr link nodes are made.

Back to Hunt-Szymanski algorithm