Files
FCES-native/include/fces/population.hpp
AI-anonymous 9bbe253810 feat: scaffold FCES-native C++ project with libtorch integration
- CMakeLists.txt with libtorch, GoogleTest, GoogleBenchmark, OpenMP, pybind11
- Header files: config, controller, population, fitness, evolution, spectral, oscillation, telemetry, optimizer
- Source implementations: controller (full micro-MLP forward pass, mutation, crossover), fitness (Welford's algorithm), oscillation (DFT), spectral (SVD rank), optimizer (sign-SGD stub)
- Tests: controller, population, fitness, optimizer (Google Test)
- Benchmarks: evolve throughput, optimizer step (Google Benchmark)
- Examples: simple optimization, PyTorch/libtorch integration
- Python extension: pybind11 bindings with setup.py
- README with architecture diagram and build instructions
2026-05-19 16:05:15 +02:00

166 lines
5.1 KiB
C++

#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 <string>
#include <vector>
#include <optional>
#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<int>(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<FuzzyController> gladiators_;
std::vector<FuzzyController> repository_;
std::vector<FuzzyController> 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<std::vector<float>> behavioral_archive_;
// Fitness history for fuzzy pacer
std::vector<float> fitness_history_;
// Phase 23: periodic reset counter
int reset_step_counter_ = 0;
// ---------------------------------------------------------------
// Internal
// ---------------------------------------------------------------
std::vector<FuzzyController*> get_elites();
void add_to_repository(const FuzzyController& controller);
};
} // namespace fces