Skip to content

Backtracking Sequential Coloring #52

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 21 commits into from
Jul 29, 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 src/SparseDiffTools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export contract_color,


include("coloring/high_level.jl")
include("coloring/backtracking_coloring.jl")
include("coloring/contraction_coloring.jl")
include("coloring/greedy_d1_coloring.jl")
include("coloring/greedy_star1_coloring.jl")
Expand Down
235 changes: 235 additions & 0 deletions src/coloring/backtracking_coloring.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
using LightGraphs

"""
color_graph(g::LightGraphs, ::BacktrackingColor)

Returns a tight, distance-1 coloring of graph g
using the minimum number of colors possible (i.e.
the chromatic number of graph, χ(g))
"""
function color_graph(g::LightGraphs.AbstractGraph, ::BacktrackingColor)
v = nv(g)

#A is list of vertices in non-increasing order of degree
A = sort_by_degree(g)

#F is the coloring of vertices, 0 means uncolored
#Fopt is the optimal coloring of the graph
F = zeros(Int, v)
Fopt= zeros(Int, v)

start = 1

#optimal color number
opt = v + 1

#current vertex to be colored
x = A[1]

#colors[j] = number of colors in A[0]...A[j]
#assume colors[0] = 1
colors = zeros(Int, v)

#set of free colors
U = zeros(Int, 0)
push!(U, 1)

#set of free colors of x
freeColors = [Vector{Int}() for _ in 1:v]
freeColors[x] = copy(U)

while (start >= 1)

back = false
for i = start:v
if i > start
x = uncolored_vertex_of_maximal_degree(A,F)
U = free_colors(x, A, colors, F, g, opt)
sort!(U)
end
if length(U) > 0
k = U[1]
F[x] = k
cp = F[x]
deleteat!(U, 1)
freeColors[x] = copy(U)
if i==1
l = 0
else
l = colors[i-1]
end
colors[i] = max(k, l)
else
start = i-1
back = true
break
end
end

if back
if start >= 1
x = A[start]
F[x] = 0
U = freeColors[x]
end
else
Fopt = copy(F)
opt = colors[v-1]
i = least_index(F,A,opt)
start = i-1
if start < 1
break
end

#uncolor all vertices A[i] with i >= start
uncolor_all!(F, A, start)

for i = 1:start+1
x = A[i]
U = freeColors[x]

#remove colors >= opt from U
U = remove_higher_colors(U, opt)
freeColors[x] = copy(U)
end
end
end
return Fopt
end

"""
sort_by_degree(g::LightGraphs.AbstractGraph)

Returns a list of the vertices of graph g sorted
in non-increasing order of their degrees
"""
function sort_by_degree(g::LightGraphs.AbstractGraph)
vs = vertices(g)
degrees = (LightGraphs.degree(g, v) for v in vs)
vertex_pairs = collect(zip(vs, degrees))
sort!(vertex_pairs, by = p -> p[2], rev = true)
return [v[1] for v in vertex_pairs]
end

"""
uncolored_vertex_of_maximal_degree(A::AbstractVector{<:Integer},F::AbstractVector{<:Integer})

Returns an uncolored vertex from the partially
colored graph which has the highest degree
"""
function uncolored_vertex_of_maximal_degree(A::AbstractVector{<:Integer},F::AbstractVector{<:Integer})
for v in A
if F[v] == 0
return v
end
end
end


"""
free_colors(x::Integer,
A::AbstractVector{<:Integer},
colors::AbstractVector{<:Integer},
F::Array{Integer,1},
g::LightGraphs.AbstractGraph,
opt::Integer)

Returns set of free colors of x which are less
than optimal color number (opt)

Arguments:

x: Vertex who's set of free colors is to be calculated
A: List of vertices of graph g sorted in non-increasing order of degree
colors: colors[i] stores the number of distinct colors used in the
coloring of vertices A[0], A[1]... A[i-1]
F: F[i] stores the color of vertex i
g: Graph to be colored
opt: Current optimal number of colors to be used in the coloring of graph g
"""
function free_colors(x::Integer,
A::AbstractVector{<:Integer},
colors::AbstractVector{<:Integer},
F::Array{Integer,1},
g::LightGraphs.AbstractGraph,
opt::Integer)
index = -1

freecolors = zeros(Int, 0)

for i in eachindex(A)
if A[i] == x
index = i
break
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible that index=-1 after the loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Since x is a vertex in the graph, we can be sure that it'll be present in vector A as well. So index would always lie between [1, nv(g)] once that code block executes.


if index == 1
colors_used = 0
else
colors_used = colors[index-1]
end

colors_used += 1
for c = 1:colors_used
c_allowed = true
for w in inneighbors(g, x)
if F[w] == c
c_allowed = false
break
end
end
if c_allowed && c < opt
push!(freecolors, c)
end
end

return freecolors

end

"""
least_index(F::AbstractVector{<:Integer}, A::AbstractVector{<:Integer}, opt::Integer)

Returns least index i such that color of vertex
A[i] is equal to `opt` (optimal color number)
"""
function least_index(F::AbstractVector{<:Integer}, A::AbstractVector{<:Integer}, opt::Integer)
for i in eachindex(A)
if F[A[i]] == opt
return i
end
end
end

"""
uncolor_all(F::AbstractVector{<:Integer}, A::AbstractVector{<:Integer}, start::Integer)

Uncolors all vertices A[i] where i is
greater than or equal to start
"""
function uncolor_all!(F::AbstractVector{<:Integer}, A::AbstractVector{<:Integer}, start::Integer)
for i = start:length(A)
F[A[i]] = 0
end
end

"""
remove_higher_colors(U::AbstractVector{<:Integer}, opt::Integer)

Remove all the colors which are greater than or
equal to the `opt` (optimal color number) from
the set of colors U
"""
function remove_higher_colors(U::AbstractVector{<:Integer}, opt::Integer)
if length(U) == 0
return U
end
u = zeros(Int, 0)
for color in U
if color < opt
push!(u, color)
end
end
return u
end
Loading