Configuring the Solvers

Dolphyn.configure_solverFunction
configure_solver(solver::String, solver_settings_path::String)

This method returns a solver-specific MathOptInterface OptimizerWithAttributes optimizer instance to be used in the DOLPHYN.generate_model() method.

The "solver" argument is a string which specifies the solver to be used. It is not case sensitive. Currently supported solvers include: "Clp", "Cbc", "HiGHS", "Gurobi" or "CPLEX".

The "solver_settings_path" argument is a string which specifies the path to the directory that contains the settings YAML file for the specified solver.

Configuring HiGHS

Dolphyn.configure_highsMethod
configure_highs(solver_settings_path::String, solver::DataType)

Reads user-specified solver settings from highs_settings.yml in the directory specified by the string solver_settings_path.

Returns a MathOptInterface OptimizerWithAttributes HiGHS optimizer instance to be used in the GenX.generate_model() method.

The HiGHS optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided: All the references are in https://github.com/jump-dev/HiGHS.jl, https://github.com/ERGO-Code/HiGHS, and https://highs.dev/

# HiGHS Solver Parameters
# Common solver settings
Feasib_Tol: 1.0e-06        # Primal feasibility tolerance # [type: double, advanced: false, range: [1e-10, inf], default: 1e-07]
Optimal_Tol: 1.0e-03       # Dual feasibility tolerance # [type: double, advanced: false, range: [1e-10, inf], default: 1e-07]
TimeLimit: Inf             # Time limit # [type: double, advanced: false, range: [0, inf], default: inf]
Pre_Solve: choose          # Presolve option: "off", "choose" or "on" # [type: string, advanced: false, default: "choose"]
Method: ipm #choose        #HiGHS-specific solver settings # Solver option: "simplex", "choose" or "ipm" # [type: string, advanced: false, default: "choose"] In order to run a case when the UCommit is set to 1, i.e. MILP instance, set the Method to choose

# HiGHS-specific solver settings
# Presolve option: "off", "choose" or "on"
# [type: string, advanced: false, default: "choose"]
presolve = choose

# Solver option: "simplex", "choose" or "ipm". If "simplex"/"ipm" is chosen then, for a MIP (QP) the integrality constraint (quadratic term) will be ignored
# [type: string, advanced: false, default: "choose"]
solver = choose

# Parallel option: "off", "choose" or "on"
# [type: string, advanced: false, default: "choose"]
parallel = choose

# Run IPM crossover: "off", "choose" or "on"
# [type: string, advanced: false, default: "off"]
run_crossover = off

# Time limit (seconds)
# [type: double, advanced: false, range: [0, inf], default: inf]
time_limit = inf

# Compute cost, bound, RHS and basic solution ranging: "off" or "on"
# [type: string, advanced: false, default: "off"]
ranging = off

# Limit on cost coefficient: values larger than this will be treated as infinite
# [type: double, advanced: false, range: [1e+15, inf], default: 1e+20]
infinite_cost = 1e+20

# Limit on |constraint bound|: values larger than this will be treated as infinite
# [type: double, advanced: false, range: [1e+15, inf], default: 1e+20]
infinite_bound = 1e+20

# Lower limit on |matrix entries|: values smaller than this will be treated as zero
# [type: double, advanced: false, range: [1e-12, inf], default: 1e-09]
small_matrix_value = 1e-09

# Upper limit on |matrix entries|: values larger than this will be treated as infinite
# [type: double, advanced: false, range: [1, inf], default: 1e+15]
large_matrix_value = 1e+15

# Primal feasibility tolerance
# [type: double, advanced: false, range: [1e-10, inf], default: 1e-07]
primal_feasibility_tolerance = 1e-07

# Dual feasibility tolerance
# [type: double, advanced: false, range: [1e-10, inf], default: 1e-07]
dual_feasibility_tolerance = 1e-07

# IPM optimality tolerance
# [type: double, advanced: false, range: [1e-12, inf], default: 1e-08]
ipm_optimality_tolerance = 1e-08

# Objective bound for termination
# [type: double, advanced: false, range: [-inf, inf], default: inf]
objective_bound = inf

# Objective target for termination
# [type: double, advanced: false, range: [-inf, inf], default: -inf]
objective_target = -inf

# random seed used in HiGHS
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 0]
random_seed = 0

# number of threads used by HiGHS (0: automatic)
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 0]
threads = 0

# Debugging level in HiGHS
# [type: HighsInt, advanced: false, range: {0, 3}, default: 0]
highs_debug_level = 0

