@@ -650,7 +650,8 @@ function postprocess!(
650650 color:: AbstractVector{<:Integer} ,
651651 star_or_tree_set:: Union{StarSet,TreeSet} ,
652652 g:: AdjacencyGraph ,
653- offsets:: AbstractVector{<:Integer} ,
653+ offsets:: AbstractVector{<:Integer} ;
654+ neutralized_first:: Symbol = :rows ,
654655)
655656 S = pattern (g)
656657 edge_to_index = edge_indices (g)
@@ -683,6 +684,7 @@ function postprocess!(
683684 end
684685
685686 # Process the trivial stars (if any)
687+ nb_nunknown_hubs = nb_trivial_stars
686688 if nb_trivial_stars > 0
687689 rvS = rowvals (S)
688690 for j in axes (S, 2 )
@@ -695,12 +697,47 @@ function postprocess!(
695697 if h < 0
696698 h = abs (h)
697699 spoke = h == j ? i : j
698- if color_used[color[spoke]]
699- # Switch the hub and the spoke to possibly avoid adding one more used color
700- hub[s] = spoke
700+ if color_used[color[h]]
701+ # The current hub of this trivial star is already a hub in a non-trivial star
702+ hub[s] = h
703+ nb_unknown_hubs -= 1
701704 else
702- # Keep the current hub
703- color_used[color[h]] = true
705+ if color_used[color[spoke]]
706+ # The current spoke of this trivial star is also a hub in a non-trivial star
707+ # Switch the hub and the spoke to avoid adding one more used color
708+ hub[s] = spoke
709+ nb_unknown_hubs -= 1
710+ end
711+ end
712+ end
713+ end
714+ end
715+ end
716+ end
717+ # Only trivial stars where both vertices can be promoted as hub are remaining.
718+ # In the context of bicoloring, if we want to minimize the number of row colors OR the number of column colors,
719+ # we can have the optimal post-processing by taking as hub the vertices in the other partition.
720+ # It is optimal because we will never increase the number of colors in the partition specified by `neutralized_first`
721+ # in this phase and everything else in the post-processing is deterministed.
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+ if neutralized_first == :rows
734+ # j represents a column in the context of bicoloring
735+ hub[s] = j
736+ color_used[j] = true
737+ else # neutralized_first == :cols
738+ # i represents a row in the context of bicoloring
739+ hub[s] = i
740+ color_used[i] = true
704741 end
705742 end
706743 end
0 commit comments