Skip to content
Open
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/ProblemReductions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export MaximalIS
export PaintShop
export BinaryMatrixFactorization, is_binary_matrix_factorization
export BicliqueCover, is_biclique_cover
export CliqueCover,is_clique_cover

# rules
export target_problem, AbstractProblem, ConstraintSatisfactionProblem, solution_size, solution_size_multiple, SolutionSize, objectives, constraints, energy_mode
Expand Down
60 changes: 60 additions & 0 deletions src/models/CliqueCover.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
$TYPEDEF
CliqueCover{K}(graph::SimpleGraph{Int64}, k::Int64)

A clique cover of a graph G is a set of cliques such that all vertices in G is coverd by the vertices union of these cliques. A K clique cover is to find whether we could use only k cliques to cover all the vertices in the graph.

"""
struct CliqueCover{Int64} <: ConstraintSatisfactionProblem{Int64}
graph::SimpleGraph{Int64}
k::Int64
function CliqueCover(graph::SimpleGraph{Int64}, k::Int64)
new{Int64}(graph, k)
end
end
problem_size(c::CliqueCover) = (; num_vertices=nv(c.graph), num_edges=ne(c.graph), k=c.k)
num_variables(c::CliqueCover) = nv(c.graph) * c.k
num_flavors(::Type{<:CliqueCover}) = 2

Check warning on line 17 in src/models/CliqueCover.jl

View check run for this annotation

Codecov / codecov/patch

src/models/CliqueCover.jl#L17

Added line #L17 was not covered by tests

# constraints interface
function constraints(c::CliqueCover)
return [LocalConstraint(num_flavors(c), v, [0,1]) for v in vertices(c.graph)]

Check warning on line 21 in src/models/CliqueCover.jl

View check run for this annotation

Codecov / codecov/patch

src/models/CliqueCover.jl#L20-L21

Added lines #L20 - L21 were not covered by tests
end
function objectives(c::CliqueCover)
return [LocalSolutionSize(num_flavors(c), [v], [0, 1]) for v in vertices(c.graph)]

Check warning on line 24 in src/models/CliqueCover.jl

View check run for this annotation

Codecov / codecov/patch

src/models/CliqueCover.jl#L23-L24

Added lines #L23 - L24 were not covered by tests
end
energy_mode(::Type{<:CliqueCover}) = SmallerSizeIsBetter()

function is_clique_cover(configs::Vector{Vector{Int64}}, c::CliqueCover)
# check if the number of cliques is equal to k
if length(configs) != c.k
print(1)
return false
end
# check if they are all valid clique
if any(config -> !is_clique(c, config), configs)
print(2)
return false
end
vertices_covered = reduce(vcat, [findall(x-> x==1,config) for config in configs])
# check if the vertices are covered by the cliques
if length(vertices_covered) != nv(c.graph)
print(3)
return false
end
return true
end
function is_clique(c::CliqueCover,config::Vector{Int64})
vertices = findall(x -> x == 1, config)
for (v1, v2) in collect(Iterators.product(vertices, vertices))
# pass if the vertices are the same
if v1 == v2
continue
end
# check if the edge exists in the graph, if not, return false
if !has_edge(c.graph, v1, v2)
return false
end
end
return true
end
1 change: 1 addition & 0 deletions src/models/models.jl
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,4 @@ include("MaximalIS.jl")
include("Paintshop.jl")
include("BicliqueCover.jl")
include("BMF.jl")
include("CliqueCover.jl")
33 changes: 33 additions & 0 deletions test/models/CliqueCover.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Test, ProblemReductions, Graphs

@testset "CliqueCover" begin
g = SimpleGraph(5)
for (i,j) in [(1,3),(1,5),(2,3),(2,4),(3,5)]
add_edge!(g,i,j)
end
c = CliqueCover(g,2)
@test num_variables(c) == 5 * 2
@test num_flavors(c) == 2
@test problem_size(c) == (; num_vertices=5, num_edges=5, k=2)
@test Base.:(==)(c, CliqueCover(g,2))
@test energy_mode(c) == SmallerSizeIsBetter()
@test is_clique_cover([[1,0,1,0,1],[0,1,0,1,0]],c) == true
@test is_clique_cover([[1,0,1,0,0],[0,1,0,1,0],[0,0,0,0,0]],c) == false
@test is_clique_cover([[1,0,1,0,0],[0,1,0,1,1]],c) == false
@test ProblemReductions.is_clique(c,[1,0,1,0,0]) == true
@test ProblemReductions.is_clique(c,[0,1,0,1,1]) == false
@test ProblemReductions.is_clique(c,[1,0,1,0,1]) == true

g1 = SimpleGraph(6)
for (i,j) in [(1,3),(1,5),(1,6),(2,3),(2,4),(3,4),(3,5),(4,6),(5,6)]
add_edge!(g1,i,j)
end
c1 = CliqueCover(g1,2)
@test is_clique_cover([[1,0,0,0,1,1],[0,1,1,1,0,0]],c1) == true
@test is_clique_cover([[1,0,1,0,1,0],[0,1,0,1,0,0]],c1) == false
@test is_clique_cover([[1,0,1,0,1,0],[0,1,0,1,0,0],[0,0,0,0,0,0]],c1) == false
@test ProblemReductions.is_clique(c1,[1,0,1,0,1,0]) == true
c2 = CliqueCover(g1,3)
@test is_clique_cover([[1,0,1,0,1,0],[0,1,0,1,0,0],[0,0,0,0,0,1]],c2) == true
@test is_clique_cover([[1,0,1,0,1,0],[0,1,0,1,0,0],[0,0,0,0,0,0]],c2) == false
end
3 changes: 3 additions & 0 deletions test/models/models.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,6 @@ end
include("BicliqueCover.jl")
end

@testset "CliqueCover" begin
include("CliqueCover.jl")
end
Loading