diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index f7593289..18c000f8 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-08-13T04:21:10","documenter_version":"1.5.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-08-14T04:24:55","documenter_version":"1.5.0"}} \ No newline at end of file diff --git a/dev/algorithm/index.html b/dev/algorithm/index.html index ab0f18a6..1b5faff7 100644 --- a/dev/algorithm/index.html +++ b/dev/algorithm/index.html @@ -1,4 +1,4 @@ Demo · Alpine

Demo

Consider the following problem as an example.

\[\min_{x}\, &c^Tx\\ s.t. &a_i^Tx \text{ sense}_i \, b_i \forall\,\, i\\ - &l \leq x \leq u\\\]

+ &l \leq x \leq u\\\]

diff --git a/dev/choosingsolver/index.html b/dev/choosingsolver/index.html index 20dcbba8..f711ca8d 100644 --- a/dev/choosingsolver/index.html +++ b/dev/choosingsolver/index.html @@ -19,4 +19,4 @@ const alpine = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => ipopt, "mip_solver" => gurobi) -m = Model(alpine)

Similarly, many such optimizer options and nonconvex problems (both NLPs and MINLPs) can be found in the examples folder.

+m = Model(alpine)

Similarly, many such optimizer options and nonconvex problems (both NLPs and MINLPs) can be found in the examples folder.

diff --git a/dev/functions/index.html b/dev/functions/index.html index 5b39911f..47089a05 100644 --- a/dev/functions/index.html +++ b/dev/functions/index.html @@ -1,10 +1,10 @@ -Methods · Alpine

Functions

High-level Algorithmic Functions

These are the high-level algorithmic functions:

Alpine.global_solveFunction

global_solve(m::Optimizer)

Perform global optimization algorithm that is based on the adaptive piecewise convexification. This iterative algorithm loops over bounding_solve and local_solve until the optimality gap between the lower bound (relaxed problem with min. objective) and the upper bound (feasible problem) is within the user prescribed limits. Each bounding_solve provides a lower bound that serves as the partitioning point for the next iteration (this feature can be modified given a different add_adaptive_partition). Each local_solve provides an incumbent feasible solution. The algorithm terminates when atleast one of these conditions are satisfied: time limit, optimality condition, or iteration limit.

source
Alpine.local_solveFunction

local_solve(m::Optimizer, presolve::Bool=false)

Perform a local NLP or MINLP solve to obtain a feasible solution. The presolve option is set to true when the function is invoked in presolve. Otherwise, the function is invoked from bounding_solve.

source
Alpine.bounding_solveFunction

bounding_solve(m::Optimizer; kwargs...)

This step usually solves a convex MILP/MIQCP/MIQCQP problem for lower bounding the given minimization problem. It solves the problem built upon a piecewise convexification based on the discretization sictionary of some variables. See create_bounding_mip for more details of the problem solved here.

source

Adapative Partitioning Methods

Alpine.create_bounding_mipFunction
create_bounding_mip(m::Optimizer; use_disc = nothing)

Set up a MILP bounding model base on variable domain partitioning information stored in use_disc. By default, if use_disc is not provided, it will use m.discretizations store in the Alpine model. The basic idea of this MILP bounding model is to use piecewise polyhedral/convex relaxations to tighten the basic relaxations of the original non-convex region. Among all presented partitions, the bounding model will choose one specific partition as the lower bound solution. The more partitions there are, the better or finer bounding model relax the original MINLP while the more efforts required to solve this MILP is required.

source
Alpine.pick_disc_varsFunction

pickdiscvars(m::Optimizer)

This function helps pick the variables for discretization. The method chosen depends on user-inputs. In case when indices::Int is provided, the method is chosen as built-in method. Currently, there are two built-in options for users as follows:

  • max_cover (get_option(m, :disc_var_pick)=0, default): pick all variables involved in the non-linear term for discretization
  • min_vertex_cover (get_option(m, :disc_var_pick)=1): pick a minimum vertex cover for variables involved in non-linear terms so that each non-linear term is at least convexified

For advanced usage, get_option(m, :disc_var_pick) allows ::Function inputs. User can provide his/her own function to choose the variables for discretization.

source
Alpine.fix_domainsFunction

fix_domains(m::Optimizer)

This function is used to fix variables to certain domains during the local solve process in the global_solve. More specifically, it is used in local_solve to fix binary and integer variables to lower bound solutions and discretizing variables to the active domain according to lower bound solution.

source
Alpine.min_vertex_coverFunction

