diff --git a/examples/TSP.cpp b/examples/TSP.cpp index d3506b974e84b7dfdc384daf0dc9cf8b8442135e..e43403f41ed671189e7b7746f21a2b0d433350c8 100644 --- a/examples/TSP.cpp +++ b/examples/TSP.cpp @@ -19,8 +19,11 @@ void setup() setProblemSize(15); setPlotTheme(3); setPlotVisible(1, false); - setPlotVisible(2, false); + setPlotVisible(2, true); setPlotTitle(0, "Travelling Salesman Problem"); + setAxisVisible(0, false, false); + setPlotTitle(2, "Runtime"); + setAxisTitles(2, "Problem Size n", "Runtime / µs"); } float length(const Point& a, const Point& b) @@ -44,6 +47,22 @@ float circ_pythagoras(const vector<pair<int, Point>>& vec) return sum; } +float circ_pythagoras(const vector<Point>& vec) +{ + float sum = 0; + for (size_t i = 0; i < (vec.size() - 1); ++i) + { + float distance = length(vec[i], vec[i + 1]); + sum += distance; + } + if (vec.back().x != vec.front().x || vec.back().y != vec.front().y) + { + float distance = length(vec.back(), vec.front()); //close circle + sum += distance; + } + return sum; +} + namespace global { vector<Point> result; @@ -65,9 +84,19 @@ void plotMyVectorLines(vector<pair<int, Point>>& vec, int plot, bool loop) void bruteForce() { resetPlot(0); - vector<Point> data = getProblemData2D(); - plotPoints(data); - plotLines(data); + vector<Point> data = getProblemData2D(); + PlotProperties start; + start.shape = rectangle; + start.color = Colors::darkMagenta; + start.legend = true; + start.name = "Start"; + start.onTop = true; + if (verbosity() >= Verbosity::result) + { + plotPoints(data); + plotPoint(data.front(), 0, start, ""); + plotLines(data); + } long long n_fac = 1; for (size_t i = 1; i <= data.size() - 1; n_fac *= i++) @@ -89,13 +118,17 @@ void bruteForce() timerStart(); do { - int circ = circ_pythagoras(vec); + float circ = circ_pythagoras(vec); if (circ < bestCirc) { bestCirc = circ; bestVec = vec; - undo(0); - plotMyVectorLines(vec, 0, true); + if (verbosity() >= partialResult) + { + undo(0); + delay(5); + plotMyVectorLines(vec, 0, true); + } } if (++i % 1000 == 0) { @@ -107,10 +140,27 @@ void bruteForce() return a.first > b.first; })); timerStop(); + if (verbosity() >= Verbosity::result) + { + undo(0); + undo(0); + plotMyVectorLines(bestVec, 0, true); + } logMessage(std::to_string(timerResult().count() / 1000.) + "ms"); setStatusMessage(to_string(i) + " of " + to_string(n_fac)); setProgress(100 * i / n_fac); - logMessage("DONE grrr"); + if (ok()) + { + std::string s; + s = "BruteForce: "; + s += to_string(data.size()) + " Points in "; + s += to_string(timerResult().count()) + "us with Distance: "; + s += to_string(bestCirc); + logMessage(s); + PlotProperties p; + p.color = Colors::red; + plotPoint({(float)data.size(), (float)timerResult().count()}, 2, p, "BruteForce @X, @Yus)"); + } } @@ -125,7 +175,10 @@ void nearestNeighbour() PlotProperties Pp; Pp.color = Colors::darkRed; Pp.onTop = true; - plotPoints(points, 0, Pp); + if (verbosity() >= Verbosity::result) + { + plotPoints(points, 0, Pp); + } PlotProperties Lp; Lp.color = Colors::green; @@ -140,7 +193,8 @@ void nearestNeighbour() setProgress(100 * i / points.size()); setStatusMessage(to_string(i) + " of " + to_string(input.size())); - while (input.size() > 0) + timerStart(); + while (input.size() > 0 && ok()) { ++i; int bestDist = INT_MAX; @@ -158,34 +212,87 @@ void nearestNeighbour() 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()); + if (verbosity() >= verbose) + { + plotLines(result, 0, false, Lp); + delay(300); + undo(0); + setStatusMessage(to_string(i) + " of " + to_string(points.size())); + setProgress(100 * i / points.size()); + } + } + timerStop(); + if (verbosity() >= Verbosity::result) + { + Lp.color = Colors::darkCyan; + Lp.name = "NN"; + plotLines(result, 0, true, Lp); } - Lp.color = Colors::cyan; - Lp.name = "NN"; - plotLines(result, 0, true, Lp); setStatusMessage("DONE! :D"); + std::string s; + if (ok()) + { + s = "NearestNeighbour: "; + s += to_string(points.size()) + " Points in "; + s += to_string(timerResult().count()) + "us with Distance: "; + s += to_string(circ_pythagoras(result)); + logMessage(s); + PlotProperties p; + p.color = Colors::blue; + plotPoint({(float)points.size(), (float)timerResult().count()}, 2, p, "NearestNeighbour @X, @Yus)"); + } } void twoOpt() { nearestNeighbour(); - delay(1000); using global::result; + if (verbosity() >= Verbosity::result) + { + delay(verbosity() >= Verbosity::partialResult ? 1000 : 300); + undo(0); + } + + PlotProperties pp; + pp.color = Colors::darkCyan; + pp.size = 12; + pp.line = LineStyle::dash; + pp.name = "NN"; + pp.legend = true; + if (verbosity() >= Verbosity::result) + { + plotLines(result, 0, true, pp); + } 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) + + pp.color = Colors::cyan; + pp.line = LineStyle::solid; + pp.legend = false; + PlotProperties markLine; + markLine.color = Colors::red; + markLine.legend = false; + markLine.line = solid; + markLine.size = 20; + PlotProperties start; + start.color = Colors::darkMagenta; + start.onTop = true; + start.size = 3 * start.size / 2; + start.shape = rectangle; + start.name = "start"; + if (verbosity() >= Verbosity::partialResult) + { + plotPoint(result.front(), 0, start, ""); + plotLines(result, 0, false, pp); + } + timerResume(); + while (didSwap && ok()) { - didSwap = false; + Verbosity verbosity = cute::verbosity(); + didSwap = false; for (size_t i = 0; (i < (result.size() - 3)); ++i) { for (size_t j = i + 2; (j < (result.size() - 1)) & !didSwap; ++j) @@ -199,25 +306,74 @@ void twoOpt() auto ac = length(a, c); auto bd = length(b, d); + if (verbosity >= all) + { + markLine.color = Colors::red; + plotLine(a, b, 0, markLine); + plotLine(c, d, 0, markLine); + } + 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"); + if (verbosity >= all) + { + markLine.color = Colors::green; + plotLine(a, c, 0, markLine); + plotLine(b, d, 0, markLine); + delay(800); + undo(0); + undo(0); + undo(0); + undo(0); + } + if (verbosity >= partialResult) + { + undo(0); + plotLines(result, 0, false, pp); + delay(100); + setStatusMessage(to_string(swaps) + " swaps"); + } + } + else + { + if (verbosity >= all) + { + delay(200); + undo(0); + undo(0); + } } } } } - pp.color = Colors::magenta; - pp.color.transparency = 3 * 255 / 4; + timerStop(); + if (swaps > 0) + undo(0); + undo(0); + pp.color.transparency = 2 * 255 / 4; pp.size = pp.size * 2; pp.name = "2-Opt"; - plotLines(result, 0, false, pp); + pp.legend = true; + if (verbosity() >= Verbosity::result) + { + plotLines(result, 0, false, pp); + } setStatusMessage("DONE! :DD"); setProgress(100); + if (ok()) + { + std::string s; + s = "2-Opt: "; + s += to_string(result.size() - 1) + " Points in "; + s += to_string(timerResult().count()) + "us with Distance: "; + s += to_string(circ_pythagoras(result)); + logMessage(s); + PlotProperties p; + p.color = Colors::green; + plotPoint({(float)result.size() - 1, (float)timerResult().count()}, 2, p, "2-Opt @X, @Yus)"); + } } diff --git a/src/cute.cpp b/src/cute.cpp index f11bc1428ce1dbbb7c301e72c9e3ffd341a5fbcf..acf0ec97bed9c4044631ae01315f34a65586fb10 100644 --- a/src/cute.cpp +++ b/src/cute.cpp @@ -262,8 +262,11 @@ bool cute::ok() { timerPauseInternal(); static int i = 0; - if (verbosity() == cute::silent && ++i % 5000 != 0) + if (verbosity() == cute::silent && ++i % 500 != 0) + { + timerResumeInternal(); return true; + } else { bool ok = !CuteControl::get().endRequested();