Skip to content

Commit f5a4acd

Browse files
committed
replaced old version with modified
1 parent c6ef819 commit f5a4acd

File tree

3 files changed

+112
-315
lines changed

3 files changed

+112
-315
lines changed

src/SparseDiffTools.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ include("coloring/backtracking_coloring.jl")
4040
include("coloring/contraction_coloring.jl")
4141
include("coloring/greedy_d1_coloring.jl")
4242
include("coloring/acyclic_coloring.jl")
43-
include("coloring/acyclic_coloring_mod.jl")
4443
include("coloring/greedy_star1_coloring.jl")
4544
include("coloring/greedy_star2_coloring.jl")
4645
include("coloring/matrix2graph.jl")

src/coloring/acyclic_coloring.jl

Lines changed: 112 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,31 @@ is a collection of trees—and hence is acyclic.
99
1010
Reference: Gebremedhin AH, Manne F, Pothen A. **New Acyclic and Star Coloring Algorithms with Application to Computing Hessians**
1111
"""
12-
function color_graph(g::LightGraphs.AbstractGraph)
13-
12+
function color_graph(g::LightGraphs.AbstractGraph, ::AcyclicColoring)
1413
color = zeros(Int, nv(g))
15-
forbidden_colors = zeros(Int, nv(g))
14+
set = DisjointSets{Int}([])
15+
16+
first_visit_to_tree = Array{Tuple{Int, Int}, 1}()
17+
first_neighbor = Array{Tuple{Int, Int}, 1}()
1618

17-
set = DisjointSets{LightGraphs.Edge}([])
19+
init_array!(first_visit_to_tree, ne(g))
20+
init_array!(first_neighbor, ne(g))
1821

19-
first_visit_to_tree = Array{Tuple{Int, Int}, 1}(undef, ne(g))
20-
first_neighbor = Array{Tuple{Int, Int}, 1}(undef, nv(g))
22+
forbidden_colors = zeros(Int, nv(g))
2123

2224
for v in vertices(g)
23-
#enforces the first condition of acyclic coloring
2425
for w in outneighbors(g, v)
25-
if color[w] != 0
26+
if color[w]!=0
2627
forbidden_colors[color[w]] = v
2728
end
2829
end
29-
#enforces the second condition of acyclic coloring
30+
3031
for w in outneighbors(g, v)
31-
if color[w] != 0 #colored neighbor
32+
if color[w]!=0
3233
for x in outneighbors(g, w)
33-
if color[x] != 0 #colored x
34+
if color[x]!=0
3435
if forbidden_colors[color[x]] != v
35-
prevent_cycle(v, w, x, g, color, forbidden_colors, first_visit_to_tree, set)
36+
prevent_cycle!(v, w, x, g, set, first_visit_to_tree, forbidden_colors,color)
3637
end
3738
end
3839
end
@@ -41,30 +42,28 @@ function color_graph(g::LightGraphs.AbstractGraph)
4142

4243
color[v] = min_index(forbidden_colors, v)
4344

44-
# grow star for every edge connecting colored vertices v and w
4545
for w in outneighbors(g, v)
46-
if color[w] != 0
47-
grow_star!(set, v, w, g, first_neighbor, color)
46+
if color[w]!=0
47+
grow_star!(v, w, g, set,first_neighbor,color)
4848
end
4949
end
5050

51-
# merge the newly formed stars into existing trees if possible
5251
for w in outneighbors(g, v)
53-
if color[w] != 0
52+
if color[w]!=0
5453
for x in outneighbors(g, w)
55-
if color[x] != 0 && x != v
56-
if color[x] == color[v]
57-
merge_trees!(set, v, w, x, g)
54+
if color[x]!=0 && x!=v
55+
if color[x]==color[v]
56+
merge_trees!(v,w,x,g,set)
5857
end
5958
end
6059
end
6160
end
6261
end
6362
end
64-
6563
return color
6664
end
6765

66+
6867
"""
6968
prevent_cycle(v::Integer,
7069
w::Integer,
@@ -79,33 +78,24 @@ Subroutine to avoid generation of 2-colored cycle due to coloring of vertex v,
7978
which is adjacent to vertices w and x in graph g. Disjoint set is used to store
8079
the induced 2-colored subgraphs/trees where the id of set is a key edge of g
8180
"""
82-
function prevent_cycle(v::Integer,
81+
function prevent_cycle!(v::Integer,
8382
w::Integer,
8483
x::Integer,
8584
g::LightGraphs.AbstractGraph,
86-
color::AbstractVector{<:Integer},
87-
forbidden_colors::AbstractVector{<:Integer},
88-
first_visit_to_tree::AbstractVector{<:Tuple{Integer, Integer}},
89-
set::DisjointSets{LightGraphs.Edge})
90-
91-
edge = find_edge(g, w, x)
92-
e = find_root(set, edge)
93-
p, q = first_visit_to_tree[edge_index(g, e)]
85+
set::DisjointSets{<:Integer},
86+
first_visit_to_tree::AbstractVector{<:Tuple{Integer,Integer}},
87+
forbidden_colors::AbstractVector{<:Tuple{Integer, Integer}},
88+
color::AbstractVector{<:Integer})
89+
e = find(w, x, g, set)
90+
p, q = first_visit_to_tree[e]
91+
9492
if p != v
95-
first_visit_to_tree[edge_index(g, e)] = (v, w)
93+
first_visit_to_tree[e] = (v,w)
9694
elseif q != w
9795
forbidden_colors[color[x]] = v
9896
end
9997
end
10098

101-
"""
102-
min_index(forbidden_colors::AbstractVector{<:Integer}, v::Integer)
103-
104-
Returns min{i > 0 such that forbidden_colors[i] != v}
105-
"""
106-
function min_index(forbidden_colors::AbstractVector{<:Integer}, v::Integer)
107-
return findfirst(!isequal(v), forbidden_colors)
108-
end
10999

110100
"""
111101
grow_star!(set::DisjointSets{LightGraphs.Edge},
@@ -120,25 +110,22 @@ previously uncolored vertex v, by comparing it with the adjacent vertex w.
120110
Disjoint set is used to store stars in sets, which are identified through key
121111
edges present in g.
122112
"""
123-
function grow_star!(set::DisjointSets{LightGraphs.Edge},
124-
v::Integer,
125-
w::Integer,
126-
g::LightGraphs.AbstractGraph,
127-
first_neighbor::AbstractVector{<:Tuple{Integer, Integer}},
128-
color::AbstractVector{<: Integer})
129-
edge = find_edge(g, v, w)
130-
push!(set, edge)
113+
function grow_star!(v::Integer,
114+
w::Integer,
115+
g::LightGraphs.AbstractGraph,
116+
set::DisjointSets{Integer},
117+
first_neighbor::AbstractVector{<:Tuple{Integer,Integer}},
118+
color::AbstractVector{<:Integer})
119+
make_set!(v,w,g,set)
131120
p, q = first_neighbor[color[w]]
121+
132122
if p != v
133-
first_neighbor[color[w]] = (v, w)
123+
first_neighbor[color[w]] = (v,w)
134124
else
135-
edge1 = find_edge(g, v, w)
136-
edge2 = find_edge(g, p, q)
137-
e1 = find_root(set, edge1)
138-
e2 = find_root(set, edge2)
125+
e1 = find(v,w,g,set)
126+
e2 = find(p,q,g,set)
139127
union!(set, e1, e2)
140128
end
141-
return nothing
142129
end
143130

144131

@@ -152,51 +139,93 @@ end
152139
Subroutine to merge trees present in the disjoint set which have a
153140
common edge.
154141
"""
155-
function merge_trees!(set::DisjointSets{LightGraphs.Edge},
156-
v::Integer,
157-
w::Integer,
158-
x::Integer,
159-
g::LightGraphs.AbstractGraph)
160-
edge1 = find_edge(g, v, w)
161-
edge2 = find_edge(g, w, x)
162-
e1 = find_root(set, edge1)
163-
e2 = find_root(set, edge2)
164-
if (e1 != e2)
142+
function merge_trees!(v::Integer,
143+
w::Integer,
144+
x::Integer,
145+
g::LightGraphs.AbstractGraph,
146+
set::DisjointSets{<:Integer})
147+
e1 = find(v,w,g,set)
148+
e2 = find(w,x,g,set)
149+
if e1 != e2
165150
union!(set, e1, e2)
166151
end
167152
end
168153

169154

155+
"""
156+
make_set!(v::Integer,
157+
w::Integer,
158+
g::LightGraphs.AbstractGraph,
159+
set::DisjointSets{<:Integer})
160+
161+
creates a new singleton set in the disjoint set 'set' consisting
162+
of the edge connecting v and w in the graph g
163+
"""
164+
function make_set!(v::Integer,
165+
w::Integer,
166+
g::LightGraphs.AbstractGraph,
167+
set::DisjointSets{<:Integer})
168+
edge_index = find_edge_index(v,w,g)
169+
push!(set,edge_index)
170+
end
171+
172+
173+
"""
174+
min_index(forbidden_colors::AbstractVector{<:Integer}, v::Integer)
175+
176+
Returns min{i > 0 such that forbidden_colors[i] != v}
177+
"""
178+
function min_index(forbidden_colors::AbstractVector{<:Integer}, v::Integer)
179+
return findfirst(!isequal(v), forbidden_colors)
180+
end
181+
182+
183+
"""
184+
find(w::Integer,
185+
x::Integer,
186+
g::LightGraphs.AbstractGraph,
187+
set::DisjointSets{<:Integer})
188+
189+
Returns the root of the disjoint set to which the edge connecting vertices w and x
190+
in the graph g belongs to
191+
"""
192+
function find(w::Integer,
193+
x::Integer,
194+
g::LightGraphs.AbstractGraph,
195+
set::DisjointSets{<:Integer})
196+
edge_index = find_edge_index(w, x, g)
197+
return find_root(set, edge_index)
198+
end
199+
200+
170201
"""
171202
find_edge(g::LightGraphs.AbstractGraph, v::Integer, w::Integer)
172203
173-
Returns an edge object of the type LightGraphs.Edge which represents the
174-
edge connecting vertices v and w of the undirected graph g
204+
Returns an integer equivalent to the index of the edge connecting the vertices
205+
v and w in the graph g
175206
"""
176-
function find_edge(g::LightGraphs.AbstractGraph,
177-
v::Integer,
178-
w::Integer)
179-
for e in edges(g)
180-
if (src(e) == v && dst(e) == w) || (src(e) == w && dst(e) == v)
181-
return e
207+
function find_edge_index(v::Integer, w::Integer, g::LightGraphs.AbstractGraph)
208+
pos = 1
209+
for i in edges(g)
210+
211+
if (src(i)==v && dst(i)==w) || (src(i)==w && dst(i)==v)
212+
return pos
182213
end
214+
pos = pos + 1
183215
end
184-
throw(ArgumentError("$v and $w are not connected in graph g"))
216+
throw(ArgumentError("$v and $w are not connected in the graph"))
185217
end
186218

219+
187220
"""
188-
edge_index(g::LightGraphs.AbstractGraph, e::LightGraphs.Edge)
221+
init_array(array::AbstractVector{<:Tuple{Integer, Integer}},
222+
n::Integer)
189223
190-
Returns an Integer value which uniquely identifies the edge e in graph
191-
g. Used as an index in main function to avoid custom arrays with non-
192-
numerical indices.
224+
Helper function to initialize the data structures with tuple (0,0)
193225
"""
194-
function edge_index(g::LightGraphs.AbstractGraph,
195-
e::LightGraphs.Edge)
196-
for (i, edge) in enumerate(edges(g))
197-
if edge == e
198-
return i
199-
end
226+
function init_array!(array::AbstractVector{<:Tuple{Integer, Integer}},
227+
n::Integer)
228+
for i in 1:n
229+
push!(array,(0,0))
200230
end
201-
throw(ArgumentError("Edge $e is not present in graph g"))
202231
end

0 commit comments

Comments
 (0)