# Analysis level in HiGHS
# [type: HighsInt, advanced: false, range: {0, 63}, default: 0]
highs_analysis_level = 0

# Strategy for simplex solver 0 => Choose; 1 => Dual (serial); 2 => Dual (PAMI); 3 => Dual (SIP); 4 => Primal
# [type: HighsInt, advanced: false, range: {0, 4}, default: 1]
simplex_strategy = 1

# Simplex scaling strategy: off / choose / equilibration / forced equilibration / max value 0 / max value 1 (0/1/2/3/4/5)
# [type: HighsInt, advanced: false, range: {0, 5}, default: 1]
simplex_scale_strategy = 1

# Strategy for simplex crash: off / LTSSF / Bixby (0/1/2)
# [type: HighsInt, advanced: false, range: {0, 9}, default: 0]
simplex_crash_strategy = 0

# Strategy for simplex dual edge weights: Choose / Dantzig / Devex / Steepest Edge (-1/0/1/2)
# [type: HighsInt, advanced: false, range: {-1, 2}, default: -1]
simplex_dual_edge_weight_strategy = -1

# Strategy for simplex primal edge weights: Choose / Dantzig / Devex / Steepest Edge (-1/0/1/2)
# [type: HighsInt, advanced: false, range: {-1, 2}, default: -1]
simplex_primal_edge_weight_strategy = -1

# Iteration limit for simplex solver
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 2147483647]
simplex_iteration_limit = 2147483647

# Limit on the number of simplex UPDATE operations
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 5000]
simplex_update_limit = 5000

# Minimum level of concurrency in parallel simplex
# [type: HighsInt, advanced: false, range: {1, 8}, default: 1]
simplex_min_concurrency = 1

# Maximum level of concurrency in parallel simplex
# [type: HighsInt, advanced: false, range: {1, 8}, default: 8]
simplex_max_concurrency = 8

# Enables or disables solver output
# [type: bool, advanced: false, range: {false, true}, default: true]
output_flag = true

# Enables or disables console logging
# [type: bool, advanced: false, range: {false, true}, default: true]
log_to_console = true

# Solution file
# [type: string, advanced: false, default: ""]
solution_file = ""

# Log file
# [type: string, advanced: false, default: ""]
log_file = ""

# Write the primal and dual solution to a file
# [type: bool, advanced: false, range: {false, true}, default: false]
write_solution_to_file = false

# Style of solution file Raw (computer-readable); Pretty (human-readable): 0 => HiGHS raw; 1 => HiGHS pretty; 2 => Glpsol raw; 3 => Glpsol pretty;
# [type: HighsInt, advanced: false, range: {-1, 3}, default: 0]
write_solution_style = 0

# Location of cost row for Glpsol file: -2 => Last; -1 => None; 0 => None if empty, otherwise data file location; 1 <= n <= num_row => Location n; n > num_row => Last
# [type: HighsInt, advanced: false, range: {-2, 2147483647}, default: 0]
glpsol_cost_row_location = 0

# Run iCrash
# [type: bool, advanced: false, range: {false, true}, default: false]
icrash = false

# Dualise strategy for iCrash
# [type: bool, advanced: false, range: {false, true}, default: false]
icrash_dualize = false

# Strategy for iCrash
# [type: string, advanced: false, default: "ICA"]
icrash_strategy = ICA

# iCrash starting weight
# [type: double, advanced: false, range: [1e-10, 1e+50], default: 0.001]
icrash_starting_weight = 0.001

# iCrash iterations
# [type: HighsInt, advanced: false, range: {0, 200}, default: 30]
icrash_iterations = 30

# iCrash approximate minimization iterations
# [type: HighsInt, advanced: false, range: {0, 100}, default: 50]
icrash_approx_iter = 50

# Exact subproblem solution for iCrash
# [type: bool, advanced: false, range: {false, true}, default: false]
icrash_exact = false

# Exact subproblem solution for iCrash
# [type: bool, advanced: false, range: {false, true}, default: false]
icrash_breakpoints = false

# Write model file
# [type: string, advanced: false, default: ""]
write_model_file = ""

# Write the model to a file
# [type: bool, advanced: false, range: {false, true}, default: false]
write_model_to_file = false

# Whether symmetry should be detected
# [type: bool, advanced: false, range: {false, true}, default: true]
mip_detect_symmetry = true

# MIP solver max number of nodes
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 2147483647]
mip_max_nodes = 2147483647

