Crate highs

Source
Expand description

Safe rust binding to the HiGHS linear programming solver.

§Usage example

§Building a problem constraint by constraint with RowProblem

Useful for traditional problem modelling where you first declare your variables, then add constraints one by one.

use highs::{Sense, Model, HighsModelStatus, RowProblem};
// max: x + 2y + z
// under constraints:
// c1: 3x +  y      <= 6
// c2:       y + 2z <= 7
let mut pb = RowProblem::default();
// Create a variable named x, with a coefficient of 1 in the objective function,
// that is bound between 0 and +∞.
let x = pb.add_column(1., 0..);
let y = pb.add_column(2., 0..);
let z = pb.add_column(1., 0..);
// constraint c1: x*3 + y*1 is bound to ]-∞; 6]
pb.add_row(..=6, &[(x, 3.), (y, 1.)]);
// constraint c2: y*1 +  z*2 is bound to ]-∞; 7]
pb.add_row(..=7, &[(y, 1.), (z, 2.)]);

let solved = pb.optimise(Sense::Maximise).solve();

assert_eq!(solved.status(), HighsModelStatus::Optimal);

let solution = solved.get_solution();
// The expected solution is x=0  y=6  z=0.5
assert_eq!(solution.columns(), vec![0., 6., 0.5]);
// All the constraints are at their maximum
assert_eq!(solution.rows(), vec![6., 7.]);

§Building a problem variable by variable with ColProblem

Useful for resource allocation problems and other problems when you know in advance the number of constraints and their bounds, but dynamically add new variables to the problem.

This is slightly more efficient than building the problem constraint by constraint.

use highs::{ColProblem, Sense};
let mut pb = ColProblem::new();
// We cannot use more then 5 units of sugar in total.
let sugar = pb.add_row(..=5);
// We cannot use more then 3 units of milk in total.
let milk = pb.add_row(..=3);
// We have a first cake that we can sell for 2€. Baking it requires 1 unit of milk and 2 of sugar.
pb.add_integer_column(2., 0.., &[(sugar, 2.), (milk, 1.)]);
// We have a second cake that we can sell for 8€. Baking it requires 2 units of milk and 3 of sugar.
pb.add_integer_column(8., 0.., &[(sugar, 3.), (milk, 2.)]);
// Find the maximal possible profit
let solution = pb.optimise(Sense::Maximise).solve().get_solution();
// The solution is to bake 1 cake of each sort
assert_eq!(solution.columns(), vec![1., 1.]);
use highs::{Sense, Model, HighsModelStatus, ColProblem};
// max: x + 2y + z
// under constraints:
// c1: 3x +  y      <= 6
// c2:       y + 2z <= 7
let mut pb = ColProblem::default();
let c1 = pb.add_row(..6.);
let c2 = pb.add_row(..7.);
// x
pb.add_column(1., 0.., &[(c1, 3.)]);
// y
pb.add_column(2., 0.., &[(c1, 1.), (c2, 1.)]);
// z
pb.add_column(1., 0.., vec![(c2, 2.)]);

let solved = pb.optimise(Sense::Maximise).solve();

assert_eq!(solved.status(), HighsModelStatus::Optimal);

let solution = solved.get_solution();
// The expected solution is x=0  y=6  z=0.5
assert_eq!(solution.columns(), vec![0., 6., 0.5]);
// All the constraints are at their maximum
assert_eq!(solution.rows(), vec![6., 7.]);

§Integer variables

HiGHS supports mixed integer-linear programming. You can use add_integer_column to add an integer variable to the problem, and the solution is then guaranteed to contain a whole number as a value for this variable.

use highs::{Sense, Model, HighsModelStatus, ColProblem};
// maximize: x + 2y under constraints x + y <= 3.5 and x - y >= 1
let mut pb = ColProblem::default();
let c1 = pb.add_row(..3.5);
let c2 = pb.add_row(1..);
// x (continuous variable)
pb.add_column(1., 0.., &[(c1, 1.), (c2, 1.)]);
// y (integer variable)
pb.add_integer_column(2., 0.., &[(c1, 1.), (c2, -1.)]);
let solved = pb.optimise(Sense::Maximise).solve();
// The expected solution is x=2.5  y=1
assert_eq!(solved.get_solution().columns(), vec![2.5, 1.]);

Structs§

Col
Represents a variable
ColMatrix
A constraint matrix to build column-by-column
Model
A model to solve
Problem
A complete optimization problem. Depending on the MATRIX type parameter, the problem will be built constraint by constraint (with ColProblem), or variable by variable (with RowProblem)
Row
Represents a constraint
RowMatrix
A complete optimization problem stored by row
Solution
Concrete values of the solution
SolvedModel
A solved model

Enums§

HighsModelStatus
The kinds of results of an optimization
HighsStatus
The status of a highs operation
Sense
Whether to maximize or minimize the objective function

Type Aliases§

ColProblem
A problem where constraints are declared first, and variables are then added dynamically. See Problem<ColMatrix>.
RowProblem
A problem where variables are declared first, and constraints are then added dynamically. See Problem<RowMatrix>.