Skip to main content

samyama_optimization/
common.rs

1use ndarray::Array1;
2use serde::{Deserialize, Serialize};
3
4/// Represents a candidate solution in the optimization space.
5#[derive(Clone, Debug, Serialize, Deserialize)]
6pub struct Individual {
7    pub variables: Array1<f64>,
8    pub fitness: f64,
9}
10
11impl Individual {
12    pub fn new(variables: Array1<f64>, fitness: f64) -> Self {
13        Self { variables, fitness }
14    }
15}
16
17/// Defines the optimization problem.
18pub trait Problem: Send + Sync {
19    /// The objective function to minimize.
20    fn objective(&self, variables: &Array1<f64>) -> f64;
21    
22    /// Optional constraints. Returns a penalty score (0 if all satisfied).
23    fn penalty(&self, _variables: &Array1<f64>) -> f64 {
24        0.0
25    }
26
27    /// Combined fitness (objective + penalty).
28    fn fitness(&self, variables: &Array1<f64>) -> f64 {
29        self.objective(variables) + self.penalty(variables)
30    }
31
32    /// Number of variables.
33    fn dim(&self) -> usize;
34
35    /// Lower and upper bounds for each variable.
36    fn bounds(&self) -> (Array1<f64>, Array1<f64>);
37}
38
39/// Represents a candidate solution in a multi-objective space.
40#[derive(Clone, Debug, Serialize, Deserialize)]
41pub struct MultiObjectiveIndividual {
42    pub variables: Array1<f64>,
43    pub fitness: Vec<f64>,
44    pub constraint_violation: f64,
45    pub rank: usize,
46    pub crowding_distance: f64,
47}
48
49impl MultiObjectiveIndividual {
50    pub fn new(variables: Array1<f64>, fitness: Vec<f64>, constraint_violation: f64) -> Self {
51        Self { 
52            variables, 
53            fitness, 
54            constraint_violation,
55            rank: 0, 
56            crowding_distance: 0.0 
57        }
58    }
59}
60
61/// Defines a multi-objective optimization problem.
62pub trait MultiObjectiveProblem: Send + Sync {
63    /// Multiple objective functions to minimize.
64    fn objectives(&self, variables: &Array1<f64>) -> Vec<f64>;
65    
66    /// Optional constraints. Returns a vector of penalties.
67    fn penalties(&self, _variables: &Array1<f64>) -> Vec<f64> {
68        vec![]
69    }
70
71    /// Number of variables.
72    fn dim(&self) -> usize;
73
74    /// Lower and upper bounds for each variable.
75    fn bounds(&self) -> (Array1<f64>, Array1<f64>);
76    
77    /// Number of objectives.
78    fn num_objectives(&self) -> usize;
79}
80
81/// The result of a multi-objective optimization run (Pareto Front).
82#[derive(Debug, Serialize, Deserialize)]
83pub struct MultiObjectiveResult {
84    pub pareto_front: Vec<MultiObjectiveIndividual>,
85    pub history: Vec<f64>, // e.g., hypervolume or min of first objective
86}
87
88/// Configuration for the solver.
89#[derive(Clone, Debug, Serialize, Deserialize)]
90pub struct SolverConfig {
91    pub population_size: usize,
92    pub max_iterations: usize,
93}
94
95impl Default for SolverConfig {
96    fn default() -> Self {
97        Self {
98            population_size: 50,
99            max_iterations: 100,
100        }
101    }
102}
103
104/// The result of an optimization run.
105#[derive(Debug, Serialize, Deserialize)]
106pub struct OptimizationResult {
107    pub best_variables: Array1<f64>,
108    pub best_fitness: f64,
109    pub history: Vec<f64>,
110}
111
112/// A simple problem defined by a closure.
113pub struct SimpleProblem<F> 
114where F: Fn(&Array1<f64>) -> f64 + Send + Sync
115{
116    pub objective_func: F,
117    pub dim: usize,
118    pub lower: Array1<f64>,
119    pub upper: Array1<f64>,
120}
121
122impl<F> Problem for SimpleProblem<F> 
123where F: Fn(&Array1<f64>) -> f64 + Send + Sync
124{
125    fn objective(&self, variables: &Array1<f64>) -> f64 {
126        (self.objective_func)(variables)
127    }
128
129    fn dim(&self) -> usize { self.dim }
130
131    fn bounds(&self) -> (Array1<f64>, Array1<f64>) {
132        (self.lower.clone(), self.upper.clone())
133    }
134}