7#include "../rng/rng_factory.hpp"
24 m_func = std::move(func);
25 m_initialized =
false;
29 m_callback = std::move(cb);
33 if (lower.size() != upper.size()) {
34 throw std::invalid_argument(
"Lower and Upper bounds must have the same dimension.");
36 m_lower_bounds = lower;
37 m_upper_bounds = upper;
38 m_initialized =
false;
44 m_initialized =
false;
47 void PSO::initialize() {
48 if (!m_func)
throw std::runtime_error(
"Objective function not set.");
49 if (m_lower_bounds.empty())
throw std::runtime_error(
"Bounds not set.");
52 const size_t dim = m_lower_bounds.size();
57 #pragma omp parallel for schedule(static)
59 for (
int p_idx = 0; p_idx < static_cast<int>(m_swarm.size()); ++p_idx) {
60 auto& p = m_swarm[
static_cast<size_t>(p_idx)];
65 std::uniform_real_distribution<Real> dist(0.0, 1.0);
67 p.position.resize(
dim);
68 p.velocity.resize(
dim);
70 for (
size_t i = 0; i <
dim; ++i) {
71 const Real span = m_upper_bounds[i] - m_lower_bounds[i];
72 p.position[i] = m_lower_bounds[i] + dist(local_gen) * span;
73 p.velocity[i] = (dist(local_gen) - 0.5) * span * 0.1;
76 p.current_value = m_func(p.position);
77 p.best_position = p.position;
78 p.best_value = p.current_value;
83 for (
const auto& p : m_swarm) {
84 Solution current_sol{p.position, p.current_value};
85 if (current_sol.isBetterThan(m_global_best, m_mode)) {
86 m_global_best = current_sol;
94 if (!m_initialized) initialize();
96 const size_t dim = m_lower_bounds.size();
97 const Solution old_global_best = m_global_best;
100 #pragma omp parallel for schedule(static)
102 for (
int p_idx = 0; p_idx < static_cast<int>(m_swarm.size()); ++p_idx) {
103 auto& p = m_swarm[
static_cast<size_t>(p_idx)];
106 std::uint64_t stream_id = 2000ULL +
107 (
static_cast<std::uint64_t
>(m_current_iter) * m_config.
population_size) +
108 static_cast<std::uint64_t
>(p_idx);
110 std::uniform_real_distribution<Real> r_dist(0.0, 1.0);
112 for (
size_t i = 0; i <
dim; ++i) {
113 const Real r1 = r_dist(local_gen);
114 const Real r2 = r_dist(local_gen);
116 const Real cognitive_comp =
118 const Real social_comp =
122 (m_config.
inertia_weight * p.velocity[i]) + cognitive_comp + social_comp;
124 p.position[i] += p.velocity[i];
129 const Real new_val = m_func(p.position);
130 p.current_value = new_val;
132 Solution new_sol{p.position, new_val};
133 Solution pbest_sol{p.best_position, p.best_value};
135 if (new_sol.isBetterThan(pbest_sol, m_mode)) {
136 p.best_value = new_val;
137 p.best_position = p.position;
144 for (
const auto& p : m_swarm) {
145 Solution sol{p.best_position, p.best_value};
146 if (sol.isBetterThan(m_global_best, m_mode)) {
155 void PSO::enforceBounds(Particle& p) {
156 for (
size_t i = 0; i < p.position.size(); ++i) {
157 if (p.position[i] < m_lower_bounds[i]) {
158 p.position[i] = m_lower_bounds[i];
159 p.velocity[i] *= -0.5;
160 }
else if (p.position[i] > m_upper_bounds[i]) {
161 p.position[i] = m_upper_bounds[i];
162 p.velocity[i] *= -0.5;
172 m_callback(m_global_best, i);
175 return m_global_best;
179 return m_global_best;
Particle Swarm Optimization (PSO) interface and data structures.
std::function< void(const Solution ¤t_best, size_t iteration)> StepCallback
Callback invoked after each step/generation.
Solution optimize() override
Execute the optimization loop for max_iterations.
PSO(const PSOConfig &config=PSOConfig{})
Construct a PSO optimizer with the given configuration.
void setBounds(const Coordinates &lower, const Coordinates &upper) override
Set lower/upper bounds of the search hyper-rectangle.
void setCallback(StepCallback cb) override
Register a callback invoked after each step().
void setObjectiveFunction(ObjectiveFunction func) override
Set the objective function to optimize.
Solution getBestSolution() const override
Get the best solution found so far.
void step() override
Perform one PSO iteration: update velocity/position, evaluate, update personal and global bests.
void setMode(OptimizationMode mode) override
Set optimization mode (minimize or maximize).
constexpr int dim
Default dimensionality for integration.
OptimizationMode
Optimization goal.
std::function< Real(const Coordinates &)> ObjectiveFunction
Objective function signature.
std::vector< Real > Coordinates
A point in the N-dimensional search space.
double Real
Scalar precision used across optimizers.
std::mt19937 make_engine(std::uint64_t stream_id)
Create a deterministic RNG engine for a specific stream.
Configuration parameters for PSO.
size_t population_size
Number of particles in the swarm.
Real social_coeff
Social coefficient (c2): scales attraction to global best.
Real cognitive_coeff
Cognitive coefficient (c1): scales attraction to particle best.
Real inertia_weight
Inertia weight (w): scales previous velocity.
size_t max_iterations
Number of iterations to run the optimizer.
Represents a candidate solution in the search space.
static Solution make_worst(OptimizationMode mode)
Helper to create a worst-case solution for initialization.
Coordinates params
Parameter vector (coordinates in the search space).