Skip to content

Commit c6ef819

Browse files
committed
code formatting and added function doc
1 parent 3ca79fc commit c6ef819

File tree

1 file changed

+130
-51
lines changed

1 file changed

+130
-51
lines changed

src/coloring/acyclic_coloring_mod.jl

Lines changed: 130 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
"""
2+
color_graph(g::LightGraphs.AbstractGraphs, ::AcyclicColoring)
3+
4+
Returns a coloring vector following the acyclic coloring rules (1) the coloring
5+
corresponds to a distance-1 coloring, and (2) vertices in every cycle of the
6+
graph are assigned at least three distinct colors. This variant of coloring is
7+
called acyclic since every subgraph induced by vertices assigned any two colors
8+
is a collection of trees—and hence is acyclic.
9+
10+
Reference: Gebremedhin AH, Manne F, Pothen A. **New Acyclic and Star Coloring Algorithms with Application to Computing Hessians**
11+
"""
112
function color_graph(g::LightGraphs.AbstractGraph, ::AcyclicColoring)
213
color = zeros(Int, nv(g))
314
set = DisjointSets{Int}([])
@@ -8,71 +19,39 @@ function color_graph(g::LightGraphs.AbstractGraph, ::AcyclicColoring)
819
init_array!(first_visit_to_tree, ne(g))
920
init_array!(first_neighbor, ne(g))
1021

11-
12-
1322
forbidden_colors = zeros(Int, nv(g))
1423

1524
for v in vertices(g)
16-
# println(">>>\nOUTER LOOP")
17-
# println(">>> v = $v")
18-
# println(">>> first block")
1925
for w in outneighbors(g, v)
20-
# println(">>> w = $w")
2126
if color[w]!=0
22-
# wc = color[w]
23-
# println(">>> $w has nonzero color = $wc")
24-
# println(">>> setting forbidden color[$wc] = $v")
2527
forbidden_colors[color[w]] = v
2628
end
2729
end
2830

29-
# println(">>> second block")
3031
for w in outneighbors(g, v)
31-
# println(">>> w = $w")
3232
if color[w]!=0
33-
# wc = color[w]
34-
# println(">>> $w has nonzero color = $wc")
3533
for x in outneighbors(g, w)
36-
# println(">>> x = $x")
37-
# wx = color[x]
38-
# println(">>> $x has color = $wx")
3934
if color[x]!=0
40-
# println(">>> $wx != 0")
41-
# fbc = forbidden_colors[color[x]]
42-
# println(">>> forbidden color[$wx] = $fbc")
4335
if forbidden_colors[color[x]] != v
44-
# println(">>> $fbc != $v")
45-
# println(">>> calling prevent cycle with $v, $w, $x")
4636
prevent_cycle!(v, w, x, g, set, first_visit_to_tree, forbidden_colors,color)
4737
end
4838
end
4939
end
5040
end
5141
end
5242

53-
# println(">>> third block")
5443
color[v] = min_index(forbidden_colors, v)
55-
# vc = color[v]
56-
# println(">>> color of v = $vc")
44+
5745
for w in outneighbors(g, v)
58-
# println(">>> w = $w")
5946
if color[w]!=0
60-
# println(">>> calling grow star for v = $v, w = $w")
6147
grow_star!(v, w, g, set,first_neighbor,color)
6248
end
6349
end
6450

65-
# println(">>> fourth block")
6651
for w in outneighbors(g, v)
67-
# println(">>> w = $w")
6852
if color[w]!=0
69-
# wc = color[w]
70-
# println(">>> $w has non zero color = $wc")
7153
for x in outneighbors(g, w)
72-
# wx = color[x]
73-
# println(">>> x = $x")
7454
if color[x]!=0 && x!=v
75-
# println(">>> $x has nonzero color = $wx")
7655
if color[x]==color[v]
7756
merge_trees!(v,w,x,g,set)
7857
end
@@ -84,29 +63,62 @@ function color_graph(g::LightGraphs.AbstractGraph, ::AcyclicColoring)
8463
return color
8564
end
8665

87-
function init_array!(array, n)
88-
for i in 1:n
89-
push!(array,(0,0))
90-
end
91-
end
9266

