worked on grid walker

This commit is contained in:
k-a-z-u
2017-11-15 16:41:57 +01:00
parent 08d8292976
commit 7af5131ccf
4 changed files with 190 additions and 92 deletions

View File

@@ -84,43 +84,67 @@ namespace GW3 {
};
/**
* data-structure to track to-be-visited nodes
* push_back, pop_front
* as pop_front is costly, we omit the pop and use a head-index instead
* memory-consumption vs speed
*/
struct ToVisit {
size_t nextIdx = 0;
std::vector<uint32_t> vec;
ToVisit() {vec.reserve(256);}
void add(const uint32_t nodeIdx) {vec.push_back(nodeIdx);}
uint32_t next() {return vec[nextIdx++];}
bool empty() const {return nextIdx >= vec.size();}
};
/** get an iterator over all nodes reachable from the given start */
template <typename Node> class ReachableIteratorUnsorted {
template <typename Node, typename Conditions> class ReachableIteratorUnsorted {
const Grid<Node>& grid;
const Node& start;
Node* curNode = nullptr;
std::unordered_set<uint32_t> visited;
std::vector<uint32_t> toVisit;
ToVisit toVisit;
Conditions cond;
public:
ReachableIteratorUnsorted(const Grid<Node>& grid, const Node& start) : grid(grid), start(start) {
toVisit.push_back(start.getIdx());
ReachableIteratorUnsorted(const Grid<Node>& grid, const Node& start, const Conditions cond) : grid(grid), start(start), cond(cond) {
toVisit.add(start.getIdx());
}
bool hasNext() const {
return !toVisit.empty();
}
const Node& next(const std::function<bool(const Node&)>& skip) {
const uint32_t curIdx = toVisit.front(); //visit from inside out (needed for correct distance)
toVisit.erase(toVisit.begin());
visited.insert(curIdx);
//const Node& next(const std::function<bool(const Node&)>& skip) {
//template <typename Skip> const Node& next(const Skip skip) {
const Node& next() {
// get the next to-be-visited node
const uint32_t curIdx = toVisit.next(); //visit from inside out (needed for correct distance)
const Node& curNode = grid[curIdx];
for (int i = 0; i < curNode.getNumNeighbors(); ++i) {
// mark as "visited"
visited.insert(curIdx);
const int neighborIdx = curNode.getNeighborIdx(i);
// get all neighbors
const int numNeighbors = curNode.getNumNeighbors();
for (int i = 0; i < numNeighbors; ++i) {
const uint32_t neighborIdx = curNode.getNeighborIdx(i);
const Node& neighbor = grid[neighborIdx];
const bool visit = cond.visit(neighbor) ;
// not yet reached -> store distance
if (!skip(neighbor)) {
if (visit) {
if (visited.find(neighborIdx) == visited.end()) {
toVisit.push_back(neighborIdx);
toVisit.add(neighborIdx);
}
}