HiGHS.jl

Build Status codecov

HiGHS.jl is a wrapper for the HiGHS solver.

It has two components:

The C API can be accessed via HiGHS.Highs_xxx functions, where the names and arguments are identical to the C API.

Installation

Install HiGHS as follows:

import Pkg
Pkg.add("HiGHS")

In addition to installing the HiGHS.jl package, this will also download and install the HiGHS binaries. (You do not need to install HiGHS separately.)

To use a custom binary, read the Custom solver binaries section of the JuMP documentation.

Issues and feedback

To report a problem (e.g., incorrect results, or a crash of the solver), or make a suggestion for how to improve HiGHS, please file a GitHub issue.

If you use HiGHS from JuMP, use JuMP.write_to_file(model, "filename.mps") to write your model an MPS file, then upload the MPS file to https://gist.github.com and provide a link to the gist in the GitHub issue.

Use with JuMP

Pass HiGHS.Optimizer to JuMP.Model to create a JuMP model with HiGHS as the optimizer. Set options using set_optimizer_attribute.

using JuMP
import HiGHS
model = Model(HiGHS.Optimizer)
set_optimizer_attribute(model, "presolve", "on")
set_optimizer_attribute(model, "time_limit", 60.0)

Options

To print the list of options supported by HiGHS, do:

using HiGHS
model = HiGHS.Optimizer()
Highs_writeOptions(model, "options.txt")
println(read("options.txt", String))

The option list as of HiGHS v1.4.0 is:

# 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: "on"]
run_crossover = on

# 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