Skip to content
Snippets Groups Projects
Commit 3aee6870 authored by tobiglaser's avatar tobiglaser
Browse files

added TSP (NN&2-opt) example

parent 36554ab1
Branches
Tags
No related merge requests found
#include "cute.h"
#include <algorithm>
#include <vector>
#include <cmath>
using namespace cute;
using namespace std;
void nearestNeighbour();
void twoOpt();
void setup()
{
registerAlgorithm(nearestNeighbour, "NearestNeighbour");
registerAlgorithm(twoOpt, "2-Opt :D");
setProblemSize(15);
setPlotTheme(3);
setPlotVisible((Plot)1, false);
setPlotVisible((Plot)2, false);
setPlotTitle((Plot)0, "Travelling Salesman Problem");
}
float length (const Point& a, const Point& b)
{
return sqrt(pow((a.x - b.x), 2) + pow((a.y - b.y), 2));
}
namespace global
{
vector<Point> result;
} //namespace global
void nearestNeighbour()
{
resetPlot(0);
vector<Point> input;
const vector<Point> points = getProblemData2D();
for (auto P : points)
input.push_back(P);
PlotProperties Pp;
Pp.color = Colors::darkRed;
Pp.onTop = true;
plotPoints(points, 0, Pp);
PlotProperties Lp;
Lp.color = Colors::green;
using global::result;
result.clear();
result.reserve(points.size());
result.push_back(input.front()); //start
Point currentPoint = input.front();
input.erase(input.begin());
int i = 1;
setProgress(100 * i / points.size());
setStatusMessage(to_string(i) + " of " + to_string(input.size()));
while (input.size() > 0)
{
++i;
int bestDist = INT_MAX;
auto bestIter = input.begin();
for (auto iter = input.begin(); iter != input.end(); ++iter)
{
float dist = length(currentPoint, *iter);
if (dist < bestDist)
{
bestDist = dist;
bestIter = iter;
}
}
currentPoint = *bestIter;
result.push_back(*bestIter);
input.erase(bestIter);
plotLines(result, 0, false, Lp);
delay(300);
undo(0);
setStatusMessage(to_string(i) + " of " + to_string(points.size()));
setProgress(100 * i / points.size());
}
Lp.color = Colors::cyan;
Lp.name = "NN";
plotLines(result, 0, true, Lp);
setStatusMessage("DONE! :D");
}
void twoOpt()
{
nearestNeighbour();
delay(1000);
using global::result;
result.emplace_back(result.front());
bool didSwap = true;
int swaps = 0;
setStatusMessage(to_string(swaps) + " swaps");
setProgress(0);
PlotProperties pp;
pp.color = Colors::darkCyan;
pp.size = 12;
while (didSwap)
{
didSwap = false;
for (size_t i = 0; (i < (result.size() - 3)); ++i)
{
for (size_t j = i + 2; (j < (result.size() - 1)) & !didSwap; ++j)
{
auto a = result[i];
auto b = result[i + 1];
auto c = result[j];
auto d = result[j + 1];
auto ab = length(a, b);
auto cd = length(c, d);
auto ac = length(a, c);
auto bd = length(b, d);
if (ac + bd < ab + cd)
{
reverse(result.begin() + i + 1,
result.begin() + j + 1); //needs j+1 otherwise doesnt include last element
didSwap = true;
++swaps;
plotLines(result, 0, false, pp);
delay(500);
undo(0);
setStatusMessage(to_string(swaps) + " swaps");
}
}
}
}
pp.color = Colors::magenta;
pp.color.transparency = 3 * 255 / 4;
pp.size = pp.size * 2;
pp.name = "2-Opt";
plotLines(result, 0, false, pp);
setStatusMessage("DONE! :DD");
setProgress(100);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment