12 #include <unordered_map>
13 #include <unordered_set>
21 template <
typename GraphType>
23 std::unordered_map<
typename GraphType::vertex_descriptor,
24 std::vector<typename GraphType::vertex_descriptor>>;
30 template <
typename GraphType>
33 typedef typename GraphType::vertex_descriptor
VD;
65 template <
typename GraphType>
73 template <
typename GraphType>
91 template <
typename GraphType>
93 std::function<double(
typename GraphType::adj_edge_iterator&,
const double,
100 template <
typename GraphType>
103 return [](
typename GraphType::adj_edge_iterator& _ei,
104 const double _sourceDistance,
105 const double _targetDistance)
107 const double edgeWeight = _ei->property().GetWeight(),
108 newDistance = _sourceDistance + edgeWeight;
118 template <
typename GraphType>
120 std::function<double(
122 typename GraphType::vertex_descriptor source,
123 typename GraphType::vertex_descriptor target)>;
127 template <
typename GraphType>
130 return [](
const GraphType* _g,
131 typename GraphType::vertex_descriptor _source,
132 typename GraphType::vertex_descriptor _target)
144 template <
typename GraphType>
148 typename GraphType::vertex_descriptor vd)>;
152 template <
typename GraphType>
155 return [](GraphType* _g,
156 typename GraphType::vertex_descriptor _vd){};
170 template<
typename GraphType>
174 const std::vector<typename GraphType::vertex_descriptor>& _starts,
175 std::vector<typename GraphType::vertex_descriptor>& _goals,
180 const double _startDistance = 0)
186 using VD =
typename GraphType::vertex_descriptor;
187 using EI =
typename GraphType::adj_edge_iterator;
203 element(
const VD _parent,
const VD _target,
const double _g,
204 const double _h) : parent(_parent), vd(_target), g(_g), h(_h) {}
207 bool operator>(
const element& _e)
const noexcept {
208 return g + h > _e.g + _e.h;
212 std::priority_queue<element,
213 std::vector<element>,
214 std::greater<element>> frontier;
216 std::unordered_set<VD> seen;
217 std::unordered_map<VD, double> cost;
221 auto relax = [&_g, &cost, &frontier, &_weight, &_heuristic](EI& _ei) {
222 const VD source = _ei->source(),
223 target = _ei->target();
225 const double sourceCost = cost[source],
226 targetCost = cost.count(target)
228 : std::numeric_limits<double>::infinity(),
229 newG = _weight(_ei, sourceCost, targetCost),
230 newH = _heuristic(_g, source, target);
232 if(newG + newH >= targetCost)
235 cost[target] = newG + newH;
236 frontier.emplace(source, target, newG, newH);
240 for(
const auto start : _starts) {
241 cost[start] = _startDistance;
243 frontier.emplace(start, start, 0, 0);
247 while(!frontier.empty()) {
249 element current = frontier.top();
253 if(seen.count(current.vd))
255 seen.insert(current.vd);
257 output.
ordering.push_back(current.vd);
258 output.
distance[current.vd] = cost[current.vd];
259 output.
successors[current.parent].push_back(current.vd);
260 output.
parent[current.vd] = current.parent;
263 _neighbors(_g, current.vd);
264 auto vi = _g->find_vertex(current.vd);
266 auto stop = _earlyStop(vi, output);
285 for(
auto ei = vi->begin(); ei != vi->end(); ++ei) {
291 for(
const auto start: _starts) {
293 startMap.erase(std::find(startMap.begin(), startMap.end(), start));
308 template<
typename GraphType>
312 const std::vector<typename GraphType::vertex_descriptor>& _starts,
313 std::vector<typename GraphType::vertex_descriptor>& _goals,
316 auto _neighbors = SSSPDefaultNeighbors<GraphType>();
317 auto _heuristic = SSSPDefaultHeuristic<GraphType>();
319 return AStarSSSP(_g, _starts, _goals, _weight, _heuristic, _neighbors, _earlyStop);
328 template <
typename GraphType>
332 const std::vector<typename GraphType::vertex_descriptor>& _starts,
336 const double _startDistance = 0)
338 static constexpr
bool debug =
false;
339 const bool customAdjacency = !_adjacencyMap.empty();
341 std::cout <<
"DijkstraSSSP" << std::endl;
343 using VD =
typename GraphType::vertex_descriptor;
344 using EI =
typename GraphType::adj_edge_iterator;
359 element(
const VD _parent,
const VD _target,
const double _distance)
360 : parent(_parent), vd(_target), distance(_distance) {}
363 bool operator>(
const element& _e)
const noexcept {
364 return distance > _e.distance;
373 std::priority_queue<element,
374 std::vector<element>,
375 std::greater<element>> pq;
380 std::unordered_set<VD> visited;
381 std::unordered_map<VD, double> distance;
387 auto relax = [&distance, &pq, &_weight](EI& _ei) {
388 const VD source = _ei->source(),
389 target = _ei->target();
391 const double sourceDistance = distance[source],
392 targetDistance = distance.count(target)
394 : std::numeric_limits<double>::infinity(),
395 newDistance = _weight(_ei, sourceDistance, targetDistance);
398 if(newDistance >= targetDistance)
402 distance[target] = newDistance;
403 pq.emplace(source, target, newDistance);
407 for(
const auto start : _starts) {
408 distance[start] = _startDistance;
409 pq.emplace(start, start, 0);
415 element current = pq.top();
419 if(visited.count(current.vd))
421 visited.insert(current.vd);
424 output.
ordering.push_back(current.vd);
425 output.
distance[current.vd] = distance[current.vd];
426 output.
successors[current.parent].push_back(current.vd);
427 output.
parent[current.vd] = current.parent;
430 auto vi = _g->find_vertex(current.vd);
431 auto stop = _earlyStop(vi, output);
434 std::cout <<
"\tVertex: " << current.vd
435 <<
", parent: " << current.parent
436 <<
", score: " << std::setprecision(4) << distance[current.vd]
437 <<
", stop: " << stop
451 for(
auto ei = vi->begin(); ei != vi->end(); ++ei) {
456 else if(_adjacencyMap.count(current.vd)) {
457 const auto& neighbors = _adjacencyMap.at(current.vd);
458 auto iter = std::find(neighbors.begin(), neighbors.end(), ei->target());
459 if(iter != neighbors.end())
466 for(
const auto start : _starts) {
468 startMap.erase(std::find(startMap.begin(), startMap.end(), start));
481 template <
typename GraphType>
485 const std::vector<typename GraphType::vertex_descriptor>& _starts,
489 auto stop = SSSPDefaultTermination<GraphType>();
491 return DijkstraSSSP(_g, _starts, _weight, stop, _adjacencyMap);
501 template <
typename GraphType>
505 const std::vector<typename GraphType::vertex_descriptor>& _starts,
509 auto weight = SSSPDefaultPathWeight<GraphType>();
511 return DijkstraSSSP(_g, _starts, weight, _stop, _adjacencyMap);
520 template <
typename GraphType>
524 const std::vector<typename GraphType::vertex_descriptor>& _starts,
527 auto weight = SSSPDefaultPathWeight<GraphType>();
528 auto stop = SSSPDefaultTermination<GraphType>();
530 return DijkstraSSSP(_g, _starts, weight, stop, _adjacencyMap);
551 template <
typename GraphType>
552 std::shared_ptr<TwoVariableSSSPNode>
555 const std::vector<typename GraphType::vertex_descriptor>& _starts,
556 std::unordered_set<size_t> _goals,
557 const double _startTime,
558 const double _minEndTime,
559 const double _lastConstraint,
560 const double _lastGoalConstraint,
563 using NodePtr = std::shared_ptr<TwoVariableSSSPNode>;
566 auto compare = [](
const NodePtr& _a,
const NodePtr& _b) {
567 return _a->m_distance > _b->m_distance;
569 std::priority_queue<NodePtr,
571 decltype(compare)> pq(compare);
574 std::unordered_set<size_t> visitedPostConstraints;
575 std::unordered_map<double, std::unordered_set<size_t>> discoveredVertices;
577 for(
const size_t vid : _starts)
580 discoveredVertices[_startTime].insert(vid);
593 const size_t vid = current->m_vid;
594 const double distance = current->m_distance;
597 const bool pastLastGoalConstraint = distance > _lastGoalConstraint;
603 if(pastLastGoalConstraint and _goals.count(vid))
606 current->m_waitTimeSteps = std::max(0., _minEndTime - distance);
611 const bool pastLastConstraint = distance > _lastConstraint;
615 if(pastLastConstraint)
618 if(visitedPostConstraints.count(vid))
621 visitedPostConstraints.insert(vid);
626 auto vit = _g->find_vertex(vid);
627 for(
auto eit = vit->begin(); eit != vit->end(); eit++)
629 const size_t target = eit->target();
635 const double bestTargetDistance = std::numeric_limits<double>::infinity();
638 const double newDistance = _weight(eit, distance, bestTargetDistance);
641 if(newDistance < bestTargetDistance and
642 !discoveredVertices[newDistance].count(target))
644 discoveredVertices[newDistance].insert(target);
std::function< SSSPTermination(typename GraphType::vertex_iterator &, const SSSPOutput< GraphType > &_sssp)> SSSPTerminationCriterion
Definition: SSSP.h:68
std::unordered_map< typename GraphType::vertex_descriptor, std::vector< typename GraphType::vertex_descriptor > > SSSPAdjacencyMap
Definition: SSSP.h:24
std::ostream & operator<<(std::ostream &_os, const SSSPTermination &_t)
Debug output for termination criteria.
Definition: SSSP.cpp:9
SSSPTermination
The possible early-termination conditions for an SSSP run.
Definition: SSSP.h:50
@ EndSearch
End the entire search process.
@ EndBranch
End the branch at this vertex and do not relax its neighbors.
@ Continue
Proceed as usual.
SSSPOutput< GraphType > DijkstraSSSP(GraphType *const _g, const std::vector< typename GraphType::vertex_descriptor > &_starts, SSSPPathWeightFunction< GraphType > &_weight, SSSPTerminationCriterion< GraphType > &_earlyStop, const SSSPAdjacencyMap< GraphType > &_adjacencyMap={}, const double _startDistance=0)
Definition: SSSP.h:330
SSSPHeuristicFunction< GraphType > SSSPDefaultHeuristic()
Definition: SSSP.h:129
SSSPTerminationCriterion< GraphType > SSSPDefaultTermination()
Definition: SSSP.h:75
std::shared_ptr< TwoVariableSSSPNode > TwoVariableDijkstraSSSP(GraphType *const _g, const std::vector< typename GraphType::vertex_descriptor > &_starts, std::unordered_set< size_t > _goals, const double _startTime, const double _minEndTime, const double _lastConstraint, const double _lastGoalConstraint, SSSPPathWeightFunction< GraphType > &_weight)
Definition: SSSP.h:553
SSSPOutput< GraphType > AStarSSSP(GraphType *const _g, const std::vector< typename GraphType::vertex_descriptor > &_starts, std::vector< typename GraphType::vertex_descriptor > &_goals, SSSPPathWeightFunction< GraphType > &_weight, SSSPHeuristicFunction< GraphType > &_heuristic, SSSPNeighborsFunction< GraphType > &_neighbors, SSSPTerminationCriterion< GraphType > &_earlyStop, const double _startDistance=0)
Definition: SSSP.h:172
SSSPNeighborsFunction< GraphType > SSSPDefaultNeighbors()
Definition: SSSP.h:154
SSSPPathWeightFunction< GraphType > SSSPDefaultPathWeight()
Definition: SSSP.h:102
std::function< void(GraphType *g, typename GraphType::vertex_descriptor vd)> SSSPNeighborsFunction
Definition: SSSP.h:148
std::function< double(const GraphType *g, typename GraphType::vertex_descriptor source, typename GraphType::vertex_descriptor target)> SSSPHeuristicFunction
Definition: SSSP.h:123
std::function< double(typename GraphType::adj_edge_iterator &, const double, const double)> SSSPPathWeightFunction
Definition: SSSP.h:94
The output of an SSSP run.
Definition: SSSP.h:31
DistanceMap distance
Distance to each cell from start.
Definition: SSSP.h:39
std::unordered_map< VD, VD > ParentMap
Definition: SSSP.h:37
GraphType::vertex_descriptor VD
Definition: SSSP.h:33
std::unordered_map< VD, double > DistanceMap
Definition: SSSP.h:34
Adjacency successors
Maps predecessor -> successors.
Definition: SSSP.h:41
SSSPAdjacencyMap< GraphType > Adjacency
Definition: SSSP.h:36
Ordering ordering
Cell discovery ordering.
Definition: SSSP.h:40
ParentMap parent
Maps successor -> parent.
Definition: SSSP.h:42
std::vector< VD > Ordering
Definition: SSSP.h:35
std::shared_ptr< TwoVariableSSSPNode > m_parent
Definition: SSSP.h:543
double m_distance
Definition: SSSP.h:542
double m_waitTimeSteps
Definition: SSSP.h:544
TwoVariableSSSPNode(size_t _vid, double _distance, std::shared_ptr< TwoVariableSSSPNode > _parent)
Definition: SSSP.h:546
size_t m_vid
Definition: SSSP.h:541