Skip to content
This repository was archived by the owner on Apr 23, 2025. It is now read-only.

Commit ceb3d57

Browse files
authored
Merge pull request #43 from pkj-m/coloring
New coloring methods
2 parents 701b096 + a088ea1 commit ceb3d57

8 files changed

+248
-11
lines changed

Project.toml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ DiffEqDiffTools = "01453d9d-ee7c-5054-8395-0335cb756afa"
1111
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
1212
LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d"
1313
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
14+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1415
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1516
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
1617
VertexSafeGraphs = "19fa3120-7c27-5ec5-8db8-b0b0aa330d6f"

src/SparseDiffTools.jl

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import Core: SSAValue
1313

1414
export contract_color,
1515
greedy_d1,
16+
greedy_star1_coloring,
17+
greedy_star2_coloring,
1618
matrix2graph,
1719
matrix_colors,
1820
forwarddiff_color_jacobian!,
@@ -33,6 +35,8 @@ export contract_color,
3335
include("coloring/high_level.jl")
3436
include("coloring/contraction_coloring.jl")
3537
include("coloring/greedy_d1_coloring.jl")
38+
include("coloring/greedy_star1_coloring.jl")
39+
include("coloring/greedy_star2_coloring.jl")
3640
include("coloring/matrix2graph.jl")
3741
include("differentiation/compute_jacobian_ad.jl")
3842
include("differentiation/jaches_products.jl")

src/coloring/greedy_d1_coloring.jl

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
"""
2-
GreedyD1 Coloring
2+
greedy_d1_coloring
33
44
Find a coloring of a given input graph such that
55
no two vertices connected by an edge have the same
66
color using greedy approach. The number of colors
77
used may be equal or greater than the chromatic
88
number χ(G) of the graph.
99
"""
10-
function color_graph(G::VSafeGraph,alg::GreedyD1Color)
11-
V = nv(G)
12-
result = zeros(Int64, V)
10+
function color_graph(g::VSafeGraph, alg::GreedyD1Color)
11+
v = nv(g)
12+
result = zeros(Int64, v)
1313
result[1] = 1
14-
available = zeros(Int64, V)
15-
for i = 2:V
16-
for j in inneighbors(G, i)
14+
available = BitArray(undef, v)
15+
for i = 2:v
16+
for j in inneighbors(g, i)
1717
if result[j] != 0
18-
available[result[j]] = 1
18+
available[result[j]] = true
1919
end
2020
end
21-
for cr = 1:V
22-
if available[cr] == 0
21+
for cr = 1:v
22+
if available[cr] == false
2323
result[i] = cr
2424
break
2525
end
2626
end
27-
available = zeros(Int64, V)
27+
fill!(available, false)
2828
end
2929
return result
3030
end

src/coloring/greedy_star1_coloring.jl

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""
2+
greedy_star1_coloring
3+
4+
Find a coloring of a given input graph such that
5+
no two vertices connected by an edge have the same
6+
color using greedy approach. The number of colors
7+
used may be equal or greater than the chromatic
8+
number `χ(G)` of the graph.
9+
10+
A star coloring is a special type of distance - 1 coloring,
11+
For a coloring to be called a star coloring, it must satisfy
12+
two conditions:
13+
14+
1. every pair of adjacent vertices receives distinct colors
15+
(a distance-1 coloring)
16+
17+
2. For any vertex v, any color that leads to a two-colored path
18+
involving v and three other vertices is impermissible for v.
19+
In other words, every path on four vertices uses at least three
20+
colors.
21+
22+
Reference: Gebremedhin AH, Manne F, Pothen A. **What color is your Jacobian? Graph coloring for computing derivatives.** SIAM review. 2005;47(4):629-705.
23+
"""
24+
function color_graph(g::LightGraphs.AbstractGraph, ::GreedyStar1Color)
25+
v = nv(g)
26+
color = zeros(Int64, v)
27+
28+
forbidden_colors = zeros(Int64, v+1)
29+
30+
for vertex_i = vertices(g)
31+
32+
for w in inneighbors(g, vertex_i)
33+
if color[w] != 0
34+
forbidden_colors[color[w]] = vertex_i
35+
end
36+
37+
for x in inneighbors(g, w)
38+
if color[x] != 0
39+
if color[w] == 0
40+
forbidden_colors[color[x]] = vertex_i
41+
else
42+
for y in inneighbors(g, x)
43+
if color[y] != 0
44+
if y != w && color[y] == color[w]
45+
forbidden_colors[color[x]] = vertex_i
46+
break
47+
end
48+
end
49+
end
50+
end
51+
end
52+
end
53+
end
54+
55+
color[vertex_i] = find_min_color(forbidden_colors, vertex_i)
56+
end
57+
58+
color
59+
end
60+
61+
function find_min_color(forbidden_colors::AbstractVector, vertex_i::Integer)
62+
c = 1
63+
while (forbidden_colors[c] == vertex_i)
64+
c+=1
65+
end
66+
c
67+
end

src/coloring/greedy_star2_coloring.jl

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""
2+
greedy_star2_coloring
3+
4+
Find a coloring of a given input graph such that
5+
no two vertices connected by an edge have the same
6+
color using greedy approach. The number of colors
7+
used may be equal or greater than the chromatic
8+
number `χ(G)` of the graph.
9+
10+
A star coloring is a special type of distance - 1 coloring,
11+
For a coloring to be called a star coloring, it must satisfy
12+
two conditions:
13+
14+
1. every pair of adjacent vertices receives distinct colors
15+
(a distance-1 coloring)
16+
17+
2. For any vertex v, any color that leads to a two-colored path
18+
involving v and three other vertices is impermissible for v.
19+
In other words, every path on four vertices uses at least three
20+
colors.
21+
22+
Reference: Gebremedhin AH, Manne F, Pothen A. **What color is your Jacobian? Graph coloring for computing derivatives.** SIAM review. 2005;47(4):629-705.
23+
24+
TODO: add text explaining the difference between star1 and
25+
star2
26+
"""
27+
function color_graph(g::LightGraphs.AbstractGraph, :: GreedyStar2Color)
28+
v = nv(g)
29+
color = zeros(Int64, v)
30+
31+
forbidden_colors = zeros(Int64, v+1)
32+
33+
for vertex_i = vertices(g)
34+
35+
for w in inneighbors(g, vertex_i)
36+
if color[w] != 0
37+
forbidden_colors[color[w]] = vertex_i
38+
end
39+
40+
for x in inneighbors(g, w)
41+
if color[x] != 0
42+
if color[w] == 0
43+
forbidden_colors[color[x]] = vertex_i
44+
else
45+
if color[x] < color[w]
46+
forbidden_colors[color[x]] = vertex_i
47+
end
48+
end
49+
end
50+
end
51+
end
52+
53+
color[vertex_i] = find_min_color(forbidden_colors, vertex_i)
54+
end
55+
56+
color
57+
end

