From c391bbf68b1099dd0264f7bdb8c556ed7ca403b7 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Sat, 18 Jan 2025 19:48:26 +0000 Subject: [PATCH] build based on 8549665 --- dev/.documenter-siteinfo.json | 2 +- dev/benchmarks/index.html | 2 +- dev/generated/rule_discovery/index.html | 2 +- dev/index.html | 2 +- dev/man/core/index.html | 10 +++++----- dev/man/mis/index.html | 4 ++-- dev/performance_tips/index.html | 2 +- dev/quick-start/index.html | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 560d9ba..4f830a2 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2025-01-18T16:08:01","documenter_version":"1.8.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.2","generation_timestamp":"2025-01-18T19:48:22","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/dev/benchmarks/index.html b/dev/benchmarks/index.html index c91d3eb..eabbc32 100644 --- a/dev/benchmarks/index.html +++ b/dev/benchmarks/index.html @@ -1,2 +1,2 @@ -Benchmarks · OptimalBranching.jl

Benchmarks

The maximum independent set problem

We benchmarked the branch-and-reduce algorithm based on the optimal branching algorithm on the maximum independent set problem against various state-of-the-art solvers, where we compared the number of branches needed to solve the problem.

Our mehtod is denoted as $\texttt{ob}$ and $\texttt{ob+xiao}$, and the previous method include $\texttt{xiao2013}$ and $\texttt{akiba2015}$. We compared the performance of these methods in 3-regular graphs, Erdős–Rényi random graphs, grid graphs and King's sub-graphs, for each size we generated 1000 random graphs.

The average number of branches needed to solve the problem is shown in the following figure:

The maximum number of branches needed to solve the problem among 1000 graphs is shown in the following figure:

These numerical results show that our method is competitive with the previous methods with less human-designed rules.

+Benchmarks · OptimalBranching.jl

Benchmarks

The maximum independent set problem

We benchmarked the branch-and-reduce algorithm based on the optimal branching algorithm on the maximum independent set problem against various state-of-the-art solvers, where we compared the number of branches needed to solve the problem.

Our mehtod is denoted as $\texttt{ob}$ and $\texttt{ob+xiao}$, and the previous method include $\texttt{xiao2013}$ and $\texttt{akiba2015}$. We compared the performance of these methods in 3-regular graphs, Erdős–Rényi random graphs, grid graphs and King's sub-graphs, for each size we generated 1000 random graphs.

The average number of branches needed to solve the problem is shown in the following figure:

The maximum number of branches needed to solve the problem among 1000 graphs is shown in the following figure:

These numerical results show that our method is competitive with the previous methods with less human-designed rules.

