Skip to content

Commit

Permalink
Merge pull request #20 from ArrogantGao/xz/new_selector
Browse files Browse the repository at this point in the history
Added a new selector `MinBoundaryHighDegreeSelector`
  • Loading branch information
ArrogantGao authored Dec 2, 2024
2 parents 65dfc28 + d58f750 commit 11a8d72
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 13 deletions.
2 changes: 1 addition & 1 deletion lib/OptimalBranchingMIS/src/OptimalBranchingMIS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using GenericTensorNetworks

export MISProblem
export MISReducer, XiaoReducer
export MinBoundarySelector
export MinBoundarySelector, MinBoundaryHighDegreeSelector
export TensorNetworkSolver
export NumOfVertices, D3Measure

Expand Down
12 changes: 6 additions & 6 deletions lib/OptimalBranchingMIS/src/interfaces.jl
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
"""
mis_size(g::AbstractGraph; bs::BranchingStrategy = BranchingStrategy(table_solver = TensorNetworkSolver(), selector = MinBoundarySelector(2), measure=D3Measure()), reducer::AbstractReducer = MISReducer())
mis_size(g::AbstractGraph; bs::BranchingStrategy = BranchingStrategy(table_solver = TensorNetworkSolver(), selector = MinBoundaryHighDegreeSelector(2, 6, 0), measure=D3Measure()), reducer::AbstractReducer = MISReducer())
Calculate the size of the Maximum Independent Set (MIS) for a given graph.
### Arguments
- `g::AbstractGraph`: The graph for which the MIS size is to be calculated.
- `bs::BranchingStrategy`: (optional) The branching strategy to be used. Defaults to a strategy using `table_solver=TensorNetworkSolver`, `selector=MinBoundarySelector(2)`, and `measure=D3Measure`.
- `bs::BranchingStrategy`: (optional) The branching strategy to be used. Defaults to a strategy using `table_solver=TensorNetworkSolver`, `selector=MinBoundaryHighDegreeSelector(2, 6, 0)`, and `measure=D3Measure`.
- `reducer::AbstractReducer`: (optional) The reducer to be applied. Defaults to `MISReducer`.
### Returns
- An integer representing the size of the Maximum Independent Set for the given graph.
"""
function mis_size(g::AbstractGraph; bs::BranchingStrategy = BranchingStrategy(table_solver = TensorNetworkSolver(), selector = MinBoundarySelector(2), measure=D3Measure()), reducer=MISReducer())
function mis_size(g::AbstractGraph; bs::BranchingStrategy = BranchingStrategy(table_solver = TensorNetworkSolver(), selector = MinBoundaryHighDegreeSelector(2, 6, 0), measure=D3Measure()), reducer=MISReducer())
p = MISProblem(g)
res = branch_and_reduce(p, bs, reducer, MaxSize)
return res.size
end

