optirs_nas/multi_objective/
core.rs1use crate::error::Result;
4use crate::nas_engine::{
5 MultiObjectiveConfig, ObjectiveConfig, ObjectiveType, OptimizationDirection,
6 OptimizerArchitecture, SearchResult,
7};
8use crate::EvaluationMetric;
9use scirs2_core::numeric::Float;
10use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12use std::fmt::Debug;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct CoverageMetrics<T: Float + Debug + Send + Sync + 'static> {
17 pub objective_space_coverage: T,
19 pub reference_distance: T,
21 pub epsilon_dominance: T,
23}
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
26pub enum CreationMethod {
27 RandomGeneration,
28 Crossover,
29 Mutation,
30 LocalSearch,
31 Repair,
32 Custom,
33}
34#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct FrontMetrics<T: Float + Debug + Send + Sync + 'static> {
37 pub hypervolume: T,
39 pub spread: T,
41 pub spacing: T,
43 pub convergence: T,
45 pub num_solutions: usize,
47 pub coverage: CoverageMetrics<T>,
49}
50#[derive(Debug, Clone)]
52pub struct Individual<T: Float + Debug + Send + Sync + 'static> {
53 pub architecture: OptimizerArchitecture<T>,
55 pub objectives: Vec<T>,
57 pub constraints: Vec<T>,
59 pub rank: usize,
61 pub crowding_distance: T,
63 pub fitness: T,
65 pub id: String,
67}
68#[derive(Debug, Clone)]
70pub struct MultiObjectiveStatistics<T: Float + Debug + Send + Sync + 'static> {
71 pub generation: usize,
73 pub total_evaluations: usize,
75 pub pareto_front_size: usize,
77 pub best_hypervolume: T,
79 pub convergence_history: Vec<T>,
81 pub diversity_history: Vec<T>,
83 pub algorithm_metrics: HashMap<String, T>,
85}
86impl<T: Float + Debug + Default + Send + Sync> Default for MultiObjectiveStatistics<T> {
87 fn default() -> Self {
88 Self {
89 generation: 0,
90 total_evaluations: 0,
91 pareto_front_size: 0,
92 best_hypervolume: T::zero(),
93 convergence_history: Vec::new(),
94 diversity_history: Vec::new(),
95 algorithm_metrics: HashMap::new(),
96 }
97 }
98}
99#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct ObjectiveBounds<T: Float + Debug + Send + Sync + 'static> {
102 pub min_values: Vec<T>,
104 pub max_values: Vec<T>,
106 pub ideal_point: Vec<T>,
108 pub nadir_point: Vec<T>,
110}
111#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct ParetoFront<T: Float + Debug + Send + Sync + 'static> {
114 pub solutions: Vec<ParetoSolution<T>>,
116 pub objective_bounds: ObjectiveBounds<T>,
118 pub metrics: FrontMetrics<T>,
120 pub generation: usize,
122 pub last_updated: std::time::SystemTime,
124}
125impl<T: Float + Debug + Default + Send + Sync> ParetoFront<T> {
126 pub(super) fn new() -> Self {
127 Self {
128 solutions: Vec::new(),
129 objective_bounds: ObjectiveBounds {
130 min_values: Vec::new(),
131 max_values: Vec::new(),
132 ideal_point: Vec::new(),
133 nadir_point: Vec::new(),
134 },
135 metrics: FrontMetrics {
136 hypervolume: T::zero(),
137 spread: T::zero(),
138 spacing: T::zero(),
139 convergence: T::zero(),
140 num_solutions: 0,
141 coverage: CoverageMetrics {
142 objective_space_coverage: T::zero(),
143 reference_distance: T::zero(),
144 epsilon_dominance: T::zero(),
145 },
146 },
147 generation: 0,
148 last_updated: std::time::SystemTime::now(),
149 }
150 }
151}
152impl<T: Float + Debug + Default + Send + Sync> Default for ParetoFront<T> {
153 fn default() -> Self {
154 Self::new()
155 }
156}
157#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct ParetoSolution<T: Float + Debug + Send + Sync + 'static> {
160 pub architecture: OptimizerArchitecture<T>,
162 pub objectives: Vec<T>,
164 pub constraint_violations: Vec<T>,
166 pub rank: usize,
168 pub crowding_distance: T,
170 pub metadata: SolutionMetadata,
172}
173#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct SolutionMetadata {
176 pub id: String,
178 pub generation: usize,
180 pub evaluation_count: usize,
182 pub parents: Vec<String>,
184 pub creation_method: CreationMethod,
186}
187pub fn evaluation_metric_for_objective(objective_type: &ObjectiveType) -> EvaluationMetric {
193 match objective_type {
194 ObjectiveType::Accuracy => EvaluationMetric::Accuracy,
195 ObjectiveType::Loss => EvaluationMetric::FinalPerformance,
196 ObjectiveType::TrainingTime => EvaluationMetric::TrainingTime,
197 ObjectiveType::InferenceTime => EvaluationMetric::ComputationTime,
198 ObjectiveType::MemoryUsage => EvaluationMetric::MemoryUsage,
199 ObjectiveType::EnergyConsumption => EvaluationMetric::ComputationTime,
200 ObjectiveType::ModelSize => EvaluationMetric::MemoryUsage,
201 ObjectiveType::Performance => EvaluationMetric::FinalPerformance,
202 ObjectiveType::Efficiency => EvaluationMetric::ComputationalEfficiency,
203 ObjectiveType::Robustness => EvaluationMetric::Robustness,
204 ObjectiveType::Interpretability => EvaluationMetric::FinalPerformance,
205 ObjectiveType::Fairness => EvaluationMetric::FinalPerformance,
206 ObjectiveType::Privacy => EvaluationMetric::FinalPerformance,
207 ObjectiveType::Sustainability => EvaluationMetric::ComputationalEfficiency,
208 ObjectiveType::Cost => EvaluationMetric::ComputationalEfficiency,
209 ObjectiveType::Custom(_) => EvaluationMetric::FinalPerformance,
210 }
211}
212
213pub fn objective_vector_for_result<T: Float + Debug + Send + Sync + 'static>(
219 objectives: &[ObjectiveConfig<T>],
220 result: &SearchResult<T>,
221) -> Vec<T> {
222 objectives
223 .iter()
224 .map(|objective| {
225 let metric = evaluation_metric_for_objective(&objective.objective_type);
226 result
227 .evaluation_results
228 .metric_scores
229 .get(&metric)
230 .copied()
231 .unwrap_or_else(T::zero)
232 })
233 .collect()
234}
235
236pub fn objective_directions<T: Float + Debug + Send + Sync + 'static>(
238 objectives: &[ObjectiveConfig<T>],
239) -> Vec<OptimizationDirection> {
240 objectives
241 .iter()
242 .map(|objective| objective.direction.clone())
243 .collect()
244}
245
246pub trait MultiObjectiveOptimizer<T: Float + Debug + Send + Sync + 'static>: Send + Sync {
248 fn initialize(&mut self, config: &MultiObjectiveConfig<T>) -> Result<()>;
250
251 fn update_pareto_front(&mut self, results: &[SearchResult<T>]) -> Result<ParetoFront<T>>;
253
254 fn get_pareto_front(&self) -> &ParetoFront<T>;
256
257 fn select_candidates(
259 &mut self,
260 population: &[OptimizerArchitecture<T>],
261 objectives: &[T],
262 ) -> Result<Vec<OptimizerArchitecture<T>>>;
263
264 fn name(&self) -> &str;
266
267 fn get_statistics(&self) -> MultiObjectiveStatistics<T>;
269}