Skip to content

Commit 3de24bc

Browse files
committed
Detect stars in the forest for acyclic coloring
1 parent 2fba12e commit 3de24bc

3 files changed

Lines changed: 44 additions & 9 deletions

File tree

src/coloring.jl

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ $TYPEDFIELDS
435435
"""
436436
struct TreeSet
437437
reverse_bfs_orders::Vector{Vector{Tuple{Int,Int}}}
438+
is_star::Vector{Bool}
438439
end
439440

440441
function TreeSet(forest::DisjointSets{Tuple{Int,Int}}, nvertices::Int)
@@ -499,9 +500,19 @@ function TreeSet(forest::DisjointSets{Tuple{Int,Int}}, nvertices::Int)
499500
# Create a queue with a fixed size nvmax
500501
queue = Vector{Int}(undef, nvmax)
501502

503+
# Specify if each tree in the forest is a star,
504+
# meaning that one vertex is directly connected to all other vertices in the tree
505+
is_star = Vector{Bool}(undef, ntrees)
506+
502507
for k in 1:ntrees
503508
tree = trees[k]
504509

510+
# Boolean indicating whether the current tree is a star (a single central vertex connected to all others)
511+
bool_star = true
512+
513+
# Candidate hub vertex if the current tree is a star
514+
virtual_hub = 0
515+
505516
# Initialize the queue to store the leaves
506517
queue_start = 1
507518
queue_end = 0
@@ -527,10 +538,24 @@ function TreeSet(forest::DisjointSets{Tuple{Int,Int}}, nvertices::Int)
527538
degrees[leaf] = 0
528539

529540
for neighbor in tree[leaf]
541+
# Check if neighbor is the parent of the leaf or if it was a child before the tree was pruned
530542
if degrees[neighbor] != 0
531543
# (leaf, neighbor) represents the next edge to visit during decompression
532544
push!(reverse_bfs_orders[k], (leaf, neighbor))
533545

546+
if bool_star
547+
# Initialize the potential hub of the star with the first parent of a leaf
548+
if virtual_hub == 0
549+
virtual_hub = neighbor
550+
else
551+
# Verify if the tree still qualifies as a star
552+
# If we find leaves with different parents, then it can't be a star
553+
if virtual_hub != neighbor
554+
bool_star = false
555+
end
556+
end
557+
end
558+
534559
# reduce the degree of the neighbor
535560
degrees[neighbor] -= 1
536561

@@ -542,9 +567,12 @@ function TreeSet(forest::DisjointSets{Tuple{Int,Int}}, nvertices::Int)
542567
end
543568
end
544569
end
570+
571+
# Specify if the tree is a star or not
572+
is_star[k] = bool_star
545573
end
546574

547-
return TreeSet(reverse_bfs_orders)
575+
return TreeSet(reverse_bfs_orders, is_star)
548576
end
549577

550578
## Postprocessing, mirrors decompression code
@@ -605,17 +633,23 @@ function postprocess!(
605633
end
606634
else
607635
# only the colors of non-leaf vertices are used
608-
(; reverse_bfs_orders) = star_or_tree_set
636+
(; reverse_bfs_orders, is_star) = star_or_tree_set
609637
nb_trivial_trees = 0
610638

611639
# Iterate through all non-trivial trees
612640
for k in eachindex(reverse_bfs_orders)
613641
reverse_bfs_order = reverse_bfs_orders[k]
614-
# Check if we have more than one edge in the tree
642+
# Check if we have more than one edge in the tree (non-trivial tree)
615643
if length(reverse_bfs_order) > 1
616-
# TODO: Optimize by avoiding iteration over all edges
617-
# Only one edge is needed if we know if it is a normal tree or a star
618-
for (i, j) in reverse_bfs_order
644+
# Determine if the tree is a star
645+
if is_star[k]
646+
# It is a non-trivial star and only the color of the hub is needed
647+
(_, hub) = reverse_bfs_order[1]
648+
color_used[color[hub]] = true
649+
else
650+
# It is not a star and both colors are needed during the decompression
651+
(i, j) = reverse_bfs_order[1]
652+
color_used[color[i]] = true
619653
color_used[color[j]] = true
620654
end
621655
else

src/decompression.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ function decompress!(
567567
for (i, j) in reverse_bfs_orders[k]
568568
val = B[i, color[j]] - buffer_right_type[i]
569569
buffer_right_type[j] = buffer_right_type[j] + val
570+
570571
if in_triangle(i, j, uplo)
571572
A[i, j] = val
572573
end

test/allocations.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ end
1919

2020
@testset "Distance-2 coloring" begin
2121
test_noallocs_distance2_coloring(1000)
22-
end;
22+
end
2323

2424
function test_noallocs_sparse_decompression(
2525
n::Integer; structure::Symbol, partition::Symbol, decompression::Symbol
@@ -121,7 +121,7 @@ end
121121
]
122122
test_noallocs_sparse_decompression(1000; structure, partition, decompression)
123123
end
124-
end;
124+
end
125125

126126
@testset "Structured decompression" begin
127127
@testset "$structure - $partition - $decompression" for (
@@ -131,4 +131,4 @@ end;
131131
]
132132
test_noallocs_structured_decompression(1000; structure, partition, decompression)
133133
end
134-
end;
134+
end

0 commit comments

Comments
 (0)