Skip to content

Commit 5d994a1

Browse files
committed
Remove dictionary in acyclic coloring
1 parent b02a2d4 commit 5d994a1

2 files changed

Lines changed: 46 additions & 43 deletions

File tree

src/coloring.jl

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ function acyclic_coloring(g::AdjacencyGraph, order::AbstractOrder; postprocessin
332332
iszero(color[x]) && continue
333333
if forbidden_colors[color[x]] != v
334334
_prevent_cycle!(
335-
v, w, x, color, first_visit_to_tree, forbidden_colors, forest
335+
v, w, x, color, g, first_visit_to_tree, forbidden_colors, forest
336336
)
337337
end
338338
end
@@ -345,14 +345,14 @@ function acyclic_coloring(g::AdjacencyGraph, order::AbstractOrder; postprocessin
345345
end
346346
for w in neighbors(g, v) # grow two-colored stars around the vertex v
347347
iszero(color[w]) && continue
348-
_grow_star!(v, w, color, first_neighbor, forest)
348+
_grow_star!(v, w, color, g, first_neighbor, forest)
349349
end
350350
for w in neighbors(g, v)
351351
iszero(color[w]) && continue
352352
for x in neighbors(g, w)
353353
(x == v || iszero(color[x])) && continue
354354
if color[x] == color[v]
355-
_merge_trees!(v, w, x, forest) # merge trees T₁ ∋ vw and T₂ ∋ wx if T₁ != T₂
355+
_merge_trees!(v, w, x, g, forest) # merge trees T₁ ∋ vw and T₂ ∋ wx if T₁ != T₂
356356
end
357357
end
358358
end
@@ -373,12 +373,14 @@ function _prevent_cycle!(
373373
x::Integer,
374374
color::AbstractVector{<:Integer},
375375
# modified
376+
g::AdjacencyGraph,
376377
first_visit_to_tree::AbstractVector{<:Tuple},
377378
forbidden_colors::AbstractVector{<:Integer},
378379
forest::Forest{<:Integer},
379380
)
380381
wx = _sort(w, x)
381-
id = find_root!(forest, wx) # The edge wx belongs to the 2-colored tree T, represented by an edge with an integer ID
382+
index_wx = g.M[wx...]
383+
id = find_root!(forest, index_wx) # The edge wx belongs to the 2-colored tree T, represented by an edge with an integer ID
382384
(p, q) = first_visit_to_tree[id]
383385
if p != v # T is being visited from vertex v for the first time
384386
vw = _sort(v, w)
@@ -395,6 +397,7 @@ function _grow_star!(
395397
w::Integer,
396398
color::AbstractVector{<:Integer},
397399
# modified
400+
g::AdjacencyGraph,
398401
first_neighbor::AbstractVector{<:Tuple},
399402
forest::Forest{<:Integer},
400403
)
@@ -406,8 +409,10 @@ function _grow_star!(
406409
else # merge T_{vw} with a two-colored star being grown around v
407410
vw = _sort(v, w)
408411
pq = _sort(p, q)
409-
root1 = find_root!(forest, vw)
410-
root2 = find_root!(forest, pq)
412+
index_vw = g.M[vw...]
413+
index_pq = g.M[pq...]
414+
root1 = find_root!(forest, index_vw)
415+
root2 = find_root!(forest, index_pq)
411416
root_union!(forest, root1, root2)
412417
end
413418
return nothing
@@ -419,12 +424,15 @@ function _merge_trees!(
419424
w::Integer,
420425
x::Integer,
421426
# modified
427+
g::AdjacencyGraph,
422428
forest::Forest{<:Integer},
423429
)
424430
vw = _sort(v, w)
425431
wx = _sort(w, x)
426-
root1 = find_root!(forest, vw)
427-
root2 = find_root!(forest, wx)
432+
index_vw = g.M[vw...]
433+
index_wx = g.M[wx...]
434+
root1 = find_root!(forest, index_vw)
435+
root2 = find_root!(forest, index_wx)
428436
if root1 != root2
429437
root_union!(forest, root1, root2)
430438
end
@@ -445,10 +453,8 @@ struct TreeSet
445453
is_star::Vector{Bool}
446454
end
447455

448-
function TreeSet(forest::Forest{Int}, nvertices::Int)
449-
# Forest is a structure defined in forest.jl
450-
# - forest.intmap: a dictionary that maps an edge (i, j) to an integer k
451-
# - forest.num_trees: the number of trees in the forest
456+
function TreeSet(g::AdjacencyGraph{Int}, forest::Forest{Int}, nvertices::Int)
457+
# he number of trees in the forest
452458
nt = forest.num_trees
453459

454460
# dictionary that maps a tree's root to the index of the tree
@@ -460,31 +466,33 @@ function TreeSet(forest::Forest{Int}, nvertices::Int)
460466

461467
# counter of the number of roots found
462468
k = 0
463-
for edge in keys(forest.intmap)
464-
i, j = edge
465-
root = find_root!(forest, edge)
466-
467-
# Update roots
468-
if !haskey(roots, root)
469-
k += 1
470-
roots[root] = k
471-
end
469+
for j in axes(g.M, 2)
470+
for edge_index in nzrange(g.M, j)
471+
i = g.M.rowval[edge_index]
472+
root = find_root!(forest, edge_index)
473+
474+
# Update roots
475+
if !haskey(roots, root)
476+
k += 1
477+
roots[root] = k
478+
end
472479

473-
# index of the tree T that contains this edge
474-
index_tree = roots[root]
480+
# index of the tree T that contains this edge
481+
index_tree = roots[root]
475482

476-
# Update the neighbors of i in the tree T
477-
if !haskey(trees[index_tree], i)
478-
trees[index_tree][i] = [j]
479-
else
480-
push!(trees[index_tree][i], j)
481-
end
483+
# Update the neighbors of i in the tree T
484+
if !haskey(trees[index_tree], i)
485+
trees[index_tree][i] = [j]
486+
else
487+
push!(trees[index_tree][i], j)
488+
end
482489

483-
# Update the neighbors of j in the tree T
484-
if !haskey(trees[index_tree], j)
485-
trees[index_tree][j] = [i]
486-
else
487-
push!(trees[index_tree][j], i)
490+
# Update the neighbors of j in the tree T
491+
if !haskey(trees[index_tree], j)
492+
trees[index_tree][j] = [i]
493+
else
494+
push!(trees[index_tree][j], i)
495+
end
488496
end
489497
end
490498

@@ -576,7 +584,7 @@ function TreeSet(forest::Forest{Int}, nvertices::Int)
576584
is_star[k] = bool_star
577585
end
578586

579-
return TreeSet(reverse_bfs_orders, is_star)
587+
return TreeSet(g, reverse_bfs_orders, is_star)
580588
end
581589

582590
## Postprocessing, mirrors decompression code

src/forest.jl

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ mutable struct Forest{T<:Integer}
1414
num_edges::T
1515
"current number of distinct trees in the forest"
1616
num_trees::T
17-
"dictionary mapping each edge represented as a tuple of vertices to its unique integer index"
18-
intmap::Dict{Tuple{T,T},T}
1917
"vector storing the index of a parent in the tree for each edge, used in union-find operations"
2018
parents::Vector{T}
2119
"vector approximating the depth of each tree to optimize path compression"
@@ -25,16 +23,13 @@ end
2523
function Forest{T}(n::Integer) where {T<:Integer}
2624
num_edges = zero(T)
2725
num_trees = zero(T)
28-
intmap = Dict{Tuple{T,T},T}()
29-
sizehint!(intmap, n)
3026
parents = collect(Base.OneTo(T(n)))
3127
ranks = zeros(T, T(n))
32-
return Forest{T}(num_edges, num_trees, intmap, parents, ranks)
28+
return Forest{T}(num_edges, num_trees,parents, ranks)
3329
end
3430

3531
function Base.push!(forest::Forest{T}, edge::Tuple{T,T}) where {T<:Integer}
3632
forest.num_edges += 1
37-
forest.intmap[edge] = forest.num_edges
3833
forest.num_trees += one(T)
3934
return forest
4035
end
@@ -47,8 +42,8 @@ function _find_root!(parents::Vector{T}, index_edge::T) where {T<:Integer}
4742
return p
4843
end
4944

50-
function find_root!(forest::Forest{T}, edge::Tuple{T,T}) where {T<:Integer}
51-
return _find_root!(forest.parents, forest.intmap[edge])
45+
function find_root!(forest::Forest{T}, edge_index::T) where {T<:Integer}
46+
return _find_root!(forest.parents, edge_index)
5247
end
5348

5449
function root_union!(forest::Forest{T}, index_edge1::T, index_edge2::T) where {T<:Integer}

0 commit comments

Comments
 (0)