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 6 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
249 changes: 142 additions & 107 deletions src/coloring/bsc_algo.jl
Original file line number Diff line number Diff line change
@@ -1,172 +1,207 @@
"""
BSCColor
#bsc 1-based indexing
using LightGraphs

Backtracking Sequential Coloring algorithm
"""
function color_graph(G::VSafeGraph,::BSCColor)
V = nv(G)
F = zeros(Int64, V)
freeColors = [Vector{Int64}() for _ in 1:V] #set of free colors for each vertex
U = zeros(Int64, 0) #stores set of free colors
#F = zeros(Int64, 0) #stores final coloring of vertices

sorted_vertices = order_by_degree(G)
function color_graph(g::LightGraphs.AbstractGraph)

#number of vertices in g
v = nv(g)

#A is order 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(Int32, v)
Fopt= zeros(Int32, v)

#start index
start = 1
optColorNumber = V + 1
x = sorted_vertices[1]
colors[0] = 0

#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(Int32, v)

#set of free colors
U = zeros(Int32, 0)
push!(U, 1)
freeColors[x] = U

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

while (start >= 1)

back = false
for i = 1:V
for i = start:v
if i > start
x = find_uncolored_vertex(sorted_vertices, F)
U = free_colors(x,F,G,optColorNumber)
sort(U)
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
deleteat!(U,1)
deleteat!(U, 1)
freeColors[x] = copy(U)
l = colors[i-1]
colors[i] = max(k,l)
if i==1
l = 0
else
l = colors[i-1]
colors[i] = max(k, l)
end
else
start = i - 1
start = i-1
back = true
break
end
end
if back
if start >= 1
x = A[start]
F[x] = 0 #uncolor x
F[x] = 0
U = freeColors[x]
end
else
F_opt = F
optColorNumber = colors[V-1]
i = least_index(sorted_vertices,optColorNumber,G)
start = i - 1
Fopt = copy(F)
opt = colors[v-1]
i = least_index(F,A,opt)
start = i-1
if start < 1
break #leave the while loop
break
end
uncolor_all(F, sorted_vertices, start, G)
for i = 0:start
x = A[i]

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

#try start+1 instead
for i = 1:start+1
x = A[i]
U = freeColors[x]
U = remove_colors(U, optColorNumber)
#remove colors >= opt from U
U = remove_higher_colors(U, opt)
freeColors[x] = copy(U)
end
end

end
return F_opt
end

F
end

"""
vertex_degree(G,z)
sort_by_degree()

Find the degree of the vertex z which belongs to the graph G.
sort and store the vertices of graph g in
non-increasing order of their degrees
"""
function degree(G::VSafeGraph,z::Int64)
return length(inneighbors(G,z))
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)
[v[1] for v in vertex_pairs]
end

"""
uncolored_vertex_of_maximal_degree(A,F)

function sorted_vertices(G::VSafeGraph)
V = nv(G)
marked = zeros(Int64,V)
sv = zeros(Int64,0)
max_degree = -1
max_degree_vertex = -1
for i = 1:V
max_degree = -1
max_degree_vertex = -1
for j = 1:V
if j != i
if degree(G,j) > max_degree && marked[j] == 0
max_degree = degree(G,j)
max_degree_vertex = j
end
end
Returns an uncolored vertex from the graph which has maximum
degree
"""
function uncolored_vertex_of_maximal_degree(A,F)
for v in A
if F[v] == 0
return v
end
push!(sv,max_degree_vertex)
marked[max_degree_vertex] = 1
end
return sv
end

#find uncolored vertex of maximal degree of saturation
function find_uncolored_vertex(sv::Array{Int64,1}, G::VSafeGraph)
colors = zeros(Int64,0)
max_colors = -1
max_color_index = -1
for i = 1:nv(G)
if F[i] != 0
for j in inneighbors(G,i)
if F[j] != 0 && F[j] in colors == false
push!(colors, F[j])
end
end
if length(colors) > max_colors
max_colors = length(colors)
max_color_index = i
end
end
colors = zeros(Int64,0)
end
for i = 1:nv(G)
if A[i] == max_color_index
return i

"""
free_colors()

returns set of free colors of x which are less
than optimal color number (opt)
"""
function free_colors(x, A, colors, F, g, opt)
index = -1

freecolors = zeros(Int64, 0)

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

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

#set of free colors of x, which are < optColorNumber
function free_colors(x::Int64, F::Array{Int64,1}, G::VSafeGraph, max_color::Int64)
colors = zeros(Int64,0)
for color in 1:max_color
present = true
for y in inneighbors(G,x)
if F[y] == color
present = false
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 present
push!(colors,color)
if c_allowed && c < ocn
push!(freecolors, c)
end
end
return colors

freecolors

end

#least index with F(A[i]) = optColorNumber
function least_index(A::Array{Int64, 1}, F::Array{Int64,1}, optColorNumber::Int64, G::VSafeGraph)
for i = 1:nv(G)
if F[A[i]] == optColorNumber
"""
least_index()

returns least index i such that color of vertex
A[i] == opt (optimal color number)
"""
function least_index(F,A,opt)
for i in eachindex(A)
if F[A[i]] == opt
return i
end
end
end

#uncolor all vertices A[i] with i >= start
function uncolor_all(F::Array{Int64,1}, A::Array{Int64,1}, start::Int64, G::VSafeGraph)
for i = start:nv(G)
"""
uncolor_all()

uncolors all vertices A[i] where
i >= start
"""
function uncolor_all!(F, A, start)
for i = start:length(A)
F[A[i]] = 0
end
end

#remove from U all colors >= optColorNumber
function remove_colors(U::Array{Int64,1}, optColorNumber::Int64)
modified_U = zeros(Int64,0)
for i = 1:length(U)
if U[i] < optColorNumber
push!(mmodified_U, U[i])
"""
remove_higher_colors()

remove all the colors >= opt (optimal color number)
from the set of colors U
"""
function remove_higher_colors(U, opt)
u = zeros(Int32, 0)
for color in U
if color < opt
push!(u, color)
end
end
return modified_U
end
1 change: 0 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ using Test
@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

36 changes: 36 additions & 0 deletions test/test_bsc.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using LightGraphs

g0 = SimpleGraph(6)
add_edge!(g0, 1,2)
add_edge!(g0, 1,4)
add_edge!(g0, 1,5)
add_edge!(g0, 3,2)
add_edge!(g0, 3,5)
add_edge!(g0, 3,6)
add_edge!(g0, 4,5)
add_edge!(g0, 5,6)
sv0 = sort_by_degree(g0)

g1 = SimpleGraph(6)
add_edge!(g1, 2,1)
add_edge!(g1, 3,2)
add_edge!(g1, 4,2)
add_edge!(g1, 5,2)
add_edge!(g1, 6,2)
sv1 = sort_by_degree(g1)

g2 = SimpleGraph(5)
add_edge!(g2, 1,2)
add_edge!(g2, 1,3)
add_edge!(g2, 1,4)
add_edge!(g2, 4,2)
add_edge!(g2, 5,2)
add_edge!(g2, 3,4)
add_edge!(g2, 4,5)
sv2 = sort_by_degree(g2)

@testset "sort_by_degree(g)" begin
@test sv0 = [5,1,3,2,4,6]
@test sv1 = [2,1,3,4,5,6]
@test sv2 = [4,1,2,3,5]
end