Skip to content

Commit 6134b6b

Browse files
committed
Improve the postprocessing for acyclic coloring
1 parent fdb55e8 commit 6134b6b

File tree

1 file changed

+92
-36
lines changed

1 file changed

+92
-36
lines changed

src/coloring.jl

Lines changed: 92 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -683,8 +683,9 @@ function postprocess!(
683683
end
684684

685685
# Process the trivial stars (if any)
686-
nb_unknown_hubs = nb_trivial_stars
687686
if nb_trivial_stars > 0
687+
nb_unknown_hubs = nb_trivial_stars
688+
688689
rvS = rowvals(S)
689690
for j in axes(S, 2)
690691
for k in nzrange(S, j)
@@ -712,35 +713,46 @@ function postprocess!(
712713
end
713714
end
714715
end
715-
end
716-
# Only trivial stars, where both vertices can be promoted as hubs, remain.
717-
# In the context of bicoloring, if we aim to minimize either the number of row colors or the number of column colors,
718-
# we can achieve optimal post-processing by choosing as hubs the vertices from the opposite partition.
719-
# This is optimal because we never increase the number of colors in the target partition during this phase,
720-
# and all preceding steps of the post-processing are deterministic.
721-
if nb_unknown_hubs > 0
722-
rvS = rowvals(S)
723-
for j in axes(S, 2)
724-
for k in nzrange(S, j)
725-
i = rvS[k]
726-
if i > j
727-
index_ij = edge_to_index[k]
728-
s = star[index_ij]
729-
h = hub[s]
730-
# The hub of this trivial star is still unknown
731-
if h < 0
732-
if postprocessing_minimizes == :row_colors
733-
# j bzlongs to a column partition in the context of bicoloring
734-
hub[s] = j
735-
color_used[color[j]] = true
736-
elseif postprocessing_minimizes == :column_colors
737-
# i belongs to a row partition in the context of bicoloring
738-
hub[s] = i
739-
color_used[color[i]] = true
740-
else postprocessing_minimizes == :all_colors
741-
l = abs(h)
742-
hub[s] = l
743-
color_used[color[l]] = true
716+
717+
# Only trivial stars, where both vertices can be promoted as hubs, remain.
718+
# In the context of bicoloring, if we aim to minimize either the number of row colors or the number of column colors,
719+
# we can achieve optimal post-processing by choosing as hubs the vertices from the opposite partition.
720+
# This is optimal because we never increase the number of colors in the target partition during this phase,
721+
# and all preceding steps of the post-processing are deterministic.
722+
if nb_unknown_hubs > 0
723+
rvS = rowvals(S)
724+
for j in axes(S, 2)
725+
for k in nzrange(S, j)
726+
i = rvS[k]
727+
if i > j
728+
index_ij = edge_to_index[k]
729+
s = star[index_ij]
730+
h = hub[s]
731+
# The hub of this trivial star is still unknown
732+
if h < 0
733+
h = abs(h)
734+
spoke = h == j ? i : j
735+
# We need to decide who is the hub
736+
if !color_used[color[i]] && !color_used[color[j]]
737+
if postprocessing_minimizes == :row_colors
738+
# j belongs to a column partition in the context of bicoloring
739+
hub[s] = j
740+
color_used[color[j]] = true
741+
elseif postprocessing_minimizes == :column_colors
742+
# i belongs to a row partition in the context of bicoloring
743+
hub[s] = i
744+
color_used[color[i]] = true
745+
else postprocessing_minimizes == :all_colors
746+
# We don't do anything special
747+
hub[s] = h
748+
color_used[color[h]] = true
749+
end
750+
else
751+
# Ensure that we use the correct hub for the decompression
752+
if color_used[color[spoke]] && !color_used[color[h]]
753+
hub[s] = spoke
754+
end
755+
end
744756
end
745757
end
746758
end
@@ -821,6 +833,8 @@ function postprocess!(
821833

822834
# Process the trivial trees (if any)
823835
if nb_trivial_trees > 0
836+
nb_unknown_roots = nb_trivial_trees
837+
824838
for k in 1:nt
825839
# Position of the first edge in the tree
826840
first = tree_edge_indices[k]
@@ -831,13 +845,55 @@ function postprocess!(
831845
# Check if we have exactly one edge in the tree
832846
if ne_tree == 1
833847
(i, j) = reverse_bfs_orders[first]
834-
if color_used[color[i]]
835-
# Make i the root to avoid possibly adding one more used color
836-
# Switch it with the (only) leaf
837-
reverse_bfs_orders[first] = (j, i)
848+
if color_used[color[j]]
849+
# The current root of this trivial tree is already an internal node in a non-trivial tree
850+
nb_unknown_roots -= 1
838851
else
839-
# Keep j as the root
840-
color_used[color[j]] = true
852+
if color_used[color[i]]
853+
# The current leaf of this trivial tree is also an internal node in a non-trivial tree
854+
# Switch the root and the leaf to avoid adding one more used color
855+
reverse_bfs_orders[first] = (j, i)
856+
nb_unknown_roots -= 1
857+
end
858+
end
859+
end
860+
end
861+
862+
# Only trivial trees, where both vertices can be promoted as roots, remain.
863+
# In the context of bicoloring, if we aim to minimize either the number of row colors or the number of column colors,
864+
# we can achieve optimal post-processing by choosing as roots the vertices from the opposite partition.
865+
# This is optimal because we never increase the number of colors in the target partition during this phase,
866+
# and all preceding steps of the post-processing are deterministic.
867+
if nb_unknown_roots > 0
868+
for k in 1:nt
869+
# Position of the first edge in the tree
870+
first = tree_edge_indices[k]
871+
872+
# Total number of edges in the tree
873+
ne_tree = tree_edge_indices[k + 1] - first
874+
875+
# Check if we have exactly one edge in the tree
876+
if ne_tree == 1
877+
(i, j) = reverse_bfs_orders[first]
878+
if !color_used[color[i]] && !color_used[color[j]]
879+
if postprocessing_minimizes == :row_colors
880+
# v belongs to a column partition in the context of bicoloring
881+
v = min(i,j)
882+
color_used[color[v]] = true
883+
elseif postprocessing_minimizes == :column_colors
884+
# v belongs to a row partition in the context of bicoloring
885+
v = max(i,j)
886+
color_used[color[v]] = true
887+
else postprocessing_minimizes == :all_colors
888+
# We don't do anything special
889+
color_used[color[j]] = true
890+
end
891+
else
892+
# Ensure that we use the correct root for the decompression
893+
if color_used[color[i]] && !color_used[color[j]]
894+
reverse_bfs_orders[first] = (j, i)
895+
end
896+
end
841897
end
842898
end
843899
end

0 commit comments

Comments
 (0)