WPILibC++ 2024.1.1-beta-4
SimulatedAnnealing.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <cmath>
8#include <functional>
9#include <limits>
10#include <random>
11
12namespace frc {
13
14/**
15 * An implementation of the Simulated Annealing stochastic nonlinear
16 * optimization method.
17 *
18 * @see <a
19 * href="https://en.wikipedia.org/wiki/Simulated_annealing">https://en.wikipedia.org/wiki/Simulated_annealing</a>
20 * @tparam State The type of the state to optimize.
21 */
22template <typename State>
24 public:
25 /**
26 * Constructor for Simulated Annealing that can be used for the same functions
27 * but with different initial states.
28 *
29 * @param initialTemperature The initial temperature. Higher temperatures make
30 * it more likely a worse state will be accepted during iteration, helping
31 * to avoid local minima. The temperature is decreased over time.
32 * @param neighbor Function that generates a random neighbor of the current
33 * state.
34 * @param cost Function that returns the scalar cost of a state.
35 */
36 constexpr SimulatedAnnealing(double initialTemperature,
37 std::function<State(const State&)> neighbor,
38 std::function<double(const State&)> cost)
39 : m_initialTemperature{initialTemperature},
40 m_neighbor{neighbor},
41 m_cost{cost} {}
42
43 /**
44 * Runs the Simulated Annealing algorithm.
45 *
46 * @param initialGuess The initial state.
47 * @param iterations Number of iterations to run the solver.
48 * @return The optimized state.
49 */
50 State Solve(const State& initialGuess, int iterations) {
51 State minState = initialGuess;
52 double minCost = std::numeric_limits<double>::infinity();
53
54 std::random_device rd;
55 std::mt19937 gen{rd()};
56 std::uniform_real_distribution<> distr{0.0, 1.0};
57
58 State state = initialGuess;
59 double cost = m_cost(state);
60
61 for (int i = 0; i < iterations; ++i) {
62 double temperature = m_initialTemperature / i;
63
64 State proposedState = m_neighbor(state);
65 double proposedCost = m_cost(proposedState);
66 double deltaCost = proposedCost - cost;
67
68 double acceptanceProbability = std::exp(-deltaCost / temperature);
69
70 // If cost went down or random number exceeded acceptance probability,
71 // accept the proposed state
72 if (deltaCost < 0 || acceptanceProbability >= distr(gen)) {
73 state = proposedState;
74 cost = proposedCost;
75 }
76
77 // If proposed cost is less than minimum, the proposed state becomes the
78 // new minimum
79 if (proposedCost < minCost) {
80 minState = proposedState;
81 minCost = proposedCost;
82 }
83 }
84
85 return minState;
86 }
87
88 private:
89 double m_initialTemperature;
90 std::function<State(const State&)> m_neighbor;
91 std::function<double(const State&)> m_cost;
92};
93
94} // namespace frc
An implementation of the Simulated Annealing stochastic nonlinear optimization method.
Definition: SimulatedAnnealing.h:23
State Solve(const State &initialGuess, int iterations)
Runs the Simulated Annealing algorithm.
Definition: SimulatedAnnealing.h:50
constexpr SimulatedAnnealing(double initialTemperature, std::function< State(const State &)> neighbor, std::function< double(const State &)> cost)
Constructor for Simulated Annealing that can be used for the same functions but with different initia...
Definition: SimulatedAnnealing.h:36
state
Definition: core.h:2271
Definition: AprilTagPoseEstimator.h:15
compound_unit< energy::joules, inverse< mass::kilogram > > rd
Definition: radiation.h:61