"""
mis_branch_count(g::AbstractGraph; bs::BranchingStrategy = BranchingStrategy(table_solver = TensorNetworkSolver(), selector = MinBoundarySelector(2), measure=D3Measure()), reducer=MISReducer())
mis_branch_count(g::AbstractGraph; bs::BranchingStrategy = BranchingStrategy(table_solver = TensorNetworkSolver(), selector = MinBoundaryHighDegreeSelector(2, 6, 0), measure=D3Measure()), reducer=MISReducer())
Calculate the size and the number of branches of the Maximum Independent Set (MIS) for a given graph.
### Arguments
- `g::AbstractGraph`: The graph for which the MIS size and the number of branches are to be calculated.
- `bs::BranchingStrategy`: (optional) The branching strategy to be used. Defaults to a strategy using `table_solver=TensorNetworkSolver`, `selector=MinBoundarySelector(2)`, and `measure=D3Measure`.
- `bs::BranchingStrategy`: (optional) The branching strategy to be used. Defaults to a strategy using `table_solver=TensorNetworkSolver`, `selector=MinBoundaryHighDegreeSelector(2, 6, 0)`, and `measure=D3Measure`.
- `reducer::AbstractReducer`: (optional) The reducer to be applied. Defaults to `MISReducer`.
### Returns
- A tuple `(size, count)` where `size` is the size of the Maximum Independent Set and `count` is the number of branches.
"""
function mis_branch_count(g::AbstractGraph; branching_strategy::BranchingStrategy = BranchingStrategy(table_solver = TensorNetworkSolver(), selector = MinBoundarySelector(2), measure=D3Measure()), reducer=MISReducer())
function mis_branch_count(g::AbstractGraph; branching_strategy::BranchingStrategy = BranchingStrategy(table_solver = TensorNetworkSolver(), selector = MinBoundaryHighDegreeSelector(2, 6, 0), measure=D3Measure()), reducer=MISReducer())
p = MISProblem(g)
res = branch_and_reduce(p, branching_strategy, reducer, MaxSizeBranchCount)
return (res.size, res.count)
Expand Down
47 changes: 43 additions & 4 deletions lib/OptimalBranchingMIS/src/selector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,61 @@ function OptimalBranchingCore.select_variables(p::MISProblem, m::M, selector::Mi
@assert nv(g) > 0
kneighbor = selector.k

local vs_min

novs_min = nv(g)
for v in 1:nv(g)
vs, ovs = neighbor_cover(g, v, kneighbor)
if length(ovs) < novs_min
vs_min = vs
novs_min = length(ovs)
end
end
return vs_min
end

"""
struct MinBoundaryHighDegreeSelector <: AbstractVertexSelector
The `MinBoundaryHighDegreeSelector` struct represents a strategy:
- if exists a vertex with degree geq high_degree_threshold, then select it and its k-degree neighbors.
- otherwise, select a subgraph with the minimum number of open vertices by k-layers of neighbors.
# Fields
- `kb::Int`: The number of layers of neighbors to consider when selecting the subgraph.
- `hd::Int`: The threshold of degree for a vertex to be selected.
- `kd::Int`: The number of layers of neighbors to consider when selecting the subgraph.
"""
struct MinBoundaryHighDegreeSelector <: AbstractSelector
kb::Int # k-boundary
hd::Int # high-degree threshold
kd::Int # k-degree
end

function OptimalBranchingCore.select_variables(p::MISProblem, m::M, selector::MinBoundaryHighDegreeSelector) where{M<:AbstractMeasure}
g = p.g
@assert nv(g) > 0
boundary_neighbor = selector.kb
high_degree_threshold = selector.hd
high_degree_neighbor = selector.kd

local vs_min
# if exists a vertex with degree geq 6, then select it and it 1st-order neighbors.
for v in 1:nv(g)
if degree(g, v) 6
vs_min = neighbor_cover(g, v, 1)[1]
if degree(g, v) high_degree_threshold
vs_min = neighbor_cover(g, v, high_degree_neighbor)[1]
return vs_min
end
end

novs_min = nv(g)
for v in 1:nv(g)
vs, ovs = neighbor_cover(g, v, kneighbor)
vs, ovs = neighbor_cover(g, v, boundary_neighbor)
if length(ovs) < novs_min
vs_min = vs
novs_min = length(ovs)
end
end
return vs_min
end
end
4 changes: 2 additions & 2 deletions lib/OptimalBranchingMIS/test/branch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ using Test, Random
mis_exact = mis2(EliminateGraph(g))
p = MISProblem(g)

for set_cover_solver in [IPSolver(10, false), LPSolver(10, false)], measure in [D3Measure(), NumOfVertices()], reducer in [NoReducer(), MISReducer(), XiaoReducer()], prune_by_env in [true, false]
branching_strategy = BranchingStrategy(; set_cover_solver, table_solver=TensorNetworkSolver(; prune_by_env), selector=MinBoundarySelector(2), measure)
for set_cover_solver in [IPSolver(10, false), LPSolver(10, false)], measure in [D3Measure(), NumOfVertices()], reducer in [NoReducer(), MISReducer(), XiaoReducer()], prune_by_env in [true, false], selector in [MinBoundarySelector(2), MinBoundaryHighDegreeSelector(2, 6, 0), MinBoundaryHighDegreeSelector(2, 6, 1)]
branching_strategy = BranchingStrategy(; set_cover_solver, table_solver=TensorNetworkSolver(; prune_by_env), selector=selector, measure)
res = branch_and_reduce(p, branching_strategy, reducer, MaxSize)
res_count = branch_and_reduce(p, branching_strategy, reducer, MaxSizeBranchCount)

Expand Down

0 comments on commit 11a8d72

Please sign in to comment.