The Batagelj-Zaversnik algorithm computes the core numbers full
This proof shows: correctness, termination.
Let G=(V,E) be a simple undirected graph with n vertices. For a set S⊆V and a vertex u, write rS(u) for the number of neighbours of u in S. Recall that core(v) is the largest k such that some set S∋v has rS(x)≥k for all x∈S.
Termination. Lines L1 to L6 are loops over V and over 0,…,md. Line L7 runs n times, and line L9 runs over the finite list Adj[v]. So the algorithm stops.
In iteration i of line L7 (counting from 0), call the vertices vert[i],…,vert[n−1] at its start the remaining vertices, and let Ri be their set. We show below that the loop never writes to vert[j] for j≤i in iteration i, so the vertex removed in iteration i is vi=vert[i], and Ri+1=Ri∖{vi}. Let Di be the value of deg[vi] at line L8, and let D−1=0.
Lemmas 1 and 2 are proved together, by induction on i.
Lemma 1 (the array). At the start of iteration i:
- vert is a permutation of V and pos is its inverse;
- deg[vert[i]]≤deg[vert[i+1]]≤⋯≤deg[vert[n−1]];
- for each d with deg[vert[i]]<d≤md, bin[d] is the least index j≥i with deg[vert[j]]≥d, or n if there is none.
Proof. At i=0: lines L3 and L4 set bin[d] to the number of vertices of degree less than d. Line L5 places the vertices of degree d at the indices bin[d],bin[d]+1,…, so vert is sorted by degree and pos is its inverse, and after line L5 each bin[d] holds the number of vertices of degree at most d. Line L6 shifts these values up by one place, from the top down so that no value is overwritten before it is read, so bin[d] is again the number of vertices of degree less than d, which is the least index of a vertex of degree at least d. This gives 1 to 3.
Now assume 1 to 3 at the start of iteration i, and let v=vert[i] and D=deg[v]. In the iteration, line L13 only changes deg[u] for a neighbour u with deg[u]>D, and lowers it by 1, so it never goes below D; and u=v since there are no self-loops, so deg[v]=D during the whole iteration. We show that one run of lines L11 to L13 keeps 1 and 2, and keeps 3 for all d>D, with j≥i read as j>i.
Let du=deg[u]>D. By 3, pw=bin[du] is the least index ≥i whose vertex has degree at least du. Since deg[v]=D<du, pw>i. Since u has degree du and sits at index pu≥i (it is remaining, because each removed vertex vj keeps deg[vj]=Dj≤D by Lemma 2), pw≤pu, and by 2 every index from pw to pu holds a vertex of degree exactly du. Line L12 swaps the entries at pw and pu and updates pos, so 1 holds, and the degrees along the array are unchanged, so 2 holds. Line L13 lowers the degree at index pw to du−1. All indices from i to pw−1 hold degrees at most du−1, and all indices after pw hold degrees at least du, so 2 still holds. For d=du, the least index with degree at least du is now pw+1 (or n), and line L13 sets bin[du]=pw+1. For other d>D, the set of indices with degree at least d did not change, so bin[d] stays right. No entry at an index ≤i was written, since pw>i and pu≥pw.
At the end of the iteration, the next vertex vert[i+1] has degree at least D by 2, so each d>deg[vert[i+1]] has d>D, and the least index j>i is the least index j≥i+1. So 1 to 3 hold at the start of iteration i+1. □
By Lemma 1, part 2, vi has the least deg value among the remaining vertices.
Lemma 2 (the degrees). At the start of iteration i, Di−1≤deg[u] and
deg[u]=max(Di−1,rRi(u))for each u∈Ri, and deg[vj]=Dj for each j<i. Moreover Di−1≤Di.
Proof. At i=0, R0=V, D−1=0 and deg[u]=∣Adj[u]∣=rV(u). Assume the claim at the start of iteration i, and let v=vi and D=Di=deg[v]. Since v has the least deg among the remaining vertices and each of them has deg≥Di−1, we get D≥Di−1. Let R′=Ri+1=Ri∖{v}. Take u∈R′.
- If u is a neighbour of v and deg[u]>D: then max(Di−1,rRi(u))>D≥Di−1, so deg[u]=rRi(u). Line L13 sets deg[u]=rRi(u)−1=rR′(u), which is at least D. So deg[u]=max(D,rR′(u)).
- If u is a neighbour of v and deg[u]≤D: then deg[u]=D by the choice of v, so rRi(u)≤D and rR′(u)<D. The value stays D=max(D,rR′(u)).
- If u is not a neighbour of v: rR′(u)=rRi(u) and deg[u] does not change. If rRi(u)≥Di−1, then deg[u]=rR′(u)≥D by the choice of v, which is max(D,rR′(u)). Else deg[u]=Di−1≥D≥Di−1, so D=Di−1=deg[u]>rR′(u), and again deg[u]=max(D,rR′(u)).
The value deg[v]=D is not changed in iteration i, as shown in Lemma 1. In later iterations, line L13 only lowers deg[x] when deg[x]>Dj≥D for the removed vj, and deg[v]=D, so it never touches v again; the same holds for each earlier vj. This gives the claim at the start of iteration i+1. □
So D0≤D1≤⋯≤Dn−1, and the returned value for vi is Di.
Theorem. For each i, Di=core(vi).
Proof. Lower bound. Let j≤i be the least index with Dj=Di. If j=0, then D0=minurV(u), so every vertex of R0=V has at least Di neighbours in R0. If j>0, then Dj>Dj−1. By Lemma 2, Dj=minu∈Rjmax(Dj−1,rRj(u)), so for each u∈Rj, max(Dj−1,rRj(u))≥Dj>Dj−1, which forces rRj(u)≥Dj. In both cases Rj is a set in which every vertex has at least Di neighbours, and it contains vi since j≤i. So core(vi)≥Di.
Upper bound. Let S∋vi be a set with rS(x)≥k for all x∈S. Let vj be the vertex of S that is removed first, so j≤i and S⊆Rj. Then rRj(vj)≥rS(vj)≥k, and by Lemma 2, Dj=deg[vj]≥rRj(vj)≥k. Since the D values do not decrease, Di≥Dj≥k. Taking k=core(vi) gives Di≥core(vi).
Line L14 returns deg, and by Lemma 2 at the end, deg[vi]=Di=core(vi) for every i. ■