minvertexcover(m::Optimizer)

min_vertex_cover chooses the variables based on the minimum vertex cover algorithm for the interaction graph of nonlinear terms which are adaptively partitioned for global optimization. This option can be activated by setting disc_var_pick = 1.

source

Presolve Methods

Alpine.bound_tightening_wrapperFunction
bound_tightening_wrapper(m::Optimizer)

Entry point to the optimization-based bound-tightening (OBBT) algorithm. The aim of the OBBT algorithm is to sequentially tighten the variable bounds until a fixed point is reached.

Currently, two OBBT methods are implemented in optimization_based_bound_tightening.

* Bound-tightening with polyhedral relaxations (McCormick, Lambda for convex-hull)
-* Bound-tightening with piecewise polyhedral relaxations: (with three partitions around the local feasible solution)

If no local feasible solution is obtained, the algorithm defaults to OBBT without partitions

source
Alpine.optimization_based_bound_tighteningFunction
optimization_based_bound_tightening(m:Optimizer; use_bound::Bool=true, use_tmc::Bool)

This function implements the OBBT algorithm to tighten the variable bounds. It utilizes either the basic polyhedral relaxations or the piecewise polyhedral relaxations (TMC) to tighten the bounds. The TMC has additional binary variables while performing OBBT.

The algorithm as two main parameters. The first is the use_tmc, which when set to true invokes the algorithm on the TMC relaxation. The second parameter use_bound takes in the objective value of the local solve solution stored in best_sol for performing OBBT. The use_bound option is set to true when the local solve is successful in obtaining a feasible solution, else this parameter is set to false.

For details, refer to section 3.1.1 of Nagarajan, Lu, Wang, Bent, Sundar, "An adaptive, multivariate partitioning algorithm for global optimization of nonconvex programs" link.

Several other user-input options can be used to tune the OBBT algorithm. For more details, see Presolve Options.

source
Alpine.resolve_var_boundsFunction
resolve_var_bounds(m::Optimizer)

Resolve the bounds of the lifted variable using the information in lvartight and uvartight. This method only takes in known or trivial bounds information to deduce lifted variable bounds and to potentially avoid the cases of infinity bounds.

source
resolve_var_bounds(nonconvex_terms::Dict, discretization::Dict)
+Methods · Alpine

Functions

High-level Algorithmic Functions

These are the high-level algorithmic functions:

Alpine.global_solveFunction

global_solve(m::Optimizer)

Perform global optimization algorithm that is based on the adaptive piecewise convexification. This iterative algorithm loops over bounding_solve and local_solve until the optimality gap between the lower bound (relaxed problem with min. objective) and the upper bound (feasible problem) is within the user prescribed limits. Each bounding_solve provides a lower bound that serves as the partitioning point for the next iteration (this feature can be modified given a different add_adaptive_partition). Each local_solve provides an incumbent feasible solution. The algorithm terminates when atleast one of these conditions are satisfied: time limit, optimality condition, or iteration limit.

source
Alpine.local_solveFunction

local_solve(m::Optimizer, presolve::Bool=false)

Perform a local NLP or MINLP solve to obtain a feasible solution. The presolve option is set to true when the function is invoked in presolve. Otherwise, the function is invoked from bounding_solve.

source
Alpine.bounding_solveFunction

bounding_solve(m::Optimizer; kwargs...)

This step usually solves a convex MILP/MIQCP/MIQCQP problem for lower bounding the given minimization problem. It solves the problem built upon a piecewise convexification based on the discretization sictionary of some variables. See create_bounding_mip for more details of the problem solved here.

source

Adapative Partitioning Methods

Alpine.create_bounding_mipFunction
create_bounding_mip(m::Optimizer; use_disc = nothing)

Set up a MILP bounding model base on variable domain partitioning information stored in use_disc. By default, if use_disc is not provided, it will use m.discretizations store in the Alpine model. The basic idea of this MILP bounding model is to use piecewise polyhedral/convex relaxations to tighten the basic relaxations of the original non-convex region. Among all presented partitions, the bounding model will choose one specific partition as the lower bound solution. The more partitions there are, the better or finer bounding model relax the original MINLP while the more efforts required to solve this MILP is required.

source
Alpine.pick_disc_varsFunction

pickdiscvars(m::Optimizer)

