@@ 0,0 1,68 @@
+use std::error::Error;
+
+use nalgebra::Dim;
+use rand::RngCore;
+
+use crate::{comparison::BetterThanOperator, evolutionary_strategy::EvolutionaryStrategy, fitness::FitnessFunction, initializer::Initializer, local_search::{LocalSearchCandidate, LocalSearchResult, LocalSearchStats}, perturbation::PerturbationOperator, terminating::TerminatingCondition};
+
+pub fn random_search<
+ D: Dim,
+ TInput,
+ TResult,
+ TFit,
+ TTerminatingCondition,
+ TPerturbationOperator,
+ TBetterThanOperator,
+ TEvolutionaryStrategy,
+ TInitializer>(
+ fit: &TFit,
+ terminating_condition: &mut TTerminatingCondition,
+ better_than_operator: &TBetterThanOperator,
+ initializer: &TInitializer,
+ size: D,
+ rng: &mut dyn RngCore
+) -> Result<LocalSearchResult<TInput, TResult>, Box<dyn Error>>
+where
+ TResult: Clone,
+ TInput: Clone,
+ TFit: FitnessFunction<In = TInput, Out = TResult>,
+ TTerminatingCondition: TerminatingCondition<TInput, TResult>,
+ TPerturbationOperator: PerturbationOperator<Chromosome = TInput>,
+ TEvolutionaryStrategy: EvolutionaryStrategy<TResult, TPerturbationOperator>,
+ TBetterThanOperator: BetterThanOperator<TResult>,
+ TInitializer: Initializer<D, TInput>
+{
+ let initial = initializer.initialize_single(size, rng);
+ let mut best_candidate = LocalSearchCandidate {
+ fit: fit.fit(&initial)?,
+ pos: initial,
+ cycle: 0
+ };
+
+ let mut stats = LocalSearchStats::new();
+ let mut cycle: usize = 0;
+
+ while !terminating_condition.should_terminate(&best_candidate, &stats, cycle) {
+ let next = initializer.initialize_single(size, rng);
+ let next_fit = fit.fit(&next)?;
+
+ // Minimize
+ if better_than_operator.better_than(&next_fit, &best_candidate.fit) {
+ best_candidate = LocalSearchCandidate {
+ pos: next,
+ fit: next_fit,
+ cycle
+ };
+
+ stats.append(best_candidate.clone());
+ }
+
+ cycle += 1;
+ }
+
+ Ok(LocalSearchResult {
+ best_candidate,
+ stats,
+ cycles: cycle
+ })
+}