Skip to main content

quantrs2_anneal/meta_learning/
mod.rs

1//! Meta-Learning Optimization Engine for Quantum Annealing Systems
2//!
3//! This module provides a sophisticated meta-learning optimization engine that learns
4//! from historical optimization experiences to automatically improve performance across
5//! different problem types and configurations.
6
7pub mod config;
8pub mod features;
9pub mod multi_objective;
10pub mod nas;
11pub mod portfolio;
12pub mod transfer_learning;
13
14use std::collections::{HashMap, VecDeque};
15use std::sync::{Arc, Mutex, RwLock};
16use std::time::{Duration, Instant};
17
18use crate::applications::{ApplicationError, ApplicationResult};
19use crate::ising::IsingModel;
20use crate::simulator::{AnnealingParams, AnnealingResult, QuantumAnnealingSimulator};
21
22// Re-export main types from submodules
23pub use config::{
24    ActivationFunction, AlgorithmType, ArchitectureSpec, ConnectionPattern,
25    FeatureExtractionConfig, LayerSpec, LayerType, MetaLearningConfig, MultiObjectiveConfig,
26    NeuralArchitectureSearchConfig, OptimizationConfiguration, OptimizationSettings, OptimizerType,
27    PortfolioManagementConfig, ProblemDomain, RegularizationConfig, ResourceAllocation,
28};
29pub use features::{
30    CorrelationFeatures, FeatureExtractor, GraphFeatures, ProblemFeatures, SpectralFeatures,
31    StatisticalFeatures,
32};
33pub use multi_objective::{MultiObjectiveOptimizer, MultiObjectiveSolution, ParetoFrontier};
34pub use nas::{NeuralArchitectureSearch, PerformancePredictor};
35pub use portfolio::{Algorithm, AlgorithmPortfolio, GuaranteeType, ResourceRequirements};
36pub use transfer_learning::{SourceDomain, TransferLearner, TransferResult, TransferStrategy};
37
38/// Main meta-learning optimization engine
39pub struct MetaLearningOptimizer {
40    /// Configuration
41    pub config: MetaLearningConfig,
42    /// Experience database
43    pub experience_db: Arc<RwLock<ExperienceDatabase>>,
44    /// Feature extractor
45    pub feature_extractor: Arc<Mutex<FeatureExtractor>>,
46    /// Meta-learner
47    pub meta_learner: Arc<Mutex<MetaLearner>>,
48    /// Neural architecture search engine
49    pub nas_engine: Arc<Mutex<NeuralArchitectureSearch>>,
50    /// Algorithm portfolio manager
51    pub portfolio_manager: Arc<Mutex<AlgorithmPortfolio>>,
52    /// Multi-objective optimizer
53    pub multi_objective_optimizer: Arc<Mutex<MultiObjectiveOptimizer>>,
54    /// Transfer learning system
55    pub transfer_learner: Arc<Mutex<TransferLearner>>,
56}
57
58/// Optimization experience record
59#[derive(Debug, Clone)]
60pub struct OptimizationExperience {
61    /// Unique experience identifier
62    pub id: String,
63    /// Problem characteristics
64    pub problem_features: ProblemFeatures,
65    /// Configuration used
66    pub configuration: OptimizationConfiguration,
67    /// Results achieved
68    pub results: OptimizationResults,
69    /// Timestamp
70    pub timestamp: Instant,
71    /// Problem domain
72    pub domain: ProblemDomain,
73    /// Success metrics
74    pub success_metrics: SuccessMetrics,
75}
76
77/// Optimization results
78#[derive(Debug, Clone)]
79pub struct OptimizationResults {
80    /// Final objective values
81    pub objective_values: Vec<f64>,
82    /// Execution time
83    pub execution_time: Duration,
84    /// Resource usage
85    pub resource_usage: ResourceUsage,
86    /// Convergence metrics
87    pub convergence: ConvergenceMetrics,
88    /// Solution quality metrics
89    pub quality_metrics: QualityMetrics,
90}
91
92/// Resource usage tracking
93#[derive(Debug, Clone)]
94pub struct ResourceUsage {
95    /// Peak CPU usage
96    pub peak_cpu: f64,
97    /// Peak memory usage (MB)
98    pub peak_memory: usize,
99    /// GPU utilization
100    pub gpu_utilization: f64,
101    /// Energy consumption
102    pub energy_consumption: f64,
103}
104
105/// Convergence metrics
106#[derive(Debug, Clone)]
107pub struct ConvergenceMetrics {
108    /// Number of iterations
109    pub iterations: usize,
110    /// Final convergence rate
111    pub convergence_rate: f64,
112    /// Plateau detection
113    pub plateau_detected: bool,
114    /// Convergence confidence
115    pub confidence: f64,
116}
117
118/// Solution quality metrics
119#[derive(Debug, Clone)]
120pub struct QualityMetrics {
121    /// Objective function value
122    pub objective_value: f64,
123    /// Constraint violation
124    pub constraint_violation: f64,
125    /// Robustness score
126    pub robustness: f64,
127    /// Diversity score
128    pub diversity: f64,
129}
130
131/// Success metrics
132#[derive(Debug, Clone)]
133pub struct SuccessMetrics {
134    /// Overall success score
135    pub success_score: f64,
136    /// Performance relative to baseline
137    pub relative_performance: f64,
138    /// User satisfaction score
139    pub user_satisfaction: f64,
140    /// Recommendation confidence
141    pub recommendation_confidence: f64,
142}
143
144/// Experience database
145pub struct ExperienceDatabase {
146    /// Stored experiences
147    pub experiences: VecDeque<OptimizationExperience>,
148    /// Index for fast retrieval
149    pub index: ExperienceIndex,
150    /// Similarity cache
151    pub similarity_cache: HashMap<String, Vec<(String, f64)>>,
152    /// Statistics
153    pub statistics: DatabaseStatistics,
154}
155
156/// Experience indexing system
157#[derive(Debug)]
158pub struct ExperienceIndex {
159    /// Domain-based index
160    pub domain_index: HashMap<ProblemDomain, Vec<String>>,
161    /// Size-based index
162    pub size_index: std::collections::BTreeMap<usize, Vec<String>>,
163    /// Performance-based index
164    pub performance_index: std::collections::BTreeMap<String, Vec<String>>,
165    /// Feature-based index
166    pub feature_index: HashMap<String, Vec<String>>,
167}
168
169/// Database statistics
170#[derive(Debug, Clone)]
171pub struct DatabaseStatistics {
172    /// Total experiences
173    pub total_experiences: usize,
174    /// Experiences per domain
175    pub domain_distribution: HashMap<ProblemDomain, usize>,
176    /// Average performance
177    pub avg_performance: f64,
178    /// Coverage statistics
179    pub coverage_stats: CoverageStatistics,
180}
181
182/// Coverage statistics
183#[derive(Debug, Clone)]
184pub struct CoverageStatistics {
185    /// Feature space coverage
186    pub feature_coverage: f64,
187    /// Problem size coverage
188    pub size_coverage: (usize, usize),
189    /// Domain coverage
190    pub domain_coverage: f64,
191    /// Performance range coverage
192    pub performance_range: (f64, f64),
193}
194
195/// Meta-learning system
196pub struct MetaLearner {
197    /// Learning algorithm
198    pub algorithm: MetaLearningAlgorithm,
199    /// Model parameters
200    pub parameters: Vec<f64>,
201    /// Training history
202    pub training_history: VecDeque<TrainingEpisode>,
203    /// Performance evaluator
204    pub evaluator: PerformanceEvaluator,
205}
206
207/// Meta-learning algorithms
208#[derive(Debug, Clone, PartialEq, Eq)]
209pub enum MetaLearningAlgorithm {
210    /// Model-Agnostic Meta-Learning
211    MAML,
212    /// Prototypical Networks
213    PrototypicalNetworks,
214    /// Matching Networks
215    MatchingNetworks,
216    /// Relation Networks
217    RelationNetworks,
218    /// Memory-Augmented Networks
219    MemoryAugmented,
220    /// Gradient-Based Meta-Learning
221    GradientBased,
222}
223
224/// Training episode
225#[derive(Debug, Clone)]
226pub struct TrainingEpisode {
227    /// Episode identifier
228    pub id: String,
229    /// Support set
230    pub support_set: Vec<OptimizationExperience>,
231    /// Query set
232    pub query_set: Vec<OptimizationExperience>,
233    /// Loss achieved
234    pub loss: f64,
235    /// Accuracy achieved
236    pub accuracy: f64,
237    /// Timestamp
238    pub timestamp: Instant,
239}
240
241/// Performance evaluator
242#[derive(Debug)]
243pub struct PerformanceEvaluator {
244    /// Evaluation metrics
245    pub metrics: Vec<EvaluationMetric>,
246    /// Cross-validation strategy
247    pub cv_strategy: CrossValidationStrategy,
248    /// Statistical tests
249    pub statistical_tests: Vec<StatisticalTest>,
250}
251
252/// Evaluation metrics
253#[derive(Debug, Clone, PartialEq, Eq)]
254pub enum EvaluationMetric {
255    /// Mean squared error
256    MeanSquaredError,
257    /// Mean absolute error
258    MeanAbsoluteError,
259    /// R-squared
260    RSquared,
261    /// Accuracy
262    Accuracy,
263    /// Precision
264    Precision,
265    /// Recall
266    Recall,
267    /// F1 score
268    F1Score,
269    /// Custom metric
270    Custom(String),
271}
272
273/// Cross-validation strategies
274#[derive(Debug, Clone, PartialEq, Eq)]
275pub enum CrossValidationStrategy {
276    /// K-fold cross-validation
277    KFold(usize),
278    /// Leave-one-out
279    LeaveOneOut,
280    /// Time series split
281    TimeSeriesSplit,
282    /// Stratified K-fold
283    StratifiedKFold(usize),
284    /// Custom strategy
285    Custom(String),
286}
287
288/// Statistical tests
289#[derive(Debug, Clone, PartialEq, Eq)]
290pub enum StatisticalTest {
291    /// t-test
292    TTest,
293    /// Wilcoxon signed-rank test
294    WilcoxonSignedRank,
295    /// Mann-Whitney U test
296    MannWhitneyU,
297    /// Kolmogorov-Smirnov test
298    KolmogorovSmirnov,
299    /// Chi-square test
300    ChiSquare,
301}
302
303/// Recommended optimization strategy
304#[derive(Debug, Clone)]
305pub struct RecommendedStrategy {
306    /// Strategy confidence
307    pub confidence: f64,
308    /// Recommended configuration
309    pub configuration: OptimizationConfiguration,
310    /// Expected performance
311    pub expected_performance: f64,
312    /// Reasoning
313    pub reasoning: String,
314    /// Alternative strategies
315    pub alternatives: Vec<AlternativeStrategy>,
316}
317
318/// Alternative strategy option
319#[derive(Debug, Clone)]
320pub struct AlternativeStrategy {
321    /// Alternative configuration
322    pub configuration: OptimizationConfiguration,
323    /// Confidence in alternative
324    pub confidence: f64,
325    /// Trade-offs
326    pub trade_offs: String,
327}
328
329/// Meta-optimization result
330#[derive(Debug, Clone)]
331pub struct MetaOptimizationResult {
332    /// Extracted problem features
333    pub problem_features: ProblemFeatures,
334    /// Recommended strategy
335    pub recommended_strategy: RecommendedStrategy,
336    /// Optimization results
337    pub optimization_result: OptimizationResults,
338    /// Number of similar experiences used
339    pub similar_experiences: usize,
340    /// Architecture used (if any)
341    pub architecture_used: Option<ArchitectureSpec>,
342    /// Meta-learning overhead
343    pub meta_learning_overhead: Duration,
344    /// Overall confidence
345    pub confidence: f64,
346}
347
348/// Meta-learning statistics
349#[derive(Debug, Clone)]
350pub struct MetaLearningStatistics {
351    /// Total stored experiences
352    pub total_experiences: usize,
353    /// Average performance across experiences
354    pub average_performance: f64,
355    /// Number of domains covered
356    pub domain_coverage: usize,
357    /// Feature space coverage
358    pub feature_coverage: f64,
359    /// Meta-learning accuracy
360    pub meta_learning_accuracy: f64,
361    /// Transfer learning success rate
362    pub transfer_learning_success_rate: f64,
363}
364
365impl MetaLearningOptimizer {
366    /// Create new meta-learning optimizer
367    #[must_use]
368    pub fn new(config: MetaLearningConfig) -> Self {
369        Self {
370            config: config.clone(),
371            experience_db: Arc::new(RwLock::new(ExperienceDatabase::new())),
372            feature_extractor: Arc::new(Mutex::new(FeatureExtractor::new(
373                config.feature_config.clone(),
374            ))),
375            meta_learner: Arc::new(Mutex::new(MetaLearner::new())),
376            nas_engine: Arc::new(Mutex::new(NeuralArchitectureSearch::new(
377                config.nas_config.clone(),
378            ))),
379            portfolio_manager: Arc::new(Mutex::new(AlgorithmPortfolio::new(
380                config.portfolio_config.clone(),
381            ))),
382            multi_objective_optimizer: Arc::new(Mutex::new(MultiObjectiveOptimizer::new(
383                config.multi_objective_config,
384            ))),
385            transfer_learner: Arc::new(Mutex::new(TransferLearner::new())),
386        }
387    }
388
389    /// Optimize a problem using meta-learning
390    pub fn optimize(&self, problem: &IsingModel) -> ApplicationResult<MetaOptimizationResult> {
391        println!(
392            "Starting meta-learning optimization for problem with {} qubits",
393            problem.num_qubits
394        );
395
396        let start_time = Instant::now();
397
398        // Step 1: Extract problem features
399        let problem_features = self.extract_problem_features(problem)?;
400
401        // Step 2: Retrieve similar experiences
402        let similar_experiences = self.find_similar_experiences(&problem_features)?;
403
404        // Step 3: Recommend optimization strategy
405        let recommended_strategy =
406            self.recommend_strategy(&problem_features, &similar_experiences)?;
407
408        // Step 4: Apply neural architecture search if needed
409        let optimized_architecture = if self.config.nas_config.enable_nas {
410            Some(self.search_optimal_architecture(&problem_features)?)
411        } else {
412            None
413        };
414
415        // Step 5: Execute optimization with meta-learned configuration
416        let optimization_result = self.execute_optimization(
417            problem,
418            &recommended_strategy,
419            optimized_architecture.as_ref(),
420        )?;
421
422        // Step 6: Store experience for future learning
423        self.store_experience(
424            problem,
425            &problem_features,
426            &recommended_strategy,
427            &optimization_result,
428        )?;
429
430        // Step 7: Update meta-learner
431        self.update_meta_learner(&problem_features, &optimization_result)?;
432
433        let total_time = start_time.elapsed();
434
435        println!("Meta-learning optimization completed in {total_time:?}");
436
437        Ok(MetaOptimizationResult {
438            problem_features,
439            recommended_strategy,
440            optimization_result,
441            similar_experiences: similar_experiences.len(),
442            architecture_used: optimized_architecture,
443            meta_learning_overhead: total_time,
444            confidence: 0.85,
445        })
446    }
447
448    /// Extract features from problem
449    fn extract_problem_features(&self, problem: &IsingModel) -> ApplicationResult<ProblemFeatures> {
450        let mut feature_extractor = self.feature_extractor.lock().map_err(|_| {
451            ApplicationError::OptimizationError(
452                "Failed to acquire feature extractor lock".to_string(),
453            )
454        })?;
455
456        feature_extractor.extract_features(problem)
457    }
458
459    /// Find similar experiences from database
460    fn find_similar_experiences(
461        &self,
462        features: &ProblemFeatures,
463    ) -> ApplicationResult<Vec<OptimizationExperience>> {
464        let experience_db = self.experience_db.read().map_err(|_| {
465            ApplicationError::OptimizationError(
466                "Failed to acquire experience database lock".to_string(),
467            )
468        })?;
469
470        experience_db.find_similar_experiences(features, 10)
471    }
472
473    /// Recommend optimization strategy based on meta-learning
474    fn recommend_strategy(
475        &self,
476        features: &ProblemFeatures,
477        experiences: &[OptimizationExperience],
478    ) -> ApplicationResult<RecommendedStrategy> {
479        let mut meta_learner = self.meta_learner.lock().map_err(|_| {
480            ApplicationError::OptimizationError("Failed to acquire meta-learner lock".to_string())
481        })?;
482
483        meta_learner.recommend_strategy(features, experiences)
484    }
485
486    /// Search for optimal neural architecture
487    fn search_optimal_architecture(
488        &self,
489        features: &ProblemFeatures,
490    ) -> ApplicationResult<ArchitectureSpec> {
491        let mut nas_engine = self.nas_engine.lock().map_err(|_| {
492            ApplicationError::OptimizationError("Failed to acquire NAS engine lock".to_string())
493        })?;
494
495        nas_engine.search_architecture(features)
496    }
497
498    /// Execute optimization with recommended strategy
499    fn execute_optimization(
500        &self,
501        problem: &IsingModel,
502        strategy: &RecommendedStrategy,
503        architecture: Option<&ArchitectureSpec>,
504    ) -> ApplicationResult<OptimizationResults> {
505        // Create annealing parameters based on strategy
506        let mut params = AnnealingParams::new();
507
508        // Apply recommended hyperparameters
509        if let Some(temp) = strategy
510            .configuration
511            .hyperparameters
512            .get("initial_temperature")
513        {
514            params.initial_temperature = *temp;
515        }
516        if let Some(temp) = strategy
517            .configuration
518            .hyperparameters
519            .get("final_temperature")
520        {
521            params.final_temperature = *temp;
522        }
523        if let Some(sweeps) = strategy.configuration.hyperparameters.get("num_sweeps") {
524            params.num_sweeps = *sweeps as usize;
525        }
526
527        params.seed = Some(42);
528
529        let start_time = Instant::now();
530
531        // Create and run simulator
532        let mut simulator = QuantumAnnealingSimulator::new(params)?;
533        let result = simulator.solve(problem)?;
534
535        let execution_time = start_time.elapsed();
536
537        // Calculate quality metrics
538        let objective_value = result.best_energy;
539        let quality_score = 1.0 / (1.0 + objective_value.abs());
540
541        Ok(OptimizationResults {
542            objective_values: vec![objective_value],
543            execution_time,
544            resource_usage: ResourceUsage {
545                peak_cpu: 0.8,
546                peak_memory: 512,
547                gpu_utilization: 0.0,
548                energy_consumption: execution_time.as_secs_f64() * 100.0,
549            },
550            convergence: ConvergenceMetrics {
551                iterations: 1000,
552                convergence_rate: 0.95,
553                plateau_detected: false,
554                confidence: 0.9,
555            },
556            quality_metrics: QualityMetrics {
557                objective_value,
558                constraint_violation: 0.0,
559                robustness: 0.85,
560                diversity: 0.7,
561            },
562        })
563    }
564
565    /// Store optimization experience
566    fn store_experience(
567        &self,
568        problem: &IsingModel,
569        features: &ProblemFeatures,
570        strategy: &RecommendedStrategy,
571        result: &OptimizationResults,
572    ) -> ApplicationResult<()> {
573        let mut experience_db = self.experience_db.write().map_err(|_| {
574            ApplicationError::OptimizationError(
575                "Failed to acquire experience database lock".to_string(),
576            )
577        })?;
578
579        let experience = OptimizationExperience {
580            id: format!("exp_{}", Instant::now().elapsed().as_nanos()),
581            problem_features: features.clone(),
582            configuration: strategy.configuration.clone(),
583            results: result.clone(),
584            timestamp: Instant::now(),
585            domain: ProblemDomain::Combinatorial,
586            success_metrics: SuccessMetrics {
587                success_score: result.quality_metrics.objective_value,
588                relative_performance: 1.0,
589                user_satisfaction: 0.8,
590                recommendation_confidence: strategy.confidence,
591            },
592        };
593
594        experience_db.add_experience(experience);
595        Ok(())
596    }
597
598    /// Update meta-learner with new experience
599    fn update_meta_learner(
600        &self,
601        features: &ProblemFeatures,
602        result: &OptimizationResults,
603    ) -> ApplicationResult<()> {
604        let mut meta_learner = self.meta_learner.lock().map_err(|_| {
605            ApplicationError::OptimizationError("Failed to acquire meta-learner lock".to_string())
606        })?;
607
608        meta_learner.update_with_experience(features, result);
609        Ok(())
610    }
611
612    /// Get current meta-learning statistics
613    pub fn get_statistics(&self) -> ApplicationResult<MetaLearningStatistics> {
614        let experience_db = self.experience_db.read().map_err(|_| {
615            ApplicationError::OptimizationError(
616                "Failed to acquire experience database lock".to_string(),
617            )
618        })?;
619
620        Ok(MetaLearningStatistics {
621            total_experiences: experience_db.statistics.total_experiences,
622            average_performance: experience_db.statistics.avg_performance,
623            domain_coverage: experience_db.statistics.domain_distribution.len(),
624            feature_coverage: experience_db.statistics.coverage_stats.feature_coverage,
625            meta_learning_accuracy: 0.85,
626            transfer_learning_success_rate: 0.75,
627        })
628    }
629}
630
631// Implementation of helper structures
632
633impl ExperienceDatabase {
634    fn new() -> Self {
635        Self {
636            experiences: VecDeque::new(),
637            index: ExperienceIndex {
638                domain_index: HashMap::new(),
639                size_index: std::collections::BTreeMap::new(),
640                performance_index: std::collections::BTreeMap::new(),
641                feature_index: HashMap::new(),
642            },
643            similarity_cache: HashMap::new(),
644            statistics: DatabaseStatistics {
645                total_experiences: 0,
646                domain_distribution: HashMap::new(),
647                avg_performance: 0.0,
648                coverage_stats: CoverageStatistics {
649                    feature_coverage: 0.0,
650                    size_coverage: (0, 0),
651                    domain_coverage: 0.0,
652                    performance_range: (0.0, 1.0),
653                },
654            },
655        }
656    }
657
658    fn add_experience(&mut self, experience: OptimizationExperience) {
659        self.experiences.push_back(experience.clone());
660        self.update_index(&experience);
661        self.update_statistics();
662
663        // Limit buffer size
664        if self.experiences.len() > 10_000 {
665            if let Some(removed) = self.experiences.pop_front() {
666                self.remove_from_index(&removed);
667            }
668        }
669    }
670
671    fn update_index(&mut self, experience: &OptimizationExperience) {
672        // Update domain index
673        self.index
674            .domain_index
675            .entry(experience.domain.clone())
676            .or_insert_with(Vec::new)
677            .push(experience.id.clone());
678
679        // Update size index
680        self.index
681            .size_index
682            .entry(experience.problem_features.size)
683            .or_insert_with(Vec::new)
684            .push(experience.id.clone());
685    }
686
687    fn remove_from_index(&mut self, experience: &OptimizationExperience) {
688        // Remove from domain index
689        if let Some(ids) = self.index.domain_index.get_mut(&experience.domain) {
690            ids.retain(|id| id != &experience.id);
691        }
692
693        // Remove from size index
694        if let Some(ids) = self
695            .index
696            .size_index
697            .get_mut(&experience.problem_features.size)
698        {
699            ids.retain(|id| id != &experience.id);
700        }
701    }
702
703    fn update_statistics(&mut self) {
704        self.statistics.total_experiences = self.experiences.len();
705
706        if !self.experiences.is_empty() {
707            let total_performance: f64 = self
708                .experiences
709                .iter()
710                .map(|exp| exp.results.quality_metrics.objective_value)
711                .sum();
712            self.statistics.avg_performance = total_performance / self.experiences.len() as f64;
713        }
714
715        // Update domain distribution
716        self.statistics.domain_distribution.clear();
717        for experience in &self.experiences {
718            *self
719                .statistics
720                .domain_distribution
721                .entry(experience.domain.clone())
722                .or_insert(0) += 1;
723        }
724    }
725
726    fn find_similar_experiences(
727        &self,
728        features: &ProblemFeatures,
729        limit: usize,
730    ) -> ApplicationResult<Vec<OptimizationExperience>> {
731        let mut similarities = Vec::new();
732
733        for experience in &self.experiences {
734            let similarity = self.calculate_similarity(features, &experience.problem_features);
735            similarities.push((experience.clone(), similarity));
736        }
737
738        // Sort by similarity (descending)
739        similarities.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
740
741        Ok(similarities
742            .into_iter()
743            .take(limit)
744            .map(|(exp, _)| exp)
745            .collect())
746    }
747
748    fn calculate_similarity(
749        &self,
750        features1: &ProblemFeatures,
751        features2: &ProblemFeatures,
752    ) -> f64 {
753        // Simple similarity calculation based on size and density
754        let size_diff = (features1.size as f64 - features2.size as f64).abs()
755            / features1.size.max(features2.size) as f64;
756        let density_diff = (features1.density - features2.density).abs();
757
758        let size_similarity = 1.0 - size_diff;
759        let density_similarity = 1.0 - density_diff;
760
761        f64::midpoint(size_similarity, density_similarity)
762    }
763}
764
765impl MetaLearner {
766    fn new() -> Self {
767        Self {
768            algorithm: MetaLearningAlgorithm::MAML,
769            parameters: Vec::new(),
770            training_history: VecDeque::new(),
771            evaluator: PerformanceEvaluator {
772                metrics: vec![
773                    EvaluationMetric::MeanSquaredError,
774                    EvaluationMetric::Accuracy,
775                ],
776                cv_strategy: CrossValidationStrategy::KFold(5),
777                statistical_tests: vec![StatisticalTest::TTest],
778            },
779        }
780    }
781
782    fn recommend_strategy(
783        &self,
784        features: &ProblemFeatures,
785        experiences: &[OptimizationExperience],
786    ) -> ApplicationResult<RecommendedStrategy> {
787        // Simple strategy recommendation based on problem size
788        let algorithm = if features.size < 100 {
789            AlgorithmType::SimulatedAnnealing
790        } else if features.size < 500 {
791            AlgorithmType::QuantumAnnealing
792        } else {
793            AlgorithmType::Hybrid(vec![
794                AlgorithmType::QuantumAnnealing,
795                AlgorithmType::TabuSearch,
796            ])
797        };
798
799        let mut hyperparameters = HashMap::new();
800
801        // Set hyperparameters based on experiences
802        if experiences.is_empty() {
803            // Default hyperparameters
804            hyperparameters.insert("initial_temperature".to_string(), 10.0);
805            hyperparameters.insert("final_temperature".to_string(), 0.1);
806        } else {
807            let avg_initial_temp = experiences
808                .iter()
809                .filter_map(|exp| exp.configuration.hyperparameters.get("initial_temperature"))
810                .sum::<f64>()
811                / experiences.len() as f64;
812            hyperparameters.insert("initial_temperature".to_string(), avg_initial_temp.max(1.0));
813
814            let avg_final_temp = experiences
815                .iter()
816                .filter_map(|exp| exp.configuration.hyperparameters.get("final_temperature"))
817                .sum::<f64>()
818                / experiences.len() as f64;
819            hyperparameters.insert("final_temperature".to_string(), avg_final_temp.max(0.01));
820        }
821
822        hyperparameters.insert(
823            "num_sweeps".to_string(),
824            (features.size as f64 * 10.0).min(10_000.0),
825        );
826
827        let configuration = OptimizationConfiguration {
828            algorithm,
829            hyperparameters,
830            architecture: None,
831            resources: ResourceAllocation {
832                cpu: 1.0,
833                memory: 512,
834                gpu: 0.0,
835                time: Duration::from_secs(60),
836            },
837        };
838
839        let confidence = if experiences.len() >= 5 { 0.9 } else { 0.6 };
840
841        Ok(RecommendedStrategy {
842            confidence,
843            configuration,
844            expected_performance: 0.8,
845            reasoning: format!(
846                "Recommendation based on {} similar experiences",
847                experiences.len()
848            ),
849            alternatives: Vec::new(),
850        })
851    }
852
853    const fn update_with_experience(
854        &self,
855        _features: &ProblemFeatures,
856        _result: &OptimizationResults,
857    ) {
858        // Update meta-learner with new experience
859        // In a real implementation, this would update neural network weights
860    }
861}
862
863/// Create example meta-learning optimizer
864pub fn create_example_meta_learning_optimizer() -> ApplicationResult<MetaLearningOptimizer> {
865    let config = MetaLearningConfig::default();
866    let optimizer = MetaLearningOptimizer::new(config);
867
868    println!("Created meta-learning optimizer with comprehensive capabilities");
869    Ok(optimizer)
870}
871
872#[cfg(test)]
873mod tests {
874    use super::*;
875
876    #[test]
877    fn test_meta_learning_optimizer_creation() {
878        let config = MetaLearningConfig::default();
879        let optimizer = MetaLearningOptimizer::new(config);
880
881        assert!(optimizer.config.enable_transfer_learning);
882        assert!(optimizer.config.enable_few_shot_learning);
883        assert_eq!(optimizer.config.experience_buffer_size, 10_000);
884    }
885
886    #[test]
887    fn test_experience_database() {
888        let mut db = ExperienceDatabase::new();
889
890        let experience = OptimizationExperience {
891            id: "test_exp".to_string(),
892            problem_features: ProblemFeatures {
893                size: 10,
894                density: 0.5,
895                graph_features: GraphFeatures::default(),
896                statistical_features: StatisticalFeatures::default(),
897                spectral_features: SpectralFeatures::default(),
898                domain_features: HashMap::new(),
899            },
900            configuration: OptimizationConfiguration {
901                algorithm: AlgorithmType::SimulatedAnnealing,
902                hyperparameters: HashMap::new(),
903                architecture: None,
904                resources: ResourceAllocation {
905                    cpu: 1.0,
906                    memory: 512,
907                    gpu: 0.0,
908                    time: Duration::from_secs(60),
909                },
910            },
911            results: OptimizationResults {
912                objective_values: vec![1.0],
913                execution_time: Duration::from_secs(10),
914                resource_usage: ResourceUsage {
915                    peak_cpu: 0.8,
916                    peak_memory: 256,
917                    gpu_utilization: 0.0,
918                    energy_consumption: 100.0,
919                },
920                convergence: ConvergenceMetrics {
921                    iterations: 1000,
922                    convergence_rate: 0.95,
923                    plateau_detected: false,
924                    confidence: 0.9,
925                },
926                quality_metrics: QualityMetrics {
927                    objective_value: 1.0,
928                    constraint_violation: 0.0,
929                    robustness: 0.8,
930                    diversity: 0.7,
931                },
932            },
933            timestamp: Instant::now(),
934            domain: ProblemDomain::Combinatorial,
935            success_metrics: SuccessMetrics {
936                success_score: 0.9,
937                relative_performance: 1.1,
938                user_satisfaction: 0.8,
939                recommendation_confidence: 0.9,
940            },
941        };
942
943        db.add_experience(experience);
944        assert_eq!(db.statistics.total_experiences, 1);
945    }
946
947    #[test]
948    fn test_meta_learner_recommendation() {
949        let mut meta_learner = MetaLearner::new();
950
951        let features = ProblemFeatures {
952            size: 50,
953            density: 0.3,
954            graph_features: GraphFeatures::default(),
955            statistical_features: StatisticalFeatures::default(),
956            spectral_features: SpectralFeatures::default(),
957            domain_features: HashMap::new(),
958        };
959
960        let experiences = vec![];
961        let recommendation = meta_learner
962            .recommend_strategy(&features, &experiences)
963            .expect("Strategy recommendation should succeed");
964
965        assert!(recommendation.confidence > 0.0);
966        assert!(recommendation.confidence <= 1.0);
967        assert!(!recommendation.configuration.hyperparameters.is_empty());
968    }
969}