Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.

improved performance of core_number - credit to @abhinavmehndiratta #1281

Merged
merged 4 commits into from
Jan 29, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 50 additions & 27 deletions src/degeneracy.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Code in this file inspired by NetworkX.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we remove this?

Copy link
Owner Author

@sbromberger sbromberger Jan 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I had.

(edit: yes. That's what the red / - means :) )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry I meant as in, should this stay?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. The code was a 1:1 transcription of NetworkX before; now it's not. There's nothing tying this to NetworkX at this point.


"""
core_number(g)

Expand Down Expand Up @@ -39,35 +37,60 @@ julia> core_number(g)
"""
function core_number(g::AbstractGraph{T}) where T
has_self_loops(g) && throw(ArgumentError("graph must not have self-loops"))
degrees = degree(g)
vs = sortperm(degrees)
bin_boundaries = [1]
curr_degree = 0
for (i, v) in enumerate(vs)
if degrees[v] > curr_degree
append!(bin_boundaries, repeat([i], (degrees[v] - curr_degree)))
curr_degree = degrees[v]
end
n = nv(g)
deg = T.(degree(g)) # this will contain core number for each vertex of graph
maxdeg = maximum(deg) # maximum degree of a vertex in graph
bin = zeros(T, maxdeg+1) # used for bin-sort and storing starting positions of bins
vert = zeros(T, n) # contains the set of vertices, sorted by their degrees
pos = zeros(T, n) # contains positions of vertices in array vert

# count number of vertices will be in each bin
for v = 1:n
bin[deg[v]+1] += one(T)
end
# from bin sizes determine starting positions of bins in array vert
start = one(T)
for d = zero(T):maxdeg
num = bin[d+1]
bin[d+1] = start
start += num
end
# sort the vertices in increasing order of their degrees and store in array vert
for v in vertices(g)
pos[v] = bin[deg[v]+1]
vert[pos[v]] = v
bin[deg[v]+1] += one(T)
end
vertex_pos = sortperm(vs)
# initial guesses for core is degree
core = degrees
nbrs = [Set(all_neighbors(g, v)) for v in vertices(g)]
for v in vs
for u in nbrs[v]
if core[u] > core[v]
pop!(nbrs[u], v)
pos = vertex_pos[u]
bin_start = bin_boundaries[core[u] + 1]
vertex_pos[u] = bin_start
vertex_pos[vs[bin_start]] = pos
vs[bin_start], vs[pos] = vs[pos], vs[bin_start]
bin_boundaries[core[u] + 1] += 1
core[u] -= 1

# recover starting positions of the bins
for d = maxdeg:-1:one(T)
bin[d+1] = bin[d]
end
bin[1] = one(T)

# cores decomposition
for i = 1:n
v = vert[i]
# for each neighbor u of vertex v with higher degree we have to decrease its degree and move it for one bin to the left
for u in all_neighbors(g, v)
if deg[u] > deg[v]
du = deg[u]
pu = pos[u]
pw = bin[du+1]
w = vert[pw]
if u != w
pos[u] = pw
vert[pu] = w
pos[w] = pu
vert[pw] = u
end
bin[du+1] += one(T)
deg[u] -= one(T)
end
end
end
return core

return deg
end

"""
Expand Down