#ifndef WALKMODULEPREVENTVISITED_H #define WALKMODULEPREVENTVISITED_H #include "WalkModule.h" #include "WalkStateHeading.h" #include "../../../../data/RingBuffer.h" #include "../../../../Assertions.h" struct WalkStatePreventVisited { struct PV { RingBuffer history; PV(const int size) : history(size) {;} } preventVisited; /** ctor */ explicit WalkStatePreventVisited(const int historySize) : preventVisited(historySize) {;} }; /** * prevent a state from visiting nodes he has already visited * within a certain timeframe (ringbuffer) * * this should avoid deadlocks in some situations where the transition * just switched back and forth between two nodes * */ template class WalkModulePreventVisited : public WalkModule { private: public: /** ctor */ WalkModulePreventVisited() { // ensure the templated WalkState inherits from 'WalkStatePreventVisited' StaticAssert::AinheritsB(); } virtual void updateBefore(WalkState& state) override { (void) state; } virtual void updateAfter(WalkState& state, const Node& startNode, const Node& endNode) override { (void) state; (void) startNode; (void) endNode; } virtual void step(WalkState& state, const Node& curNode, const Node& nextNode) override { (void) curNode; state.preventVisited.history.add(nextNode.getIdx()); } double getProbability(const WalkState& state, const Node& startNode, const Node& curNode, const Node& potentialNode) const override { (void) startNode; (void) curNode; return (state.preventVisited.history.contains(potentialNode.getIdx())) ? 0.001 : 0.999; } }; #endif // WALKMODULEPREVENTVISITED_H