Independent Set -> Set Packing
In this tutorial, we will demonstrate how to reduce the IndependentSet
problem to the SetPacking
problem and how to extract solutions back to the original problem.
Reduction Framework
Given an undirected graph $G=(V,E)$ and parameter $k$, we can have an instance of the IndependentSet
problem $(G, k)$. we aim to generate a corresponding SetPacking
instance $(U, S, k)$ (where $U$ is the union set, $S$ is the set of subsets and parameter $k$ is the required set packing size).
- Step-0: $k$ are the same;
- Step-1: Each edge $(u,v)\in E$ -> Create an element $x_{u,v}$ in $U$;
- Step-2: Each vertex $v \in V$ -> Create a subset $\{S_{u,v}|(u,v)\in E \}$.
It can be proven that:
- The instance $(G,k)$ is an yes-instance if and only if generated $(U,S,k)$ is an yes-instance;
- This transformation is within polynomial time.
Construct Reduction
We can firstly define a IndependentSet
problem over a simple graph with $4$ vertices.
julia> using ProblemReductions, Graphs
julia> graph = SimpleGraph(4)
{4, 0} undirected simple Int64 graph
julia> for (i, j) in [(1, 2), (1, 3), (3, 4), (2, 3)] add_edge!(graph, i, j) end
julia> IS = IndependentSet(graph)
IndependentSet{SimpleGraph{Int64}, Int64, UnitWeight}(SimpleGraph{Int64}(4, [[2, 3], [1, 3], [1, 2, 4], [3]]), [1, 1, 1, 1])
Then the reduction ReductionIndependentSetToSetPacking
can be easily constructed by the reduceto
function.
julia> result = reduceto(SetPacking, IS)
ReductionIndependentSetToSetPacking{Int64}(SetPacking{Int64, Int64, UnitWeight}([1, 2, 3, 4], [[1, 2], [1, 3], [2, 3, 4], [4]], [1, 1, 1, 1]), [1, 2, 3, 4])
The target SetPacking
problem can be accessed by the target
field:
julia> SP = result.target
SetPacking{Int64, Int64, UnitWeight}([1, 2, 3, 4], [[1, 2], [1, 3], [2, 3, 4], [4]], [1, 1, 1, 1])
Extract Solutions
We can extract solutions from the target SetPacking
problem either by extracting individual solutions via extract_solution
or extracting mutilple solutions via extract_multiple_solutions
.
julia> sol_SP = findbest(SP, BruteForce())
2-element Vector{Vector{Int64}}: [1, 0, 0, 1] [0, 1, 0, 1]
julia> sol_extract_single = Set( unique( extract_solution.(Ref(result), sol_SP) ) )
Set{Vector{Int64}} with 2 elements: [0, 1, 0, 1] [1, 0, 0, 1]
julia> sol_extract_mutilple = Set( extract_multiple_solutions(result, sol_SP) )
Set{Vector{Int64}} with 2 elements: [0, 1, 0, 1] [1, 0, 0, 1]
We can find that these extracted solutions indeed match with the solutions to the original IndependentSet
problem.
julia> sol_IS = findbest(IS, BruteForce())
2-element Vector{Vector{Int64}}: [1, 0, 0, 1] [0, 1, 0, 1]