# MIP solver max number of nodes where estimate is above cutoff bound
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 2147483647]
mip_max_stall_nodes = 2147483647

# MIP solver max number of leave nodes
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 2147483647]
mip_max_leaves = 2147483647

# limit on the number of improving solutions found to stop the MIP solver prematurely
# [type: HighsInt, advanced: false, range: {1, 2147483647}, default: 2147483647]
mip_max_improving_sols = 2147483647

# maximal age of dynamic LP rows before they are removed from the LP relaxation
# [type: HighsInt, advanced: false, range: {0, 32767}, default: 10]
mip_lp_age_limit = 10

# maximal age of rows in the cutpool before they are deleted
# [type: HighsInt, advanced: false, range: {0, 1000}, default: 30]
mip_pool_age_limit = 30

# soft limit on the number of rows in the cutpool for dynamic age adjustment
# [type: HighsInt, advanced: false, range: {1, 2147483647}, default: 10000]
mip_pool_soft_limit = 10000

# minimal number of observations before pseudo costs are considered reliable
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 8]
mip_pscost_minreliable = 8

# minimal number of entries in the cliquetable before neighborhood queries of the conflict graph use parallel processing
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 100000]
mip_min_cliquetable_entries_for_parallelism = 100000

# MIP solver reporting level
# [type: HighsInt, advanced: false, range: {0, 2}, default: 1]
mip_report_level = 1

# MIP feasibility tolerance
# [type: double, advanced: false, range: [1e-10, inf], default: 1e-06]
mip_feasibility_tolerance = 1e-06

# effort spent for MIP heuristics
# [type: double, advanced: false, range: [0, 1], default: 0.05]
mip_heuristic_effort = 0.05

# tolerance on relative gap, |ub-lb|/|ub|, to determine whether optimality has been reached for a MIP instance
# [type: double, advanced: false, range: [0, inf], default: 0.0001]
mip_rel_gap = 0.0001

# tolerance on absolute gap of MIP, |ub-lb|, to determine whether optimality has been reached for a MIP instance
# [type: double, advanced: false, range: [0, inf], default: 1e-06]
mip_abs_gap = 1e-06

# Iteration limit for IPM solver
# [type: HighsInt, advanced: false, range: {0, 2147483647}, default: 2147483647]
ipm_iteration_limit = 2147483647

# Output development messages: 0 => none; 1 => info; 2 => verbose
# [type: HighsInt, advanced: true, range: {0, 3}, default: 0]
log_dev_level = 0

# Solve the relaxation of discrete model components
# [type: bool, advanced: true, range: {false, true}, default: false]
solve_relaxation = false

# Allow ModelStatus::kUnboundedOrInfeasible
# [type: bool, advanced: true, range: {false, true}, default: false]
allow_unbounded_or_infeasible = false

# Use relaxed implied bounds from presolve
# [type: bool, advanced: true, range: {false, true}, default: false]
use_implied_bounds_from_presolve = false

# Prevents LP presolve steps for which postsolve cannot maintain a basis
# [type: bool, advanced: true, range: {false, true}, default: true]
lp_presolve_requires_basis_postsolve = true

# Use the free format MPS file reader
# [type: bool, advanced: true, range: {false, true}, default: true]
mps_parser_type_free = true

# For multiple N-rows in MPS files: delete rows / delete entries / keep rows (-1/0/1)
# [type: HighsInt, advanced: true, range: {-1, 1}, default: -1]
keep_n_rows = -1

# Scaling factor for costs
# [type: HighsInt, advanced: true, range: {-20, 20}, default: 0]
cost_scale_factor = 0

# Largest power-of-two factor permitted when scaling the constraint matrix
# [type: HighsInt, advanced: true, range: {0, 30}, default: 20]
allowed_matrix_scale_factor = 20

# Largest power-of-two factor permitted when scaling the costs
# [type: HighsInt, advanced: true, range: {0, 20}, default: 0]
allowed_cost_scale_factor = 0

# Strategy for dualising before simplex
# [type: HighsInt, advanced: true, range: {-1, 1}, default: -1]
simplex_dualise_strategy = -1

# Strategy for permuting before simplex
# [type: HighsInt, advanced: true, range: {-1, 1}, default: -1]
simplex_permute_strategy = -1

# Max level of dual simplex cleanup
# [type: HighsInt, advanced: true, range: {0, 2147483647}, default: 1]
max_dual_simplex_cleanup_level = 1

