13#ifndef OPTIMIST_OPTIMIZER_PARTICLE_SWARM_HH
14#define OPTIMIST_OPTIMIZER_PARTICLE_SWARM_HH
25 template <
typename Scalar>
49 return this->m_weight;
68 template <
typename Scalar>
96 const Integer max_iterations)
const {
97 Scalar factor{
static_cast<Scalar
>(iteration) /
98 static_cast<Scalar
>(max_iterations)};
99 return this->m_min_weight +
100 (this->m_max_weight - this->m_min_weight) * factor;
119 template <
typename Scalar>
146 const Integer max_iterations)
const {
147 Scalar exponent{
static_cast<Scalar
>(iteration) /
148 (
static_cast<Scalar
>(max_iterations) / 10.0)};
149 return this->m_min_weight +
150 (this->m_max_weight - this->m_min_weight) * std::exp(-exponent);
169 template <
typename Scalar>
197 const Integer max_iterations)
const {
198 Scalar exponent{
static_cast<Scalar
>(iteration) /
199 (
static_cast<Scalar
>(max_iterations) / 4.0)};
200 exponent *= exponent;
201 return this->m_min_weight +
202 (this->m_max_weight - this->m_min_weight) * std::exp(-exponent);
221 template <
typename Scalar>
244 const Scalar max_weight,
259 const Integer max_iterations)
const {
260 const Scalar factor{
static_cast<Scalar
>(iteration) /
261 static_cast<Scalar
>(max_iterations)};
262 const Scalar exponent{1.0 / (1.0 + this->m_d_2 * factor)};
263 return (this->m_max_weight - this->m_min_weight - this->m_d_1) *
293 template <
typename Vector,
294 typename InertiaWeightStrategy =
295 ConstantWeight<typename Vector::Scalar>>
311 InertiaWeightStrategy
333 return "ParticleSwarm";
341 for (
Integer i{0}; i < particles.size(); ++i) {
342 for (
Integer j{0}; j < particles.rows(); ++j) {
345 particles(j, i) = lb + (this->m_dice() * (ub - lb));
356 for (
Integer i{0}; i < velocities.cols(); ++i) {
357 for (
Integer j{0}; j < velocities.rows(); ++j) {
361 Scalar vel{-diff + (this->m_dice() * 2.0 * diff)};
363 std::min(m_max_velocity, std::max(-m_max_velocity, vel));
369 for (
Integer i{0}; i < particles.size(); ++i) {
370 fvals(i) = objective_(particles.col(i));
375 for (
Integer i{0}; i < particles.size(); ++i) {
376 for (
Integer j{0}; j < particles.rows(); ++j) {
380 std::min(maxval, std::max(minval, particles[j](i)));
386 const Matrix &best_particles,
389 Matrix &velocities) {
390 assert(velocities.rows() == particles.rows());
391 assert(velocities.cols() == particles.size());
392 assert(velocities.rows() == best_particles.rows());
393 assert(velocities.cols() == best_particles.size());
394 assert(gbest < best_particles.size());
398 for (
Integer i{0}; i < velocities.cols(); ++i) {
399 for (
Integer j{0}; j < velocities.rows(); ++j) {
401 this->m_dice() * (best_particles(j, i) - particles(j, i));
403 this->m_dice() * (best_particles(j, gbest) - particles(j, i));
407 if (m_max_velocity > 0)
408 vel = std::min(m_max_velocity, std::max(-m_max_velocity, vel));
410 velocities(j, i) = vel;
416 Matrix velocities(particles.rows(), particles.size());
418 Vector fvals(particles.size());
420 Matrix best_particles = particles;
421 Vector bestFvals(particles.size());
423 Matrix prevParticles(particles.rows(), particles.size());
424 Vector prevFvals(particles.size());
426 Vector diff(particles.rows());
436 bestFvals.minCoeff(&gbest);
453 particles += velocities;
459 prevParticles = best_particles;
460 prevFvals = bestFvals;
462 for (
Integer i{0}; i < fvals.size(); ++i) {
464 if (fvals(i) < bestFvals(i)) {
465 bestFvals(i) = fvals(i);
466 best_particles.col(i) = particles.col(i);
469 bestFvals.minCoeff(&gbest);
472 xchange = (best_particles - prevParticles).colwise().norm().sum();
473 fchange = (bestFvals - prevFvals).array().abs().sum();
475 xchange /= best_particles.size();
476 fchange /= bestFvals.size();
486 result.converged = fchange <=
feps_ || xchange <=
xeps_;
487 result.fval = bestFvals(gbest);
488 result.xval = best_particles.col(gbest);
500 m_max_velocity(static_cast<
Scalar>(0.0)),
503 std::default_random_engine gen(std::time(0));
504 std::uniform_real_distribution<Scalar> distrib(0.0, 1.0);
505 this->m_dice = std::bind(distrib, gen);
515 const Scalar change = ParticleSwarm::SQRT_EPSILON) {
524 const Scalar change = ParticleSwarm::SQRT_EPSILON) {
556 this->m_max_velocity = max_velocity;
560 const InertiaWeightStrategy &t_weightStrategy) {
577 throw std::runtime_error(
"particle count cannot be 0");
579 throw std::runtime_error(
"bounds has not exactly 2 rows (min, max)");
582 throw std::runtime_error(
"bounds min is greater than max");
585 Matrix particles(
bounds.cols(), cnt);
610 throw std::runtime_error(
"particle count cannot be 0");
612 throw std::runtime_error(
"bounds has not exactly 2 rows (min, max)");
615 throw std::runtime_error(
"bounds min is greater than max");
617 if (
bounds.cols() != initGuess.size())
618 throw std::runtime_error(
619 "init guess and bounds have different dimensions");
621 Matrix particles(
bounds.cols(), cnt);
623 particles.col(0) = initGuess;
640 throw std::runtime_error(
"bounds has not exactly 2 rows (min, max)");
641 if (
bounds.cols() != particles.rows())
642 throw std::runtime_error(
643 "columns of bounds and rows of "
644 "particles do not match");
647 throw std::runtime_error(
"bounds min is greater than max");
656 particles.resize(
bounds.cols(), cnt);
Scalar m_weight
Definition ParticleSwarm.hh:27
ConstantWeight(const Scalar weight)
Definition ParticleSwarm.hh:39
Scalar operator()(const Integer, const Integer) const
Definition ParticleSwarm.hh:47
ConstantWeight()
Definition ParticleSwarm.hh:33
Scalar operator()(const Integer iteration, const Integer max_iterations) const
Definition ParticleSwarm.hh:145
ExponentialDecrease1(const Scalar min_weight, const Scalar max_weight)
Definition ParticleSwarm.hh:136
ExponentialDecrease1()
Definition ParticleSwarm.hh:129
Scalar m_min_weight
Definition ParticleSwarm.hh:121
Scalar m_max_weight
Definition ParticleSwarm.hh:122
Scalar operator()(const Integer iteration, const Integer max_iterations) const
Definition ParticleSwarm.hh:196
ExponentialDecrease2()
Definition ParticleSwarm.hh:179
Scalar m_max_weight
Definition ParticleSwarm.hh:172
Scalar m_min_weight
Definition ParticleSwarm.hh:171
ExponentialDecrease2(const Scalar min_weight, const Scalar max_weight)
Definition ParticleSwarm.hh:187
Scalar m_min_weight
Definition ParticleSwarm.hh:223
ExponentialDecrease3()
Definition ParticleSwarm.hh:233
ExponentialDecrease3(const Scalar min_weight, const Scalar max_weight, const Scalar d_1, const Scalar d_2)
Definition ParticleSwarm.hh:243
Scalar m_d_1
Definition ParticleSwarm.hh:225
Scalar operator()(const Integer iteration, const Integer max_iterations) const
Definition ParticleSwarm.hh:258
Scalar m_d_2
Definition ParticleSwarm.hh:226
Scalar m_max_weight
Definition ParticleSwarm.hh:224
LinearDecrease(const Scalar min_weight, const Scalar max_weight)
Definition ParticleSwarm.hh:86
Scalar m_max_weight
Definition ParticleSwarm.hh:71
Scalar operator()(const Integer iteration, const Integer max_iterations) const
Definition ParticleSwarm.hh:95
Scalar m_min_weight
Definition ParticleSwarm.hh:70
LinearDecrease()
Definition ParticleSwarm.hh:78
Optimizer()
Definition Optimizer.hh:67
Result _minimize(const Matrix &bounds, Matrix &particles)
Definition ParticleSwarm.hh:415
constexpr std::string name_impl() const
Definition ParticleSwarm.hh:332
std::function< Scalar()> this m_dice
Definition ParticleSwarm.hh:320
static constexpr bool RequiresSecondDerivative
Definition ParticleSwarm.hh:303
Result minimize(const Integer cnt)
Definition ParticleSwarm.hh:575
void setPhiGlobal(const Scalar phig)
Definition ParticleSwarm.hh:546
static constexpr bool RequiresFunction
Definition ParticleSwarm.hh:301
void setMaxVelocity(const Scalar max_velocity)
Definition ParticleSwarm.hh:555
Scalar m_phi_g
Definition ParticleSwarm.hh:315
Scalar feps_
Definition ParticleSwarm.hh:319
ParticleSwarm()
Definition ParticleSwarm.hh:326
InertiaWeightStrategy m_weight_strategy
Definition ParticleSwarm.hh:312
void randomize_particles(Particles &particles) const
Definition ParticleSwarm.hh:340
Result minimize(const Integer cnt, const Vector &initGuess)
Definition ParticleSwarm.hh:608
ParticleSwarmOptimization()
Definition ParticleSwarm.hh:494
Scalar xeps_
Definition ParticleSwarm.hh:318
Scalar m_phi_p
Definition ParticleSwarm.hh:314
void maintainBounds(Matrix &particles) const
Definition ParticleSwarm.hh:374
void setMinParticleChange(const Scalar change=ParticleSwarm::SQRT_EPSILON)
Definition ParticleSwarm.hh:514
void getRandomParticles(const Integer cnt, Matrix &particles)
Definition ParticleSwarm.hh:655
static constexpr bool RequiresFirstDerivative
Definition ParticleSwarm.hh:302
void evaluate_objective(const Particles &particles, Vector &fvals)
Definition ParticleSwarm.hh:368
void inertia_weight_strategy(const InertiaWeightStrategy &t_weightStrategy)
Definition ParticleSwarm.hh:559
typename Vector::Scalar Scalar
Definition ParticleSwarm.hh:306
void randomize_velocities(Particles &velocities) const
Definition ParticleSwarm.hh:355
TypeTrait< Vector > VectorTrait
Definition ParticleSwarm.hh:305
void setPhiParticles(const Scalar phip)
Definition ParticleSwarm.hh:535
void setMinFunctionChange(const Scalar change=ParticleSwarm::SQRT_EPSILON)
Definition ParticleSwarm.hh:523
std::vector< Vector > Particles
Definition ParticleSwarm.hh:308
void calculateVelocities(const Matrix &particles, const Matrix &best_particles, const Integer gbest, const Integer iteration, Matrix &velocities)
Definition ParticleSwarm.hh:385
Result minimize(Matrix &particles)
Definition ParticleSwarm.hh:638
void info(Scalar residuals, const std::string ¬es="-")
Definition SolverBase.hh:1230
Integer m_max_iterations
Definition SolverBase.hh:121
Vector m_lower_bound
Definition SolverBase.hh:101
void bounds(const Vector &t_lower_bound, const Vector &t_upper_bound)
Definition SolverBase.hh:313
Integer iterations() const
Definition SolverBase.hh:440
Vector m_upper_bound
Definition SolverBase.hh:102
bool m_verbose
Definition SolverBase.hh:130
Namespace for the Optimist library.
Definition Optimist.hh:89
OPTIMIST_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Optimist.hh:97
Definition Optimist.hh:113