// Copyright 2017, University of Freiburg, // Chair of Algorithms and Data Structures. // Authors: Patrick Brosi #ifndef UTIL_GRAPH_SHORTESTPATH_H_ #define UTIL_GRAPH_SHORTESTPATH_H_ #include #include #include #include #include #include #include #include "util/graph/Edge.h" #include "util/graph/Graph.h" #include "util/graph/Node.h" namespace util { namespace graph { using util::graph::Edge; using util::graph::Graph; using util::graph::Node; template using EList = std::vector*>; template using NList = std::vector*>; template struct CostFunc { virtual C operator()(const Node* from, const Edge* e, const Node* to) const = 0; virtual C operator()(const Edge* from, const Node* n, const Edge* to) const = 0; virtual C inf() const = 0; }; template struct HeurFunc { virtual C operator()(const Node* a, const std::set*>& b) const = 0; virtual C operator()(const Edge* a, const std::set*>& b) const = 0; }; template struct ZeroHeurFunc : public HeurFunc { C operator()(const Node* a, const std::set*>& b) const { UNUSED(a); UNUSED(b); return C(); } C operator()(const Edge* a, const std::set*>& b) const { UNUSED(a); UNUSED(b); return C(); } }; // shortest path base class template class ShortestPath { public: template using EList = std::vector*>; template using NList = std::vector*>; template static C shortestPath(Node* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, EList* resEdges, NList* resNodes) { return D::shortestPathImpl(from, to, costFunc, heurFunc, resEdges, resNodes); } template static C shortestPath(const std::set*>& from, const std::set*>& to, const CostFunc& costFunc) { EList* el = 0; NList* nl = 0; return D::shortestPathImpl(from, to, costFunc, ZeroHeurFunc(), el, nl); } template static C shortestPath(const std::set*> from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, EList* resEdges, NList* resNodes) { return D::shortestPathImpl(from, to, costFunc, heurFunc, resEdges, resNodes); } template static C shortestPath(const std::set*> from, const std::set*>& to, const CostFunc& costFunc, EList* resEdges, NList* resNodes) { return D::shortestPathImpl(from, to, costFunc, ZeroHeurFunc(), resEdges, resNodes); } template static C shortestPath(Node* from, const std::set*>& to, const CostFunc& costFunc, EList* resEdges, NList* resNodes) { return D::shortestPathImpl(from, to, costFunc, ZeroHeurFunc(), resEdges, resNodes); } template static std::unordered_map*, C> shortestPath( Node* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, std::unordered_map*, EList*> resEdges, std::unordered_map*, NList*> resNodes) { return D::shortestPathImpl(from, to, costFunc, heurFunc, resEdges, resNodes); } template static std::unordered_map*, C> shortestPath( Node* from, const std::set*>& to, const CostFunc& costFunc, std::unordered_map*, EList*> resEdges, std::unordered_map*, NList*> resNodes) { return D::shortestPathImpl(from, to, costFunc, ZeroHeurFunc(), resEdges, resNodes); } template static std::unordered_map*, C> shortestPath( Node* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, std::unordered_map*, EList*> resEdges) { std::unordered_map*, NList*> dummyRet; return D::shortestPathImpl(from, to, costFunc, heurFunc, resEdges, dummyRet); } template static std::unordered_map*, C> shortestPath( Node* from, const std::set*>& to, const CostFunc& costFunc, std::unordered_map*, EList*> resEdges) { std::unordered_map*, NList*> dummyRet; return D::shortestPathImpl(from, to, costFunc, ZeroHeurFunc(), resEdges, dummyRet); } template static std::unordered_map*, C> shortestPath( Node* from, const std::set*>& to, const CostFunc& costFunc, std::unordered_map*, NList*> resNodes) { std::unordered_map*, EList*> dummyRet; return D::shortestPathImpl(from, to, costFunc, ZeroHeurFunc(), dummyRet, resNodes); } template static std::unordered_map*, C> shortestPath( Node* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, std::unordered_map*, NList*> resNodes) { std::unordered_map*, EList*> dummyRet; return D::shortestPathImpl(from, to, costFunc, heurFunc, dummyRet, resNodes); } template static C shortestPath(Node* from, Node* to, const CostFunc& costFunc, EList* resEdges, NList* resNodes) { if (to->getInDeg() == 0) return costFunc.inf(); std::set*> tos; tos.insert(to); return shortestPath(from, tos, costFunc, resEdges, resNodes); } template static C shortestPath(Node* from, const std::set*>& tos, const CostFunc& costFunc) { EList* el = 0; NList* nl = 0; return shortestPath(from, tos, costFunc, el, nl); } template static C shortestPath(Node* from, Node* to, const CostFunc& costFunc) { if (to->getInDeg() == 0) return costFunc.inf(); std::set*> tos; tos.insert(to); EList* el = 0; NList* nl = 0; return shortestPath(from, tos, costFunc, el, nl); } template static C shortestPath(Node* from, Node* to, const CostFunc& costFunc, NList* resNodes) { if (to->getInDeg() == 0) return costFunc.inf(); std::set*> tos; tos.insert(to); EList* el = 0; return shortestPath(from, tos, costFunc, el, resNodes); } template static C shortestPath(Node* from, Node* to, const CostFunc& costFunc, EList* resEdges) { if (to->getInDeg() == 0) return costFunc.inf(); std::set*> tos; tos.insert(to); NList* nl = 0; return shortestPath(from, tos, costFunc, resEdges, nl); } template static C shortestPath(Node* from, const std::set*>& to, const CostFunc& costFunc, NList* resNodes) { EList* el = 0; return shortestPath(from, to, costFunc, el, resNodes); } template static C shortestPath(Node* from, const std::set*>& to, const CostFunc& costFunc, EList* resEdges) { NList* nl = 0; return shortestPath(from, to, costFunc, resEdges, nl); } template static C shortestPath(Node* from, Node* to, const CostFunc& costFunc, const HeurFunc& heurFunc, EList* resEdges, NList* resNodes) { if (to->getInDeg() == 0) return costFunc.inf(); std::set*> tos; tos.insert(to); return D::shortestPathImpl(from, tos, costFunc, heurFunc, resEdges, resNodes); } template static C shortestPath(Node* from, Node* to, const CostFunc& costFunc, const HeurFunc& heurFunc, NList* resNodes) { if (to->getInDeg() == 0) return costFunc.inf(); std::set*> tos; tos.insert(to); EList* el = 0; return D::shortestPathImpl(from, tos, costFunc, heurFunc, el, resNodes); } template static C shortestPath(Node* from, Node* to, const CostFunc& costFunc, const HeurFunc& heurFunc, EList* resEdges) { if (to->getInDeg() == 0) return costFunc.inf(); std::set*> tos; tos.insert(to); NList* nl = 0; return D::shortestPathImpl(from, tos, costFunc, heurFunc, resEdges, nl); } template static C shortestPath(Node* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, NList* resNodes) { EList* el = 0; return D::shortestPathImpl(from, to, costFunc, heurFunc, el, resNodes); } template static C shortestPath(Node* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, EList* resEdges) { NList* nl = 0; return D::shortestPathImpl(from, to, costFunc, heurFunc, resEdges, nl); } template static C shortestPath(Edge* from, Edge* to, const CostFunc& costFunc, const HeurFunc& heurFunc, EList* resEdges) { NList dummyRet; std::set*> froms{from}; std::set*> tos{to}; return D::shortestPathImpl(froms, tos, costFunc, heurFunc, resEdges, &dummyRet); } template static std::unordered_map*, C> shortestPath( Edge* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, std::unordered_map*, EList*> resEdges, std::unordered_map*, NList*> resNodes) { return D::shortestPathImpl(from, to, costFunc, heurFunc, resEdges, resNodes); } template static std::unordered_map*, C> shortestPath( Edge* from, const std::set*>& to, const CostFunc& costFunc, std::unordered_map*, EList*> resEdges, std::unordered_map*, NList*> resNodes) { return D::shortestPathImpl(from, to, costFunc, ZeroHeurFunc() , resEdges, resNodes); } template static std::unordered_map*, C> shortestPath( Edge* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, std::unordered_map*, EList*> resEdges) { std::unordered_map*, NList*> dummyRet; return D::shortestPathImpl(from, to, costFunc, heurFunc, resEdges, dummyRet); } template static std::unordered_map*, C> shortestPath( Edge* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc) { std::unordered_map*, NList*> dummyRet; std::unordered_map*, EList*> dummyRetE; return D::shortestPathImpl(from, to, costFunc, heurFunc, dummyRetE, dummyRet); } template static C shortestPath(Edge* from, const std::set*>& to, const CostFunc& costFunc) { NList* nl = 0; EList* el = 0; std::set*> fromS; fromS.insert(from); return D::shortestPathImpl(fromS, to, costFunc, ZeroHeurFunc(), el, nl); } template static C shortestPath(const std::set*>& from, const std::set*>& to, const CostFunc& costFunc) { NList* nl = 0; EList* el = 0; return D::shortestPathImpl(from, to, costFunc, ZeroHeurFunc(), el, nl); } template static C shortestPath(const std::set*>& from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc) { NList* nl = 0; EList* el = 0; return D::shortestPathImpl(from, to, costFunc, heurFunc, el, nl); } template static C shortestPath(const std::set*>& from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, EList* el) { NList* nl = 0; return D::shortestPathImpl(from, to, costFunc, heurFunc, el, nl); } template static std::unordered_map*, C> shortestPath( const std::set*>& from, const std::set*>& to, const std::unordered_map*, C>& initCosts, const CostFunc& costFunc, const HeurFunc& heurFunc, std::unordered_map*, EList*> resEdges, std::unordered_map*, NList*> resNodes) { return D::shortestPathImpl(from, to, initCosts, costFunc.inf(), costFunc, heurFunc, resEdges, resNodes); } template static std::unordered_map*, C> shortestPath( const std::set*>& from, const std::set*>& to, const std::unordered_map*, C>& initCosts, const CostFunc& costFunc, const HeurFunc& heurFunc, std::unordered_map*, EList*> resEdges) { std::unordered_map*, NList*> dummyRet; return D::shortestPathImpl(from, to, initCosts, costFunc.inf(), costFunc, heurFunc, resEdges, dummyRet); } template static std::unordered_map*, C> shortestPath( const std::set*>& from, const std::set*>& to, const std::unordered_map*, C>& initCosts, const CostFunc& costFunc, const HeurFunc& heurFunc) { std::unordered_map*, NList*> dummyRet; std::unordered_map*, EList*> dummyRetE; return D::shortestPathImpl(from, to, initCosts, costFunc.inf(), costFunc, heurFunc, dummyRetE, dummyRet); } template static std::unordered_map*, C> shortestPath( const std::set*>& from, const std::set*>& to, const std::unordered_map*, C>& initCosts, C stall, const CostFunc& costFunc, const HeurFunc& heurFunc, std::unordered_map*, EList*> resEdges, std::unordered_map*, NList*> resNodes) { return D::shortestPathImpl(from, to, initCosts, stall, costFunc, heurFunc, resEdges, resNodes); } template static std::unordered_map*, C> shortestPath( const std::set*>& from, const std::set*>& to, const std::unordered_map*, C>& initCosts, C stall, const CostFunc& costFunc, const HeurFunc& heurFunc, std::unordered_map*, EList*> resEdges) { std::unordered_map*, NList*> dummyRet; return D::shortestPathImpl(from, to, initCosts, stall, costFunc, heurFunc, resEdges, dummyRet); } template static std::unordered_map*, std::pair*, C>> shortestPath( const std::set*>& from, const std::set*>& to, const std::unordered_map*, C>& initCosts, C stall, const CostFunc& costFunc, const HeurFunc& heurFunc) { return D::shortestPathImpl(from, to, initCosts, stall, costFunc, heurFunc); } template static C shortestPath(Edge* from, Edge* to, const CostFunc& costFunc) { NList* nl = 0; EList* el = 0; std::set*> tos{to}; std::set*> froms{from}; return D::shortestPathImpl(froms, tos, costFunc, ZeroHeurFunc(), el, nl); } template static C shortestPath(Edge* from, Edge* to, const CostFunc& costFunc, const HeurFunc& heurFunc) { NList* nl = 0; EList* el = 0; std::set*> tos{to}; std::set*> froms{from}; return D::shortestPathImpl(froms, tos, costFunc, heurFunc, el, nl); } template static C shortestPath(Edge* from, const std::set*>& to, const CostFunc& costFunc, const HeurFunc& heurFunc, EList* el, NList* nl) { return D::shortestPathImpl(from, to, costFunc, heurFunc, el, nl); } template static C shortestPath(Edge* from, const std::set*>& to, const CostFunc& costFunc, EList* el, NList* nl) { return D::shortestPathImpl(from, to, costFunc, ZeroHeurFunc(), el, nl); } template static C shortestPath(Edge* from, Node* to, const CostFunc& costFunc, const HeurFunc& heurFunc, EList* el, NList* nl) { std::set*> tos{to}; return D::shortestPathImpl(from, tos, costFunc, heurFunc, el, nl); } template static C shortestPath(Edge* from, Node* to, const CostFunc& costFunc, EList* el, NList* nl) { std::set*> tos{to}; return D::shortestPathImpl(from, tos, costFunc, ZeroHeurFunc(), el, nl); } template static std::unordered_map*, C> shortestPath( Edge* from, const CostFunc& costFunc) { std::set*> froms{from}; return D::shortestPathImpl(froms, costFunc, false); } template static std::unordered_map*, C> shortestPathRev( Edge* from, const CostFunc& costFunc) { std::set*> froms{from}; return D::shortestPathImpl(froms, costFunc, true); } template static std::unordered_map*, C> shortestPath( Node* from, const CostFunc& costFunc) { std::set*> froms; froms.insert(from->getAdjListOut().begin(), from->getAdjListOut().end()); return D::shortestPathImpl(froms, costFunc, false); } template static std::unordered_map*, C> shortestPathRev( Node* from, const CostFunc& costFunc) { std::set*> froms; froms.insert(from->getAdjListOut().begin(), from->getAdjListOut().end()); return D::shortestPathImpl(froms, costFunc, true); } }; } // namespace graph } // namespace util #endif // UTIL_GRAPH_SHORTESTPATH_H_