Files
rust-optimizer/examples/early_stopping.rs
T
Manuel Raimann 964b4d5749 feat: add Objective trait and unify optimize API
- Add `Objective<V>` trait with lifecycle hooks (`before_trial`,
  `after_trial`, `max_retries`) in new `src/objective.rs`
- Replace 14+ optimize variants with 6 methods: `optimize`,
  `optimize_with`, and async/parallel counterparts
- `optimize*` methods accept closures directly (FnMut for sync, Fn for
  async); `optimize_with*` methods accept `impl Objective<V>` for
  struct-based objectives with hooks and retries
- Remove `optimize_until`, `optimize_with_callback`,
  `optimize_with_retries`, `optimize_with_checkpoint`, and all
  deprecated `_with_sampler` methods
2026-02-12 12:49:24 +01:00

59 lines
1.5 KiB
Rust

//! Early stopping — halt an entire study once a target is reached.
//!
//! Implements the [`Objective`] trait on a custom struct and uses the
//! [`after_trial`](Objective::after_trial) hook to return
//! `ControlFlow::Break(())` when the best value drops below a threshold.
//!
//! Run with: `cargo run --example early_stopping`
use std::ops::ControlFlow;
use optimizer::prelude::*;
/// An objective that minimises `(x - 3)^2` and stops early once the
/// value drops below `target`.
struct EarlyStopObjective {
x: FloatParam,
target: f64,
}
impl Objective<f64> for EarlyStopObjective {
type Error = Error;
fn evaluate(&self, trial: &mut Trial) -> Result<f64> {
let v = self.x.suggest(trial)?;
Ok((v - 3.0).powi(2))
}
fn after_trial(&self, _study: &Study<f64>, trial: &CompletedTrial<f64>) -> ControlFlow<()> {
if trial.value < self.target {
println!("Target {} reached at trial #{}", self.target, trial.id);
ControlFlow::Break(())
} else {
ControlFlow::Continue(())
}
}
}
fn main() -> optimizer::Result<()> {
let study: Study<f64> = Study::new(Direction::Minimize);
let x = FloatParam::new(-10.0, 10.0).name("x");
let objective = EarlyStopObjective {
x: x.clone(),
target: 0.01,
};
study.optimize_with(100, objective)?;
let best = study.best_trial()?;
println!(
"Stopped after {} trials — best f({:.4}) = {:.6}",
study.n_trials(),
best.get(&x).unwrap(),
best.value,
);
Ok(())
}