diff --git a/src/ProblemReductions.jl b/src/ProblemReductions.jl index 8f31faf..b0e561a 100644 --- a/src/ProblemReductions.jl +++ b/src/ProblemReductions.jl @@ -45,6 +45,7 @@ export ReductionSATToIndependentSet, ReductionSATToDominatingSet export ReductionIndependentSetToSetPacking, ReductionSetPackingToIndependentSet export ReductionSATToCircuit export ReductionIndependentSetToVertexCovering +export ReductionMatchingToSetPacking # reduction path export ReductionGraph, reduction_graph, reduction_paths, ConcatenatedReduction diff --git a/src/rules/matching_setpacking.jl b/src/rules/matching_setpacking.jl new file mode 100644 index 0000000..9a4be0a --- /dev/null +++ b/src/rules/matching_setpacking.jl @@ -0,0 +1,31 @@ +""" +$TYPEDEF +The reduction result of a vertex matching to a set packing problem. + +### Fields +- `SetPacking{WT<:AbstractVector{Int}}`: the target set packing problem +""" +struct ReductionMatchingToSetPacking{ET,T,WT<:AbstractVector{T}} <: AbstractReductionResult + setpacking::SetPacking{ET, T, WT} +end +Base.:(==)(a::ReductionMatchingToSetPacking, b::ReductionMatchingToSetPacking) = a.setpacking == b.setpacking + +target_problem(res::ReductionMatchingToSetPacking) = res.setpacking + +function reduceto(::Type{SetPacking}, s::Matching) + sp = matching2setpacking(s.graph, s.weights) + return ReductionMatchingToSetPacking(sp) +end + +function matching2setpacking(g::SimpleGraph, weights) + subsets = Vector{Vector{Int}}() + # map edges to subset + for edge in edges(g) + push!(subsets,[edge.src, edge.dst]) + end + return SetPacking(subsets, weights) +end + +function extract_solution(res::ReductionMatchingToSetPacking, sol) + return sol +end \ No newline at end of file diff --git a/src/rules/rules.jl b/src/rules/rules.jl index c2f4733..a81b74d 100644 --- a/src/rules/rules.jl +++ b/src/rules/rules.jl @@ -87,4 +87,5 @@ include("sat_independentset.jl") include("sat_dominatingset.jl") include("independentset_setpacking.jl") include("circuit_sat.jl") -include("vertexcovering_independentset.jl") \ No newline at end of file +include("vertexcovering_independentset.jl") +include("matching_setpacking.jl") \ No newline at end of file diff --git a/test/rules/matching_setpacking.jl b/test/rules/matching_setpacking.jl new file mode 100644 index 0000000..67dbe3a --- /dev/null +++ b/test/rules/matching_setpacking.jl @@ -0,0 +1,29 @@ +using Test, ProblemReductions, Graphs + +@testset "matching_setpacking" begin + + # UnitWeight Graph + g1 = SimpleGraph(4) + for (i, j) in [(1, 2), (1, 3), (3, 4), (2, 3)] + add_edge!(g1, i, j) + end + Matching1 = Matching(g1) + SP1 = reduceto(SetPacking, Matching1) + @test target_problem(SP1) == SP1.setpacking + @test target_problem(SP1) == SetPacking([[1,2], [1,3],[2,3] ,[3,4]], [1, 1, 1, 1]) + sol = findbest(SP1.setpacking, BruteForce()) + @test extract_solution(SP1, sol) == sol + + # Weighted Graph + g2 = SimpleGraph(4) + for (i, j) in [(1, 2), (1, 3), (3, 4), (2, 3)] + add_edge!(g2, i, j) + end + Matching2 = Matching(g2, [1, 2, 3, 4]) + SP2 = reduceto(SetPacking, Matching2) + @test target_problem(SP2) == SP2.setpacking + @test target_problem(SP2) == SetPacking([[1,2], [1,3], [2,3], [3,4]], [1, 2, 3, 4]) + sol1 = findbest(SP2.setpacking, BruteForce()) + sol2 = findbest(Matching2,BruteForce()) + @test extract_solution(SP2, sol1) == sol2 +end \ No newline at end of file diff --git a/test/rules/rules.jl b/test/rules/rules.jl index 06dd8ac..8a24877 100644 --- a/test/rules/rules.jl +++ b/test/rules/rules.jl @@ -48,6 +48,10 @@ end include("vertexcovering_independentset.jl") end +@testset "matching_setpacking" begin + include("matching_setpacking.jl") +end + @testset "rules" begin circuit = CircuitSAT(@circuit begin x = a ∨ ¬b @@ -65,6 +69,7 @@ end is = IndependentSet(graph) is2 = IndependentSet(graph2) setpacking = SetPacking([[1, 2, 5], [1, 3], [2, 4], [3, 6], [2, 3, 6]]) + matching = Matching(graph) for (source, target_type) in [ # please add more tests here circuit => SpinGlass{<:SimpleGraph}, @@ -83,6 +88,7 @@ end is2 => SetPacking, setpacking => IndependentSet{<:SimpleGraph}, is => VertexCovering, + matching => SetPacking ] @info "Testing reduction from $(typeof(source)) to $(target_type)" # directly solve