https://github.com/germanheim/globalsearch-rs
Global optimization with scatter search and local NLP solvers written in Rust
https://github.com/germanheim/globalsearch-rs
math numerical-optimization optimization optimization-algorithms rust scatter-search
Last synced: about 1 year ago
JSON representation
Global optimization with scatter search and local NLP solvers written in Rust
- Host: GitHub
- URL: https://github.com/germanheim/globalsearch-rs
- Owner: GermanHeim
- License: mit
- Created: 2025-01-29T17:58:39.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-04-12T21:09:17.000Z (about 1 year ago)
- Last Synced: 2025-04-12T22:21:21.515Z (about 1 year ago)
- Topics: math, numerical-optimization, optimization, optimization-algorithms, rust, scatter-search
- Language: Rust
- Homepage: https://docs.rs/globalsearch
- Size: 412 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.txt
Awesome Lists containing this project
README
Global optimization with scatter search and local NLP solvers written in Rust
`globalsearch-rs`: Rust implementation of the _OQNLP_ (_OptQuest/NLP_) algorithm with the core ideas from "Scatter Search and Local NLP Solvers: A Multistart Framework for Global Optimization" by Ugray et al. (2007). It combines scatter search metaheuristics with local minimization for global optimization of nonlinear problems.
Similar to MATLAB's `GlobalSearch` \[2\], using argmin, rayon and ndarray.
## Features
- π [Python Bindings](https://github.com/GermanHeim/globalsearch-rs/tree/main/python)
- π― Multistart heuristic framework for global optimization
- π¦ Local optimization using the argmin crate \[3\]
- π Parallel execution of initial stage using Rayon
## Installation
### Using as a dependency
Add this to your `Cargo.toml`:
```toml
[dependencies]
globalsearch = "0.2.0"
```
Or use `cargo add globalsearch` in your project directory.
### Building from source
1. Install Rust toolchain using [rustup](https://rustup.rs/).
2. Clone repository:
```bash
git clone https://github.com/GermanHeim/globalsearch-rs.git
cd globalsearch-rs
```
3. Build the project:
```bash
cargo build --release
```
## Usage
1. Define a problem by implementing the `Problem` trait.
```rust
use ndarray::{array, Array1, Array2};
use globalsearch::problem::Problem;
use globalsearch::types::EvaluationError;
pub struct MinimizeProblem;
impl Problem for MinimizeProblem {
fn objective(&self, x: &Array1) -> Result {
Ok(
..., // Your objective function here
)
}
fn gradient(&self, x: &Array1) -> Result, EvaluationError> {
Ok(array![
..., // Optional: Gradient of your objective function here
])
}
fn hessian(&self, x: &Array1) -> Result, EvaluationError> {
Ok(array![
..., // Optional: Hessian of your objective function here
])
}
fn variable_bounds(&self) -> Array2 {
array![[..., ...], [..., ...]] // Lower and upper bounds for each variable
}
}
```
Where the `Problem` trait is defined as:
```rust
pub trait Problem {
fn objective(&self, x: &Array1) -> Result;
fn gradient(&self, x: &Array1) -> Result, EvaluationError>;
fn hessian(&self, x: &Array1) -> Result, EvaluationError>;
fn variable_bounds(&self) -> Array2;
}
```
Depending on your choice of local solver, you might need to implement the `gradient` and `hessian` methods. Learn more about the local solver configuration in the [argmin docs](https://docs.rs/argmin/latest/argmin/solver/index.html) or the [`LocalSolverType`](https://docs.rs/globalsearch/latest/globalsearch/types/enum.LocalSolverType.html).
> π΄ **Note:** Variable bounds are only used in the scatter search phase of the algorithm. The local solver is unconstrained (See [argmin issue #137](https://github.com/argmin-rs/argmin/issues/137)) and therefor can return solutions out of bounds.
2. Set OQNLP parameters
```rust
use globalsearch::types::{LocalSolverType, OQNLPParams};
use globalsearch::local_solver::builders::SteepestDescentBuilder;
let params: OQNLPParams = OQNLPParams {
iterations: 125,
wait_cycle: 10,
threshold_factor: 0.2,
distance_factor: 0.75,
population_size: 250,
local_solver_type: LocalSolverType::SteepestDescent,
local_solver_config: SteepestDescentBuilder::default().build(),
seed: 0,
};
```
Where `OQNLPParams` is defined as:
```rust
pub struct OQNLPParams {
pub iterations: usize,
pub wait_cycle: usize,
pub threshold_factor: f64,
pub distance_factor: f64,
pub population_size: usize,
pub local_solver_type: LocalSolverType,
pub local_solver_config: LocalSolverConfig,
pub seed: u64,
}
```
And `LocalSolverType` is defined as:
```rust
pub enum LocalSolverType {
LBFGS,
NelderMead,
SteepestDescent,
TrustRegion,
NewtonCG,
}
```
You can also modify the local solver configuration for each type of local solver. See [`builders.rs`](https://github.com/GermanHeim/globalsearch-rs/tree/main/src/local_solver/builders.rs) for more details.
3. Run the optimizer
```rust
use oqnlp::{OQNLP, OQNLPParams};
use types::{SolutionSet}
fn main() -> Result<(), Box> {
let problem = MinimizeProblem;
let params: OQNLPParams = OQNLPParams {
iterations: 125,
wait_cycle: 10,
threshold_factor: 0.2,
distance_factor: 0.75,
population_size: 250,
local_solver_type: LocalSolverType::SteepestDescent,
local_solver_config: SteepestDescentBuilder::default().build(),
seed: 0,
};
let mut optimizer: OQNLP = OQNLP::new(problem, params)?;
// OQNLP returns a solution set with the best solutions found
let solution_set: SolutionSet = optimizer.run()?;
println!("{}", solution_set)
Ok(())
}
```
## Project Structure
```plaintext
src/
βββ lib.rs # Module declarations
βββ oqnlp.rs # Core OQNLP algorithm implementation
βββ scatter_search.rs # Scatter search component
βββ local_solver/
β βββ builders.rs # Local solver configuration builders
β βββ runner.rs # Local solver runner
βββ filters.rs # Merit and distance filtering logic
βββ problem.rs # Problem trait
βββ types.rs # Data structures and parameters
python/ # Python bindings
```
## Dependencies
- [argmin](https://github.com/argmin-rs/argmin)
- [ndarray](https://github.com/rust-ndarray/ndarray)
- [rayon](https://github.com/rayon-rs/rayon) [feature: `rayon`]
- [kdam](https://github.com/clitic/kdam) [feature: `progress_bar`]
- [rand](https://github.com/rust-random/rand)
- [thiserror](https://github.com/dtolnay/thiserror)
- [criterion.rs](https://github.com/bheisler/criterion.rs) [dev-dependency]
## License
Distributed under the MIT License. See [`LICENSE.txt`](https://github.com/GermanHeim/globalsearch-rs/blob/main/LICENSE.txt) for more information.
## References
\[1\] Zsolt Ugray, Leon Lasdon, John Plummer, Fred Glover, James Kelly, Rafael MartΓ, (2007) Scatter Search and Local NLP Solvers: A Multistart Framework for Global Optimization. INFORMS Journal on Computing 19(3):328-340.
\[2\] GlobalSearch. The MathWorks, Inc. Available at: (Accessed: 27 January 2025)
\[3\] Kroboth, S. argmin{}. Available at: (Accessed: 25 January 2025)