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
This commit is contained in:
165
include/fces/population.hpp
Normal file
165
include/fces/population.hpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user