43 : m_cost{
std::move(cost)} {}
57 template <
size_t Poses>
64 for (
int i = 0; i < state.rows(); ++i) {
66 m_cost(poses[
static_cast<int>(state(i))],
67 poses[
static_cast<int>(state((i + 1) % poses.size()))]);
72 Eigen::Vector<double, Poses> initial;
73 for (
int i = 0; i < initial.rows(); ++i) {
77 auto indices = solver.
Solve(initial, iterations);
80 for (
size_t i = 0; i < poses.size(); ++i) {
81 solution[i] = poses[
static_cast<int>(indices[i])];
85 std::rotate(solution.begin(),
86 std::find(solution.begin(), solution.end(), poses[0]),
103 std::vector<Pose2d>
Solve(std::span<const Pose2d> poses,
int iterations) {
105 1.0, &Neighbor<Eigen::Dynamic>, [&](
const Eigen::VectorXd& state) {
108 for (
int i = 0; i < state.rows(); ++i) {
110 m_cost(poses[
static_cast<int>(state(i))],
111 poses[
static_cast<int>(state((i + 1) % poses.size()))]);
116 Eigen::VectorXd initial{poses.size()};
117 for (
int i = 0; i < initial.rows(); ++i) {
121 auto indices = solver.
Solve(initial, iterations);
123 std::vector<Pose2d> solution;
124 for (
size_t i = 0; i < poses.size(); ++i) {
125 solution.emplace_back(poses[
static_cast<int>(indices[i])]);
129 std::rotate(solution.begin(),
130 std::find(solution.begin(), solution.end(), poses[0]),
138 std::function<double(
const Pose2d&,
const Pose2d&)> m_cost =
140 return wpi::units::math::hypot(a.
X() - b.X(), a.
Y() - b.Y()).value();
153 static Eigen::Vector<double, Poses> Neighbor(
154 const Eigen::Vector<double, Poses>& state) {
155 Eigen::Vector<double, Poses> proposedState = state;
157 std::random_device rd;
158 std::mt19937 gen{rd()};
159 std::uniform_int_distribution<> distr{0,
160 static_cast<int>(state.rows()) - 1};
162 int rangeStart = distr(gen);
163 int rangeEnd = distr(gen);
164 if (rangeEnd < rangeStart) {
168 for (
int i = rangeStart; i <= (rangeStart + rangeEnd) / 2; ++i) {
169 double temp = proposedState(i, 0);
170 proposedState(i, 0) =
state(rangeEnd - (i - rangeStart), 0);
171 proposedState(rangeEnd - (i - rangeStart), 0) = temp;
174 return proposedState;
Represents a 2D pose containing translational and rotational elements.
Definition Pose2d.hpp:27
constexpr wpi::units::meter_t X() const
Returns the X component of the pose's translation.
Definition Pose2d.hpp:114
constexpr wpi::units::meter_t Y() const
Returns the Y component of the pose's translation.
Definition Pose2d.hpp:121
An implementation of the Simulated Annealing stochastic nonlinear optimization method.
Definition SimulatedAnnealing.hpp:30
State Solve(const State &initialGuess, int iterations)
Runs the Simulated Annealing algorithm.
Definition SimulatedAnnealing.hpp:57
wpi::util::array< Pose2d, Poses > Solve(const wpi::util::array< Pose2d, Poses > &poses, int iterations)
Finds the path through every pose that minimizes the cost.
Definition TravelingSalesman.hpp:58
TravelingSalesman(std::function< double(Pose2d, Pose2d)> cost)
Constructs a traveling salesman problem solver with a user-provided cost function.
Definition TravelingSalesman.hpp:42
constexpr TravelingSalesman()=default
Constructs a traveling salesman problem solver with a cost function defined as the 2D distance betwee...
std::vector< Pose2d > Solve(std::span< const Pose2d > poses, int iterations)
Finds the path through every pose that minimizes the cost.
Definition TravelingSalesman.hpp:103
This class is a wrapper around std::array that does compile time size checking.
Definition array.hpp:26
state
Definition base.h:1467
Definition StringMap.hpp:773
void swap(wpi::util::StringMap< T > &lhs, wpi::util::StringMap< T > &rhs)
Definition StringMap.hpp:775
Definition LinearSystem.hpp:20
Eigen::Vector< double, Size > Vectord
Definition EigenCore.hpp:12
constexpr empty_array_t empty_array
Definition array.hpp:16