diff --git a/dev/generated/rule_discovery/index.html b/dev/generated/rule_discovery/index.html index 878f625..8848b57 100644 --- a/dev/generated/rule_discovery/index.html +++ b/dev/generated/rule_discovery/index.html @@ -108,4 +108,4 @@ result = solve_greedy_rule(branching_region, graph, vs)
OptimalBranchingResult{BitBasis.LongLongUInt{1}, Float64}:
  optimal_rule: DNF{BitBasis.LongLongUInt{1}}: (#1 ∧ ¬#2 ∧ ¬#3 ∧ ¬#4 ∧ #5 ∧ #7 ∧ #9 ∧ ¬#11 ∧ ¬#12 ∧ ¬#15 ∧ ¬#16 ∧ ¬#19 ∧ ¬#20) ∨ (#1 ∧ ¬#2 ∧ ¬#3 ∧ ¬#4 ∧ ¬#5 ∧ #6 ∧ #7 ∧ #9 ∧ #11 ∧ #12 ∧ ¬#13 ∧ ¬#14 ∧ ¬#15 ∧ ¬#16 ∧ ¬#19 ∧ ¬#20) ∨ (#1 ∧ ¬#2 ∧ ¬#3 ∧ ¬#4 ∧ #5 ∧ ¬#7 ∧ #8 ∧ #9 ∧ ¬#11 ∧ ¬#12 ∧ #15 ∧ #16 ∧ ¬#17 ∧ ¬#18 ∧ ¬#19 ∧ ¬#20) ∨ (#1 ∧ ¬#2 ∧ ¬#3 ∧ ¬#4 ∧ ¬#5 ∧ #6 ∧ ¬#7 ∧ #8 ∧ #9 ∧ #11 ∧ #12 ∧ ¬#13 ∧ ¬#14 ∧ #15 ∧ #16 ∧ ¬#17 ∧ ¬#18 ∧ ¬#19 ∧ ¬#20) ∨ (¬#1 ∧ #2 ∧ #3 ∧ ¬#4 ∧ ¬#5 ∧ ¬#6 ∧ ¬#7 ∧ ¬#8 ∧ #9 ∧ ¬#19 ∧ ¬#20) ∨ (#1 ∧ ¬#2 ∧ ¬#3 ∧ ¬#4 ∧ #5 ∧ #7 ∧ ¬#9 ∧ #10 ∧ ¬#11 ∧ ¬#12 ∧ ¬#15 ∧ ¬#16 ∧ #19 ∧ #20 ∧ ¬#21 ∧ ¬#22) ∨ (#1 ∧ ¬#2 ∧ ¬#3 ∧ ¬#4 ∧ ¬#5 ∧ #6 ∧ #7 ∧ ¬#9 ∧ #10 ∧ #11 ∧ #12 ∧ ¬#13 ∧ ¬#14 ∧ ¬#15 ∧ ¬#16 ∧ #19 ∧ #20 ∧ ¬#21 ∧ ¬#22) ∨ (#1 ∧ ¬#2 ∧ ¬#3 ∧ ¬#4 ∧ #5 ∧ ¬#7 ∧ #8 ∧ ¬#9 ∧ #10 ∧ ¬#11 ∧ ¬#12 ∧ #15 ∧ #16 ∧ ¬#17 ∧ ¬#18 ∧ #19 ∧ #20 ∧ ¬#21 ∧ ¬#22) ∨ (#1 ∧ ¬#2 ∧ ¬#3 ∧ ¬#4 ∧ ¬#5 ∧ #6 ∧ ¬#7 ∧ #8 ∧ ¬#9 ∧ #10 ∧ #11 ∧ #12 ∧ ¬#13 ∧ ¬#14 ∧ #15 ∧ #16 ∧ ¬#17 ∧ ¬#18 ∧ #19 ∧ #20 ∧ ¬#21 ∧ ¬#22) ∨ (¬#1 ∧ #3 ∧ #4 ∧ ¬#7 ∧ ¬#8 ∧ ¬#9 ∧ ¬#10) ∨ (¬#1 ∧ #2 ∧ ¬#3 ∧ #4 ∧ ¬#5 ∧ ¬#6 ∧ #7 ∧ ¬#9 ∧ ¬#10 ∧ ¬#15 ∧ ¬#16)
  branching_vector: [28.0, 34.0, 34.0, 40.0, 24.0, 34.0, 40.0, 40.0, 46.0, 16.0, 24.0]
- γ: 1.0842073740067577

This page was generated using Literate.jl.

+ γ: 1.0842073740067577

This page was generated using Literate.jl.

diff --git a/dev/index.html b/dev/index.html index 6746024..ed534d0 100644 --- a/dev/index.html +++ b/dev/index.html @@ -11,4 +11,4 @@ archivePrefix={arXiv}, primaryClass={math.OC}, url={https://arxiv.org/abs/2412.07685}, -} +} diff --git a/dev/man/core/index.html b/dev/man/core/index.html index b0c113a..e05f1f4 100644 --- a/dev/man/core/index.html +++ b/dev/man/core/index.html @@ -1,6 +1,6 @@ -OptimalBranchingCore · OptimalBranching.jl

OptimalBranchingCore

Literal, Clause and DNF

Literals, clauses and disjunctive normal form (DNF) are basic concepts in boolean logic, where literals are boolean variables, clauses are boolean expressions, and DNF is a disjunction of one or more conjunctions of literals.

Here is an example, given a truth table as follows:

abcvalue
0001
0011
0100
0110
1000
1011
1100
1110

where $a, b, c$ are boolean variables called literals. The true statements can be represented as a conjunction of literals, for example,

\[\neg a \land \neg b \land \neg c, \neg a \land \neg b \land c, a \land \neg b \land c\]

and these clauses can be combined into a DNF:

\[(\neg a \land \neg b) \lor (a \land \neg b \land c).\]

In OptimalBranchingCore, a clause is represented by the Clause type, and a DNF is represented by the DNF type, based on the BitBasis.jl package.

julia> using OptimalBranchingCore, BitBasis
julia> c1 = Clause(bit"011", bit"000")Clause{BitBasis.DitStr{2, 3, Int64}}: ¬#1 ∧ ¬#2
julia> c2 = Clause(bit"111", bit"101")Clause{BitBasis.DitStr{2, 3, Int64}}: #1 ∧ ¬#2 ∧ #3
julia> dnf = DNF(c1, c2)DNF{BitBasis.DitStr{2, 3, Int64}}: (¬#1 ∧ ¬#2) ∨ (#1 ∧ ¬#2 ∧ #3)

The branch and bound algorithm

The branch and bound algorithm is a method to exactly solve the combinatorial optimization problems.

API

OptimalBranchingCore.apply_branchFunction
apply_branch(problem::AbstractProblem, clause::Clause, vertices::Vector)::Tuple

Create a branch from the given clause applied to the specified vertices.

Arguments

  • problem: The problem instance.
  • clause: The clause that containing the information about how to fix the values of the variables.
  • vertices: A vector of vertices to be considered for the branch.

Returns

  • AbstractProblem: A new instance of AbstractProblem with reduced size.
source
OptimalBranchingCore.branch_and_reduceMethod
branch_and_reduce(problem::AbstractProblem, config::BranchingStrategy; reducer::AbstractReducer=NoReducer(), result_type=Int, show_progress=false)

Branch the given problem using the specified solver configuration.

Arguments

  • problem: The problem instance to solve.
  • config: The configuration for the solver, which is a BranchingStrategy instance.

Keyword Arguments

  • reducer::AbstractReducer=NoReducer(): The reducer to reduce the problem size.
  • result_type::Type{TR}: The type of the result that the solver will produce.

Returns

The resulting value, which may have different type depending on the result_type.

source
OptimalBranchingCore.branching_tableFunction
branching_table(problem::AbstractProblem, table_solver::AbstractTableSolver, variables::Vector{Int})

Obtains the branching table for a given problem using a specified table solver.

Arguments

  • problem: The problem instance.
  • table_solver: The table solver, which is a subtype of AbstractTableSolver.
  • variables: A vector of indices of the variables to be considered for the branching table.

Returns

A branching table, which is a BranchingTable object.

source
OptimalBranchingCore.candidate_clausesMethod
candidate_clauses(tbl::BranchingTable{INT}) where {INT}

Generates candidate clauses from a branching table.

Arguments

  • tbl::BranchingTable{INT}: The branching table containing bit strings.

Returns

  • Vector{Clause{INT}}: A vector of Clause objects generated from the branching table.
source
OptimalBranchingCore.complexity_bvMethod
complexity_bv(branching_vector::Vector)::Float64

Calculates the complexity that associated with the provided branching vector by solving the equation:

\[γ^0 = \sum_{δρ \in \text{branching_vector}} γ^{-δρ}\]

Arguments

  • branching_vector: a vector of problem size reductions in the branches.

Returns

  • Float64: The computed γ value.
source
OptimalBranchingCore.covered_byMethod
covered_by(t::BranchingTable, dnf::DNF)

Check if the branching table t is covered by the logic expression dnf. Returns true if there exists at least one bitstring in each group of t that satisfies dnf, false otherwise.

source
OptimalBranchingCore.covered_byMethod
covered_by(a::Integer, clause_or_dnf)

Check if a is covered by the logic expression clause_or_dnf.

Arguments

  • a: A bit string.
  • clause_or_dnf: Logic expression, which can be a Clause object or a DNF object.

Returns

true if a satisfies clause_or_dnf, false otherwise.

source
OptimalBranchingCore.measureFunction
measure(problem::AbstractProblem, measure::AbstractMeasure)::Number

Calculate the size of the problem, reducing which serves as the guiding principle for the branching strategy.

Arguments

  • problem: The problem instance.
  • measure: The measure of the problem size.

Returns

A real number representing the problem size.

source
OptimalBranchingCore.minimize_γMethod
minimize_γ(table::BranchingTable, candidates::Vector{Clause}, Δρ::Vector, solver)

Finds the optimal cover based on the provided vector of problem size reduction. This function implements a cover selection algorithm using an iterative process. It utilizes an integer programming solver to optimize the selection of sub-covers based on their complexity.

Arguments

  • table::BranchingTable: A branching table containing clauses that need to be covered, a table entry is covered by a clause if one of its bit strings satisfies the clause. Please refer to covered_by for more details.
  • candidates::Vector{Clause}: A vector of candidate clauses to form the branching rule (in the form of DNF).
  • Δρ::Vector: A vector of problem size reduction for each candidate clause.
  • solver: The solver to be used. It can be an instance of LPSolver or IPSolver.

Keyword Arguments

  • γ0::Float64: The initial γ value.

Returns

A tuple of two elements: (indices of selected subsets, γ)

source
OptimalBranchingCore.optimal_branching_ruleMethod
optimal_branching_rule(table::BranchingTable, variables::Vector, problem::AbstractProblem, measure::AbstractMeasure, solver::AbstractSetCoverSolver)::OptimalBranchingResult

Generate an optimal branching rule from a given branching table.

Arguments

  • table: A BranchingTable instance containing candidate clauses.
  • variables: A vector of variables to perform the branching.
  • problem: The problem instance being solved.
  • measure: The measure used for evaluating the problem size reduction in the branches.
  • solver: The solver used for the weighted minimum set cover problem, which can be either LPSolver or IPSolver.

Returns

A OptimalBranchingResult object representing the optimal branching rule.

source
OptimalBranchingCore.reduce_problemMethod
reduce_problem(::Type{R}, problem::AbstractProblem, reducer::AbstractReducer) where R

Reduces the problem size directly, e.g. by graph rewriting. It is a crucial step in the reduce and branch strategy.

Arguments

  • R: The element type used for computing the size of solution. The should have an additive commutative monoid structure.
  • problem: The problem instance.
  • reducer: The reducer.

Returns

A tuple of two values:

  • AbstractProblem: A new instance of AbstractProblem with reduced size.
  • Number: The local gain of the reduction, which will be added to the global gain.
source
OptimalBranchingCore.select_variablesFunction
select_variables(problem::AbstractProblem, measure::AbstractMeasure, selector::AbstractSelector)::Vector{Int}

Selects a branching strategy for a AbstractProblem instance.

Arguments

  • problem: The problem instance.
  • measure: The measure of the problem size.
  • selector: The variables selection strategy, which is a subtype of AbstractSelector.

Returns

A vector of indices of the selected variables.

source
OptimalBranchingCore.weighted_minimum_set_coverMethod
weighted_minimum_set_cover(solver, weights::AbstractVector, subsets::Vector{Vector{Int}}, num_items::Int)

Solves the weighted minimum set cover problem.

Arguments

  • solver: The solver to be used. It can be an instance of LPSolver or IPSolver.
  • weights::AbstractVector: The weights of the subsets.
  • subsets::Vector{Vector{Int}}: A vector of subsets.
  • num_items::Int: The number of elements to cover.

Returns

A vector of indices of selected subsets.

source
OptimalBranchingCore.AbstractMeasureType
AbstractMeasure

The base type for the measure of the problem size in terms of computational hardness. Some widely used measures include the number of variables, the vertices with connectivity of at least 3, etc.

source
OptimalBranchingCore.AbstractReducerType
AbstractReducer

An abstract type representing a reducer in the context of branching problems. This serves as a base type for all specific reducer implementations.

source
OptimalBranchingCore.BranchingStrategyType
BranchingStrategy
-BranchingStrategy(; kwargs...)

A struct representing the configuration for a solver, including the reducer and branching strategy.

Fields

  • table_solver::AbstractTableSolver: The solver to resolve the relevant bit strings and generate a branching table.
  • set_cover_solver::AbstractSetCoverSolver = IPSolver(): The solver to solve the set covering problem.
  • selector::AbstractSelector: The selector to select the next branching variable or decision.
  • m::AbstractMeasure: The measure to evaluate the performance of the branching strategy.
source
OptimalBranchingCore.BranchingTableType
BranchingTable{INT <: Integer}

A list of groupped bitstrings, which is used for designing the branching rule. A valid branching rule, which is represented by a logic expression in Disjunctive Normal Form (DNF), should cover at least one bitstring from each group, where by cover, we mean there exists at least one bitstring in the group that satisfies the logic expression. Please check covered_by for more details.

Fields

  • bit_length::Int: The length of the bit string.
  • table::Vector{Vector{INT}}: The list of groupped bitstrings used for branching, where each group is a vector of bitstrings. The bitstrings uses INT type to store the bitstring.
source
OptimalBranchingCore.CandidateClauseType
CandidateClause{INT <: Integer}

A candidate clause is a clause containing the formation related to how it can cover the items in the branching table.

Fields

  • covered_items::Set{Int}: The items in the branching table that are covered by the clause.
  • clause::Clause{INT}: The clause itself.
source
OptimalBranchingCore.ClauseType
Clause{INT <: Integer}

A Clause is conjunction of literals, which is specified by a pair of bit strings. The type parameter INT is the integer type for storing the bit strings.

Fields

  • mask: A bit string that indicates the variables involved in the clause.
  • val: A bit string that indicates the positive literals in the clause.

Examples

To check if a bit string satisfies a clause, use OptimalBranchingCore.covered_by.

julia> using OptimalBranchingCore
+OptimalBranchingCore · OptimalBranching.jl

OptimalBranchingCore

Literal, Clause and DNF

Literals, clauses and disjunctive normal form (DNF) are basic concepts in boolean logic, where literals are boolean variables, clauses are boolean expressions, and DNF is a disjunction of one or more conjunctions of literals.

Here is an example, given a truth table as follows:

abcvalue
0001
0011
0100
0110
1000
1011
1100
1110

where $a, b, c$ are boolean variables called literals. The true statements can be represented as a conjunction of literals, for example,

\[\neg a \land \neg b \land \neg c, \neg a \land \neg b \land c, a \land \neg b \land c\]

and these clauses can be combined into a DNF:

\[(\neg a \land \neg b) \lor (a \land \neg b \land c).\]

In OptimalBranchingCore, a clause is represented by the Clause type, and a DNF is represented by the DNF type, based on the BitBasis.jl package.

julia> using OptimalBranchingCore, BitBasis
julia> c1 = Clause(bit"011", bit"000")Clause{BitBasis.DitStr{2, 3, Int64}}: ¬#1 ∧ ¬#2
julia> c2 = Clause(bit"111", bit"101")Clause{BitBasis.DitStr{2, 3, Int64}}: #1 ∧ ¬#2 ∧ #3
julia> dnf = DNF(c1, c2)DNF{BitBasis.DitStr{2, 3, Int64}}: (¬#1 ∧ ¬#2) ∨ (#1 ∧ ¬#2 ∧ #3)

The branch and bound algorithm

The branch and bound algorithm is a method to exactly solve the combinatorial optimization problems.

API

OptimalBranchingCore.apply_branchFunction
apply_branch(problem::AbstractProblem, clause::Clause, vertices::Vector)::Tuple

Create a branch from the given clause applied to the specified vertices.

Arguments

  • problem: The problem instance.
  • clause: The clause that containing the information about how to fix the values of the variables.
  • vertices: A vector of vertices to be considered for the branch.

Returns

  • AbstractProblem: A new instance of AbstractProblem with reduced size.
source
OptimalBranchingCore.branch_and_reduceMethod
branch_and_reduce(problem::AbstractProblem, config::BranchingStrategy; reducer::AbstractReducer=NoReducer(), result_type=Int, show_progress=false)

Branch the given problem using the specified solver configuration.

Arguments

  • problem: The problem instance to solve.
  • config: The configuration for the solver, which is a BranchingStrategy instance.

Keyword Arguments

  • reducer::AbstractReducer=NoReducer(): The reducer to reduce the problem size.
  • result_type::Type{TR}: The type of the result that the solver will produce.

Returns

The resulting value, which may have different type depending on the result_type.

source
OptimalBranchingCore.branching_tableFunction
branching_table(problem::AbstractProblem, table_solver::AbstractTableSolver, variables::Vector{Int})

Obtains the branching table for a given problem using a specified table solver.

Arguments

  • problem: The problem instance.
  • table_solver: The table solver, which is a subtype of AbstractTableSolver.
  • variables: A vector of indices of the variables to be considered for the branching table.

Returns

A branching table, which is a BranchingTable object.

source
OptimalBranchingCore.candidate_clausesMethod
candidate_clauses(tbl::BranchingTable{INT}) where {INT}

Generates candidate clauses from a branching table.

Arguments

  • tbl::BranchingTable{INT}: The branching table containing bit strings.

Returns

  • Vector{Clause{INT}}: A vector of Clause objects generated from the branching table.
source
OptimalBranchingCore.complexity_bvMethod
complexity_bv(branching_vector::Vector)::Float64

Calculates the complexity that associated with the provided branching vector by solving the equation:

\[γ^0 = \sum_{δρ \in \text{branching_vector}} γ^{-δρ}\]

Arguments

  • branching_vector: a vector of problem size reductions in the branches.

Returns

  • Float64: The computed γ value.
source
OptimalBranchingCore.covered_byMethod
covered_by(t::BranchingTable, dnf::DNF)

Check if the branching table t is covered by the logic expression dnf. Returns true if there exists at least one bitstring in each group of t that satisfies dnf, false otherwise.

source
OptimalBranchingCore.covered_byMethod
covered_by(a::Integer, clause_or_dnf)

Check if a is covered by the logic expression clause_or_dnf.

Arguments

  • a: A bit string.
  • clause_or_dnf: Logic expression, which can be a Clause object or a DNF object.

Returns

true if a satisfies clause_or_dnf, false otherwise.

source
OptimalBranchingCore.measureFunction
measure(problem::AbstractProblem, measure::AbstractMeasure)::Number

Calculate the size of the problem, reducing which serves as the guiding principle for the branching strategy.

Arguments

  • problem: The problem instance.
  • measure: The measure of the problem size.

Returns

A real number representing the problem size.

source
OptimalBranchingCore.minimize_γMethod
minimize_γ(table::BranchingTable, candidates::Vector{Clause}, Δρ::Vector, solver)

Finds the optimal cover based on the provided vector of problem size reduction. This function implements a cover selection algorithm using an iterative process. It utilizes an integer programming solver to optimize the selection of sub-covers based on their complexity.

Arguments

  • table::BranchingTable: A branching table containing clauses that need to be covered, a table entry is covered by a clause if one of its bit strings satisfies the clause. Please refer to covered_by for more details.
  • candidates::Vector{Clause}: A vector of candidate clauses to form the branching rule (in the form of DNF).
  • Δρ::Vector: A vector of problem size reduction for each candidate clause.
  • solver: The solver to be used. It can be an instance of LPSolver or IPSolver.

Keyword Arguments

  • γ0::Float64: The initial γ value.

Returns

A tuple of two elements: (indices of selected subsets, γ)

source
OptimalBranchingCore.optimal_branching_ruleMethod
optimal_branching_rule(table::BranchingTable, variables::Vector, problem::AbstractProblem, measure::AbstractMeasure, solver::AbstractSetCoverSolver)::OptimalBranchingResult

Generate an optimal branching rule from a given branching table.

Arguments

  • table: A BranchingTable instance containing candidate clauses.
  • variables: A vector of variables to perform the branching.
  • problem: The problem instance being solved.
  • measure: The measure used for evaluating the problem size reduction in the branches.
  • solver: The solver used for the weighted minimum set cover problem, which can be either LPSolver or IPSolver.

Returns

A OptimalBranchingResult object representing the optimal branching rule.

source
OptimalBranchingCore.reduce_problemMethod
reduce_problem(::Type{R}, problem::AbstractProblem, reducer::AbstractReducer) where R

Reduces the problem size directly, e.g. by graph rewriting. It is a crucial step in the reduce and branch strategy.

Arguments

  • R: The element type used for computing the size of solution. The should have an additive commutative monoid structure.
  • problem: The problem instance.
  • reducer: The reducer.

Returns

A tuple of two values:

  • AbstractProblem: A new instance of AbstractProblem with reduced size.
  • Number: The local gain of the reduction, which will be added to the global gain.
source
OptimalBranchingCore.select_variablesFunction
select_variables(problem::AbstractProblem, measure::AbstractMeasure, selector::AbstractSelector)::Vector{Int}

Selects a branching strategy for a AbstractProblem instance.

Arguments

  • problem: The problem instance.
  • measure: The measure of the problem size.
  • selector: The variables selection strategy, which is a subtype of AbstractSelector.

Returns

A vector of indices of the selected variables.

source
OptimalBranchingCore.weighted_minimum_set_coverMethod
weighted_minimum_set_cover(solver, weights::AbstractVector, subsets::Vector{Vector{Int}}, num_items::Int)

Solves the weighted minimum set cover problem.

Arguments

  • solver: The solver to be used. It can be an instance of LPSolver or IPSolver.
  • weights::AbstractVector: The weights of the subsets.
  • subsets::Vector{Vector{Int}}: A vector of subsets.
  • num_items::Int: The number of elements to cover.

Returns

A vector of indices of selected subsets.

source
OptimalBranchingCore.AbstractMeasureType
AbstractMeasure

The base type for the measure of the problem size in terms of computational hardness. Some widely used measures include the number of variables, the vertices with connectivity of at least 3, etc.

source
OptimalBranchingCore.AbstractReducerType
AbstractReducer

An abstract type representing a reducer in the context of branching problems. This serves as a base type for all specific reducer implementations.

source
OptimalBranchingCore.BranchingStrategyType
BranchingStrategy
+BranchingStrategy(; kwargs...)

A struct representing the configuration for a solver, including the reducer and branching strategy.

Fields

  • table_solver::AbstractTableSolver: The solver to resolve the relevant bit strings and generate a branching table.
  • set_cover_solver::AbstractSetCoverSolver = IPSolver(): The solver to solve the set covering problem.
  • selector::AbstractSelector: The selector to select the next branching variable or decision.
  • m::AbstractMeasure: The measure to evaluate the performance of the branching strategy.
source
OptimalBranchingCore.BranchingTableType
BranchingTable{INT <: Integer}

A list of groupped bitstrings, which is used for designing the branching rule. A valid branching rule, which is represented by a logic expression in Disjunctive Normal Form (DNF), should cover at least one bitstring from each group, where by cover, we mean there exists at least one bitstring in the group that satisfies the logic expression. Please check covered_by for more details.

Fields

  • bit_length::Int: The length of the bit string.
  • table::Vector{Vector{INT}}: The list of groupped bitstrings used for branching, where each group is a vector of bitstrings. The bitstrings uses INT type to store the bitstring.
source
OptimalBranchingCore.CandidateClauseType
CandidateClause{INT <: Integer}

A candidate clause is a clause containing the formation related to how it can cover the items in the branching table.

Fields

  • covered_items::Set{Int}: The items in the branching table that are covered by the clause.
  • clause::Clause{INT}: The clause itself.
source
OptimalBranchingCore.ClauseType
Clause{INT <: Integer}

A Clause is conjunction of literals, which is specified by a pair of bit strings. The type parameter INT is the integer type for storing the bit strings.

Fields

  • mask: A bit string that indicates the variables involved in the clause.
  • val: A bit string that indicates the positive literals in the clause.

Examples

To check if a bit string satisfies a clause, use OptimalBranchingCore.covered_by.

julia> using OptimalBranchingCore
 
 julia> clause = Clause(0b1110, 0b1010)
 Clause{UInt8}: #2 ∧ ¬#3 ∧ #4
@@ -9,6 +9,6 @@
 false
 
 julia> OptimalBranchingCore.covered_by(0b1010, clause)
-true
source
OptimalBranchingCore.DNFType
DNF{INT}

A data structure representing a logic expression in Disjunctive Normal Form (DNF), which is a disjunction of one or more conjunctions of literals. In OptimalBranchingCore, a DNF is used to represent the branching rule.

Fields

  • clauses::Vector{Clause{INT}}: A vector of Clause objects.
source
OptimalBranchingCore.IPSolverType
IPSolver <: AbstractSetCoverSolver
-IPSolver(; optimizer = HiGHS.Optimizer, max_itr::Int = 5, verbose::Bool = false)

An integer programming solver for set covering problems.

Fields

  • optimizer: The optimizer to be used.
  • max_itr::Int: The maximum number of iterations to be performed.
  • verbose::Bool: Whether to print the solver's output.
source
OptimalBranchingCore.LPSolverType
LPSolver <: AbstractSetCoverSolver
-LPSolver(; optimizer = HiGHS.Optimizer, max_itr::Int = 5, verbose::Bool = false)

A linear programming solver for set covering problems.

Fields

  • optimizer: The optimizer to be used.
  • max_itr::Int: The maximum number of iterations to be performed.
  • verbose::Bool: Whether to print the solver's output.
source
OptimalBranchingCore.MaxSizeType
MaxSize

A struct representing the maximum size of a result. (actually a tropical int)

Fields

  • size::Int: The maximum size value.

Constructors

  • MaxSize(size::Int): Creates a MaxSize instance with the specified size.
source
OptimalBranchingCore.MaxSizeBranchCountType
struct MaxSizeBranchCount

Reture both the max size of the results and number of branches.

Fields

  • size::Int: The max size of the results.
  • count::Int: The number of branches of that size.

Constructors

  • MaxSizeBranchCount(size::Int): Creates a MaxSizeBranchCount with the given size and initializes the count to 1.
  • MaxSizeBranchCount(size::Int, count::Int): Creates a MaxSizeBranchCount with the specified size and count.
source
OptimalBranchingCore.MockTableSolverType
struct MockTableSolver <: AbstractTableSolver

The MockTableSolver randomly generates a branching table with a given number of rows. Each row must have at least one variable to be covered by the branching rule.

Fields

  • n::Int: The number of rows in the branching table.
  • p::Float64 = 0.0: The probability of generating more than one variables in a row, following the Poisson distribution.
source
OptimalBranchingCore.OptimalBranchingResultType
OptimalBranchingResult{INT <: Integer}

The result type for the optimal branching rule.

Fields

  • optimal_rule::DNF{INT}: The optimal branching rule.
  • branching_vector::Vector{T<:Real}: The branching vector that records the size reduction in each subproblem.
  • γ::Float64: The optimal γ value (the complexity of the branching rule).
source
OptimalBranchingCore.RandomSelectorType
struct RandomSelector <: AbstractSelector

The RandomSelector struct represents a strategy for selecting a subset of variables randomly.

Fields

  • n::Int: The number of variables to select.
source
+true
source
OptimalBranchingCore.DNFType
DNF{INT}

A data structure representing a logic expression in Disjunctive Normal Form (DNF), which is a disjunction of one or more conjunctions of literals. In OptimalBranchingCore, a DNF is used to represent the branching rule.

Fields

  • clauses::Vector{Clause{INT}}: A vector of Clause objects.
source
OptimalBranchingCore.IPSolverType
IPSolver <: AbstractSetCoverSolver
+IPSolver(; optimizer = HiGHS.Optimizer, max_itr::Int = 5, verbose::Bool = false)

An integer programming solver for set covering problems.

Fields

  • optimizer: The optimizer to be used.
  • max_itr::Int: The maximum number of iterations to be performed.
  • verbose::Bool: Whether to print the solver's output.
source
OptimalBranchingCore.LPSolverType
LPSolver <: AbstractSetCoverSolver
+LPSolver(; optimizer = HiGHS.Optimizer, max_itr::Int = 5, verbose::Bool = false)

A linear programming solver for set covering problems.

Fields

  • optimizer: The optimizer to be used.
  • max_itr::Int: The maximum number of iterations to be performed.
  • verbose::Bool: Whether to print the solver's output.
source
OptimalBranchingCore.MaxSizeType
MaxSize

A struct representing the maximum size of a result. (actually a tropical int)

Fields

  • size::Int: The maximum size value.

Constructors

  • MaxSize(size::Int): Creates a MaxSize instance with the specified size.
source
OptimalBranchingCore.MaxSizeBranchCountType
struct MaxSizeBranchCount

Reture both the max size of the results and number of branches.

Fields

  • size::Int: The max size of the results.
  • count::Int: The number of branches of that size.

Constructors

  • MaxSizeBranchCount(size::Int): Creates a MaxSizeBranchCount with the given size and initializes the count to 1.
  • MaxSizeBranchCount(size::Int, count::Int): Creates a MaxSizeBranchCount with the specified size and count.
source
OptimalBranchingCore.MockTableSolverType
struct MockTableSolver <: AbstractTableSolver

The MockTableSolver randomly generates a branching table with a given number of rows. Each row must have at least one variable to be covered by the branching rule.

Fields

  • n::Int: The number of rows in the branching table.
  • p::Float64 = 0.0: The probability of generating more than one variables in a row, following the Poisson distribution.
source
OptimalBranchingCore.OptimalBranchingResultType
OptimalBranchingResult{INT <: Integer}

The result type for the optimal branching rule.

Fields

  • optimal_rule::DNF{INT}: The optimal branching rule.
  • branching_vector::Vector{T<:Real}: The branching vector that records the size reduction in each subproblem.
  • γ::Float64: The optimal γ value (the complexity of the branching rule).
source
OptimalBranchingCore.RandomSelectorType
struct RandomSelector <: AbstractSelector

The RandomSelector struct represents a strategy for selecting a subset of variables randomly.

Fields

  • n::Int: The number of variables to select.
source
diff --git a/dev/man/mis/index.html b/dev/man/mis/index.html index 4ec51c3..17b738b 100644 --- a/dev/man/mis/index.html +++ b/dev/man/mis/index.html @@ -1,3 +1,3 @@ -OptimalBranchingMIS · OptimalBranching.jl

OptimalBranchingMIS

The maximum independent set problem

The maximum independent set problem is a classical combinatorial optimization problem, which is to find the largest subset of vertices in a graph such that no two vertices in the subset are adjacent.

Designing a branch-and-reduce algorithm using the optimal branching algorithm

To solve the MIS problem, we use the framework provided by the OptimalBranchingCore package to design a branch-and-reduce algorithm.

API

OptimalBranchingCore.measureMethod
measure(p::MISProblem, ::D3Measure)

Calculates the D3 measure for the given MISProblem, which is defined as the sum of the maximum degree of each vertex minus 2, for all vertices in the graph.

Arguments

  • p::MISProblem: The problem instance containing the graph.

Returns

  • Int: The computed D3 measure value.
source
OptimalBranchingCore.measureMethod
measure(p::MISProblem, ::NumOfVertices)

Calculates the number of vertices in the given MISProblem.

Arguments

  • p::MISProblem: The problem instance containing the graph.

Returns

  • Int: The number of vertices in the graph.
source
OptimalBranchingCore.reduce_problemMethod
reduce_problem(::Type{R}, p::MISProblem, ::MISReducer) where R

Reduces the given MISProblem by removing vertices based on their degrees and returns a new MISProblem instance along with the count of removed vertices.

Arguments

  • p::MISProblem: The problem instance containing the graph to be reduced.
  • ::MISReducer: An instance of the MISReducer struct.
  • ::Type{R}: The type of the result expected.

Returns

  • A tuple containing:
    • A new MISProblem instance with specified vertices removed.
    • An integer representing the count of removed vertices.

Description

The function checks the number of vertices in the graph:

  • If there are no vertices, it returns an empty instance and a count of 0.
  • If there is one vertex, it returns an empty instance and a count of 1.
  • If there are two vertices, it returns an empty instance and a count based on the presence of an edge between them.
  • For graphs with more than two vertices, it calculates the degrees of the vertices and identifies the vertex with the minimum degree to determine which vertices to remove.
source
OptimalBranchingMIS.closed_neighborsMethod
closed_neighbors(g::SimpleGraph, vertices::Vector{Int})

Returns a set of vertices that includes the input vertices as well as their open neighbors.

Arguments

  • g::SimpleGraph: The input graph.
  • vertices::Vector{Int}: The vertices for which closed neighbors are to be computed.

Returns

A set of vertices that includes the input vertices as well as their open neighbors.

source
OptimalBranchingMIS.counting_mis1Method
counting_mis1(g::SimpleGraph)

Calculates the maximum independent set (MIS) for a given SimpleGraph by first converting it into an EliminateGraph and then applying the counting_mis1 function.

Arguments

  • g::SimpleGraph: The input graph for which the maximum independent set is to be calculated.

Returns

  • MISCount: The size of the maximum independent set for the provided graph and the count of branches.
source
OptimalBranchingMIS.counting_xiao2013Method
counting_xiao2013(g::SimpleGraph)

This function counts the maximum independent set (MIS) in a given simple graph using the Xiao 2013 algorithm.

Arguments

  • g::SimpleGraph: A simple graph for which the maximum independent set is to be counted.

Returns

  • CountingMIS: An object representing the size of the maximum independent set and the count of branches.
source
OptimalBranchingMIS.mis_branch_countMethod
mis_branch_count(g::AbstractGraph; branching_strategy::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.
  • branching_strategy::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.
source
OptimalBranchingMIS.mis_sizeMethod
mis_size(g::AbstractGraph; branching_strategy::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.
  • branching_strategy::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.
source
OptimalBranchingMIS.neighbor_coverMethod
neighbor_cover(g::SimpleGraph, v::Int, k::Int)

Compute the neighbor cover of a vertex in a graph.

Arguments

  • g::SimpleGraph: The input graph.
  • v::Int: The vertex for which to compute the neighbor cover.
  • k::Int: The number of iterations to perform.

Returns

  • vertices: An array containing the vertices in the neighbor cover.
  • openvertices: An array containing the open vertices in the neighbor cover.
source
OptimalBranchingMIS.neighbors_2ndMethod
neighbors_2nd(g::SimpleGraph, v::Int)

Return the second-order neighbors of a vertex v in a simple graph g.

Arguments

  • g::SimpleGraph: The simple graph.
  • v::Int: The vertex.

Returns

  • Array{Int}: An array of second-order neighbors of v.
source
OptimalBranchingMIS.open_neighborsMethod
open_neighbors(g::SimpleGraph, vertices::Vector{Int})

Returns a vector of vertices in the graph g, which are neighbors of the given vertices and not in the given vertices.

Arguments

  • g::SimpleGraph: The graph in which to find the open neighbors.
  • vertices::Vector{Int}: The vertices for which to find the open neighbors.

Returns

A vector of open neighbors of the given vertices.

source
OptimalBranchingMIS.open_verticesMethod
open_vertices(g::SimpleGraph, vertices::Vector{Int})

Remove vertices from the given vector that are connected to all other vertices in the graph.

Arguments

  • g::SimpleGraph: The graph object.
  • vertices::Vector{Int}: The vector of vertices.

Returns

  • Vector{Int}: The open vertices.
source
OptimalBranchingMIS.removed_verticesMethod
removed_vertices(vertices::Vector{Int}, g::SimpleGraph, clause::Clause{N}) where N

Given a list of vertices, a graph, and a clause, this function returns a list of removed vertices.

The vertices argument is a vector of integers representing the vertices to consider. The g argument is a SimpleGraph object representing the graph. The clause argument is a Clause object representing a clause.

The function iterates over the vertices and checks if the corresponding bit in the clause.mask is 1. If it is, the vertex is added to the list of removed vertices (rvs). If the corresponding bit in the clause.val is also 1, the neighbors of the vertex are also added to rvs.

The function returns the list of removed vertices with duplicates removed.

source
OptimalBranchingMIS.D3MeasureType
D3Measure

A struct representing a measure that calculates the sum of the maximum degree minus 2 for each vertex in the graph.

Fields

  • None
source
OptimalBranchingMIS.MISCountType
struct MISCount

Represents the count of Maximum Independent Sets (MIS).

Fields

  • mis_size::Int: The size of the Maximum Independent Set.
  • mis_count::Int: The number of Maximum Independent Sets of that size.

Constructors

  • MISCount(mis_size::Int): Creates a MISCount with the given size and initializes the count to 1.
  • MISCount(mis_size::Int, mis_count::Int): Creates a MISCount with the specified size and count.
source
OptimalBranchingMIS.MISProblemType
mutable struct MISProblem <: AbstractProblem

Represents a Maximum Independent Set (MIS) problem.

Fields

  • g::SimpleGraph: The graph associated with the MIS problem.

Methods

  • copy(p::MISProblem): Creates a copy of the given MISProblem.
  • Base.show(io::IO, p::MISProblem): Displays the number of vertices in the MISProblem.
source
OptimalBranchingMIS.MISReducerType
MISReducer

A struct representing a reducer for the Maximum Independent Set (MIS) problem. This struct serves as a specific implementation of the AbstractReducer type.

source
OptimalBranchingMIS.MinBoundaryHighDegreeSelectorType
struct MinBoundaryHighDegreeSelector <: AbstractVertexSelector

The MinBoundaryHighDegreeSelector struct represents a strategy: - if exists a vertex with degree geq highdegreethreshold, 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.
source
OptimalBranchingMIS.MinBoundarySelectorType
struct MinBoundarySelector <: AbstractVertexSelector

The MinBoundarySelector struct represents a strategy for selecting a subgraph with the minimum number of open vertices by k-layers of neighbors.

Fields

  • k::Int: The number of layers of neighbors to consider when selecting the subgraph.
source
OptimalBranchingMIS.TensorNetworkSolverType
TensorNetworkSolver
-TensorNetworkSolver(; prune_by_env::Bool = true)

A struct representing a solver for tensor network problems. This struct serves as a specific implementation of the AbstractTableSolver type.

source
+OptimalBranchingMIS · OptimalBranching.jl

OptimalBranchingMIS

The maximum independent set problem

The maximum independent set problem is a classical combinatorial optimization problem, which is to find the largest subset of vertices in a graph such that no two vertices in the subset are adjacent.

Designing a branch-and-reduce algorithm using the optimal branching algorithm

To solve the MIS problem, we use the framework provided by the OptimalBranchingCore package to design a branch-and-reduce algorithm.

API

OptimalBranchingCore.measureMethod
measure(p::MISProblem, ::D3Measure)

Calculates the D3 measure for the given MISProblem, which is defined as the sum of the maximum degree of each vertex minus 2, for all vertices in the graph.

Arguments

  • p::MISProblem: The problem instance containing the graph.

Returns

  • Int: The computed D3 measure value.
source
OptimalBranchingCore.measureMethod
measure(p::MISProblem, ::NumOfVertices)

Calculates the number of vertices in the given MISProblem.

Arguments

  • p::MISProblem: The problem instance containing the graph.

Returns

  • Int: The number of vertices in the graph.
source
OptimalBranchingCore.reduce_problemMethod
reduce_problem(::Type{R}, p::MISProblem, ::MISReducer) where R

Reduces the given MISProblem by removing vertices based on their degrees and returns a new MISProblem instance along with the count of removed vertices.

Arguments

  • p::MISProblem: The problem instance containing the graph to be reduced.
  • ::MISReducer: An instance of the MISReducer struct.
  • ::Type{R}: The type of the result expected.

Returns

  • A tuple containing:
    • A new MISProblem instance with specified vertices removed.
    • An integer representing the count of removed vertices.

Description

The function checks the number of vertices in the graph:

  • If there are no vertices, it returns an empty instance and a count of 0.
  • If there is one vertex, it returns an empty instance and a count of 1.
  • If there are two vertices, it returns an empty instance and a count based on the presence of an edge between them.
  • For graphs with more than two vertices, it calculates the degrees of the vertices and identifies the vertex with the minimum degree to determine which vertices to remove.
source
OptimalBranchingMIS.closed_neighborsMethod
closed_neighbors(g::SimpleGraph, vertices::Vector{Int})

Returns a set of vertices that includes the input vertices as well as their open neighbors.

Arguments

  • g::SimpleGraph: The input graph.
  • vertices::Vector{Int}: The vertices for which closed neighbors are to be computed.

Returns

A set of vertices that includes the input vertices as well as their open neighbors.

source
OptimalBranchingMIS.counting_mis1Method
counting_mis1(g::SimpleGraph)

Calculates the maximum independent set (MIS) for a given SimpleGraph by first converting it into an EliminateGraph and then applying the counting_mis1 function.

Arguments

  • g::SimpleGraph: The input graph for which the maximum independent set is to be calculated.

Returns

  • MISCount: The size of the maximum independent set for the provided graph and the count of branches.
source
OptimalBranchingMIS.counting_xiao2013Method
counting_xiao2013(g::SimpleGraph)

This function counts the maximum independent set (MIS) in a given simple graph using the Xiao 2013 algorithm.

Arguments

  • g::SimpleGraph: A simple graph for which the maximum independent set is to be counted.

Returns

  • CountingMIS: An object representing the size of the maximum independent set and the count of branches.
source
OptimalBranchingMIS.mis_branch_countMethod
mis_branch_count(g::AbstractGraph; branching_strategy::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.
  • branching_strategy::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.
source
OptimalBranchingMIS.mis_sizeMethod
mis_size(g::AbstractGraph; branching_strategy::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.
  • branching_strategy::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.
source
OptimalBranchingMIS.neighbor_coverMethod
neighbor_cover(g::SimpleGraph, v::Int, k::Int)

Compute the neighbor cover of a vertex in a graph.

Arguments

  • g::SimpleGraph: The input graph.
  • v::Int: The vertex for which to compute the neighbor cover.
  • k::Int: The number of iterations to perform.

Returns

  • vertices: An array containing the vertices in the neighbor cover.
  • openvertices: An array containing the open vertices in the neighbor cover.
source
OptimalBranchingMIS.neighbors_2ndMethod
neighbors_2nd(g::SimpleGraph, v::Int)

Return the second-order neighbors of a vertex v in a simple graph g.

Arguments

  • g::SimpleGraph: The simple graph.
  • v::Int: The vertex.

Returns

  • Array{Int}: An array of second-order neighbors of v.
source
OptimalBranchingMIS.open_neighborsMethod
open_neighbors(g::SimpleGraph, vertices::Vector{Int})

Returns a vector of vertices in the graph g, which are neighbors of the given vertices and not in the given vertices.

Arguments

  • g::SimpleGraph: The graph in which to find the open neighbors.
  • vertices::Vector{Int}: The vertices for which to find the open neighbors.

Returns

A vector of open neighbors of the given vertices.

source
OptimalBranchingMIS.open_verticesMethod
open_vertices(g::SimpleGraph, vertices::Vector{Int})

Remove vertices from the given vector that are connected to all other vertices in the graph.

Arguments

  • g::SimpleGraph: The graph object.
  • vertices::Vector{Int}: The vector of vertices.

Returns

  • Vector{Int}: The open vertices.
source
OptimalBranchingMIS.removed_verticesMethod
removed_vertices(vertices::Vector{Int}, g::SimpleGraph, clause::Clause{N}) where N

Given a list of vertices, a graph, and a clause, this function returns a list of removed vertices.

The vertices argument is a vector of integers representing the vertices to consider. The g argument is a SimpleGraph object representing the graph. The clause argument is a Clause object representing a clause.

The function iterates over the vertices and checks if the corresponding bit in the clause.mask is 1. If it is, the vertex is added to the list of removed vertices (rvs). If the corresponding bit in the clause.val is also 1, the neighbors of the vertex are also added to rvs.

The function returns the list of removed vertices with duplicates removed.

source
OptimalBranchingMIS.D3MeasureType
D3Measure

A struct representing a measure that calculates the sum of the maximum degree minus 2 for each vertex in the graph.

Fields

  • None
source
OptimalBranchingMIS.MISCountType
struct MISCount

Represents the count of Maximum Independent Sets (MIS).

Fields

  • mis_size::Int: The size of the Maximum Independent Set.
  • mis_count::Int: The number of Maximum Independent Sets of that size.

Constructors

  • MISCount(mis_size::Int): Creates a MISCount with the given size and initializes the count to 1.
  • MISCount(mis_size::Int, mis_count::Int): Creates a MISCount with the specified size and count.
source
OptimalBranchingMIS.MISProblemType
mutable struct MISProblem <: AbstractProblem

Represents a Maximum Independent Set (MIS) problem.

Fields

  • g::SimpleGraph: The graph associated with the MIS problem.

Methods

  • copy(p::MISProblem): Creates a copy of the given MISProblem.
  • Base.show(io::IO, p::MISProblem): Displays the number of vertices in the MISProblem.
source
OptimalBranchingMIS.MISReducerType
MISReducer

A struct representing a reducer for the Maximum Independent Set (MIS) problem. This struct serves as a specific implementation of the AbstractReducer type.

source
OptimalBranchingMIS.MinBoundaryHighDegreeSelectorType
struct MinBoundaryHighDegreeSelector <: AbstractVertexSelector

The MinBoundaryHighDegreeSelector struct represents a strategy: - if exists a vertex with degree geq highdegreethreshold, 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.
source
OptimalBranchingMIS.MinBoundarySelectorType
struct MinBoundarySelector <: AbstractVertexSelector

The MinBoundarySelector struct represents a strategy for selecting a subgraph with the minimum number of open vertices by k-layers of neighbors.

Fields

  • k::Int: The number of layers of neighbors to consider when selecting the subgraph.
source
OptimalBranchingMIS.TensorNetworkSolverType
TensorNetworkSolver
+TensorNetworkSolver(; prune_by_env::Bool = true)

A struct representing a solver for tensor network problems. This struct serves as a specific implementation of the AbstractTableSolver type.

source
diff --git a/dev/performance_tips/index.html b/dev/performance_tips/index.html index 8fabdf5..5b8bc67 100644 --- a/dev/performance_tips/index.html +++ b/dev/performance_tips/index.html @@ -27,4 +27,4 @@ Closest candidates are: mis_size(::Graphs.AbstractGraph; branching_strategy, reducer) got unsupported keyword argument "bs" - @ OptimalBranchingMIS ~/work/OptimalBranching.jl/OptimalBranching.jl/lib/OptimalBranchingMIS/src/interfaces.jl:14

The default backend is also HiGHS. While the result is consistent, the rule searching is usually faster.

+ @ OptimalBranchingMIS ~/work/OptimalBranching.jl/OptimalBranching.jl/lib/OptimalBranchingMIS/src/interfaces.jl:14

The default backend is also HiGHS. While the result is consistent, the rule searching is usually faster.

diff --git a/dev/quick-start/index.html b/dev/quick-start/index.html index 6597c43..b697c47 100644 --- a/dev/quick-start/index.html +++ b/dev/quick-start/index.html @@ -38,4 +38,4 @@ Clause{BitBasis.LongLongUInt{1}}: ¬#4

For each candidate clause, we calculate the size reduction of the problem after applying the clause. Here, we use a simple measure: counting the number of variables eliminated by the clause.

julia> Δρ = [length(literals(sc)) for sc in candidates]; println(Δρ)[2, 5, 2, 1, 5, 4, 5, 5, 2, 2, 5, 1, 4, 1]

Finally, we solve the set cover problem to find the optimal branching rule. The solver is set to be the IPSolver. For more options, please refer to the Performance Tips section.

julia> res_ip = OptimalBranchingCore.minimize_γ(tbl, candidates, Δρ, IPSolver())OptimalBranchingResult{BitBasis.LongLongUInt{1}, Int64}:
  optimal_rule: DNF{BitBasis.LongLongUInt{1}}: (¬#1 ∧ ¬#3 ∧ #4 ∧ ¬#5) ∨ (¬#1 ∧ ¬#2 ∧ #3 ∧ ¬#4 ∧ #5) ∨ (#1 ∧ #2 ∧ #3 ∧ ¬#4 ∧ ¬#5)
  branching_vector: [4, 5, 5]
- γ: 1.2671683045421243

The result is an instance of OptimalBranchingResult, which contains the selected clauses, the optimal branching rule, and the branching vector.

+ γ: 1.2671683045421243

The result is an instance of OptimalBranchingResult, which contains the selected clauses, the optimal branching rule, and the branching vector.