Algorithm Search⌘K

Proofs: Compressed sparse column

These are the human proofs of Compressed sparse column, at full length.

BUILD-FROM-CSR makes a valid compressed sparse column array and the queries answer for the stored graph full

This proof shows: correctness, termination.

Let GG be a directed graph on {0,…,n−1}\{0, \ldots, n-1\} with mm distinct edges, given by CSR arrays off\mathit{off} and adj\mathit{adj}: the row adj[off[u]…off[u+1]−1]\mathit{adj}[\mathit{off}[u] \ldots \mathit{off}[u+1] - 1] lists the heads of the edges out of uu, each once, and off[n]=m\mathit{off}[n] = m. Write d−(v)d^-(v) for the number of edges into vv. The CSC arrays stand for the graph with an edge (u,v)(u, v) for each uu in the column src[coff[v]…coff[v+1]−1]\mathit{src}[\mathit{coff}[v] \ldots \mathit{coff}[v+1] - 1]. The invariant (K) is (K1) on the offsets and (K2) strictly sorted columns.

Lemma 1 (offsets). After line L3, coff[v]=∑x<vd−(x)\mathit{coff}[v] = \sum_{x < v} d^-(x) for 0≤v≤n0 \le v \le n. So (K1) holds and the column of vv has d−(v)d^-(v) slots.

Proof. Line L2 reads each of the mm entries of adj\mathit{adj} once, and each entry is the head of one edge, so afterwards cnt[x+1]=d−(x)\mathit{cnt}[x + 1] = d^-(x). Line L3 then computes the prefix sums, so the claim follows by induction on vv, with coff[n]=∑xd−(x)=m\mathit{coff}[n] = \sum_x d^-(x) = m and coff[v+1]−coff[v]=d−(v)≥0\mathit{coff}[v+1] - \mathit{coff}[v] = d^-(v) \ge 0. □\square

Lemma 2 (placement). After lines L5 to L7, the column of each vv holds exactly the tails of the edges into vv, in increasing order.

Proof. Lines L5 and L6 visit the CSR entries row by row, for u=0,1,…,n−1u = 0, 1, \ldots, n-1, so they visit each edge (u,v)(u, v) once, in non-decreasing order of uu. We claim that before each visit, for each vv, pos[v]=coff[v]+kv\mathit{pos}[v] = \mathit{coff}[v] + k_v, where kvk_v is the number of edges into vv visited so far, and the slots coff[v],…,pos[v]−1\mathit{coff}[v], \ldots, \mathit{pos}[v] - 1 hold their tails in the order of the visits. This holds after line L4 with kv=0k_v = 0, and line L7 keeps it by writing uu at slot pos[v]\mathit{pos}[v] and increasing pos[v]\mathit{pos}[v]. Since kv≤d−(v)k_v \le d^-(v), each write stays within the column of vv by Lemma 1. At the end kv=d−(v)k_v = d^-(v), so each column is full and holds exactly the tails of the edges into vv, in the order of the visits, which is non-decreasing in uu. The edges are distinct, so two edges into vv have different tails, and the column is strictly increasing. The loops run over nn rows and mm entries, so they stop. □\square

So after BUILD-FROM-CSR, (K) holds and the stored graph is GG.

Theorem. With (K) holding, IN-NEIGHBORS(v)(v) outputs the tails of the edges into vv in increasing order, IN-DEGREE(v)(v) returns d−(v)d^-(v), and ADJACENT(u,v)(u, v) returns whether (u,v)(u, v) is an edge. Each of them stops.

Proof. IN-NEIGHBORS reads exactly the column of vv, which by Lemma 2 is the sorted list of the tails. IN-DEGREE returns the length of the column, which is d−(v)d^-(v) by Lemma 1.

For ADJACENT, let a=coff[v]a = \mathit{coff}[v] and b=coff[v+1]b = \mathit{coff}[v+1]. The loop of lines L11 to L13 keeps the condition that a≤lo≤hi≤ba \le \mathit{lo} \le \mathit{hi} \le b, each entry of the column at an index in [a,lo)[a, \mathit{lo}) is less than uu, and each entry at an index in [hi,b)[\mathit{hi}, b) is at least uu. Line L10 makes it true with empty ranges. In a step, lo≤mid<hi\mathit{lo} \le \mathit{mid} < \mathit{hi}; if src[mid]<u\mathit{src}[\mathit{mid}] < u then, as the column is sorted, all entries up to mid\mathit{mid} are less than uu, and lo←mid+1\mathit{lo} \leftarrow \mathit{mid} + 1 keeps the condition; otherwise all entries from mid\mathit{mid} on are at least uu, and hi←mid\mathit{hi} \leftarrow \mathit{mid} keeps it. Each step shrinks hi−lo\mathit{hi} - \mathit{lo}, so the loop stops with lo=hi\mathit{lo} = \mathit{hi}. Then uu, if it is in the column, can only be at index lo\mathit{lo}, so line L14 returns true exactly when uu is in the column of vv, that is, when (u,v)(u, v) is an edge. ■\blacksquare

Back to Compressed sparse column