35 releases (5 stable)
1.1.3 | Apr 1, 2021 |
---|---|
1.1.2 | Mar 29, 2021 |
0.4.3 | Mar 19, 2021 |
0.3.10 | Mar 16, 2021 |
0.0.5 | Feb 12, 2021 |
#24 in Math
320 downloads per month
Used in kair
86KB
1.5K
SLoC
good_lp
A Linear Programming modeler that is easy to use, performant with large problems, and well-typed.
use std::error::Error;
use good_lp::{constraint, default_solver, Solution, SolverModel, variables};
fn main() -> Result<(), Box<dyn Error>> {
variables! {
vars:
a <= 1;
2 <= b <= 4;
}
let solution = vars.maximise(10 * (a - b / 5) - b)
.using(default_solver)
.with(constraint!(a + 2 <= b))
.with(constraint!(1 + a >= 4 - b))
.solve()?;
println!("a={} b={}", solution.value(a), solution.value(b));
println!("a + b = {}", solution.eval(a + b));
Ok(())
}
Features and limitations
- Linear programming. This crate currently supports only the definition of linear programs. You cannot use it with
quadratic functions, for instance:
you can maximise
3 * x + y
, but not3 * x * y
. - Continuous and integer variables. good_lp supports mixed integer-linear programming (MILP), but not all underlying solvers support integer variables.
- Not a solver. This crate uses other rust crates to provide the solvers. There is no solving algorithm in good_lp itself. If you have an issue with a solver, report it to the solver directly. See below for the list of supported solvers.
Contributing
Pull requests are welcome ! If you need any of the features mentioned above, get in touch. Also, do not hesitate to open issues to discuss the implementation.
Alternatives
If you need non-linear programming or integer variables, you can use lp-modeler. However, it is currently very slow with large problems.
You can also directly use the underlying solver libraries, such as coin_cbc or minilp if you don't need a way to express your objective function and constraints using an idiomatic rust syntax.
Usage examples
You can find a resource allocation problem example in
resource_allocation_problem.rs
.
Solvers
This library offers an abstraction over multiple solvers. By default, it uses cbc, but you can also activate other solvers using cargo features.
solver feature name | integer variables | no C compiler* | no additional libs** | fast |
---|---|---|---|---|
coin_cbc |
✅ | ✅ | ❌ | ✅ |
highs |
❌ | ❌ | ✅ | ✅ |
lpsolve |
✅ | ❌ | ✅ | ❌ |
minilp |
❌ | ✅ | ✅ | ❌ |
lp-solvers |
✅ | ✅ | ✅ | ❌ |
- * no C compiler: builds with only cargo, without requiring you to install a C compiler
- ** no additional libs: works without additional libraries at runtime, all the dependencies are statically linked
To use an alternative solver, put the following in your Cargo.toml
:
good_lp = { version = "*", features = ["your solver feature name"], default-features = false }
cbc
Used by default, performant, but requires to have the cbc C library headers available on the build machine, and the cbc dynamic library available on any machine where you want to run your program.
In ubuntu, you can install it with:
sudo apt-get install coinor-cbc coinor-libcbc-dev
In MacOS, using homebrew :
brew install cbc
minilp
minilp is a pure rust solver, which means it works out of the box without installing anything else.
Minilp is written in pure rust, and performs poorly when compiled in debug mode. Be sure to compile your code
in --release
mode when solving large problems.
lpsolve
lp_solve is a free (LGPL) linear (integer) programming solver written in C and based on the revised simplex method.
good_lp uses the lpsolve crate to call lpsolve. You will need a C compiler, but you won't have to install any additional library.
HiGHS
HiGHS is a free (MIT) parallel linear programming solver written in C++. It currently doesn't support integer variables. It is able to use OpenMP to fully leverage all the available processor cores to solve a problem.
good_lp uses the highs crate to call HiGHS. You will need a C compiler, but you shouldn't have to install any additional library on linux (it depends only on OpenMP and the C++ standard library). More information in the highs-sys crate.
lp-solvers
The lp-solvers
is particular: it doesn't contain any solver.
Instead, it calls other solvers at runtime.
It write the given problem to a .lp
file, and launches an external solver command
(such as gurobi, cplex, cbc, or glpk) to solve it.
There is some overhead associated to this method: it can take a few hundred milliseconds to write the problem to a file, launch the external solver, wait for it to finish, and then parse its solution. If you are not solving a few large problems but many small ones (in a web server, for instance), then this method may not be appropriate.
Additionally, the end user of your program will have to install the desired solver on his own.
License
This library is published under the MIT license. The solver themselves have various licenses, please refer to their individual documentation.
Dependencies
~0–1.3MB
~29K SLoC