This function helps pick the variables for discretization. The method chosen depends on user-inputs. In case when indices::Int is provided, the method is chosen as built-in method. Currently, there are two built-in options for users as follows:

  • max_cover (get_option(m, :disc_var_pick)=0, default): pick all variables involved in the non-linear term for discretization
  • min_vertex_cover (get_option(m, :disc_var_pick)=1): pick a minimum vertex cover for variables involved in non-linear terms so that each non-linear term is at least convexified

For advanced usage, get_option(m, :disc_var_pick) allows ::Function inputs. User can provide his/her own function to choose the variables for discretization.

source
Alpine.fix_domainsFunction

fix_domains(m::Optimizer)

This function is used to fix variables to certain domains during the local solve process in the global_solve. More specifically, it is used in local_solve to fix binary and integer variables to lower bound solutions and discretizing variables to the active domain according to lower bound solution.

source
Alpine.min_vertex_coverFunction

minvertexcover(m::Optimizer)

min_vertex_cover chooses the variables based on the minimum vertex cover algorithm for the interaction graph of nonlinear terms which are adaptively partitioned for global optimization. This option can be activated by setting disc_var_pick = 1.

source

Presolve Methods

Alpine.bound_tightening_wrapperFunction
bound_tightening_wrapper(m::Optimizer)

Entry point to the optimization-based bound-tightening (OBBT) algorithm. The aim of the OBBT algorithm is to sequentially tighten the variable bounds until a fixed point is reached.

Currently, two OBBT methods are implemented in optimization_based_bound_tightening.

* Bound-tightening with polyhedral relaxations (McCormick, Lambda for convex-hull)
+* Bound-tightening with piecewise polyhedral relaxations: (with three partitions around the local feasible solution)

If no local feasible solution is obtained, the algorithm defaults to OBBT without partitions

source
Alpine.optimization_based_bound_tighteningFunction
optimization_based_bound_tightening(m:Optimizer; use_bound::Bool=true, use_tmc::Bool)

This function implements the OBBT algorithm to tighten the variable bounds. It utilizes either the basic polyhedral relaxations or the piecewise polyhedral relaxations (TMC) to tighten the bounds. The TMC has additional binary variables while performing OBBT.

The algorithm as two main parameters. The first is the use_tmc, which when set to true invokes the algorithm on the TMC relaxation. The second parameter use_bound takes in the objective value of the local solve solution stored in best_sol for performing OBBT. The use_bound option is set to true when the local solve is successful in obtaining a feasible solution, else this parameter is set to false.

For details, refer to section 3.1.1 of Nagarajan, Lu, Wang, Bent, Sundar, "An adaptive, multivariate partitioning algorithm for global optimization of nonconvex programs" link.

Several other user-input options can be used to tune the OBBT algorithm. For more details, see Presolve Options.

source
Alpine.resolve_var_boundsFunction
resolve_var_bounds(m::Optimizer)

Resolve the bounds of the lifted variable using the information in lvartight and uvartight. This method only takes in known or trivial bounds information to deduce lifted variable bounds and to potentially avoid the cases of infinity bounds.

source
resolve_var_bounds(nonconvex_terms::Dict, discretization::Dict)
 
 For discretization to be performed, we do not allow a variable being discretized to have infinite bounds.
 The lifted/auxiliary variables may have infinite bounds and the function infers bounds on these variables. This process
 can help speed up the subsequent solve times.
 
-Only used in presolve bound tightening
source
Alpine.post_objective_boundFunction
post_objective_bound(m::Optimizer, bound::Float64; kwargs...)

This function adds the upper/lower bounding constraint on the objective function for the optimization models solved within the OBBT algorithm.

source

Utility Methods

Alpine.update_var_boundsFunction
update_var_bounds(m::Optimizer, discretization::Dict; len::Float64=length(keys(discretization)))

This function takes in a dictionary-based discretization information and convert them into two bounds vectors (lvar, uvar) by picking the smallest and largest numbers. User can specify a certain length that may contains variables that is out of the scope of discretization.

Output::

l_var::Vector{Float64}, u_var::Vector{Float64}
source
Alpine.init_discFunction
init_disc(m::Optimizer)

This function initialize the dynamic discretization used for any bounding models. By default, it takes (.lvarorig, .uvarorig) as the base information. User is allowed to use alternative bounds for initializing the discretization dictionary. The output is a dictionary with MathProgBase variable indices keys attached to the :Optimizer.discretization.

source
Alpine._get_discretization_dictFunction
_get_discretization_dict(m::Optimizer, lbs::Vector{Float64}, ubs::Vector{Float64})

Utility functions to convert bounds vectors to Dictionary based structures that are more suitable for partition operations.