# Max level of dual simplex phase 1 cleanup
# [type: HighsInt, advanced: true, range: {0, 2147483647}, default: 2]
max_dual_simplex_phase1_cleanup_level = 2

# Strategy for PRICE in simplex
# [type: HighsInt, advanced: true, range: {0, 3}, default: 3]
simplex_price_strategy = 3

# Strategy for solving unscaled LP in simplex
# [type: HighsInt, advanced: true, range: {0, 2}, default: 1]
simplex_unscaled_solution_strategy = 1

# Perform initial basis condition check in simplex
# [type: bool, advanced: true, range: {false, true}, default: true]
simplex_initial_condition_check = true

# No unnecessary refactorization on simplex rebuild
# [type: bool, advanced: true, range: {false, true}, default: true]
no_unnecessary_rebuild_refactor = true

# Tolerance on initial basis condition in simplex
# [type: double, advanced: true, range: [1, inf], default: 1e+14]
simplex_initial_condition_tolerance = 1e+14

# Tolerance on solution error when considering refactorization on simplex rebuild
# [type: double, advanced: true, range: [-inf, inf], default: 1e-08]
rebuild_refactor_solution_error_tolerance = 1e-08

# Tolerance on dual steepest edge weight errors
# [type: double, advanced: true, range: [0, inf], default: inf]
dual_steepest_edge_weight_error_tolerance = inf

# Threshold on dual steepest edge weight errors for Devex switch
# [type: double, advanced: true, range: [1, inf], default: 10]
dual_steepest_edge_weight_log_error_threshold = 10.0

# Dual simplex cost perturbation multiplier: 0 => no perturbation
# [type: double, advanced: true, range: [0, inf], default: 1]
dual_simplex_cost_perturbation_multiplier = 1.0

# Primal simplex bound perturbation multiplier: 0 => no perturbation
# [type: double, advanced: true, range: [0, inf], default: 1]
primal_simplex_bound_perturbation_multiplier = 1.0

# Dual simplex pivot growth tolerance
# [type: double, advanced: true, range: [1e-12, inf], default: 1e-09]
dual_simplex_pivot_growth_tolerance = 1e-09

# Matrix factorization pivot threshold for substitutions in presolve
# [type: double, advanced: true, range: [0.0008, 0.5], default: 0.01]
presolve_pivot_threshold = 0.01

# Bit mask of presolve rules that are not allowed
# [type: HighsInt, advanced: true, range: {0, 2147483647}, default: 0]
presolve_rule_off = 0

# Log effectiveness of presolve rules for LP
# [type: bool, advanced: true, range: {false, true}, default: true]
presolve_rule_logging = true

# Maximal fillin allowed for substitutions in presolve
# [type: HighsInt, advanced: true, range: {0, 2147483647}, default: 10]
presolve_substitution_maxfillin = 10

# Matrix factorization pivot threshold
# [type: double, advanced: true, range: [0.0008, 0.5], default: 0.1]
factor_pivot_threshold = 0.1

# Matrix factorization pivot tolerance
# [type: double, advanced: true, range: [0, 1], default: 1e-10]
factor_pivot_tolerance = 1e-10

# Tolerance to be satisfied before IPM crossover will start
# [type: double, advanced: true, range: [1e-12, inf], default: 1e-08]
start_crossover_tolerance = 1e-08

# Use original HFactor logic for sparse vs hyper-sparse TRANs
# [type: bool, advanced: true, range: {false, true}, default: true]
use_original_HFactor_logic = true

# Check whether LP is candidate for LiDSE
# [type: bool, advanced: true, range: {false, true}, default: true]
less_infeasible_DSE_check = true

# Use LiDSE if LP has right properties
# [type: bool, advanced: true, range: {false, true}, default: true]
less_infeasible_DSE_choose_row = true

Configuring Gurobi

Dolphyn.configure_gurobiMethod
configure_gurobi(solver_settings_path::String, solver::DataType)

Reads user-specified solver settings from gurobi_settings.yml in the directory specified by the string solver_settings_path.

Returns a MathOptInterface OptimizerWithAttributes Gurobi optimizer instance to be used in the generate_model() method.

