#pragma once /** * @file population.hpp * @brief Population management — the evolutionary ecosystem. * * Manages a population of FuzzyControllers with: * - Elitism (protected top-N) * - Tournament selection with age weighting * - Crossover, mutation, and Phoenix rebirth * - Island migration (optional) * - Novelty search (optional) * - Phase 23 stale elite mitigation strategies * - Phase 24 violator synchronization * * Port of: packages/fces/core/population.py (~1260 LOC) */ #include #include #include #include "controller.hpp" namespace fces { /** * Elite selection strategy for stale elite mitigation (Phase 23). */ enum class EliteStrategy { Cumulative, // Raw cumulative fitness EMA, // Exponential moving average Rolling, // Rolling window average Reset, // Periodic reset every 500 steps AgePenalty // fitness / log(age + 2) }; /** * Population — manages the ecosystem of FuzzyControllers. */ class Population { public: // Configuration constants static constexpr int ELITE_COUNT = 2; static constexpr float NOVELTY_WEIGHT = 0.1f; static constexpr float ISLAND_MIGRATION_RATE = 0.05f; static constexpr int BEHAVIORAL_ARCHIVE_SIZE = 100; // --------------------------------------------------------------- // Construction // --------------------------------------------------------------- explicit Population(int active_size = 75, int repo_size = 10000, EliteStrategy elite_strategy = EliteStrategy::Cumulative, bool link_mutation = false, bool link_elite = false, bool link_violator = false, bool use_fuzzy_pacer = false, bool use_fuzzy_importance = false, bool direct_construction = false, bool use_banach_fission = false); // --------------------------------------------------------------- // Core API // --------------------------------------------------------------- /// Get the currently active controller (sticky selection) FuzzyController &get_active_controller(); /// Select a controller via fitness-weighted tournament FuzzyController &select_weighted(); /// Get the best controller in the active population FuzzyController &get_best_active(); /// Get the worst non-elite controller FuzzyController &get_worst_active(); /// Remove a specific controller (unless elite) void kill(FuzzyController &controller); /// Update a controller's fitness void update_controller_fitness(FuzzyController &controller, float reward, bool increment_eval = true); /// Mark a controller as a violator (rollback) void mark_violated(FuzzyController &controller); /// Get the effective fitness considering elite strategy and training progress float get_effective_fitness(const FuzzyController &controller, float training_progress) const; // --------------------------------------------------------------- // Evolution // --------------------------------------------------------------- /** * Evolve the population: select parents, crossover/mutate, replace worst. * * @param current_loss Current training loss * @param velocity Loss velocity * @param training_progress Training progress [0, 1] */ void evolve(float current_loss, float velocity = 0.0f, float training_progress = 0.0f); /// Resize the population (dynamic expansion/contraction) void resize(int target_size, float training_progress = 0.5f); /// Reduce mutation variance after rollback void calm_down(); // --------------------------------------------------------------- // Accessors // --------------------------------------------------------------- int size() const { return static_cast(gladiators_.size()); } float global_sigma_modifier() const { return global_sigma_modifier_; } /// Compute diversity index (behavioral spread) float get_diversity_index() const; /// Serialization // TODO: state_dict / load_state_dict private: std::vector gladiators_; std::vector repository_; std::vector violated_controllers_; float global_sigma_modifier_ = 1.0f; // Sticky controller selection FuzzyController *active_controller_ = nullptr; int steps_active_ = 0; int selection_interval_ = 20; // Configuration EliteStrategy elite_strategy_; bool link_mutation_; bool link_elite_; bool link_violator_; bool use_fuzzy_pacer_; bool use_fuzzy_importance_; bool direct_construction_; bool use_banach_fission_; // Novelty search std::vector> behavioral_archive_; // Fitness history for fuzzy pacer std::vector fitness_history_; // Phase 23: periodic reset counter int reset_step_counter_ = 0; // --------------------------------------------------------------- // Internal // --------------------------------------------------------------- std::vector get_elites(); void add_to_repository(const FuzzyController &controller); }; } // namespace fces