From bf8e11ed52587eaca15a6bdb22de9a6bfe0d3b20 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sat, 18 Oct 2025 10:46:59 +0200 Subject: [PATCH] refactor: properly handle errors in local_search --- env/Cargo.lock | 1 + env/Cargo.toml | 1 + env/src/binary_string.rs | 7 ++++--- env/src/evolutionary_strategy.rs | 6 +++--- env/src/fitness/mod.rs | 4 ++-- env/src/local_search/mod.rs | 20 +++++++++----------- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/env/Cargo.lock b/env/Cargo.lock index 5a70ec41086efe32dc03e1ebb39c28c6ce7d1cc8..a45fc5bf880a322d2ba752ea06e518564f64cfb1 100644 --- a/env/Cargo.lock +++ b/env/Cargo.lock @@ -208,6 +208,7 @@ dependencies = [ "plotters", "rand", "rand_distr", + "thiserror", ] [[package]] diff --git a/env/Cargo.toml b/env/Cargo.toml index 00fc0305d2cdd8341ceabee40915fbd9d2ebc7c1..2fb77112c042379f14dda8a93fe30a318238cf08 100644 --- a/env/Cargo.toml +++ b/env/Cargo.toml @@ -8,3 +8,4 @@ nalgebra = "0.33.2" plotters = "0.3.7" rand = "0.9.2" rand_distr = "0.5.1" +thiserror = "2.0.17" diff --git a/env/src/binary_string.rs b/env/src/binary_string.rs index f2b5cf4dac32613df413b4abd7b7ffe65283e71c..75b5ba9c46016a5811b29610a4ade2fd08f54799 100644 --- a/env/src/binary_string.rs +++ b/env/src/binary_string.rs @@ -1,6 +1,7 @@ -use std::str::FromStr; +use std::{error::Error, str::FromStr}; use nalgebra::{allocator::Allocator, Const, DefaultAllocator, Dim, DimName, Dynamic, OVector, SVector, U1}; use rand::{Rng, RngCore}; +use thiserror::Error; #[derive(Debug, Clone, PartialEq)] pub struct Bounds { @@ -30,10 +31,10 @@ pub struct BinaryString { pub vec: Vec } -#[derive(Debug, Clone, PartialEq)] +#[derive(Error, Debug, Clone, PartialEq)] pub enum BinaryStringConversionError { + #[error("The dimension of the bounds does not divide the length of the binary string.")] DimensionMismatch, - NoBounds } impl BinaryString { diff --git a/env/src/evolutionary_strategy.rs b/env/src/evolutionary_strategy.rs index da8805e62c43231f748c0cfe0d069430b245b4f2..d2758c5629c770822bdd0d2a5ff977f249ba38f4 100644 --- a/env/src/evolutionary_strategy.rs +++ b/env/src/evolutionary_strategy.rs @@ -1,12 +1,12 @@ -use std::convert::Infallible; +use std::{convert::Infallible, error::Error}; use nalgebra::SVector; use rand_distr::{Normal, NormalError}; -use crate::{local_search::{LocalSearchCandidate, LocalSearchStats}, perturbation::{BoundedPerturbation, PerturbationOperator, RandomDistributionPerturbation}}; +use crate::{local_search::LocalSearchStats, perturbation::{BoundedPerturbation, PerturbationOperator, RandomDistributionPerturbation}}; pub trait EvolutionaryStrategy { - type Err; + type Err: Error + 'static; fn step(&mut self, perturbation: &mut TPerturbation, diff --git a/env/src/fitness/mod.rs b/env/src/fitness/mod.rs index e24623ed647c54eeb1788cd4de0f639be404c909..0dcccaf665133d1b62c25a7eb3da71ea8df3ae0b 100644 --- a/env/src/fitness/mod.rs +++ b/env/src/fitness/mod.rs @@ -1,4 +1,4 @@ -use std::convert::Infallible; +use std::{convert::Infallible, error::Error}; use nalgebra::{allocator::Allocator, DefaultAllocator, Dim, OVector, SVector}; @@ -13,7 +13,7 @@ pub mod real; pub trait FitnessFunction { type In; type Out; - type Err; + type Err: Error + 'static; fn fit(self: &Self, inp: &Self::In) -> Result; } diff --git a/env/src/local_search/mod.rs b/env/src/local_search/mod.rs index 53e5f4f23db7a360fe002f867ba0b421181bdac2..c3ca90ff25e2f6709386c6c0d31d32e0b52610ed 100644 --- a/env/src/local_search/mod.rs +++ b/env/src/local_search/mod.rs @@ -1,3 +1,4 @@ +use std::error::Error; use std::fmt::Debug; use crate::binary_string::{BinaryString, BinaryStringConversionError}; use crate::evolutionary_strategy::{EvolutionaryStrategy, IdentityStrategy}; @@ -82,17 +83,17 @@ pub struct LocalSearchResult } pub fn local_search_first_improving< - TInput, TResult, TErr, TFit, TTerminatingCondition, TPerturbationOperator, TBetterThanOperator>( + TInput, TResult, TFit, TTerminatingCondition, TPerturbationOperator, TBetterThanOperator>( fit: &TFit, terminating_condition: &mut TTerminatingCondition, perturbation_operator: &mut TPerturbationOperator, better_than_operator: &TBetterThanOperator, initial: &TInput -) -> Result, TErr> +) -> Result, Box> where TResult: Clone, TInput: Clone, - TFit: FitnessFunction, + TFit: FitnessFunction, TTerminatingCondition: TerminatingCondition, TPerturbationOperator: PerturbationOperator, TBetterThanOperator: BetterThanOperator, @@ -108,23 +109,22 @@ where } pub fn local_search_first_improving_evolving< - TInput, TResult, TErr, TFit, TTerminatingCondition, TPerturbationOperator, TBetterThanOperator, TEvolutionaryStrategy>( + TInput, TResult, TFit, TTerminatingCondition, TPerturbationOperator, TBetterThanOperator, TEvolutionaryStrategy>( fit: &TFit, terminating_condition: &mut TTerminatingCondition, perturbation_operator: &mut TPerturbationOperator, better_than_operator: &TBetterThanOperator, evolutionary_strategy: &mut TEvolutionaryStrategy, initial: &TInput -) -> Result, TErr> +) -> Result, Box> where TResult: Clone, TInput: Clone, - TFit: FitnessFunction, + TFit: FitnessFunction, TTerminatingCondition: TerminatingCondition, TPerturbationOperator: PerturbationOperator, TEvolutionaryStrategy: EvolutionaryStrategy, - TBetterThanOperator: BetterThanOperator, - >::Err: Debug + TBetterThanOperator: BetterThanOperator { let mut best_candidate = LocalSearchCandidate { pos: initial.clone(), @@ -157,9 +157,7 @@ where evolutionary_strategy.step( perturbation_operator, better, - &stats) - // TODO - .expect("Evolution failed."); + &stats)?; cycle += 1; }