Skip to content

Commit 1b6c126

Browse files
authored
refactor(tearing): use OrderedSet instead of sort() for deterministic SCC tearing
1 parent 5c8c3cd commit 1b6c126

1 file changed

Lines changed: 7 additions & 10 deletions

File tree

src/carpanzano_tearing.jl

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ function (alg::CarpanzanoTearing)(structure::SystemStructure)
5252
full_var_eq_matching = copy(var_eq_matching)
5353
var_sccs = find_var_sccs(graph, var_eq_matching)
5454

55-
active_vars = Set{Int}()
56-
active_eqs = Set{Int}()
55+
active_vars = OrderedSet{Int}()
56+
active_eqs = OrderedSet{Int}()
5757
for vars in var_sccs
5858
for var in vars
5959
# Identify variables and equations in this SCC
@@ -87,13 +87,12 @@ In the context of the paper, `structure.graph` is the associated bipartite graph
8787
"""
8888
function find_single_solvable_eq!(
8989
structure::SystemStructure, var_eq_matching::MatchingT,
90-
active_vars::Set{Int}, active_eqs::Set{Int}, condition::F = _ -> true;
90+
active_vars::AbstractSet{Int}, active_eqs::AbstractSet{Int}, condition::F = _ -> true;
9191
nbors_buffer::Vector{Int} = Int[]
9292
) where {F}
9393
(; graph, solvable_graph) = structure
9494
nbors = nbors_buffer
95-
# Sort active_eqs iteration for deterministic equation selection regardless of hash order
96-
for ieq in sort(collect(active_eqs))
95+
for ieq in active_eqs
9796
empty!(nbors)
9897
append!(nbors, Iterators.filter(in(active_vars), 𝑠neighbors(graph, ieq)))
9998
length(nbors) == 1 || continue
@@ -117,7 +116,7 @@ all of `active_vars` to `unassigned`, and will be modified to match solvable var
117116
"""
118117
function carpanzano_tear_scc!(
119118
alg::CarpanzanoTearing, structure::SystemStructure, var_eq_matching::MatchingT,
120-
active_vars::Set{Int}, active_eqs::Set{Int}
119+
active_vars::AbstractSet{Int}, active_eqs::AbstractSet{Int}
121120
)
122121
# TODO: This is an implementation of algorithm A1 in the paper. Find an efficient
123122
# way to implement algorithm A2 and analyze the benefits.
@@ -162,8 +161,7 @@ function carpanzano_tear_scc!(
162161
# is the corresponding number of incident edges.
163162
empty!(enodes_with_min_incidence)
164163
min_incidence_cnt = typemax(Int)
165-
# Sort active_eqs for deterministic tie-breaking regardless of hash order
166-
for ieq in sort(collect(active_eqs))
164+
for ieq in active_eqs
167165
cnt = count(in(active_vars), 𝑠neighbors(graph, ieq))
168166
cnt > min_incidence_cnt && continue
169167
if cnt == min_incidence_cnt
@@ -208,8 +206,7 @@ function carpanzano_tear_scc!(
208206
alg_var = 0
209207
max_incidence_cnt = typemin(Int)
210208
min_solvable_cnt = typemax(Int)
211-
# Sort active_vars for deterministic selection; also fix missing max/min updates
212-
for ivar in sort(collect(active_vars))
209+
for ivar in active_vars
213210
cnt = count(in(active_eqs), 𝑑neighbors(graph, ivar))
214211
solvable_cnt = count(in(active_eqs), 𝑑neighbors(solvable_graph, ivar))
215212
if iszero(alg_var) || cnt > max_incidence_cnt || cnt == max_incidence_cnt && solvable_cnt < min_solvable_cnt

0 commit comments

Comments
 (0)