src/coloring/high_level.jl

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ abstract type ColoringAlgorithm end
22
struct GreedyD1Color <: ColoringAlgorithm end
33
struct BSCColor <: ColoringAlgorithm end
44
struct ContractionColor <: ColoringAlgorithm end
5+
struct GreedyStar1Color <: ColoringAlgorithm end
6+
struct GreedyStar2Color <: ColoringAlgorithm end
57

68
"""
79
matrix_colors(A,alg::ColoringAlgorithm = GreedyD1Color())

test/runtests.jl

+2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ using Test
44

55
@testset "Exact coloring via contraction" begin include("test_contraction.jl") end
66
@testset "Greedy distance-1 coloring" begin include("test_greedy_d1.jl") end
7+
@testset "Greedy star coloring" begin include("test_greedy_star.jl") end
78
@testset "Matrix to graph conversion" begin include("test_matrix2graph.jl") end
89
@testset "AD using color vector" begin include("test_ad.jl") end
910
@testset "Integration test" begin include("test_integration.jl") end
1011
@testset "Special matrices" begin include("test_specialmatrices.jl") end
1112
@testset "Jac Vecs and Hes Vecs" begin include("test_jaches_products.jl") end
1213
@testset "Program sparsity computation" begin include("program_sparsity/testall.jl") end
14+

test/test_greedy_star.jl

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using SparseDiffTools
2+
using LightGraphs
3+
using Random
4+
5+
Random.seed!(123)
6+
7+
#= Test data =#
8+
test_graphs = Array{SimpleGraph, 1}(undef, 0)
9+
10+
for _ in 1:5
11+
nv = rand(5:20)
12+
ne = rand(1:100)
13+
graph = SimpleGraph(nv)
14+
for e in 1:ne
15+
v1 = rand(1:nv)
16+
v2 = rand(1:nv)
17+
while v1 == v2
18+
v2 = rand(1:nv)
19+
end
20+
add_edge!(graph, v1, v2)
21+
end
22+
push!(test_graphs, copy(graph))
23+
end
24+
25+
#=
26+
Coloring needs to satisfy two conditions:
27+
28+
1. every pair of adjacent vertices receives distinct colors
29+
(a distance-1 coloring)
30+
31+
2. For any vertex v, any color that leads to a two-colored path
32+
involving v and three other vertices is impermissible for v.
33+
In other words, every path on four vertices uses at least three
34+
colors.
35+
=#
36+
37+
38+
#Sample graph from Gebremedhin AH, Manne F, Pothen A. **What color is your Jacobian? Graph coloring for computing derivatives.**
39+
40+
#=
41+
(2)
42+
/ \
43+
/ \
44+
(1)----(3)----(4)
45+
46+
=#
47+
48+
gx = SimpleGraph(4)
49+
50+
add_edge!(gx,1,2)
51+
add_edge!(gx,1,3)
52+
add_edge!(gx,2,3)
53+
add_edge!(gx,3,4)
54+
55+
push!(test_graphs, gx)
56+
57+
#begin testing
58+
for i in 1:6
59+
g = test_graphs[i]
60+
61+
out_colors1 = SparseDiffTools.color_graph(g,SparseDiffTools.GreedyStar1Color())
62+
out_colors2 = SparseDiffTools.color_graph(g,SparseDiffTools.GreedyStar2Color())
63+
64+
#test condition 1
65+
for v = vertices(g)
66+
color = out_colors1[v]
67+
for j in inneighbors(g, v)
68+
@test out_colors1[j] != color
69+
end
70+
end
71+
72+
#test condition 2
73+
for j = vertices(g)
74+
walk = LightGraphs.saw(g, j, 4)
75+
walk_colors = zeros(Int64, 0)
76+
if length(walk) >= 4
77+
for t in walk
78+
push!(walk_colors, out_colors1[t])
79+
end
80+
@test length(unique(walk_colors)) >= 3
81+
end
82+
end
83+
84+
#test condition 1
85+
for v = vertices(g)
86+
color = out_colors2[v]
87+
for j in inneighbors(g, v)
88+
@test out_colors2[j] != color
89+
end
90+
end
91+
92+
#test condition 2
93+
for j = vertices(g)
94+
walk = LightGraphs.saw(g, j, 4)
95+
walk_colors = zeros(Int64, 0)
96+
if length(walk) >= 4
97+
for t in walk
98+
push!(walk_colors, out_colors2[t])
99+
end
100+
@test length(unique(walk_colors)) >= 3
101+
end
102+
end
103+
104+
end

0 commit comments

Comments
 (0)