{"id":13748737,"url":"https://github.com/rust-or/good_lp","last_synced_at":"2025-08-10T17:10:31.923Z","repository":{"id":47163619,"uuid":"338118456","full_name":"rust-or/good_lp","owner":"rust-or","description":"Linear Programming for Rust, with a user-friendly API. This crate allows modeling LP problems, and lets you solve them with various solvers.","archived":false,"fork":false,"pushed_at":"2025-06-27T19:16:30.000Z","size":306,"stargazers_count":344,"open_issues_count":15,"forks_count":40,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-07-23T02:03:23.554Z","etag":null,"topics":["cbc","linear-programming","linear-programs","lp-modeler","lpsolve","optimization","solvers"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/good_lp","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rust-or.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-02-11T18:38:34.000Z","updated_at":"2025-07-12T18:35:51.000Z","dependencies_parsed_at":"2023-02-12T18:45:50.774Z","dependency_job_id":"343dddff-e18e-43cd-8e01-cdd902ef1d19","html_url":"https://github.com/rust-or/good_lp","commit_stats":{"total_commits":184,"total_committers":9,"mean_commits":"20.444444444444443","dds":0.5,"last_synced_commit":"a3be875005582c2a9af02fd3694164c37dcc96d6"},"previous_names":[],"tags_count":56,"template":false,"template_full_name":null,"purl":"pkg:github/rust-or/good_lp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-or%2Fgood_lp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-or%2Fgood_lp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-or%2Fgood_lp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-or%2Fgood_lp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rust-or","download_url":"https://codeload.github.com/rust-or/good_lp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rust-or%2Fgood_lp/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269756394,"owners_count":24470566,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cbc","linear-programming","linear-programs","lp-modeler","lpsolve","optimization","solvers"],"created_at":"2024-08-03T07:00:48.445Z","updated_at":"2025-08-10T17:10:31.913Z","avatar_url":"https://github.com/rust-or.png","language":"Rust","funding_links":[],"categories":["Projects"],"sub_categories":["Provers and Solvers"],"readme":"# good_lp\n\nA Mixed Integer Linear Programming modeler that is easy to use, performant with large problems, and well-typed.\n\n[![Crates.io](https://img.shields.io/crates/v/good_lp.svg)](https://crates.io/crates/good_lp)\n[![documentation](https://docs.rs/good_lp/badge.svg)](https://docs.rs/good_lp)\n[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)\n\n```rust\nuse std::error::Error;\n\nuse good_lp::{constraint, default_solver, Solution, SolverModel, variables};\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn Error\u003e\u003e {\n    variables! {\n        vars:\n               a \u003c= 1;\n          2 \u003c= b \u003c= 4;\n    } // variables can also be added dynamically with ProblemVariables::add\n    let solution = vars.maximise(10 * (a - b / 5) - b)\n        .using(default_solver) // IBM's coin_cbc by default\n        .with(constraint!(a + 2 \u003c= b))\n        .with(constraint!(1 + a \u003e= 4 - b)) // .with_all(iter) is also available\n        .solve()?;\n    println!(\"a={}   b={}\", solution.value(a), solution.value(b));\n    println!(\"a + b = {}\", solution.eval(a + b));\n    Ok(())\n}\n```\n\nFor a more complex example, see the [resource allocation problem](https://github.com/lovasoa/good_lp/blob/main/tests/resource_allocation_problem.rs).\n\n## Features and limitations\n\n- **Linear programming**. This crate currently supports only the definition of linear programs. You cannot use it with\n  quadratic functions. For instance:\n  you can maximise `3 * x + y`, but not `3 * x * y`.\n- **Continuous and integer variables**. good_lp itself supports mixed integer-linear programming (MILP),\n  but not all underlying solvers support integer variables. (see also [variable types](#variable-types))\n- **Not a solver**. This crate uses other rust crates to provide the solvers.\n  There is no solving algorithm in good_lp itself. If you have an issue with a solver,\n  report it to the solver directly. See below for the list of supported solvers.\n\n### Contributing\n\nPull requests are welcome !\nIf you need a feature that is not yet implemented, get in touch.\nAlso, do not hesitate to open issues to discuss the implementation.\n\n### Alternatives\n\nIf you need non-linear programming, you can use\n[lp-modeler](https://crates.io/crates/lp-modeler).\nHowever, it is currently very slow with large problems.\n\nYou can also directly use the underlying solver libraries, such as\n[coin_cbc](https://docs.rs/coin_cbc/) or\n[microlp](https://crates.io/crates/microlp)\nif you don't need a way to express your objective function and\nconstraints using an idiomatic rust syntax.\n\n## Usage examples\n\nYou can find a resource allocation problem example in\n[`resource_allocation_problem.rs`](https://github.com/lovasoa/good_lp/blob/main/tests/resource_allocation_problem.rs).\n\n## Solvers\n\nThis library offers an abstraction over multiple solvers. By default, it uses [cbc][cbc], but\nyou can also activate other solvers using cargo features.\n\n| solver feature name    | integer variables | no C compiler\\* | no additional libs\\*   | fast\\* | WASM\\* |\n| ---------------------- | ----------------- | --------------- | ---------------------- | ---- | ---- |\n| [`coin_cbc`][cbc]      | ✅                | ✅              | ❌                     | ✅   | ❌   |\n| [`highs`][highs]       | ✅                | ❌              | ✅¹                    | ✅   | ❌   |\n| [`lpsolve`][lpsolve]   | ✅                | ❌              | ✅                     | ❌   | ❌   |\n| [`microlp`][microlp]   | ✅                | ✅              | ✅                     | ❌   | ✅   |\n| [`lp-solvers`][lps]    | ✅                | ✅              | ✅                     | ❌   | ❌   |\n| [`scip`][scip]         | ✅                | ✅              | ✅²                    | ✅   | ❌   |\n| [`cplex-rs`][cplex]    | ✅                | ❌              | ✅³                    | ✅   | ❌   |\n| [`clarabel`][clarabel] | ❌                | ✅              | ✅                     | ✅   | ✅   |\n\n- \\* *no C compiler*: builds with only cargo, without requiring you to install a C compiler\n- \\* *no additional libs*: works without additional libraries at runtime, all the dependencies are statically linked\n- \\* *fast*: the solver does good on large problems according to published benchmarks ([*caveats*](https://github.com/rust-or/good_lp/issues/68))\n- \\* *WASM*: the solver can compile to WASM targets and run in web browsers\n- ¹ highs itself is statically linked and does not require manual installation. However, on some systems, you may have to [install dependencies of highs itself](https://github.com/rust-or/good_lp/issues/29).\n- ² using the precompiled binary is possible by enabling the optional `scip_bundled` feature\n- ³ the [cplex_rs crate](https://crates.io/crates/cplex-rs) links statically to a local installation of the proprietary [IBM ILOG CPLEX Optimizer](https://www.ibm.com/products/ilog-cplex-optimization-studio/cplex-optimizer).\n\nTo use an alternative solver, put the following in your `Cargo.toml`:\n\n```toml\ngood_lp = { version = \"*\", features = [\"your solver feature name\"], default-features = false }\n```\n\nNote that the `lpsolve` and `cplex-rs` features are mutually exclusive, and they will produce a compilation error when simultaneously activated. In particular, this means that the building with the `--all-features` option will produce a compilation error.\n\n### [cbc][cbc]\n\nUsed by default, performant, but requires to have the cbc C library headers available on the build machine,\nand the cbc dynamic library available on any machine where you want to run your program.\n\nIn ubuntu, you can install it with:\n\n```bash\nsudo apt-get install coinor-cbc coinor-libcbc-dev\n```\n\nIn MacOS, using [homebrew](https://brew.sh/) :\n\n```bash\nbrew install cbc\n```\n\nBe careful if you disable the default features of this crate and activate the cbc feature manually.\nIn this case, you have to also activate `singlethread-cbc`,\nunless you compiled Cbc yourself with the [`CBC_THREAD_SAFE`](https://github.com/coin-or/Cbc/issues/332)\noption. Otherwise, using Cbc from multiple threads would be unsafe.\n\n[cbc]: https://www.coin-or.org/Cbc/\n\n### [microlp](https://docs.rs/microlp)\n\nMicrolp is a fork of [minilp](https://docs.rs/minilp), a pure rust solver, which means it works out of the box without installing anything else.\n\n[microlp]: https://docs.rs/microlp\n\nMicrolp is written in pure rust, so you can use it without having to install a C compiler on your machine,\nor having to install any external library, but it is slower than other solvers.\n\nIt performs very poorly when compiled in debug mode, so be sure to compile your code\nin `--release` mode when solving large problems. This solver can compile to WASM targets.\n\n### [HiGHS][highs]\n\nHiGHS is a free ([MIT](https://github.com/ERGO-Code/HiGHS/blob/master/LICENSE)) parallel mixed integer linear programming\nsolver written in C++.\nIt is able to fully leverage all the available processor cores to solve a problem.\n\ngood_lp uses the [highs crate](https://docs.rs/highs) to call HiGHS.\nYou will need a C compiler, but you shouldn't have to install any additional library on linux\n(it depends only on the C++ standard library).\nMore information in the [highs-sys crate](https://crates.io/crates/highs-sys).\n\n[highs]: https://highs.dev\n\n### [lpsolve][lpsolve]\n\nlp_solve is a free ([LGPL](http://lpsolve.sourceforge.net/5.5/LGPL.htm)) linear (integer) programming solver\nwritten in C and based on the revised simplex method.\n\ngood_lp uses the [lpsolve crate](https://docs.rs/lpsolve/) to call lpsolve.\nYou will need a C compiler, but you won't have to install any additional library.\n\n[lpsolve]: http://lpsolve.sourceforge.net/5.5/\n\n### [lp-solvers][lps]\n\nThe `lp-solvers` feature is particular: it doesn't contain any solver.\nInstead, it calls other solvers at runtime.\nIt writes the given problem to a `.lp` file, and launches an external solver command\n(such as **gurobi**, **cplex**, **cbc**, or **glpk**) to solve it.\n\nThere is some overhead associated to this method: it can take a few hundred milliseconds\nto write the problem to a file, launch the external solver, wait for it to finish, and then parse its solution.\nIf you are not solving a few large problems but many small ones (in a web server, for instance),\nthen this method may not be appropriate.\n\nAdditionally, the end user of your program will have to install the desired solver on his own.\n\n[lps]: https://crates.io/crates/lp-solvers\n\n### [SCIP][scip]\n\nSCIP is currently one of the fastest open-source solvers for mixed integer programming (MIP) and mixed integer nonlinear programming (MINLP). It is also a framework for constraint integer programming and branch-cut-and-price. It allows for total control of the solution process and the access of detailed information down to the guts of the solver.\n\n`good_lp` uses SCIP through its rust interface [russcip](https://github.com/mmghannam/russcip) which can ship a precompiled binary. The easiest way to use SCIP with `good_lp` is therefore to enable both the `scip` and the `scip_bundled` features.\n\nYou can also use a custom installation of SCIP by enabling only the `scip` feature. A good way of installing SCIP is by downloading a precompiled package from [here](https://scipopt.org/index.php#download) or through conda by running\n\n```sh\nconda install --channel conda-forge scip\n```\n\n[scip]: https://scipopt.org/\n\n### [cplex-rs][cplex]\n\nThe IBM ILOG CPLEX Optimizer is a commercial high-performance optimization solver for linear, mixed-integer and quadratic programming.\n\ngood_lp uses the [cplex-rs](https://github.com/mbiggio/cplex-rs/tree/main) crate to call CPLEX through safe rust bindings, which in turn uses the [cplex-rs-sys](https://crates.io/crates/highs-sys) crate to call the raw bindings to the CPLEX C API.\n\nYou will need a valid CPLEX installation to use this feature. CPLEX should be installed in its default installation directory, or alternatively you can specify its installation directory through the `CPLEX_PATH` environment variable at compile time\n\nSince cplex-rs-sys uses [bindgen](https://github.com/rust-lang/rust-bindgen) to generate the raw C bindings, you will also need need an installation of clang and llvm as indicated in the [bindgen requirements](https://rust-lang.github.io/rust-bindgen/requirements.html).\n\n[cplex]: https://www.ibm.com/products/ilog-cplex-optimization-studio/cplex-optimizer\n\n### [Clarabel][clarabel]\n\n**Clarabel** is a free\n([Apache 2.0](https://github.com/oxfordcontrol/Clarabel.rs/blob/main/LICENSE.md))\nlinear programming solver written in Rust by the\n[Oxford Control group](https://eng.ox.ac.uk/control/).\n\nIt does not support integer variables, but it is fast and easy to install.\nIt does implement the [SolutionWithDual](https://docs.rs/good_lp/latest/good_lp/solvers/trait.SolutionWithDual.html)\ntrait, which allows you to access the dual values of the constraints (the shadow prices).\n\n[clarabel]: https://github.com/oxfordcontrol/Clarabel.rs\n\n## Variable types\n\n`good_lp` internally represents all [variable](https://docs.rs/good_lp/latest/good_lp/variable/struct.Variable.html) values and coefficients as `f64`.\nIt lets you express constraints on the range of possible values using either `f64` or `i32` (in the latter case, the integer will be losslessly converted to a floating point number).\nThe solution's [values are `f64`](https://docs.rs/good_lp/latest/good_lp/solvers/trait.Solution.html#tymethod.value) as well.\n\nFor instance:\n\n```rust\n// Correct use of f64 and i32 to specify feasible ranges for Variables\n  variables! {\n    problem:\n      a \u003c= 10.0;\n      2 \u003c= b (integer) \u003c= 4;  // Variables can be restricted using qualifiers like (integer)\n  };\n  let model = problem\n    .maximise(b)\n    .using(default_solver)\n    .with(constraint!(a + 2 \u003c= b))\n    .with(constraint!(1 + a \u003e= 4.0 - b));\n```\n\nHere, `a` and `b` are `Variable` instances that can take either continuous (floating-point) or [integer values](https://docs.rs/good_lp/latest/good_lp/variable/struct.VariableDefinition.html#method.integer).\nConstraints on possible values can be expressed using either `f64` or `i32`, as shown in the example (but replacing for example `4.0` with a `usize` variable would fail, because an usize cannot be converted to an f64 losslessly).\nThe [`variables!` macro](https://docs.rs/good_lp/latest/good_lp/macro.variables.html) also allows constraining variables to integer values using qualifiers like `2 \u003c= b (integer) \u003c= 4` above.\n\n\nSolution values will always be `f64`, regardless of whether the variables were defined with `f64` or `i32`.\nSo, even if you use integer variables, the solution object will store the integer variable values as `f64`.\n\nFor example, when printing the solution:\n\n```rust\n// Correct use of f64 for solution values\nprintln!(\"a={}   b={}\", solution.value(a), solution.value(b));\nprintln!(\"a + b = {}\", solution.eval(a + b));\n\n// Incorrect use of i32 in combination with solution value (Will fail!)\nprintln!(\"a + 1 = {}\", solution.value(a) + 1); // This will cause a compilation error!\n```\n\nThe `solution.value(a)` and `solution.value(b)` will return `f64` values, and `solution.eval(a + b)` will also provide an `f64` value.\n\n### License\n\nThis library is published under the MIT license.\nThe solver themselves have various licenses, please refer to their individual documentation.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frust-or%2Fgood_lp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frust-or%2Fgood_lp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frust-or%2Fgood_lp/lists"}