93-
function prevent_cycle!(v:: Int, w:: Int, x::Int, g, set, first_visit_to_tree, forbidden_colors,color)
67+
"""
68+
prevent_cycle(v::Integer,
69+
w::Integer,
70+
x::Integer,
71+
g::LightGraphs.AbstractGraph,
72+
color::AbstractVector{<:Integer},
73+
forbidden_colors::AbstractVector{<:Integer},
74+
first_visit_to_tree::Array{Tuple{Integer, Integer}, 1},
75+
set::DisjointSets{LightGraphs.Edge})
76+
77+
Subroutine to avoid generation of 2-colored cycle due to coloring of vertex v,
78+
which is adjacent to vertices w and x in graph g. Disjoint set is used to store
79+
the induced 2-colored subgraphs/trees where the id of set is a key edge of g
80+
"""
81+
function prevent_cycle!(v::Integer,
82+
w::Integer,
83+
x::Integer,
84+
g::LightGraphs.AbstractGraph,
85+
set::DisjointSets{<:Integer},
86+
first_visit_to_tree::AbstractVector{<:Tuple{Integer,Integer}},
87+
forbidden_colors::AbstractVector{<:Tuple{Integer, Integer}},
88+
color::AbstractVector{<:Integer})
9489
e = find(w, x, g, set)
9590
p, q = first_visit_to_tree[e]
96-
# println(">>> first visit to tree : p = $p, q = $q")
91+
9792
if p != v
9893
first_visit_to_tree[e] = (v,w)
9994
elseif q != w
10095
forbidden_colors[color[x]] = v
10196
end
10297
end
10398

104-
function grow_star!(v, w,g,set,first_neighbor,color)
99+
100+
"""
101+
grow_star!(set::DisjointSets{LightGraphs.Edge},
102+
v::Integer,
103+
w::Integer,
104+
g::LightGraphs.AbstractGraph,
105+
first_neighbor::AbstractVector{<:Tuple{Integer, Integer}},
106+
color::AbstractVector{<: Integer})
107+
108+
Grow a 2-colored star after assigning a new color to the
109+
previously uncolored vertex v, by comparing it with the adjacent vertex w.
110+
Disjoint set is used to store stars in sets, which are identified through key
111+
edges present in g.
112+
"""
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})
105119
make_set!(v,w,g,set)
106120
p, q = first_neighbor[color[w]]
107-
# wc = color[w]
108-
# println(">>> color of w = $wc")
109-
# println(">>> first neighbor : p = $p, q = $q")
121+
110122
if p != v
111123
first_neighbor[color[w]] = (v,w)
112124
else
@@ -116,37 +128,104 @@ function grow_star!(v, w,g,set,first_neighbor,color)
116128
end
117129
end
118130

119-
function merge_trees!(v,w,x,g,set)
131+
132+
"""
133+
merge_trees!(v::Integer,
134+
w::Integer,
135+
x::Integer,
136+
g::LightGraphs.AbstractGraph,
137+
set::DisjointSets{LightGraphs.Edge})
138+
139+
Subroutine to merge trees present in the disjoint set which have a
140+
common edge.
141+
"""
142+
function merge_trees!(v::Integer,
143+
w::Integer,
144+
x::Integer,
145+
g::LightGraphs.AbstractGraph,
146+
set::DisjointSets{<:Integer})
120147
e1 = find(v,w,g,set)
121148
e2 = find(w,x,g,set)
122149
if e1 != e2
123150
union!(set, e1, e2)
124151
end
125152
end
126153

127-
function make_set!(v,w,g,set)
154+
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})
128168
edge_index = find_edge_index(v,w,g)
129169
push!(set,edge_index)
130170
end
131171

132-
function min_index(forbidden_colors, v)
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)
133179
return findfirst(!isequal(v), forbidden_colors)
134180
end
135181

136-
function find(w, x, g, set)
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})
137196
edge_index = find_edge_index(w, x, g)
138197
return find_root(set, edge_index)
139198
end
140199

141-
function find_edge_index(v, w, g)
142-
#print("function called")
200+
201+
"""
202+
find_edge(g::LightGraphs.AbstractGraph, v::Integer, w::Integer)
203+
204+
Returns an integer equivalent to the index of the edge connecting the vertices
205+
v and w in the graph g
206+
"""
207+
function find_edge_index(v::Integer, w::Integer, g::LightGraphs.AbstractGraph)
143208
pos = 1
144209
for i in edges(g)
145-
#print("inside loop")
210+
146211
if (src(i)==v && dst(i)==w) || (src(i)==w && dst(i)==v)
147212
return pos
148213
end
149214
pos = pos + 1
150215
end
151216
throw(ArgumentError("$v and $w are not connected in the graph"))
152217
end
218+
219+
220+
"""
221+
init_array(array::AbstractVector{<:Tuple{Integer, Integer}},
222+
n::Integer)
223+
224+
Helper function to initialize the data structures with tuple (0,0)
225+
"""
226+
function init_array!(array::AbstractVector{<:Tuple{Integer, Integer}},
227+
n::Integer)
228+
for i in 1:n
229+
push!(array,(0,0))
230+
end
231+
end

0 commit comments

Comments
 (0)