Skip to content

Commit df101d7

Browse files
authored
More efficient reset of visited vertices in order.jl (#244)
1 parent fc9d63a commit df101d7

File tree

1 file changed

+30
-49
lines changed

1 file changed

+30
-49
lines changed

src/order.jl

Lines changed: 30 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -88,25 +88,22 @@ end
8888
function vertices(bg::BipartiteGraph{T}, ::Val{side}, ::LargestFirst) where {T,side}
8989
other_side = 3 - side
9090
n = nb_vertices(bg, Val(side))
91-
visited = fill(false, n) # necessary for distance-2 neighborhoods
91+
visited = zeros(T, n) # necessary for distance-2 neighborhoods
9292
degrees_dist2 = zeros(T, n)
9393
for v in vertices(bg, Val(side))
9494
for u in neighbors(bg, Val(side), v)
9595
for w in neighbors(bg, Val(other_side), u)
96-
if w != v && !visited[w]
96+
if w != v && visited[w] != v
9797
degrees_dist2[v] += 1
98-
visited[w] = true # avoid double counting
98+
visited[w] = v # avoid double counting
9999
end
100100
end
101101
end
102-
for u in neighbors(bg, Val(side), v)
103-
for w in neighbors(bg, Val(other_side), u)
104-
visited[w] = false # reset only the toggled ones to false
105-
end
106-
end
107102
end
103+
# Recycle the vector visited to store the ordering
104+
visited .= 1:n
108105
criterion(v) = degrees_dist2[v]
109-
return sort(vertices(bg, Val(side)); by=criterion, rev=true)
106+
return sort!(visited; by=criterion, rev=true)
110107
end
111108

112109
const COLPACK_WARNING = """
@@ -273,7 +270,7 @@ function rotate_bucket_right!(db::DegreeBuckets, d::Integer)
273270
return nothing
274271
end
275272

276-
function update_bucket!(db::DegreeBuckets, v::Integer; degtype, direction)
273+
function update_bucket!(db::DegreeBuckets, v::Integer; degtype::Symbol, direction::Symbol)
277274
(; degrees, bucket_storage, bucket_low, bucket_high, positions, reproduce_colpack) = db
278275
d, p = degrees[v], positions[v]
279276
low, high = bucket_low[d + 1], bucket_high[d + 1]
@@ -336,19 +333,17 @@ function vertices(
336333
g::AdjacencyGraph{T}, order::DynamicDegreeBasedOrder{degtype,direction}
337334
) where {T<:Integer,degtype,direction}
338335
true_degrees = degrees = T[degree(g, v) for v in vertices(g)]
336+
max_degrees = maximum(true_degrees)
339337
if degree_increasing(; degtype, direction)
340-
degrees = zeros(T, nb_vertices(g))
341-
else
342-
degrees = true_degrees
338+
fill!(degrees, zero(T))
343339
end
344-
db = DegreeBuckets(
345-
T, degrees, maximum(true_degrees); reproduce_colpack=order.reproduce_colpack
346-
)
347-
π = T[]
348-
sizehint!(π, nb_vertices(g))
349-
for _ in 1:nb_vertices(g)
340+
db = DegreeBuckets(T, degrees, max_degrees; reproduce_colpack=order.reproduce_colpack)
341+
nv = nb_vertices(g)
342+
π = Vector{T}(undef, nv)
343+
index_π = (direction == :low2high) ? (1:nv) : (nv:-1:1)
344+
for index in index_π
350345
u = pop_next_candidate!(db; direction)
351-
direction == :low2high ? push!(π, u) : pushfirst!(π, u)
346+
π[index] = u
352347
for v in neighbors(g, u)
353348
!has_diagonal(g) || (u == v && continue)
354349
already_ordered(db, v) && continue
@@ -364,50 +359,36 @@ function vertices(
364359
other_side = 3 - side
365360
# compute dist-2 degrees in an optimized way
366361
n = nb_vertices(g, Val(side))
367-
degrees_dist2 = zeros(T, n)
368-
visited = fill(false, n)
362+
degrees_dist2 = degrees = zeros(T, n)
363+
visited = zeros(T, n)
369364
for v in vertices(g, Val(side))
370365
for w1 in neighbors(g, Val(side), v)
371366
for w2 in neighbors(g, Val(other_side), w1)
372-
if w2 != v && !visited[w2]
367+
if w2 != v && visited[w2] != v
373368
degrees_dist2[v] += 1
374-
visited[w2] = true
369+
visited[w2] = v
375370
end
376371
end
377372
end
378-
for w1 in neighbors(g, Val(side), v)
379-
for w2 in neighbors(g, Val(other_side), w1)
380-
visited[w2] = false
381-
end
382-
end
383373
end
374+
maxd2 = maximum(degrees_dist2)
384375
if degree_increasing(; degtype, direction)
385-
degrees = zeros(T, n)
386-
else
387-
degrees = degrees_dist2
376+
fill!(degrees, zero(T))
388377
end
389-
maxd2 = maximum(degrees_dist2)
390378
db = DegreeBuckets(T, degrees, maxd2; reproduce_colpack=order.reproduce_colpack)
391-
π = T[]
392-
sizehint!(π, n)
393-
fill!(visited, false)
394-
for _ in 1:nb_vertices(g, Val(side))
379+
π = Vector{T}(undef, n)
380+
index_π = (direction == :low2high) ? (1:n) : (n:-1:1)
381+
for index in index_π
395382
u = pop_next_candidate!(db; direction)
396-
direction == :low2high ? push!(π, u) : pushfirst!(π, u)
383+
π[index] = u
397384
for w in neighbors(g, Val(side), u)
398385
for v in neighbors(g, Val(other_side), w)
399-
if v == u || visited[v]
400-
continue
401-
else
402-
visited[v] = true
386+
if v != u && visited[v] != -u
387+
# Use -u such that we don't need to fill "visited" with 0 after the computation of the dist-2 degrees
388+
visited[v] = -u
389+
already_ordered(db, v) && continue
390+
update_bucket!(db, v; degtype, direction)
403391
end
404-
already_ordered(db, v) && continue
405-
update_bucket!(db, v; degtype, direction)
406-
end
407-
end
408-
for w in neighbors(g, Val(side), u)
409-
for v in neighbors(g, Val(other_side), w)
410-
visited[v] = false # reset only the toggled ones to false
411392
end
412393
end
413394
end

0 commit comments

Comments
 (0)