Skip to content

Commit f2eb1c2

Browse files
committed
[Nonlinear] add amontoison's Forest type and remove DataStructures.jl
1 parent 034a527 commit f2eb1c2

File tree

5 files changed

+61
-25
lines changed

5 files changed

+61
-25
lines changed

Project.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ version = "1.46.0"
66
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
77
CodecBzip2 = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd"
88
CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193"
9-
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
109
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
1110
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
1211
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
@@ -23,7 +22,6 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2322
BenchmarkTools = "1"
2423
CodecBzip2 = "0.6, 0.7, 0.8"
2524
CodecZlib = "0.6, 0.7"
26-
DataStructures = "0.18, 0.19"
2725
ForwardDiff = "0.10, 1"
2826
JSON3 = "1"
2927
JSONSchema = "1"

src/FileFormats/MPS/MPS.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module MPS
88

99
import ..FileFormats
1010
import MathOptInterface as MOI
11-
import DataStructures: OrderedDict
11+
import OrderedCollections: OrderedDict
1212

1313
const IndicatorLessThanTrue{T} =
1414
MOI.Indicator{MOI.ACTIVATE_ON_ONE,MOI.LessThan{T}}

src/Nonlinear/ReverseAD/Coloring/Coloring.jl

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66

77
module Coloring
88

9-
import DataStructures
10-
9+
include("Forest.jl")
1110
include("topological_sort.jl")
1211

1312
"""
@@ -154,7 +153,7 @@ function _prevent_cycle(
154153
forbiddenColors,
155154
color,
156155
)
157-
er = DataStructures.find_root!(S, e_idx2)
156+
er = _find_root!(S, e_idx2)
158157
@inbounds first = firstVisitToTree[er]
159158
p = first.source # but this depends on the order?
160159
q = first.target
@@ -172,29 +171,18 @@ function _grow_star(v, w, e_idx, firstNeighbor, color, S)
172171
@inbounds if p != v
173172
firstNeighbor[color[w]] = _Edge(e_idx, v, w)
174173
else
175-
union!(S, e_idx, e.index)
174+
_root_union!(S, e_idx, e.index)
176175
end
177176
return
178177
end
179178

180-
function _merge_trees(eg, eg1, S)
181-
e1 = DataStructures.find_root!(S, eg)
182-
e2 = DataStructures.find_root!(S, eg1)
183-
if e1 != e2
184-
union!(S, eg, eg1)
179+
function _merge_trees(S::_Forest, eg::Int, eg1::Int)
180+
if _find_root!(S, eg) != _find_root!(S, eg1)
181+
_root_union!(S, eg, eg1)
185182
end
186183
return
187184
end
188185

189-
# Work-around a deprecation in DataStructures@0.19
190-
function _IntDisjointSet(n)
191-
@static if isdefined(DataStructures, :IntDisjointSet)
192-
return DataStructures.IntDisjointSet(n)
193-
else
194-
return DataStructures.IntDisjointSets(n) # COV_EXCL_LINE
195-
end
196-
end
197-
198186
"""
199187
acyclic_coloring(g::UndirectedGraph)
200188
@@ -214,8 +202,7 @@ function acyclic_coloring(g::UndirectedGraph)
214202
firstNeighbor = _Edge[]
215203
firstVisitToTree = fill(_Edge(0, 0, 0), _num_edges(g))
216204
color = fill(0, _num_vertices(g))
217-
# disjoint set forest of edges in the graph
218-
S = _IntDisjointSet(_num_edges(g))
205+
S = _Forest(_num_edges(g))
219206
@inbounds for v in 1:_num_vertices(g)
220207
n_neighbor = _num_neighbors(v, g)
221208
start_neighbor = _start_neighbors(v, g)
@@ -293,7 +280,7 @@ function acyclic_coloring(g::UndirectedGraph)
293280
continue
294281
end
295282
if color[x] == color[v]
296-
_merge_trees(e_idx, e2_idx, S)
283+
_merge_trees(S, e_idx, e2_idx)
297284
end
298285
end
299286
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Copyright (c) 2017: Miles Lubin and contributors
2+
# Copyright (c) 2017: Google Inc.
3+
# Copyright (c) 2024: Guillaume Dalle and Alexis Montoison
4+
#
5+
# Use of this source code is governed by an MIT-style license that can be found
6+
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
7+
8+
# The code in this file was taken from
9+
# https://github.com/gdalle/SparseMatrixColorings.jl/blob/main/src/forest.jl
10+
#
11+
# It was copied at the suggestion of Alexis in his JuMP-dev 2025 talk.
12+
#
13+
# @odow made minor changes to match MOI coding styles.
14+
#
15+
# x-ref https://github.com/gdalle/SparseMatrixColorings.jl/pull/190
16+
17+
mutable struct _Forest
18+
# current number of distinct trees in the forest
19+
number_of_trees::Int
20+
# vector storing the index of a parent in the tree for each edge, used in
21+
# union-find operations
22+
parents::Vector{Int}
23+
# vector approximating the depth of each tree to optimize path compression
24+
ranks::Vector{Int}
25+
26+
_Forest(n::Integer) = new(n, collect(Base.OneTo(n)), zeros(Int, n))
27+
end
28+
29+
function _find_root!(parents::Vector{Int}, index_edge::Integer)
30+
p = parents[index_edge]
31+
if parents[p] != p
32+
parents[index_edge] = p = _find_root!(parents, p)
33+
end
34+
return p
35+
end
36+
37+
function _find_root!(forest::_Forest, index_edge::Integer)
38+
return _find_root!(forest.parents, index_edge)
39+
end
40+
41+
function _root_union!(forest::_Forest, index_edge1::Int, index_edge2::Int)
42+
rank1, rank2 = forest.ranks[index_edge1], forest.ranks[index_edge2]
43+
if rank1 < rank2
44+
index_edge1, index_edge2 = index_edge2, index_edge1
45+
elseif rank1 == rank2
46+
forest.ranks[index_edge1] += 1
47+
end
48+
forest.parents[index_edge2] = index_edge1
49+
forest.number_of_trees -= 1
50+
return
51+
end

test/FileFormats/MPS/MPS.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ using Test
1010

1111
import MathOptInterface as MOI
1212
import MathOptInterface.FileFormats: MPS
13-
import DataStructures: OrderedDict
13+
import OrderedCollections: OrderedDict
1414

1515
function runtests()
1616
for name in names(@__MODULE__; all = true)

0 commit comments

Comments
 (0)