Skip to content

New coloring methods #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Jul 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ DiffEqDiffTools = "01453d9d-ee7c-5054-8395-0335cb756afa"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
VertexSafeGraphs = "19fa3120-7c27-5ec5-8db8-b0b0aa330d6f"
Expand Down
4 changes: 4 additions & 0 deletions src/SparseDiffTools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import Core: SSAValue

export contract_color,
greedy_d1,
greedy_star1_coloring,
greedy_star2_coloring,
matrix2graph,
matrix_colors,
forwarddiff_color_jacobian!,
Expand All @@ -33,6 +35,8 @@ export contract_color,
include("coloring/high_level.jl")
include("coloring/contraction_coloring.jl")
include("coloring/greedy_d1_coloring.jl")
include("coloring/greedy_star1_coloring.jl")
include("coloring/greedy_star2_coloring.jl")
include("coloring/matrix2graph.jl")
include("differentiation/compute_jacobian_ad.jl")
include("differentiation/jaches_products.jl")
Expand Down
22 changes: 11 additions & 11 deletions src/coloring/greedy_d1_coloring.jl
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
"""
GreedyD1 Coloring
greedy_d1_coloring

Find a coloring of a given input graph such that
no two vertices connected by an edge have the same
color using greedy approach. The number of colors
used may be equal or greater than the chromatic
number χ(G) of the graph.
"""
function color_graph(G::VSafeGraph,alg::GreedyD1Color)
V = nv(G)
result = zeros(Int64, V)
function color_graph(g::VSafeGraph, alg::GreedyD1Color)
v = nv(g)
result = zeros(Int64, v)
result[1] = 1
available = zeros(Int64, V)
for i = 2:V
for j in inneighbors(G, i)
available = BitArray(undef, v)
for i = 2:v
for j in inneighbors(g, i)
if result[j] != 0
available[result[j]] = 1
available[result[j]] = true
end
end
for cr = 1:V
if available[cr] == 0
for cr = 1:v
if available[cr] == false
result[i] = cr
break
end
end
available = zeros(Int64, V)
fill!(available, false)
end
return result
end
67 changes: 67 additions & 0 deletions src/coloring/greedy_star1_coloring.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
"""
greedy_star1_coloring

Find a coloring of a given input graph such that
no two vertices connected by an edge have the same
color using greedy approach. The number of colors
used may be equal or greater than the chromatic
number `χ(G)` of the graph.

A star coloring is a special type of distance - 1 coloring,
For a coloring to be called a star coloring, it must satisfy
two conditions:

1. every pair of adjacent vertices receives distinct colors
(a distance-1 coloring)

2. For any vertex v, any color that leads to a two-colored path
involving v and three other vertices is impermissible for v.
In other words, every path on four vertices uses at least three
colors.

Reference: Gebremedhin AH, Manne F, Pothen A. **What color is your Jacobian? Graph coloring for computing derivatives.** SIAM review. 2005;47(4):629-705.
"""
function color_graph(g::LightGraphs.AbstractGraph, ::GreedyStar1Color)
v = nv(g)
color = zeros(Int64, v)

forbidden_colors = zeros(Int64, v+1)

for vertex_i = vertices(g)

for w in inneighbors(g, vertex_i)
if color[w] != 0
forbidden_colors[color[w]] = vertex_i
end

for x in inneighbors(g, w)
if color[x] != 0
if color[w] == 0
forbidden_colors[color[x]] = vertex_i
else
for y in inneighbors(g, x)
if color[y] != 0
if y != w && color[y] == color[w]
forbidden_colors[color[x]] = vertex_i
break
end
end
end
end
end
end
end

color[vertex_i] = find_min_color(forbidden_colors, vertex_i)
end

color
end

function find_min_color(forbidden_colors::AbstractVector, vertex_i::Integer)
c = 1
while (forbidden_colors[c] == vertex_i)
c+=1
end
c
end
57 changes: 57 additions & 0 deletions src/coloring/greedy_star2_coloring.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""
greedy_star2_coloring

Find a coloring of a given input graph such that
no two vertices connected by an edge have the same
color using greedy approach. The number of colors
used may be equal or greater than the chromatic
number `χ(G)` of the graph.