source
Alpine.flatten_discretizationFunction
flatten_discretization(discretization::Dict)

Utility functions to eliminate all partition on discretizing variable and keep the loose bounds.

source
Alpine.add_adaptive_partitionFunction
add_adaptive_partition(m::Optimizer; use_disc::Dict, use_solution::Vector)

A built-in method used to add a new partition on feasible domains of variables chosen for partitioning.

This can be illustrated by the following example. Let the previous iteration's partition vector on variable "x" be given by [0, 3, 7, 9]. And say, the lower bounding solution has a value of 4 for variable "x". In the case when partition_scaling_factor = 4, this function creates the new partition vector as follows: [0, 3, 3.5, 4, 4.5, 7, 9]

There are two options for this function,

* `use_disc(default=m.discretization)`:: to regulate which is the base to add new partitions on
-* `use_solution(default=m.best_bound_sol)`:: to regulate which solution to use when adding new partitions on

This function can be accordingly modified by the user to change the behavior of the solver, and thus the convergence.

source
+Only used in presolve bound tightening
source
Alpine.post_objective_boundFunction
post_objective_bound(m::Optimizer, bound::Float64; kwargs...)

This function adds the upper/lower bounding constraint on the objective function for the optimization models solved within the OBBT algorithm.

source

Utility Methods

Alpine.update_var_boundsFunction
update_var_bounds(m::Optimizer, discretization::Dict; len::Float64=length(keys(discretization)))

This function takes in a dictionary-based discretization information and convert them into two bounds vectors (lvar, uvar) by picking the smallest and largest numbers. User can specify a certain length that may contains variables that is out of the scope of discretization.

Output::

l_var::Vector{Float64}, u_var::Vector{Float64}
source
Alpine.init_discFunction
init_disc(m::Optimizer)

This function initialize the dynamic discretization used for any bounding models. By default, it takes (.lvarorig, .uvarorig) as the base information. User is allowed to use alternative bounds for initializing the discretization dictionary. The output is a dictionary with MathProgBase variable indices keys attached to the :Optimizer.discretization.

source
Alpine._get_discretization_dictFunction
_get_discretization_dict(m::Optimizer, lbs::Vector{Float64}, ubs::Vector{Float64})

Utility functions to convert bounds vectors to Dictionary based structures that are more suitable for partition operations.

source
Alpine.flatten_discretizationFunction
flatten_discretization(discretization::Dict)

Utility functions to eliminate all partition on discretizing variable and keep the loose bounds.

source
Alpine.add_adaptive_partitionFunction
add_adaptive_partition(m::Optimizer; use_disc::Dict, use_solution::Vector)

A built-in method used to add a new partition on feasible domains of variables chosen for partitioning.

This can be illustrated by the following example. Let the previous iteration's partition vector on variable "x" be given by [0, 3, 7, 9]. And say, the lower bounding solution has a value of 4 for variable "x". In the case when partition_scaling_factor = 4, this function creates the new partition vector as follows: [0, 3, 3.5, 4, 4.5, 7, 9]

There are two options for this function,

* `use_disc(default=m.discretization)`:: to regulate which is the base to add new partitions on
+* `use_solution(default=m.best_bound_sol)`:: to regulate which solution to use when adding new partitions on

This function can be accordingly modified by the user to change the behavior of the solver, and thus the convergence.

