Dijkstra.tpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright 2017, University of Freiburg,
  2. // Chair of Algorithms and Data Structures.
  3. // Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
  4. // _____________________________________________________________________________
  5. template <typename N, typename E, typename C>
  6. C Dijkstra::shortestPathImpl(Node<N, E>* from, const std::set<Node<N, E>*>& to,
  7. const ShortestPath::CostFunc<N, E, C>& costFunc,
  8. const ShortestPath::HeurFunc<N, E, C>& heurFunc,
  9. EList<N, E>* resEdges, NList<N, E>* resNodes) {
  10. if (from->getOutDeg() == 0) return costFunc.inf();
  11. Settled<N, E, C> settled;
  12. PQ<N, E, C> pq;
  13. bool found = false;
  14. pq.emplace(from);
  15. RouteNode<N, E, C> cur;
  16. while (!pq.empty()) {
  17. Dijkstra::ITERS++;
  18. if (settled.find(pq.top().n) != settled.end()) {
  19. pq.pop();
  20. continue;
  21. }
  22. cur = pq.top();
  23. pq.pop();
  24. settled[cur.n] = cur;
  25. if (to.find(cur.n) != to.end()) {
  26. found = true;
  27. break;
  28. }
  29. relax(cur, to, costFunc, heurFunc, pq);
  30. }
  31. if (!found) return costFunc.inf();
  32. buildPath(cur.n, settled, resNodes, resEdges);
  33. return cur.d;
  34. }
  35. // _____________________________________________________________________________
  36. template <typename N, typename E, typename C>
  37. C Dijkstra::shortestPathImpl(const std::set<Node<N, E>*> from,
  38. const std::set<Node<N, E>*>& to,
  39. const ShortestPath::CostFunc<N, E, C>& costFunc,
  40. const ShortestPath::HeurFunc<N, E, C>& heurFunc,
  41. EList<N, E>* resEdges, NList<N, E>* resNodes) {
  42. Settled<N, E, C> settled;
  43. PQ<N, E, C> pq;
  44. bool found = false;
  45. // put all nodes in from onto PQ
  46. for (auto n : from) pq.emplace(n);
  47. RouteNode<N, E, C> cur;
  48. while (!pq.empty()) {
  49. Dijkstra::ITERS++;
  50. if (settled.find(pq.top().n) != settled.end()) {
  51. pq.pop();
  52. continue;
  53. }
  54. cur = pq.top();
  55. pq.pop();
  56. settled[cur.n] = cur;
  57. if (to.find(cur.n) != to.end()) {
  58. found = true;
  59. break;
  60. }
  61. relax(cur, to, costFunc, heurFunc, pq);
  62. }
  63. if (!found) return costFunc.inf();
  64. buildPath(cur.n, settled, resNodes, resEdges);
  65. return cur.d;
  66. }
  67. // _____________________________________________________________________________
  68. template <typename N, typename E, typename C>
  69. std::unordered_map<Node<N, E>*, C> Dijkstra::shortestPathImpl(
  70. Node<N, E>* from, const std::set<Node<N, E>*>& to,
  71. const ShortestPath::CostFunc<N, E, C>& costFunc,
  72. const ShortestPath::HeurFunc<N, E, C>& heurFunc,
  73. std::unordered_map<Node<N, E>*, EList<N, E>*> resEdges,
  74. std::unordered_map<Node<N, E>*, NList<N, E>*> resNodes) {
  75. std::unordered_map<Node<N, E>*, C> costs;
  76. if (to.size() == 0) return costs;
  77. // init costs with inf
  78. for (auto n : to) costs[n] = costFunc.inf();
  79. if (from->getOutDeg() == 0) return costs;
  80. Settled<N, E, C> settled;
  81. PQ<N, E, C> pq;
  82. size_t found = 0;
  83. pq.emplace(from);
  84. RouteNode<N, E, C> cur;
  85. while (!pq.empty()) {
  86. Dijkstra::ITERS++;
  87. if (settled.find(pq.top().n) != settled.end()) {
  88. pq.pop();
  89. continue;
  90. }
  91. cur = pq.top();
  92. pq.pop();
  93. settled[cur.n] = cur;
  94. if (to.find(cur.n) != to.end()) {
  95. found++;
  96. }
  97. if (found == to.size()) break;
  98. relax(cur, to, costFunc, heurFunc, pq);
  99. }
  100. for (auto nto : to) {
  101. if (!settled.count(nto)) continue;
  102. Node<N, E>* curN = nto;
  103. costs[nto] = settled[curN].d;
  104. buildPath(nto, settled, resNodes[nto], resEdges[nto]);
  105. }
  106. return costs;
  107. }
  108. // _____________________________________________________________________________
  109. template <typename N, typename E, typename C>
  110. void Dijkstra::relax(RouteNode<N, E, C>& cur, const std::set<Node<N, E>*>& to,
  111. const ShortestPath::CostFunc<N, E, C>& costFunc,
  112. const ShortestPath::HeurFunc<N, E, C>& heurFunc, PQ<N, E, C>& pq) {
  113. for (auto edge : cur.n->getAdjListOut()) {
  114. C newC = costFunc(cur.n, edge, edge->getOtherNd(cur.n));
  115. newC = cur.d + newC;
  116. if (costFunc.inf() <= newC) continue;
  117. const C& newH = newC + heurFunc(edge->getOtherNd(cur.n), to);
  118. pq.emplace(edge->getOtherNd(cur.n), cur.n, newC, newH, &(*edge));
  119. }
  120. }
  121. // _____________________________________________________________________________
  122. template <typename N, typename E, typename C>
  123. void Dijkstra::buildPath(Node<N, E>* curN,
  124. Settled<N, E, C>& settled, NList<N, E>* resNodes,
  125. EList<N, E>* resEdges) {
  126. while (true) {
  127. const RouteNode<N, E, C>& curNode = settled[curN];
  128. if (resNodes) resNodes->push_back(curNode.n);
  129. if (!curNode.parent) break;
  130. if (resEdges) resEdges->push_back(curNode.e);
  131. curN = curNode.parent;
  132. }
  133. }