A star coloring is a special type of distance - 1 coloring,
For a coloring to be called a star coloring, it must satisfy
two conditions:

1. every pair of adjacent vertices receives distinct colors
(a distance-1 coloring)

2. For any vertex v, any color that leads to a two-colored path
involving v and three other vertices is impermissible for v.
In other words, every path on four vertices uses at least three
colors.

Reference: Gebremedhin AH, Manne F, Pothen A. **What color is your Jacobian? Graph coloring for computing derivatives.** SIAM review. 2005;47(4):629-705.

TODO: add text explaining the difference between star1 and
star2
"""
function color_graph(g::LightGraphs.AbstractGraph, :: GreedyStar2Color)
v = nv(g)
color = zeros(Int64, v)

forbidden_colors = zeros(Int64, v+1)

for vertex_i = vertices(g)

for w in inneighbors(g, vertex_i)
if color[w] != 0
forbidden_colors[color[w]] = vertex_i
end

for x in inneighbors(g, w)
if color[x] != 0
if color[w] == 0
forbidden_colors[color[x]] = vertex_i
else
if color[x] < color[w]
forbidden_colors[color[x]] = vertex_i
end
end
end
end
end

color[vertex_i] = find_min_color(forbidden_colors, vertex_i)
end

color
end
2 changes: 2 additions & 0 deletions src/coloring/high_level.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ abstract type ColoringAlgorithm end
struct GreedyD1Color <: ColoringAlgorithm end
struct BSCColor <: ColoringAlgorithm end
struct ContractionColor <: ColoringAlgorithm end
struct GreedyStar1Color <: ColoringAlgorithm end
struct GreedyStar2Color <: ColoringAlgorithm end

"""
matrix_colors(A,alg::ColoringAlgorithm = GreedyD1Color())
Expand Down
2 changes: 2 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ using Test

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

104 changes: 104 additions & 0 deletions test/test_greedy_star.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using SparseDiffTools
using LightGraphs
using Random

Random.seed!(123)

#= Test data =#
test_graphs = Array{SimpleGraph, 1}(undef, 0)

for _ in 1:5
nv = rand(5:20)
ne = rand(1:100)
graph = SimpleGraph(nv)
for e in 1:ne
v1 = rand(1:nv)
v2 = rand(1:nv)
while v1 == v2
v2 = rand(1:nv)
end
add_edge!(graph, v1, v2)
end
push!(test_graphs, copy(graph))
end

#=
Coloring needs to satisfy two conditions:

1. every pair of adjacent vertices receives distinct colors
(a distance-1 coloring)

2. For any vertex v, any color that leads to a two-colored path
involving v and three other vertices is impermissible for v.
In other words, every path on four vertices uses at least three
colors.
=#


#Sample graph from Gebremedhin AH, Manne F, Pothen A. **What color is your Jacobian? Graph coloring for computing derivatives.**

#=
(2)
/ \
/ \
(1)----(3)----(4)

=#

gx = SimpleGraph(4)

add_edge!(gx,1,2)
add_edge!(gx,1,3)
add_edge!(gx,2,3)
add_edge!(gx,3,4)

push!(test_graphs, gx)

#begin testing
for i in 1:6
g = test_graphs[i]

out_colors1 = SparseDiffTools.color_graph(g,SparseDiffTools.GreedyStar1Color())
out_colors2 = SparseDiffTools.color_graph(g,SparseDiffTools.GreedyStar2Color())

#test condition 1
for v = vertices(g)
color = out_colors1[v]
for j in inneighbors(g, v)
@test out_colors1[j] != color
end
end

#test condition 2
for j = vertices(g)
walk = LightGraphs.saw(g, j, 4)
walk_colors = zeros(Int64, 0)
if length(walk) >= 4
for t in walk
push!(walk_colors, out_colors1[t])
end
@test length(unique(walk_colors)) >= 3
end
end

#test condition 1
for v = vertices(g)
color = out_colors2[v]
for j in inneighbors(g, v)
@test out_colors2[j] != color
end
end

#test condition 2
for j = vertices(g)
walk = LightGraphs.saw(g, j, 4)
walk_colors = zeros(Int64, 0)
if length(walk) >= 4
for t in walk
push!(walk_colors, out_colors2[t])
end
@test length(unique(walk_colors)) >= 3
end
end

end