source
diff --git a/dev/index.html b/dev/index.html index 791f8e8b..29898f2f 100644 --- a/dev/index.html +++ b/dev/index.html @@ -42,4 +42,4 @@ journal={arXiv preprint:2301.00306}, url={https://arxiv.org/abs/2301.00306}, year={2022} -} +} diff --git a/dev/parameters/index.html b/dev/parameters/index.html index 56534eed..ecdeec50 100644 --- a/dev/parameters/index.html +++ b/dev/parameters/index.html @@ -1,2 +1,2 @@ -Solver Options · Alpine

Solver options for Alpine

General Options

Here are a few general solver options which control the performance of Alpine:

  • log_level (default = 0): verbosity level of Alpine; choose 1 for turning on logging, else 100 for detailed debugging mode.

  • time_limit (default = Inf): total limit on run time for Alpine in seconds.

  • max_iter (default = 999): total number of iterations allowed in the global_solve.

  • rel_gap (default = 1e-4): relative gap considered for global convergence during global_solve. Bounds are evaluated using $\frac{UB-LB}{UB} \cdot 100 \%$.

  • tol (default = 1e-6): numerical tolerance used during the process of global_solve.

Adaptive Partitioning Options

  • apply_partitioning (default = true): applies Alpine's built-in MIP-based partitioning algorithm only when activated; else terminates with the presolve solution.

  • partition_scaling_factor (default = 10): used during add_adaptive_partition for scaling the width of new partitions relative to the active partition chosen in the sequentially-solved lower-bounding MIP models. This value can substantially affect the run time for global convergence; this value can be set to different integer values (>= 4) for various classes of problems.

  • disc_var_pick (default = 0): controls Alpine's algorithm used for selecting variables for partitioning; 0 is for max-cover, 1 is for minimum-vertex-cover. This parameter allows functional inputs.

  • disc_add_partition_method: allows functional input on how new partitions could be constructed.

Presolve Options

  • presolve_track_time (default = true): includes/excludes presolve run time in the total Alpine's run time.

  • presolve_bt (default = false): performs sequential, optimization-based bound tightening (OBBT) at the presolve step.

  • presolve_bt_max_iter (default = 9999): maximum number of iterations allowed using the sequential OBBT step.

  • presolve_bt_width_tol (default = 1e-3): numerical tolerance value used in the OBBT step. Note that smaller values of this tolerance can lead to inaccurate solutions.

  • presolve_bt_algo (default = 1): method chosen to perform the presolve step; choose 1 for the built-in OBBT, else 2 for user-input functions for presolve.

  • presolve_bt_relax_integrality (default = false): relaxes the integrality of the existing integer variables in the OBBT step, if the input problem is an MINLP.

  • presolve_bt_mip_time_limit (default = Inf): time limit for individual MILPs solved during the sequential OBBT procedure.

  • use_start_as_incumbent (default = false): if true, Alpine does not perform any local optimization during the presolve and uses the starting value instead (warning: Alpine assumes the feasibility of the starting value and does not check it).

Note that the above-mentioned list of solver options is not comprehensive, but can be found in solver.jl.

+Solver Options · Alpine

Solver options for Alpine

General Options

Here are a few general solver options which control the performance of Alpine:

  • log_level (default = 0): verbosity level of Alpine; choose 1 for turning on logging, else 100 for detailed debugging mode.

  • time_limit (default = Inf): total limit on run time for Alpine in seconds.

  • max_iter (default = 999): total number of iterations allowed in the global_solve.

  • rel_gap (default = 1e-4): relative gap considered for global convergence during global_solve. Bounds are evaluated using $\frac{UB-LB}{UB} \cdot 100 \%$.

  • tol (default = 1e-6): numerical tolerance used during the process of global_solve.

Adaptive Partitioning Options

  • apply_partitioning (default = true): applies Alpine's built-in MIP-based partitioning algorithm only when activated; else terminates with the presolve solution.

  • partition_scaling_factor (default = 10): used during add_adaptive_partition for scaling the width of new partitions relative to the active partition chosen in the sequentially-solved lower-bounding MIP models. This value can substantially affect the run time for global convergence; this value can be set to different integer values (>= 4) for various classes of problems.

  • disc_var_pick (default = 0): controls Alpine's algorithm used for selecting variables for partitioning; 0 is for max-cover, 1 is for minimum-vertex-cover. This parameter allows functional inputs.

  • disc_add_partition_method: allows functional input on how new partitions could be constructed.

Presolve Options

  • presolve_track_time (default = true): includes/excludes presolve run time in the total Alpine's run time.

  • presolve_bt (default = false): performs sequential, optimization-based bound tightening (OBBT) at the presolve step.

  • presolve_bt_max_iter (default = 9999): maximum number of iterations allowed using the sequential OBBT step.

  • presolve_bt_width_tol (default = 1e-3): numerical tolerance value used in the OBBT step. Note that smaller values of this tolerance can lead to inaccurate solutions.

  • presolve_bt_algo (default = 1): method chosen to perform the presolve step; choose 1 for the built-in OBBT, else 2 for user-input functions for presolve.

  • presolve_bt_relax_integrality (default = false): relaxes the integrality of the existing integer variables in the OBBT step, if the input problem is an MINLP.

  • presolve_bt_mip_time_limit (default = Inf): time limit for individual MILPs solved during the sequential OBBT procedure.

  • use_start_as_incumbent (default = false): if true, Alpine does not perform any local optimization during the presolve and uses the starting value instead (warning: Alpine assumes the feasibility of the starting value and does not check it).

Note that the above-mentioned list of solver options is not comprehensive, but can be found in solver.jl.