andres::graph
shortest-paths.hxx
1 #pragma once
2 #ifndef ANDRES_GRAPH_SHORTEST_PATHS_HXX
3 #define ANDRES_GRAPH_SHORTEST_PATHS_HXX
4 
5 #include <cstddef>
6 #include <limits> // std::numeric_limits
7 #include <deque>
8 #include <queue>
9 #include <vector>
10 #include <algorithm> // std::reverse
11 
12 #include "subgraph.hxx" // DefaultSubgraphMask
13 #include "edge-value.hxx" // UnitEdgeValueIterator
14 
15 namespace andres {
16 namespace graph {
17 
18 template<class GRAPH>
19 bool
20 spsp(
21  const GRAPH&,
22  const std::size_t,
23  const std::size_t,
24  std::deque<std::size_t>&,
25  std::vector<std::ptrdiff_t>&
26 );
27 
28 template<class GRAPH>
29 bool
30 spsp(
31  const GRAPH&,
32  const std::size_t,
33  const std::size_t,
34  std::deque<std::size_t>&
35 );
36 
37 template<class GRAPH, class SUBGRAPH_MASK>
38 bool
39 spsp(
40  const GRAPH&,
41  const SUBGRAPH_MASK&,
42  const std::size_t,
43  const std::size_t,
44  std::deque<std::size_t>&
45 );
46 
47 template<class GRAPH, class SUBGRAPH_MASK>
48 bool
49 spsp(
50  const GRAPH&,
51  const SUBGRAPH_MASK&,
52  const std::size_t,
53  const std::size_t,
54  std::deque<std::size_t>&,
55  std::vector<std::ptrdiff_t>&
56 );
57 
58 template<
59  class GRAPH,
60  class EDGE_VALUE_ITERATOR,
61  class T
62 >
63 void
64 spsp(
65  const GRAPH&,
66  const std::size_t,
67  const std::size_t,
68  EDGE_VALUE_ITERATOR,
69  std::deque<std::size_t>&,
70  T&
71 );
72 
73 template<
74  class GRAPH,
75  class SUBGRAPH_MASK,
76  class EDGE_VALUE_ITERATOR,
77  class T
78 >
79 void
80 spsp(
81  const GRAPH&,
82  const SUBGRAPH_MASK&,
83  const std::size_t,
84  const std::size_t,
85  EDGE_VALUE_ITERATOR,
86  std::deque<std::size_t>&,
87  T&
88 );
89 
90 template<class GRAPH, class DISTANCE_ITERATOR>
91 void
92 sssp(
93  const GRAPH&,
94  const std::size_t,
95  DISTANCE_ITERATOR
96 );
97 
98 template<class GRAPH, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
99 void
100 sssp(
101  const GRAPH&,
102  const std::size_t,
103  DISTANCE_ITERATOR,
104  PARENT_ITERATOR
105 );
106 
107 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR>
108 void
109 sssp(
110  const GRAPH&,
111  const SUBGRAPH_MASK&,
112  const std::size_t,
113  DISTANCE_ITERATOR
114 );
115 
116 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
117 void
118 sssp(
119  const GRAPH&,
120  const SUBGRAPH_MASK&,
121  const std::size_t,
122  DISTANCE_ITERATOR,
123  PARENT_ITERATOR
124 );
125 
126 template<class GRAPH, class EDGE_VALUE_ITERATOR, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
127 void
128 sssp(
129  const GRAPH&,
130  const std::size_t,
131  const EDGE_VALUE_ITERATOR,
132  DISTANCE_ITERATOR,
133  PARENT_ITERATOR
134 );
135 
136 template<
137  class GRAPH,
138  class SUBGRAPH_MASK,
139  class EDGE_VALUE_ITERATOR,
140  class DISTANCE_ITERATOR,
141  class PARENT_ITERATOR
142 >
143 void
144 sssp(
145  const GRAPH&,
146  const SUBGRAPH_MASK&,
147  const std::size_t,
148  const EDGE_VALUE_ITERATOR,
149  DISTANCE_ITERATOR,
150  PARENT_ITERATOR
151 );
152 
153 template<
154  class GRAPH,
155  class SUBGRAPH_MASK,
156  class EDGE_VALUE_ITERATOR,
157  class DISTANCE_ITERATOR,
158  class PARENT_ITERATOR,
159  class VISITOR
160 >
161 void
162 sssp(
163  const GRAPH&,
164  const SUBGRAPH_MASK&,
165  const std::size_t,
166  const EDGE_VALUE_ITERATOR,
167  DISTANCE_ITERATOR,
168  PARENT_ITERATOR,
169  VISITOR&
170 );
171 
172 template<
173  class GRAPH,
174  class SUBGRAPH_MASK,
175  class EDGE_VALUE_ITERATOR,
176  class T,
177  class DISTANCE_ITERATOR,
178  class PARENT_ITERATOR
179 >
180 void
181 spsp(
182  const GRAPH&,
183  const SUBGRAPH_MASK&,
184  const std::size_t,
185  const std::size_t,
186  EDGE_VALUE_ITERATOR,
187  std::deque<std::size_t>&,
188  T&,
189  DISTANCE_ITERATOR,
190  PARENT_ITERATOR
191 );
192 
193 template<class GRAPH>
194 bool
195 spspEdges(
196  const GRAPH&,
197  const std::size_t,
198  const std::size_t,
199  std::deque<std::size_t>&,
200  std::vector<std::ptrdiff_t>&
201 );
202 
203 template<class GRAPH>
204 bool
205 spspEdges(
206  const GRAPH&,
207  const std::size_t,
208  const std::size_t,
209  std::deque<std::size_t>&
210 );
211 
212 template<class GRAPH, class SUBGRAPH_MASK>
213 bool
214 spspEdges(
215  const GRAPH&,
216  const SUBGRAPH_MASK&,
217  const std::size_t,
218  const std::size_t,
219  std::deque<std::size_t>&
220 );
221 
222 template<class GRAPH, class SUBGRAPH_MASK>
223 bool
224 spspEdges(
225  const GRAPH&,
226  const SUBGRAPH_MASK&,
227  const std::size_t,
228  const std::size_t,
229  std::deque<std::size_t>&,
230  std::vector<std::ptrdiff_t>&
231 );
232 
233 
234 template<
235 class GRAPH,
236 class EDGE_VALUE_ITERATOR,
237 class T
238 >
239 void
240 spspEdges(
241  const GRAPH&,
242  const std::size_t,
243  const std::size_t,
244  EDGE_VALUE_ITERATOR,
245  std::deque<std::size_t>&,
246  T&
247 );
248 
249 template<
250 class GRAPH,
251 class SUBGRAPH_MASK,
252 class EDGE_VALUE_ITERATOR,
253 class T
254 >
255 void
256 spspEdges(
257  const GRAPH&,
258  const SUBGRAPH_MASK&,
259  const std::size_t,
260  const std::size_t,
261  EDGE_VALUE_ITERATOR,
262  std::deque<std::size_t>&,
263  T&
264 );
265 
266 template<class GRAPH, class DISTANCE_ITERATOR>
267 void
268 ssspEdges(
269  const GRAPH&,
270  const std::size_t,
271  DISTANCE_ITERATOR
272 );
273 
274 template<class GRAPH, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
275 void
276 ssspEdges(
277  const GRAPH&,
278  const std::size_t,
279  DISTANCE_ITERATOR,
280  PARENT_ITERATOR
281 );
282 
283 template<class GRAPH, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
284 void
285 ssspEdges(
286  const GRAPH&,
287  const std::size_t,
288  DISTANCE_ITERATOR,
289  PARENT_ITERATOR,
290  PARENT_ITERATOR
291 );
292 
293 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR>
294 void
295 ssspEdges(
296  const GRAPH&,
297  const SUBGRAPH_MASK&,
298  const std::size_t,
299  DISTANCE_ITERATOR
300 );
301 
302 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
303 void
304 ssspEdges(
305  const GRAPH&,
306  const SUBGRAPH_MASK&,
307  const std::size_t,
308  DISTANCE_ITERATOR,
309  PARENT_ITERATOR
310 );
311 
312 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
313 void
314 ssspEdges(
315  const GRAPH&,
316  const SUBGRAPH_MASK&,
317  const std::size_t,
318  DISTANCE_ITERATOR,
319  PARENT_ITERATOR,
320  PARENT_ITERATOR
321 );
322 
323 template<class GRAPH, class EDGE_VALUE_ITERATOR, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
324 void
325 ssspEdges(
326  const GRAPH&,
327  const std::size_t,
328  const EDGE_VALUE_ITERATOR,
329  DISTANCE_ITERATOR,
330  PARENT_ITERATOR
331 );
332 
333 template<class GRAPH, class EDGE_VALUE_ITERATOR, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
334 void
335 ssspEdges(
336  const GRAPH&,
337  const std::size_t,
338  const EDGE_VALUE_ITERATOR,
339  DISTANCE_ITERATOR,
340  PARENT_ITERATOR,
341  PARENT_ITERATOR
342 );
343 
344 template<
345 class GRAPH,
346 class SUBGRAPH_MASK,
347 class EDGE_VALUE_ITERATOR,
348 class DISTANCE_ITERATOR,
349 class PARENT_ITERATOR
350 >
351 void
352 ssspEdges(
353  const GRAPH&,
354  const SUBGRAPH_MASK&,
355  const std::size_t,
356  const EDGE_VALUE_ITERATOR,
357  DISTANCE_ITERATOR,
358  PARENT_ITERATOR
359 );
360 
361 template<
362 class GRAPH,
363 class SUBGRAPH_MASK,
364 class EDGE_VALUE_ITERATOR,
365 class DISTANCE_ITERATOR,
366 class PARENT_ITERATOR
367 >
368 void
369 ssspEdges(
370  const GRAPH&,
371  const SUBGRAPH_MASK&,
372  const std::size_t,
373  const EDGE_VALUE_ITERATOR,
374  DISTANCE_ITERATOR,
375  PARENT_ITERATOR,
376  PARENT_ITERATOR
377 );
378 
379 template<
380 class GRAPH,
381 class SUBGRAPH_MASK,
382 class EDGE_VALUE_ITERATOR,
383 class DISTANCE_ITERATOR,
384 class PARENT_ITERATOR,
385 class VISITOR
386 >
387 void
388 ssspEdges(
389  const GRAPH&,
390  const SUBGRAPH_MASK&,
391  const std::size_t,
392  const EDGE_VALUE_ITERATOR,
393  DISTANCE_ITERATOR,
394  PARENT_ITERATOR,
395  VISITOR&
396 );
397 
398 template<
399 class GRAPH,
400 class SUBGRAPH_MASK,
401 class EDGE_VALUE_ITERATOR,
402 class T,
403 class DISTANCE_ITERATOR,
404 class PARENT_ITERATOR
405 >
406 void
407 spspEdges(
408  const GRAPH&,
409  const SUBGRAPH_MASK&,
410  const std::size_t,
411  const std::size_t,
412  EDGE_VALUE_ITERATOR,
413  std::deque<std::size_t>&,
414  T&,
415  DISTANCE_ITERATOR,
416  PARENT_ITERATOR
417 );
418 
419 // \cond SUPPRESS_DOXYGEN
420 namespace graph_detail {
421 
422 template<class T>
423 inline void
424 spspHelper(
425  const std::vector<std::ptrdiff_t>& parents,
426  const T vPositive,
427  const T vNegative,
428  std::deque<T>& path
429 ) {
430  assert(vPositive >= 0);
431  assert(vNegative >= 0);
432  T t = vPositive;
433  for(;;) {
434  path.push_front(t);
435  if(parents[t] - 1 == t) {
436  break;
437  }
438  else {
439  t = parents[t] - 1;
440  }
441  }
442  t = vNegative;
443  for(;;) {
444  path.push_back(t);
445  if(-parents[t] - 1 == t) {
446  break;
447  }
448  else {
449  t = -parents[t] - 1;
450  }
451  }
452 }
453 
454 template<class T>
455 struct DijkstraQueueEntry {
456  typedef T Value;
457 
458  DijkstraQueueEntry(const std::size_t vertex = 0, const Value distance = Value())
459  : vertex_(vertex), distance_(distance)
460  {}
461  bool operator<(const DijkstraQueueEntry<Value>& other) const
462  { return distance_ > other.distance_; }
463  bool operator==(const DijkstraQueueEntry<Value>& other) const
464  { return vertex_ == other.vertex_ && distance_ == other.distance_; }
465  bool operator!=(const DijkstraQueueEntry<Value>& other) const
466  { return vertex_ != other.vertex_ || distance_ != other.distance_; }
467 
468  std::size_t vertex_;
469  Value distance_;
470 };
471 
472 // Single source shortest path visitor for Dijkstra's algorithm.
473 template<class DISTANCE_ITERATOR, class PARENT_ITERATOR>
474 class DijkstraSPSPVisitor {
475 public:
476  typedef DISTANCE_ITERATOR Distances;
477  typedef PARENT_ITERATOR Parents;
478  typedef typename std::iterator_traits<DISTANCE_ITERATOR>::value_type Value;
479 
480  DijkstraSPSPVisitor(
481  const std::size_t vs,
482  const std::size_t vt,
483  std::deque<std::size_t>& path
484  )
485  : vs_(vs), vt_(vt), path_(path)
486  {
487  path_.clear(); // so the path will be empty if no path is found
488  }
489 
490  bool operator()(
491  Distances distances,
492  Parents parents,
493  std::size_t vertex
494  ) {
495  if(vertex == vt_) {
496  const Value infinity = std::numeric_limits<Value>::has_infinity
497  ? std::numeric_limits<Value>::infinity()
498  : std::numeric_limits<Value>::max();
499  if(distances[vertex] == infinity) {
500  path_.clear();
501  return false; // stop the algorithm
502  }
503  for(;;) {
504  path_.push_front(vertex);
505  if(vertex == vs_) {
506  return false; // stop the algorithm
507  }
508  else {
509  vertex = parents[vertex];
510  }
511  }
512  }
513  else {
514  return true; // continue with the algorithm
515  }
516  }
517 
518  bool operator()(
519  Distances distances,
520  Parents parents,
521  Parents parentsEdges,
522  std::size_t vertex
523  ) {
524  if(vertex == vt_) {
525  const Value infinity = std::numeric_limits<Value>::has_infinity
526  ? std::numeric_limits<Value>::infinity()
527  : std::numeric_limits<Value>::max();
528  if(distances[vertex] == infinity) {
529  path_.clear();
530  return false; // stop the algorithm
531  }
532  for(;;) {
533  if(vertex == vs_) {
534  return false; // stop the algorithm
535  }
536  else {
537  path_.push_front(parentsEdges[vertex]);
538  vertex = parents[vertex];
539  }
540  }
541  }
542  else {
543  return true; // continue with the algorithm
544  }
545  }
546 
547  std::size_t vs_;
548  std::size_t vt_;
549  std::deque<std::size_t>& path_;
550 };
551 
552 } // namespace graph_detail
553 // \endcond
554 
569 template<class GRAPH>
570 inline bool
572  const GRAPH& g,
573  const std::size_t vs,
574  const std::size_t vt,
575  std::deque<std::size_t>& path,
576  std::vector<std::ptrdiff_t>& parents
577 ) {
578  return spsp(g, DefaultSubgraphMask<>(), vs, vt, path, parents);
579 }
580 
581 template<class GRAPH>
582 inline bool
584  const GRAPH& g,
585  const std::size_t vs,
586  const std::size_t vt,
587  std::deque<std::size_t>& path
588 ) {
589  std::vector<std::ptrdiff_t> parents = std::vector<std::ptrdiff_t>();
590  return spsp(g, DefaultSubgraphMask<>(), vs, vt, path, parents);
591 }
592 
607 template<class GRAPH, class SUBGRAPH_MASK>
608 bool
610  const GRAPH& g,
611  const SUBGRAPH_MASK& mask,
612  const std::size_t vs,
613  const std::size_t vt,
614  std::deque<std::size_t>& path
615 ) {
616 
617  std::vector<std::ptrdiff_t> parents = std::vector<std::ptrdiff_t>();
618  return spsp(g, mask, vs, vt, path, parents);
619 
620 }
621 
637 template<class GRAPH, class SUBGRAPH_MASK>
638 bool
640  const GRAPH& g,
641  const SUBGRAPH_MASK& mask,
642  const std::size_t vs,
643  const std::size_t vt,
644  std::deque<std::size_t>& path,
645  std::vector<std::ptrdiff_t>& parents// = std::vector<std::ptrdiff_t>()
646 ) {
647  path.clear();
648  if(!mask.vertex(vs) || !mask.vertex(vt)) {
649  return false;
650  }
651  if(vs == vt) {
652  path.push_back(vs);
653  return true;
654  }
655  parents.resize(g.numberOfVertices());
656  std::fill(parents.begin(), parents.end(), 0);
657  parents[vs] = vs + 1;
658  parents[vt] = -static_cast<std::ptrdiff_t>(vt) - 1;
659  std::queue<std::size_t> queues[2];
660  queues[0].push(vs);
661  queues[1].push(vt);
662  for(std::size_t q = 0; true; q = 1 - q) { // infinite loop, alternating queues
663  const std::size_t numberOfNodesAtFront = queues[q].size();
664  for(std::size_t n = 0; n < numberOfNodesAtFront; ++n) {
665  const std::size_t v = queues[q].front();
666  queues[q].pop();
667  typename GRAPH::AdjacencyIterator it;
668  typename GRAPH::AdjacencyIterator end;
669  if(q == 0) {
670  it = g.adjacenciesFromVertexBegin(v);
671  end = g.adjacenciesFromVertexEnd(v);
672  }
673  else {
674  it = g.adjacenciesToVertexBegin(v);
675  end = g.adjacenciesToVertexEnd(v);
676  }
677  for(; it != end; ++it) {
678  if(!mask.edge(it->edge()) || !mask.vertex(it->vertex())) {
679  continue;
680  }
681  if(parents[it->vertex()] < 0 && q == 0) {
682  graph_detail::spspHelper(parents, v, it->vertex(), path);
683  assert(path[0] == vs);
684  assert(path.back() == vt);
685  return true;
686  }
687  else if(parents[it->vertex()] > 0 && q == 1) {
688  graph_detail::spspHelper(parents, it->vertex(), v, path);
689  assert(path[0] == vs);
690  assert(path.back() == vt);
691  return true;
692  }
693  else if(parents[it->vertex()] == 0) {
694  if(q == 0) {
695  parents[it->vertex()] = v + 1;
696  }
697  else {
698  parents[it->vertex()] = -static_cast<std::ptrdiff_t>(v) - 1;
699  }
700  queues[q].push(it->vertex());
701  }
702  }
703  }
704  if(queues[0].empty() && queues[1].empty()) {
705  return false;
706  }
707  }
708 }
709 
721 template<
722  class GRAPH,
723  class EDGE_VALUE_ITERATOR,
724  class T
725 >
726 inline void
728  const GRAPH& g,
729  const std::size_t vs,
730  const std::size_t vt,
731  EDGE_VALUE_ITERATOR edgeWeights,
732  std::deque<std::size_t>& path,
733  T& distance
734 ) {
735  std::vector<T> distances(g.numberOfVertices());
736  std::vector<std::size_t> parents(g.numberOfVertices());
737  spsp(g, DefaultSubgraphMask<>(), vs, vt, edgeWeights, path, distance,
738  distances.begin(), parents.begin()
739  );
740 }
741 
754 template<
755  class GRAPH,
756  class SUBGRAPH_MASK,
757  class EDGE_VALUE_ITERATOR,
758  class T
759 >
760 inline void
762  const GRAPH& g,
763  const SUBGRAPH_MASK& mask,
764  const std::size_t vs,
765  const std::size_t vt,
766  EDGE_VALUE_ITERATOR edgeWeights,
767  std::deque<std::size_t>& path,
768  T& distance
769 ) {
770  std::vector<T> distances(g.numberOfVertices());
771  std::vector<std::size_t> parents(g.numberOfVertices());
772  spsp(g, mask, vs, vt, edgeWeights, path, distance,
773  distances.begin(), parents.begin()
774  );
775 }
776 
783 template<class GRAPH, class DISTANCE_ITERATOR>
784 inline void
786  const GRAPH& g,
787  const std::size_t vs,
788  DISTANCE_ITERATOR distances
789 ) {
790  std::vector<std::size_t> parents(g.numberOfVertices());
791  sssp(g, vs, distances, parents.begin());
792 }
793 
801 template<class GRAPH, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
802 inline void
804  const GRAPH& g,
805  const std::size_t vs,
806  DISTANCE_ITERATOR distances,
807  PARENT_ITERATOR parents
808 ) {
809  typedef typename std::iterator_traits<DISTANCE_ITERATOR>::value_type Value;
811  distances, parents
812  );
813 }
814 
822 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR>
823 inline void
825  const GRAPH& g,
826  const SUBGRAPH_MASK& mask,
827  const std::size_t vs,
828  DISTANCE_ITERATOR distances
829 ) {
830  std::vector<std::size_t> parents(g.numberOfVertices());
831  sssp(g, mask, vs, distances, parents.begin());
832 }
833 
842 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
843 inline void
845  const GRAPH& g,
846  const SUBGRAPH_MASK& mask,
847  const std::size_t vs,
848  DISTANCE_ITERATOR distances,
849  PARENT_ITERATOR parents
850 ) {
851  typedef typename std::iterator_traits<DISTANCE_ITERATOR>::value_type Value;
852  sssp(g, mask, vs, UnitEdgeValueIterator<Value>(), distances, parents);
853 }
854 
863 template<class GRAPH, class EDGE_VALUE_ITERATOR, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
864 inline void
866  const GRAPH& g,
867  const std::size_t vs,
868  const EDGE_VALUE_ITERATOR edgeWeights,
869  DISTANCE_ITERATOR distances,
870  PARENT_ITERATOR parents
871 ) {
872  sssp(g, DefaultSubgraphMask<>(), vs, edgeWeights, distances, parents);
873 }
874 
877 template<class DISTANCE_ITERATOR, class PARENT_ITERATOR>
879  typedef DISTANCE_ITERATOR Distances;
880  typedef PARENT_ITERATOR Parents;
881 
882  bool operator()(Distances, Parents, const std::size_t) const
883  { return true; /* continue with the algorithm */ }
884  bool operator()(Distances, Parents, Parents, const std::size_t) const
885  { return true; /* continue with the algorithm */ }
886 };
887 
897 template<
898  class GRAPH,
899  class SUBGRAPH_MASK,
900  class EDGE_VALUE_ITERATOR,
901  class DISTANCE_ITERATOR,
902  class PARENT_ITERATOR
903 >
904 inline void
906  const GRAPH& g,
907  const SUBGRAPH_MASK& mask,
908  const std::size_t vs,
909  const EDGE_VALUE_ITERATOR edgeWeights,
910  DISTANCE_ITERATOR distances,
911  PARENT_ITERATOR parents
912 ) {
914  Visitor visitor;
915  sssp<GRAPH, SUBGRAPH_MASK, EDGE_VALUE_ITERATOR, DISTANCE_ITERATOR, PARENT_ITERATOR, Visitor>(
916  g, mask, vs, edgeWeights, distances, parents, visitor
917  );
918 }
919 
930 template<
931  class GRAPH,
932  class SUBGRAPH_MASK,
933  class EDGE_VALUE_ITERATOR,
934  class DISTANCE_ITERATOR,
935  class PARENT_ITERATOR,
936  class VISITOR
937 >
938 void
940  const GRAPH& g,
941  const SUBGRAPH_MASK& mask,
942  const std::size_t vs,
943  const EDGE_VALUE_ITERATOR edgeWeights,
944  DISTANCE_ITERATOR distances,
945  PARENT_ITERATOR parents,
946  VISITOR& visitor
947 ) {
948  typedef typename std::iterator_traits<DISTANCE_ITERATOR>::value_type Value;
949  typedef typename graph_detail::DijkstraQueueEntry<Value> Entry;
950 
951  assert(mask.vertex(vs));
952  const Value infinity = std::numeric_limits<Value>::has_infinity
953  ? std::numeric_limits<Value>::infinity()
954  : std::numeric_limits<Value>::max();
955  std::priority_queue<Entry> queue;
956  queue.push(vs);
957  for(std::size_t v = 0; v < g.numberOfVertices(); ++v) {
958  distances[v] = infinity;
959  if(mask.vertex(v)) {
960  queue.push(Entry(v, infinity));
961  }
962  }
963  distances[vs] = 0;
964  while(!queue.empty()) {
965  const std::size_t v = queue.top().vertex_;
966  const bool proceed = visitor(distances, parents, v);
967  if(!proceed) {
968  return;
969  }
970  queue.pop();
971  if(distances[v] == infinity) {
972  return;
973  }
974  for(typename GRAPH::AdjacencyIterator it = g.adjacenciesFromVertexBegin(v);
975  it != g.adjacenciesFromVertexEnd(v); ++it) {
976  if(mask.vertex(it->vertex()) && mask.edge(it->edge())) {
977  const Value alternativeDistance = distances[v] + edgeWeights[it->edge()];
978  if(alternativeDistance < distances[it->vertex()]) {
979  distances[it->vertex()] = alternativeDistance;
980  parents[it->vertex()] = v;
981  queue.push(Entry(it->vertex(), alternativeDistance));
982  // pushing v another time, not worring about existing entries
983  // v in the queue at deprecated positions.
984  // alternatively, one could use a heap from which elements
985  // can be removed. this is beneficial for dense graphs in
986  // which many weights are equal.
987  }
988  }
989  }
990  }
991 }
992 
1007 template<
1008  class GRAPH,
1009  class SUBGRAPH_MASK,
1010  class EDGE_VALUE_ITERATOR,
1011  class T,
1012  class DISTANCE_ITERATOR,
1013  class PARENT_ITERATOR
1014 >
1015 inline void
1017  const GRAPH& g,
1018  const SUBGRAPH_MASK& mask,
1019  const std::size_t vs,
1020  const std::size_t vt,
1021  EDGE_VALUE_ITERATOR edgeWeights,
1022  std::deque<std::size_t>& path,
1023  T& distance,
1024  DISTANCE_ITERATOR distances,
1025  PARENT_ITERATOR parents
1026 ) {
1027  typedef graph_detail::DijkstraSPSPVisitor<DISTANCE_ITERATOR, PARENT_ITERATOR> Visitor;
1028  Visitor visitor(vs, vt, path);
1029  sssp<GRAPH, SUBGRAPH_MASK, EDGE_VALUE_ITERATOR, DISTANCE_ITERATOR, PARENT_ITERATOR, Visitor>(
1030  g, mask, vs, edgeWeights, distances, parents, visitor
1031  );
1032  distance = distances[vt];
1033 }
1034 
1035 // edge output versions below.
1036 
1051 template<class GRAPH>
1052 inline bool
1054  const GRAPH& g,
1055  const std::size_t vs,
1056  const std::size_t vt,
1057  std::deque<std::size_t>& path,
1058  std::vector<std::ptrdiff_t>& parents
1059 ) {
1060  return spspEdges(g, DefaultSubgraphMask<>(), vs, vt, path, parents);
1061 }
1062 
1063 template<class GRAPH>
1064 inline bool
1066  const GRAPH& g,
1067  const std::size_t vs,
1068  const std::size_t vt,
1069  std::deque<std::size_t>& path
1070 ) {
1071  std::vector<std::ptrdiff_t> parents = std::vector<std::ptrdiff_t>();
1072  return spspEdges(g, DefaultSubgraphMask<>(), vs, vt, path, parents);
1073 }
1074 
1089 template<class GRAPH, class SUBGRAPH_MASK>
1090 inline bool
1092  const GRAPH& g,
1093  const SUBGRAPH_MASK& mask,
1094  const std::size_t vs,
1095  const std::size_t vt,
1096  std::deque<std::size_t>& path
1097 ) {
1098  std::vector<std::ptrdiff_t> parents = std::vector<std::ptrdiff_t>();
1099  return spspEdges(g, mask, vs, vt, path, parents);
1100 }
1101 
1117 template<class GRAPH, class SUBGRAPH_MASK>
1118 bool
1120  const GRAPH& g,
1121  const SUBGRAPH_MASK& mask,
1122  const std::size_t vs,
1123  const std::size_t vt,
1124  std::deque<std::size_t>& path, // sequence of edges
1125  std::vector<std::ptrdiff_t>& parents // sequence of edges
1126 ) {
1127  path.clear();
1128  if(!mask.vertex(vs) || !mask.vertex(vt)) {
1129  return false;
1130  }
1131  if(vs == vt) {
1132  return true;
1133  }
1134  for (typename GRAPH::AdjacencyIterator i = g.adjacenciesFromVertexBegin(vs); i < g.adjacenciesFromVertexEnd(vs) ; ++i) {
1135  if (i->vertex() == vt && mask.edge(i->edge())) {
1136  path.push_front(i->edge());
1137  return true;
1138  }
1139  }
1140  parents.resize(g.numberOfEdges());
1141  std::fill(parents.begin(), parents.end(), 0);
1142  std::queue<std::size_t> queues[2];
1143  for (typename GRAPH::AdjacencyIterator i = g.adjacenciesFromVertexBegin(vs); i < g.adjacenciesFromVertexEnd(vs) ; ++i) {
1144  if (mask.edge(i->edge()) && mask.vertex(i->vertex())) {
1145  queues[0].push(i->edge());
1146  parents[i->edge()] = i->edge() + 1;
1147  }
1148  }
1149  for (typename GRAPH::AdjacencyIterator i = g.adjacenciesToVertexBegin(vt); i < g.adjacenciesToVertexEnd(vt) ; ++i) {
1150  if (mask.edge(i->edge()) && mask.vertex(i->vertex())) {
1151  queues[1].push(i->edge());
1152  parents[i->edge()] = -static_cast<std::ptrdiff_t>(i->edge()) - 1;
1153  }
1154  }
1155  for(std::size_t q = 0; true; q = 1 - q) { // infinite loop, alternating queues
1156  const std::size_t numberOfEdgesAtFront = queues[q].size();
1157  for(std::size_t n = 0; n < numberOfEdgesAtFront; ++n) {
1158  const std::size_t e = queues[q].front();
1159  queues[q].pop();
1160  typename GRAPH::AdjacencyIterator it;
1161  typename GRAPH::AdjacencyIterator end;
1162  if(q == 0) {
1163  it = g.adjacenciesFromVertexBegin(g.vertexOfEdge(e, 1));
1164  end = g.adjacenciesFromVertexEnd(g.vertexOfEdge(e, 1));
1165  }
1166  else {
1167  it = g.adjacenciesToVertexBegin(g.vertexOfEdge(e, 0));
1168  end = g.adjacenciesToVertexEnd(g.vertexOfEdge(e, 0));
1169  }
1170  for(; it != end; ++it) {
1171  if(!mask.edge(it->edge()) || !mask.vertex(it->vertex())) {
1172  continue;
1173  }
1174  if(parents[it->edge()] < 0 && q == 0) {
1175  graph_detail::spspHelper(parents, e, it->edge(), path);
1176  return true;
1177  }
1178  else if(parents[it->edge()] > 0 && q == 1) {
1179  graph_detail::spspHelper(parents, it->edge(), e, path);
1180  return true;
1181  }
1182  else if(parents[it->edge()] == 0) {
1183  if(q == 0) {
1184  parents[it->edge()] = e + 1;
1185  }
1186  else {
1187  parents[it->edge()] = -static_cast<std::ptrdiff_t>(e) - 1;
1188  }
1189  queues[q].push(it->edge());
1190  }
1191  }
1192  }
1193  if(queues[0].empty() && queues[1].empty()) {
1194  return false;
1195  }
1196  }
1197 }
1198 
1210 template<
1211 class GRAPH,
1212 class EDGE_VALUE_ITERATOR,
1213 class T
1214 >
1215 inline void
1217  const GRAPH& g,
1218  const std::size_t vs,
1219  const std::size_t vt,
1220  EDGE_VALUE_ITERATOR edgeWeights,
1221  std::deque<std::size_t>& path,
1222  T& distance
1223 ) {
1224  std::vector<T> distances(g.numberOfVertices());
1225  std::vector<std::size_t> parents(g.numberOfVertices());
1226  std::vector<std::size_t> parentsEdges(g.numberOfVertices());
1227  spspEdges(g, DefaultSubgraphMask<>(), vs, vt, edgeWeights, path, distance,
1228  distances.begin(), parents.begin(), parentsEdges.begin());
1229 }
1230 
1243 template<
1244 class GRAPH,
1245 class SUBGRAPH_MASK,
1246 class EDGE_VALUE_ITERATOR,
1247 class T
1248 >
1249 inline void
1251  const GRAPH& g,
1252  const SUBGRAPH_MASK& mask,
1253  const std::size_t vs,
1254  const std::size_t vt,
1255  EDGE_VALUE_ITERATOR edgeWeights,
1256  std::deque<std::size_t>& path,
1257  T& distance
1258 ) {
1259  std::vector<T> distances(g.numberOfVertices());
1260  std::vector<std::size_t> parents(g.numberOfVertices());
1261  std::vector<std::size_t> parentsEdges(g.numberOfVertices());
1262  spspEdges(g, mask, vs, vt, edgeWeights, path, distance,
1263  distances.begin(), parents.begin(), parentsEdges.begin());
1264 }
1265 
1272 template<class GRAPH, class DISTANCE_ITERATOR>
1273 inline void
1275  const GRAPH& g,
1276  const std::size_t vs,
1277  DISTANCE_ITERATOR distances
1278 ) {
1279  std::vector<std::size_t> parents(g.numberOfVertices());
1280  ssspEdges(g, vs, distances, parents.begin());
1281 }
1282 
1290 template<class GRAPH, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
1291 inline void
1293  const GRAPH& g,
1294  const std::size_t vs,
1295  DISTANCE_ITERATOR distances,
1296  PARENT_ITERATOR parents
1297 ) {
1298  typedef typename std::iterator_traits<DISTANCE_ITERATOR>::value_type Value;
1299  std::vector<std::size_t> parentsEdges(g.numberOfVertices());
1301  distances, parents, parentsEdges.begin());
1302 }
1303 
1312 template<class GRAPH, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
1313 inline void
1315  const GRAPH& g,
1316  const std::size_t vs,
1317  DISTANCE_ITERATOR distances,
1318  PARENT_ITERATOR parents,
1319  PARENT_ITERATOR parentsEdges
1320 ) {
1321  typedef typename std::iterator_traits<DISTANCE_ITERATOR>::value_type Value;
1323  distances, parents, parentsEdges);
1324 }
1325 
1333 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR>
1334 inline void
1336  const GRAPH& g,
1337  const SUBGRAPH_MASK& mask,
1338  const std::size_t vs,
1339  DISTANCE_ITERATOR distances
1340 ) {
1341  std::vector<std::size_t> parents(g.numberOfVertices());
1342  ssspEdges(g, mask, vs, distances, parents.begin());
1343 }
1344 
1353 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
1354 inline void
1356  const GRAPH& g,
1357  const SUBGRAPH_MASK& mask,
1358  const std::size_t vs,
1359  DISTANCE_ITERATOR distances,
1360  PARENT_ITERATOR parents
1361 ) {
1362  typedef typename std::iterator_traits<DISTANCE_ITERATOR>::value_type Value;
1363  std::vector<std::size_t> parentsEdges(g.numberOfVertices());
1364  ssspEdges(g, mask, vs, UnitEdgeValueIterator<Value>(), distances, parentsEdges.begin());
1365 }
1366 
1376 template<class GRAPH, class SUBGRAPH_MASK, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
1377 inline void
1379  const GRAPH& g,
1380  const SUBGRAPH_MASK& mask,
1381  const std::size_t vs,
1382  DISTANCE_ITERATOR distances,
1383  PARENT_ITERATOR parents,
1384  PARENT_ITERATOR parentsEdges
1385 ) {
1386  typedef typename std::iterator_traits<DISTANCE_ITERATOR>::value_type Value;
1387  ssspEdges(g, mask, vs, UnitEdgeValueIterator<Value>(), distances, parents, parentsEdges);
1388 }
1389 
1398 template<class GRAPH, class EDGE_VALUE_ITERATOR, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
1399 inline void
1401  const GRAPH& g,
1402  const std::size_t vs,
1403  const EDGE_VALUE_ITERATOR edgeWeights,
1404  DISTANCE_ITERATOR distances,
1405  PARENT_ITERATOR parents
1406 ) {
1407  ssspEdges(g, DefaultSubgraphMask<>(), vs, edgeWeights, distances, parents);
1408 }
1409 
1419 template<class GRAPH, class EDGE_VALUE_ITERATOR, class DISTANCE_ITERATOR, class PARENT_ITERATOR>
1420 inline void
1422  const GRAPH& g,
1423  const std::size_t vs,
1424  const EDGE_VALUE_ITERATOR edgeWeights,
1425  DISTANCE_ITERATOR distances,
1426  PARENT_ITERATOR parents,
1427  PARENT_ITERATOR parentsEdges
1428 ) {
1429  ssspEdges(g, DefaultSubgraphMask<>(), vs, edgeWeights, distances, parents, parentsEdges);
1430 }
1431 
1441 template<
1442 class GRAPH,
1443 class SUBGRAPH_MASK,
1444 class EDGE_VALUE_ITERATOR,
1445 class DISTANCE_ITERATOR,
1446 class PARENT_ITERATOR
1447 >
1448 inline void
1450  const GRAPH& g,
1451  const SUBGRAPH_MASK& mask,
1452  const std::size_t vs,
1453  const EDGE_VALUE_ITERATOR edgeWeights,
1454  DISTANCE_ITERATOR distances,
1455  PARENT_ITERATOR parents
1456 ) {
1458  Visitor visitor;
1459  std::vector<std::size_t> parentsEdges(g.numberOfVertices());
1460  ssspEdges<GRAPH, SUBGRAPH_MASK, EDGE_VALUE_ITERATOR, DISTANCE_ITERATOR, PARENT_ITERATOR, Visitor>(g, mask, vs, edgeWeights, distances, parents, parentsEdges.begin(), visitor);
1461 }
1462 
1473 template<
1474 class GRAPH,
1475 class SUBGRAPH_MASK,
1476 class EDGE_VALUE_ITERATOR,
1477 class DISTANCE_ITERATOR,
1478 class PARENT_ITERATOR
1479 >
1480 inline void
1482  const GRAPH& g,
1483  const SUBGRAPH_MASK& mask,
1484  const std::size_t vs,
1485  const EDGE_VALUE_ITERATOR edgeWeights,
1486  DISTANCE_ITERATOR distances,
1487  PARENT_ITERATOR parents,
1488  PARENT_ITERATOR parentsEdges
1489 ) {
1491  Visitor visitor;
1492  ssspEdges<GRAPH, SUBGRAPH_MASK, EDGE_VALUE_ITERATOR, DISTANCE_ITERATOR, PARENT_ITERATOR, Visitor>(
1493  g, mask, vs, edgeWeights, distances, parents, parentsEdges, visitor);
1494 }
1495 
1507 template<
1508 class GRAPH,
1509 class SUBGRAPH_MASK,
1510 class EDGE_VALUE_ITERATOR,
1511 class DISTANCE_ITERATOR,
1512 class PARENT_ITERATOR,
1513 class VISITOR
1514 >
1515 void
1517  const GRAPH& g,
1518  const SUBGRAPH_MASK& mask,
1519  const std::size_t vs,
1520  const EDGE_VALUE_ITERATOR edgeWeights,
1521  DISTANCE_ITERATOR distances,
1522  PARENT_ITERATOR parents,
1523  PARENT_ITERATOR parentsEdges,
1524  VISITOR& visitor
1525 ) {
1526  typedef typename std::iterator_traits<DISTANCE_ITERATOR>::value_type Value;
1527  typedef typename graph_detail::DijkstraQueueEntry<Value> Entry;
1528 
1529  assert(mask.vertex(vs));
1530  const Value infinity = std::numeric_limits<Value>::has_infinity
1531  ? std::numeric_limits<Value>::infinity()
1532  : std::numeric_limits<Value>::max();
1533  std::priority_queue<Entry> queue;
1534  queue.push(vs);
1535  for(std::size_t v = 0; v < g.numberOfVertices(); ++v) {
1536  distances[v] = infinity;
1537  if(mask.vertex(v)) {
1538  queue.push(Entry(v, infinity));
1539  }
1540  }
1541  distances[vs] = 0;
1542  while(!queue.empty()) {
1543  const std::size_t v = queue.top().vertex_;
1544  const bool proceed = visitor(distances, parents, parentsEdges, v);
1545  if(!proceed) {
1546  // return;
1547  break;
1548  }
1549  queue.pop();
1550  if(distances[v] == infinity) {
1551  // return;
1552  break;
1553  }
1554  for(typename GRAPH::AdjacencyIterator it = g.adjacenciesFromVertexBegin(v);
1555  it != g.adjacenciesFromVertexEnd(v); ++it) {
1556  if(mask.vertex(it->vertex()) && mask.edge(it->edge())) {
1557  const Value alternativeDistance = distances[v] + edgeWeights[it->edge()];
1558  if(alternativeDistance < distances[it->vertex()]) {
1559  distances[it->vertex()] = alternativeDistance;
1560  parentsEdges[it->vertex()] = it->edge();
1561  parents[it->vertex()] = v;
1562  queue.push(Entry(it->vertex(), alternativeDistance));
1563  // pushing v another time, not worring about existing entries
1564  // v in the queue at deprecated positions.
1565  // alternatively, one could use a heap from which elements
1566  // can be removed. this is beneficial for dense graphs in
1567  // which many weights are equal.
1568  }
1569  }
1570  }
1571  }
1572 }
1573 
1589 template<
1590 class GRAPH,
1591 class SUBGRAPH_MASK,
1592 class EDGE_VALUE_ITERATOR,
1593 class T,
1594 class DISTANCE_ITERATOR,
1595 class PARENT_ITERATOR
1596 >
1597 inline void
1599  const GRAPH& g,
1600  const SUBGRAPH_MASK& mask,
1601  const std::size_t vs,
1602  const std::size_t vt,
1603  EDGE_VALUE_ITERATOR edgeWeights,
1604  std::deque<std::size_t>& path,
1605  T& distance,
1606  DISTANCE_ITERATOR distances,
1607  PARENT_ITERATOR parents,
1608  PARENT_ITERATOR parentsEdges
1609 )
1610 {
1611  typedef graph_detail::DijkstraSPSPVisitor<DISTANCE_ITERATOR, PARENT_ITERATOR> Visitor;
1612  Visitor visitor(vs, vt, path);
1613  ssspEdges<GRAPH, SUBGRAPH_MASK, EDGE_VALUE_ITERATOR, DISTANCE_ITERATOR, PARENT_ITERATOR, Visitor>(g, mask, vs, edgeWeights, distances, parents, parentsEdges, visitor);
1614  distance = distances[vt];
1615 }
1616 
1617 } // namespace graph
1618 } // namespace andres
1619 
1620 #endif // #ifndef ANDRES_GRAPH_SHORTEST_PATHS_HXX