diff --git a/CMakeLists.txt b/CMakeLists.txt index 7460753..1d32b87 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,7 @@ ADD_DEFINITIONS( -DWITH_TESTS -DWITH_ASSERTIONS + -DWITH_DEBUG_LOG -march=native ) diff --git a/grid/walk/GridWalkLightAtTheEndOfTheTunnel.h b/grid/walk/GridWalkLightAtTheEndOfTheTunnel.h index 703ead9..eccff20 100644 --- a/grid/walk/GridWalkLightAtTheEndOfTheTunnel.h +++ b/grid/walk/GridWalkLightAtTheEndOfTheTunnel.h @@ -49,7 +49,7 @@ public: gen.seed(1234); // build all shortest path to reach th target - dijkstra.build(target, target, acc); + dijkstra.build(&target, acc); // attach a corresponding weight-information to each user-grid-node for (T& node : grid) { diff --git a/grid/walk/GridWalkPathControl.h b/grid/walk/GridWalkPathControl.h index 4eca917..bf5bb21 100644 --- a/grid/walk/GridWalkPathControl.h +++ b/grid/walk/GridWalkPathControl.h @@ -45,7 +45,7 @@ public: gen.seed(1234); // build all shortest path to reach th target - dijkstra.build(target, target, acc); + dijkstra.build(&target, acc); // attach a corresponding weight-information to each user-grid-node for (T& node : grid) { diff --git a/grid/walk/GridWalkShortestPathControl.h b/grid/walk/GridWalkShortestPathControl.h index 7ae0183..32512a3 100644 --- a/grid/walk/GridWalkShortestPathControl.h +++ b/grid/walk/GridWalkShortestPathControl.h @@ -108,7 +108,7 @@ public: gen.seed(1234); // build all shortest path to reach th target - dijkstra.build(target, target, acc); + dijkstra.build(&target, acc); } diff --git a/misc/Debug.h b/misc/Debug.h index 31a1386..5897a64 100644 --- a/misc/Debug.h +++ b/misc/Debug.h @@ -9,12 +9,12 @@ /** quick and dirty workaround */ static decltype(Time::tick()) LogLastTick; +#ifdef WITH_DEBUG_LOG + class Log { public: - - static void add(const char* comp, const std::string what, const bool nl = true) { addComp(comp); std::cout << what; @@ -50,4 +50,16 @@ private: }; +#else + +class Log { +public: + static void add(const char* comp, const std::string what, const bool nl = true) { (void)comp; (void) what; (void) nl; } + static void add(const std::string& component, const std::string what, const bool nl = true) { (void)component; (void) what; (void) nl; } + static void tick() {;} + static void tock() {;} +}; + +#endif + #endif // DEBUG_H diff --git a/nav/dijkstra/Dijkstra.h b/nav/dijkstra/Dijkstra.h index 5eebcb6..c6ac063 100644 --- a/nav/dijkstra/Dijkstra.h +++ b/nav/dijkstra/Dijkstra.h @@ -22,20 +22,34 @@ template class Dijkstra { public: + /** dtor: cleanup */ + ~Dijkstra() { + for (auto it : nodes) {delete it.second;} + } + /** get the dijkstra-pendant for the given user-node. null if none matches */ DijkstraNode* getNode(const T& userNode) const { auto it = nodes.find(&userNode); return (unlikely(it == nodes.end())) ? (nullptr) : (it->second); } - /** build shortest path from start to end using the provided wrapper-class */ - template void build(const T& start, const T& end, const Access& acc) { + /** calculate all shortest paths from ANY node to the given destination */ + template void build(const T* end, const Access& acc) { + build(end, nullptr, acc, NAN); + } + + /** + * build the shortest path from start to end using the provided access-wrapper-class. + * if end is null, the algorithm will terminate only if every possible node was checked. + * if given, the algorithm will also terminate if the current distance is already > the given maximum + */ + template void build(const T* start, const T* end, const Access& acc, const float maxWeight = 0) { // NOTE: end is currently ignored! // runs until all nodes were evaluated (void) end; - Log::add("Dijkstra", "calculating dijkstra from " + (std::string)start + " to ALL OTHER nodes", false); + Log::add("Dijkstra", "calculating dijkstra from " + (std::string)*start + " to ALL OTHER nodes", false); Log::tick(); // cleanup previous runs @@ -45,7 +59,7 @@ public: ToProcess toBeProcessedNodes; // run from start - const T* cur = &start; + const T* cur = start; // create a node for the start element DijkstraNode* dnStart = getOrCreateNode(cur); @@ -60,8 +74,11 @@ public: // get the next to-be-processed node DijkstraNode* dnSrc = toBeProcessedNodes.pop(); - // stop when end was reached?? - //if (dnSrc->element == &end) {break;} + // when an end is given, stop when end was reached + if (end != nullptr && dnSrc->element == end) {break;} + + // when a maximum weight is given, stop when current cum-dist > maxWeight + if (maxWeight != 0 && dnSrc->cumWeight > maxWeight) {break;} // visit (and maybe update) each neighbor of the current element for (int i = 0; i < acc.getNumNeighbors(*dnSrc->element); ++i) { diff --git a/tests/grid/TestAll.cpp b/tests/grid/TestAll.cpp index ca83c00..d824a22 100644 --- a/tests/grid/TestAll.cpp +++ b/tests/grid/TestAll.cpp @@ -53,7 +53,7 @@ TEST(TestAll, Nav) { const GP& start = g.getNodeFor(GridPoint(500,200,20)); const GP& end = g.getNodeFor(GridPoint(1200,200,340)); //const GP& end = g.getNodeFor(GridPoint(1300,1300,20)); - d.build(start, end, tmp); + d.build(&start, &end, tmp); // add the path's importance to the grid gi.addImportance(g, d.getNode(start), d.getNode(end)); diff --git a/tests/nav/dijkstra/TestDijkstra.cpp b/tests/nav/dijkstra/TestDijkstra.cpp index 8a33976..63e7f99 100644 --- a/tests/nav/dijkstra/TestDijkstra.cpp +++ b/tests/nav/dijkstra/TestDijkstra.cpp @@ -31,7 +31,7 @@ TEST(Dijkstra, build) { } tmp(grid); Dijkstra d; - d.build(grid[idx5], grid[idx3], tmp); + d.build(&grid[idx5], &grid[idx3], tmp, 99999); // start node must be "idx5" DijkstraNode* n = d.getNode(grid[idx5]); @@ -98,7 +98,7 @@ void dijkstra(Grid& grid) { } tmp(grid); Dijkstra d; - d.build(grid[0], grid[0], tmp); + d.build(&grid[0], tmp); }