Skip to content

Commit

Permalink
Merge branch 'sheldon'
Browse files Browse the repository at this point in the history
  • Loading branch information
c-allergic committed Jul 15, 2024
2 parents 5ea4303 + b2afd00 commit 95f1a21
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 1 deletion.
59 changes: 59 additions & 0 deletions src/models/Coloring.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""
$(TYPEDEF)
Coloring{K}(graph; weights=UnitWeight())
The [Vertex Coloring](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/Coloring/) problem.
Positional arguments
-------------------------------
* `graph` is the problem graph.
* `weights` are associated with the edges of the `graph`, default to `UnitWeight()`.
"""
struct Coloring{K, WT<:Union{UnitWeight, Vector}} <:AbstractProblem
graph::SimpleGraph{Int64}
weights::WT
function Coloring{K}(graph::SimpleGraph{Int64}, weights::Union{UnitWeight, Vector}=UnitWeight()) where {K}
@assert weights isa UnitWeight || length(weights) == ne(graph) "length of weights must be equal to the number of edges $(ne(graph)), got: $(length(weights))"
new{K, typeof(weights)}(graph, weights)
end
end
Base.:(==)(a::Coloring, b::Coloring) = a.graph == b.graph && a.weights == b.weights

variables(gp::Coloring{K}) where K = collect(1:nv(gp.graph))
flavors(::Type{<:Coloring{K}}) where K = collect(0:K-1) # colors
num_flavors(c::Type{<:Coloring{K}}) where K = length(flavors(c)) # number of colors
terms(gp::Coloring{K}) where K = [[minmax(e.src,e.dst)...] for e in Graphs.edges(gp.graph)] # return the edges of the graph


# weights interface
# ?whether weights information would be useful here? I think in sat-coloring, we only need to consider unweighted graphs
parameters(c::Coloring) = c.weights
set_parameters(c::Coloring{K}, weights) where K = Coloring{K}(c.graph, weights)

# utilities
"""
evaluate(c::Coloring, config)
Compute the energy of the vertex coloring configuration `config`, the energy is the number of violated edges.
"""
function evaluate(c::Coloring, config)
@assert length(config) == nv(c.graph)
coloring_energy(terms(c), c.weights,config)
end

coloring_energy(terms::AbstractVector, weights::AbstractVector, config) = sum([(config[e[1]] == config[e[2]]) * w for (e, w) in zip(terms, weights)])
coloring_energy(terms::AbstractVector,::UnitWeight, config) = sum([(config[e[1]] == config[e[2]]) for e in terms])


"""
is_vertex_coloring(graph::SimpleGraph, config)
Returns true if the coloring specified by config is a valid one, i.e. does not violate the contraints of vertices of an edges having different colors.
"""
function is_vertex_coloring(graph::SimpleGraph, config)
for e in edges(graph)
config[e.src] == config[e.dst] && return false
end
return true
end

3 changes: 2 additions & 1 deletion src/models/SpinGlass.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ function SpinGlass(graph::SimpleGraph, J::Vector, h::Vector)
@assert length(h) == nv(graph) "length of h must be equal to the number of vertices $(nv(graph)), got: $(length(h))"
SpinGlass(HyperGraph(nv(graph), Vector{Int}[[[src(e), dst(e)] for e in edges(graph)]..., [[i] for i in 1:nv(graph)]...]), [J..., h...])
end
# Base.:(<symbol>) to overload the operators
Base.:(==)(a::SpinGlass, b::SpinGlass) = a.graph == b.graph && a.weights == b.weights
function spin_glass_from_matrix(M::AbstractMatrix, h::AbstractVector)
g = SimpleGraph((!iszero).(M))
Expand Down Expand Up @@ -72,7 +73,7 @@ function spinglass_energy(cliques::AbstractVector{Vector{Int}}, config; weights)
end
function spinglass_energy(g::SimpleGraph, config; J, h)
eng = zero(promote_type(eltype(J), eltype(h)))
# NOTE: cast to Int to avoid using unsigned :nt
# NOTE: cast to Int to avoid using unsigned Int
s = 1 .- 2 .* Int.(config) # 0 -> spin 1, 1 -> spin -1
# coupling terms
for (i, e) in enumerate(edges(g))
Expand Down
6 changes: 6 additions & 0 deletions src/models/models.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,11 @@ Find the best configurations of the `problem` using the `method`.
"""
function findbest end

struct UnitWeight end
Base.getindex(::UnitWeight, i) = 1
Base.eltype(::UnitWeight) = Int


include("SpinGlass.jl")
include("Circuit.jl")
include("Coloring.jl")
32 changes: 32 additions & 0 deletions test/models/Coloring.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Test, ProblemReductions, Graphs
using ProblemReductions: Coloring, SimpleGraph, add_edge!, UnitWeight, variables, flavors, num_flavors,
terms, evaluate, coloring_energy, is_vertex_coloring,set_parameters,parameters

# create a graph

@testset "coloring" begin
# constructor function
@test flavors(Coloring{3}) == [0,1,2]
@test num_flavors(Coloring{3}) == 3

g = SimpleGraph(4)
add_edge!(g, 1, 2)
add_edge!(g, 2, 3)
add_edge!(g, 3, 4)
add_edge!(g, 4, 1)
c = Coloring{3}(g,UnitWeight())
@test c.graph == g && c.weights isa UnitWeight
@test variables(c) == [1, 2, 3, 4]
@test terms(c)==[[1, 2],[1,4],[2, 3], [3, 4]]

# weights interface
@test parameters(c) == UnitWeight()
@test set_parameters(c, [1, 2, 2, 1]) == Coloring{3}(g, [1, 2, 2, 1])

# evaluate,here I found the definition of Config is not clear, so I can't test the evaluate function
@test evaluate(c,[0, 1, 2, 0]) == 1
@test coloring_energy(terms(c),[1, 3, 2, 5],[0, 1, 2, 0]) == 3


end

4 changes: 4 additions & 0 deletions test/models/models.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ end

@testset "SpinGlass" begin
include("SpinGlass.jl")
end

@testset "Coloring" begin
include("Coloring.jl")
end

0 comments on commit 95f1a21

Please sign in to comment.