diff --git a/src/ProblemReductions.jl b/src/ProblemReductions.jl index 550928c..242a33f 100644 --- a/src/ProblemReductions.jl +++ b/src/ProblemReductions.jl @@ -22,6 +22,7 @@ export BoolVar, CNFClause, CNF, Satisfiability, is_kSAT, satisfiable export MaxCut export IndependentSet export VertexCovering, is_vertex_covering, vertex_covering_energy +export DominatingSet # rules export target_problem, AbstractProblem, AbstractReductionResult, reduceto, extract_solution, reduction_complexity diff --git a/src/models/DominatingSet.jl b/src/models/DominatingSet.jl new file mode 100644 index 0000000..933619d --- /dev/null +++ b/src/models/DominatingSet.jl @@ -0,0 +1,42 @@ +""" +$TYPEDEF + DominatingSet(graph; weights=UnitWeight()) + +The [dominating set](https://queracomputing.github.io/GenericTensorNetworks.jl/dev/generated/DominatingSet/) problem. + +Positional arguments +------------------------------- +* `graph` is the problem graph. + +We don't have weights for this problem. +""" +struct DominatingSet{ GT<:AbstractGraph} <: AbstractProblem + graph::GT + function DominatingSet( graph::AbstractGraph) + return new{typeof(graph)}(graph) + end +end +Base.:(==)(a::DominatingSet, b::DominatingSet) = ( a.graph == b.graph ) + +# Variables Interface +variables(gp::DominatingSet) = [1:nv(gp.graph)...] +flavors(::Type{<:DominatingSet}) = [0, 1] + +""" + evaluate(c::DominatingSet, config) + +Firstly, we count the number of vertices outside the dominating set and the neighbours of the dominating set: +If this number is zero, this configuration corresponds to a dominating set. +* If the configuration is not a dominating set return Inf; +* If the configuration is a dominating set return size(dominating set). +""" + +function evaluate(c::DominatingSet, config) + g = c.graph + num_outside_vertices = count(w -> config[w] == 0 && all(v-> config[v] == 0, neighbors(g, w)), Graphs.vertices(g)) + if num_outside_vertices == 0 + return count(x -> x == 1, config) + else + return Inf + end +end \ No newline at end of file diff --git a/src/models/models.jl b/src/models/models.jl index 098bc33..ecf01d4 100644 --- a/src/models/models.jl +++ b/src/models/models.jl @@ -86,3 +86,4 @@ include("SetCovering.jl") include("MaxCut.jl") include("IndependentSet.jl") include("VertexCovering.jl") +include("DominatingSet.jl") diff --git a/test/models/DominatingSet.jl b/test/models/DominatingSet.jl new file mode 100644 index 0000000..45f3bb6 --- /dev/null +++ b/test/models/DominatingSet.jl @@ -0,0 +1,37 @@ +using Test, ProblemReductions, Graphs + +@testset "dominatingset" begin + # construct two equivalent graphs + g01 = SimpleGraph(5) + add_edge!(g01, 1, 2) + add_edge!(g01, 2, 3) + add_edge!(g01, 3, 4) + add_edge!(g01, 4, 5) + + g02 = SimpleGraph(5) + add_edge!(g02, 4, 5) + add_edge!(g02, 1, 2) + add_edge!(g02, 3, 4) + add_edge!(g02, 2, 3) + + # construct corresponding DominatingSet problems + DS_01 = DominatingSet(g01) + DS_02 = DominatingSet(g02) + @test DS_01 == DS_02 + + # variables + @test variables(DS_01) == [1, 2, 3, 4, 5] + @test num_variables(DS_01) == 5 + @test flavors(DominatingSet) == [0, 1] + + # evaluate + # Positive examples + @test evaluate(DS_01, [1, 0, 1, 0, 1]) == 3 + @test evaluate(DS_01, [0, 1, 0, 1, 0]) == 2 + @test evaluate(DS_01, [1, 1, 1, 1, 0]) == 4 + # Negative examples + @test evaluate(DS_01, [0, 1, 1, 0, 0]) == Inf + @test evaluate(DS_01, [1, 0, 0, 0, 1]) == Inf + # findbest function + @test findbest(DS_01, BruteForce()) == [[1, 0, 0, 1, 0], [0, 1, 0, 1, 0], [0, 1, 0, 0, 1]] +end \ No newline at end of file diff --git a/test/models/models.jl b/test/models/models.jl index 307067a..bb9626c 100644 --- a/test/models/models.jl +++ b/test/models/models.jl @@ -30,4 +30,8 @@ end @testset "VertexCovering" begin include("VertexCovering.jl") +end + +@testset "DominatingSet" begin + include("DominatingSet.jl") end \ No newline at end of file diff --git a/test/rules/rules.jl b/test/rules/rules.jl index ca21194..18fdca0 100644 --- a/test/rules/rules.jl +++ b/test/rules/rules.jl @@ -4,7 +4,7 @@ using Test, ProblemReductions, Graphs include("spinglass_sat.jl") end -@testset "spinglass_sat" begin +@testset "spinglass_maxcut" begin include("spinglass_maxcut.jl") end