The Gurobi optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:

  • FeasibilityTol = 1e-6 (Constraint (primal) feasibility tolerances. See here.)
  • OptimalityTol = 1e-6 (Dual feasibility tolerances. See here.)
  • Presolve = -1 (Controls presolve level. See here.)
  • AggFill = -1 (Allowed fill during presolve aggregation. See here.)
  • PreDual = -1 (Presolve dualization. See here.)
  • TimeLimit = Inf (Limits total time solver. See here.)
  • MIPGap = 1e-4 (Relative (p.u. of optimal) mixed integer optimality tolerance for MIP problems (ignored otherwise). See here.)
  • Crossover = -1 (Barrier crossver strategy. See here.)
  • Method = -1 (Algorithm used to solve continuous models (including MIP root relaxation). See here.)
  • BarConvTol = 1e-8 (Barrier convergence tolerance (determines when barrier terminates). See here.)
  • NumericFocus = 0 (Numerical precision emphasis. See here.)

Configuring CPLEX

Dolphyn.configure_cplexMethod
configure_cplex(solver_settings_path::String, solver::DataType)

Reads user-specified solver settings from cplex_settings.yml in the directory specified by the string solver_settings_path.

Returns a MathOptInterface OptimizerWithAttributes CPLEX optimizer instance to be used in the generate_model() method.

The CPLEX optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:

  • CPX_PARAM_EPRHS = 1e-6 (Constraint (primal) feasibility tolerances. See here.)
  • CPX_PARAM_EPOPT = 1e-6 (Dual feasibility tolerances. See here.)
  • CPX_PARAM_AGGFILL = 10 (Allowed fill during presolve aggregation. See here.)
  • CPX_PARAM_PREDUAL = 0 (Decides whether presolve should pass the primal or dual linear programming problem to the LP optimization algorithm. See here.)
  • CPX_PARAM_TILIM = 1e+75 (Limits total time solver. See here.)
  • CPX_PARAM_EPGAP = 1e-4 (Relative (p.u. of optimal) mixed integer optimality tolerance for MIP problems (ignored otherwise). See here.)
  • CPX_PARAM_LPMETHOD = 0 (Algorithm used to solve continuous models (including MIP root relaxation). See here.)
  • CPX_PARAM_BAREPCOMP = 1e-8 (Barrier convergence tolerance (determines when barrier terminates). See here.)
  • CPX_PARAM_NUMERICALEMPHASIS = 0 (Numerical precision emphasis. See here.)
  • CPX_PARAM_BAROBJRNG = 1e+75 (Sets the maximum absolute value of the objective function. See here.)
  • CPX_PARAM_SOLUTIONTYPE = 2 (Solution type for LP or QP. See here.)

Configuring Clp

Dolphyn.configure_clpMethod
configure_clp(solver_settings_path::String, solver::DataType)

Reads user-specified solver settings from clp_settings.yml in the directory specified by the string solver_settings_path.

Returns a MathOptInterface OptimizerWithAttributes Clp optimizer instance to be used in the generate_model() method.

The Clp optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:

  • PrimalTolerance = 1e-7 (Primal feasibility tolerance)
  • DualTolerance = 1e-7 (Dual feasibility tolerance)
  • DualObjectiveLimit = 1e308 (When using dual simplex (where the objective is monotonically changing), terminate when the objective exceeds this limit)
  • MaximumIterations = 2147483647 (Terminate after performing this number of simplex iterations)
  • MaximumSeconds = -1.0 (Terminate after this many seconds have passed. A negative value means no time limit)
  • LogLevel = 1 (Set to 1, 2, 3, or 4 for increasing output. Set to 0 to disable output)
  • PresolveType = 0 (Set to 1 to disable presolve)
  • SolveType = 5 (Solution method: dual simplex (0), primal simplex (1), sprint (2), barrier with crossover (3), barrier without crossover (4), automatic (5))
  • InfeasibleReturn = 0 (Set to 1 to return as soon as the problem is found to be infeasible (by default, an infeasibility proof is computed as well))
  • Scaling = 3 (0 0ff, 1 equilibrium, 2 geometric, 3 auto, 4 dynamic (later))
  • Perturbation = 100 (switch on perturbation (50), automatic (100), don't try perturbing (102))

Configuring Cbc

Dolphyn.configure_cbcMethod
configure_cbc(solver_settings_path::String, solver::DataType)

Reads user-specified solver settings from cbc_settings.yml in the directory specified by the string solver_settings_path.

Returns a MathOptInterface OptimizerWithAttributes Cbc optimizer instance to be used in the generate_model() method.

The Cbc optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:

  • seconds = 1e-6
  • logLevel = 1e-6
  • maxSolutions = -1
  • maxNodes = -1
  • allowableGap = -1
  • ratioGap = Inf
  • threads = 1

Configuring SCIP