Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Dijkstra.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/EpsilonTest.h>
35 #include <ogdf/basic/Graph.h>
36 #include <ogdf/basic/GraphList.h>
37 #include <ogdf/basic/List.h>
39 #include <ogdf/basic/basic.h>
41 
42 #include <functional>
43 #include <limits>
44 
45 namespace ogdf {
46 
59 template<typename T, template<typename P, class C> class H = PairingHeap>
60 class Dijkstra {
61 protected:
63 
64 public:
67 
77  void callUnbound(const Graph& G, const EdgeArray<T>& weight, const List<node>& sources,
78  NodeArray<edge>& predecessor, NodeArray<T>& distance, bool directed = false,
79  bool arcsReversed = false) {
81  distance.init(G, std::numeric_limits<T>::max());
82  predecessor.init(G, nullptr);
83 
84 #ifdef OGDF_DEBUG
85  // No source should be given multiple times.
86  NodeArray<bool> isSource {G, false};
87  for (node s : sources) {
88  OGDF_ASSERT(!isSource[s]);
89  isSource[s] = true;
90  }
91 #endif
92 
93  // initialization
94  for (node v : G.nodes) {
95  queue.push(v, distance[v]);
96  }
97  for (node s : sources) {
98  queue.decrease(s, (distance[s] = 0));
99  }
100 
101 #ifdef OGDF_DEBUG
102  for (edge de : G.edges) {
103  OGDF_ASSERT(weight[de] >= 0);
104  }
105 #endif
106 
107  while (!queue.empty()) {
108  node v = queue.topElement();
109  queue.pop();
110  if (!predecessor[v]
111  && m_eps.greater(distance[v], static_cast<T>(0))) { // v is unreachable, ignore
112  continue;
113  }
114  for (adjEntry adj : v->adjEntries) {
115  edge e = adj->theEdge();
116  node w = adj->twinNode();
117  if (directed
118  && ((!arcsReversed && e->target() == v)
119  || (arcsReversed && e->target() != v))) {
120  continue;
121  }
122 
123  if (m_eps.greater(distance[w], distance[v] + weight[e])) {
124  OGDF_ASSERT(std::numeric_limits<T>::max() - weight[e] >= distance[v]);
125  queue.decrease(w, (distance[w] = distance[v] + weight[e]));
126  predecessor[w] = e;
127  }
128  }
129  }
130  }
131 
133 
145  void callBound(const Graph& G, const EdgeArray<T>& weight, const List<node>& sources,
146  NodeArray<edge>& predecessor, NodeArray<T>& distance, bool directed, bool arcsReversed,
147  node target, T maxLength = std::numeric_limits<T>::max()) {
149  distance.init(G, std::numeric_limits<T>::max());
150  predecessor.init(G, nullptr);
151 
152  // initialization
153  for (node s : sources) {
154  queue.push(s, (distance[s] = 0));
155  }
156 
157 #ifdef OGDF_DEBUG
158  for (edge de : G.edges) {
159  OGDF_ASSERT(weight[de] >= 0);
160  }
161 #endif
162 
163  while (!queue.empty()) {
164  node v = queue.topElement();
165  if (v == target) { // terminate early if this is our sole target
166  break;
167  }
168 
169  queue.pop();
170  if (!predecessor[v]
171  && m_eps.greater(distance[v], static_cast<T>(0))) { // v is unreachable, ignore
172  continue;
173  }
174  for (adjEntry adj : v->adjEntries) {
175  edge e = adj->theEdge();
176  node w = adj->twinNode();
177  if (directed
178  && ((!arcsReversed && e->target() == v)
179  || (arcsReversed && e->target() != v))) {
180  continue;
181  }
182 
183  const T newDistance = distance[v] + weight[e];
184  if (m_eps.greater(newDistance, maxLength)) {
185  // using this edge would result in a path length greater than our upper bound
186  continue;
187  }
188  if (m_eps.greater(distance[w], newDistance)) {
189  OGDF_ASSERT(std::numeric_limits<T>::max() - weight[e] >= distance[v]);
190  distance[w] = newDistance;
191  if (queue.contains(w)) {
192  queue.decrease(w, distance[w]);
193  } else {
194  queue.push(w, distance[w]);
195  }
196  predecessor[w] = e;
197  }
198  }
199  }
200  }
201 
204 
214  void callUnbound(const Graph& G, const EdgeArray<T>& weight, node s, NodeArray<edge>& predecessor,
215  NodeArray<T>& distance, bool directed = false, bool arcsReversed = false) {
216  List<node> sources;
217  sources.pushBack(s);
218  callUnbound(G, weight, sources, predecessor, distance, directed, arcsReversed);
219  }
220 
222 
233  void callBound(const Graph& G, const EdgeArray<T>& weight, node s, NodeArray<edge>& predecessor,
234  NodeArray<T>& distance, bool directed, bool arcsReversed, node target,
235  T maxLength = std::numeric_limits<T>::max()) {
236  List<node> sources;
237  sources.pushBack(s);
238  callBound(G, weight, sources, predecessor, distance, directed, arcsReversed, target,
239  maxLength);
240  }
241 
243 
253  void call(const Graph& G, const EdgeArray<T>& weight, const List<node>& sources,
254  NodeArray<edge>& predecessor, NodeArray<T>& distance, bool directed = false,
255  bool arcsReversed = false, node target = nullptr,
256  T maxLength = std::numeric_limits<T>::max()) {
257  if (target == nullptr && maxLength == std::numeric_limits<T>::max()) {
258  callUnbound(G, weight, sources, predecessor, distance, directed, arcsReversed);
259  } else {
260  callBound(G, weight, sources, predecessor, distance, directed, arcsReversed, target,
261  maxLength);
262  }
263  }
264 
266 
276  void call(const Graph& G, const EdgeArray<T>& weight, const node s, NodeArray<edge>& predecessor,
277  NodeArray<T>& distance, bool directed = false, bool arcsReversed = false,
278  node target = nullptr, T maxLength = std::numeric_limits<T>::max()) {
279  if (target == nullptr && maxLength == std::numeric_limits<T>::max()) {
280  callUnbound(G, weight, s, predecessor, distance, directed, arcsReversed);
281  } else {
282  callBound(G, weight, s, predecessor, distance, directed, arcsReversed, target, maxLength);
283  }
284  }
285 };
286 
287 }
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
EpsilonTest.h
Compare floating point numbers with epsilons and integral numbers with normal compare operators.
Graph.h
Includes declaration of graph class.
ogdf::EpsilonTest
Definition: EpsilonTest.h:39
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::pq_internal::PrioritizedArrayQueueBase< E, P, std::less< P >, PairingHeap, HashArray< E, PrioritizedQueue< E, P, std::less< P >, PairingHeap >::Handle, DefHashFunc< E > > >::pop
void pop()
Removes the topmost element from the queue.
Definition: PriorityQueue.h:341
PriorityQueue.h
Priority queue interface wrapping various heaps.
ogdf::pq_internal::PrioritizedArrayQueueBase< E, P, std::less< P >, PairingHeap, HashArray< E, PrioritizedQueue< E, P, std::less< P >, PairingHeap >::Handle, DefHashFunc< E > > >::push
void push(const E &element, const P &priority)
Adds a new element to the queue.
Definition: PriorityQueue.h:333
ogdf::Dijkstra::callUnbound
void callUnbound(const Graph &G, const EdgeArray< T > &weight, const List< node > &sources, NodeArray< edge > &predecessor, NodeArray< T > &distance, bool directed=false, bool arcsReversed=false)
Calculates, based on the graph G with corresponding edge costs and source nodes, the shortest paths a...
Definition: Dijkstra.h:77
ogdf::Dijkstra::callUnbound
void callUnbound(const Graph &G, const EdgeArray< T > &weight, node s, NodeArray< edge > &predecessor, NodeArray< T > &distance, bool directed=false, bool arcsReversed=false)
Calculates, based on the graph G with corresponding edge costs and a source node s,...
Definition: Dijkstra.h:214
ogdf::Dijkstra::callBound
void callBound(const Graph &G, const EdgeArray< T > &weight, const List< node > &sources, NodeArray< edge > &predecessor, NodeArray< T > &distance, bool directed, bool arcsReversed, node target, T maxLength=std::numeric_limits< T >::max())
Calculates, based on the graph G with corresponding edge costs and source nodes, the shortest paths a...
Definition: Dijkstra.h:145
ogdf::pq_internal::PrioritizedArrayQueueBase< E, P, std::less< P >, PairingHeap, HashArray< E, PrioritizedQueue< E, P, std::less< P >, PairingHeap >::Handle, DefHashFunc< E > > >::contains
bool contains(const E &element) const
Returns whether this queue contains that key.
Definition: PriorityQueue.h:318
ogdf::AdjElement
Class for adjacency list elements.
Definition: Graph_d.h:142
ogdf::Dijkstra
Dijkstra's single source shortest path algorithm.
Definition: Dijkstra.h:60
ogdf::AdjElement::theEdge
edge theEdge() const
Returns the edge associated with this adjacency entry.
Definition: Graph_d.h:160
ogdf::PriorityQueue::empty
bool empty() const
Checks whether the queue is empty.
Definition: PriorityQueue.h:211
ogdf::gml::Key::H
@ H
GraphList.h
Decralation of GraphElement and GraphList classes.
ogdf::PrioritizedMapQueue
Prioritized queue interface wrapper for heaps.
Definition: PriorityQueue.h:411
ogdf::Dijkstra::call
void call(const Graph &G, const EdgeArray< T > &weight, const List< node > &sources, NodeArray< edge > &predecessor, NodeArray< T > &distance, bool directed=false, bool arcsReversed=false, node target=nullptr, T maxLength=std::numeric_limits< T >::max())
Calculates, based on the graph G with corresponding edge costs and source nodes, the shortest paths a...
Definition: Dijkstra.h:253
ogdf::List
Doubly linked lists (maintaining the length of the list).
Definition: DfsMakeBiconnected.h:40
ogdf::internal::GraphRegisteredArray
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition: Graph_d.h:658
ogdf::Dijkstra::call
void call(const Graph &G, const EdgeArray< T > &weight, const node s, NodeArray< edge > &predecessor, NodeArray< T > &distance, bool directed=false, bool arcsReversed=false, node target=nullptr, T maxLength=std::numeric_limits< T >::max())
Calculates, based on the graph G with corresponding edge costs and a source node s,...
Definition: Dijkstra.h:276
ogdf::Graph
Data type for general directed graphs (adjacency list representation).
Definition: Graph_d.h:869
PairingHeap.h
Implementation of pairing heap data structure.
ogdf::EpsilonTest::greater
std::enable_if< std::is_integral< T >::value, bool >::type greater(const T &x, const T &y) const
Compare if x is GREATER than y for integral types.
Definition: EpsilonTest.h:159
ogdf::pq_internal::PrioritizedQueue< E, P, std::less< P >, PairingHeap >::topElement
const E & topElement() const
Returns the topmost element in the queue.
Definition: PriorityQueue.h:286
ogdf::Dijkstra::m_eps
EpsilonTest m_eps
For floating point comparisons (if floating point is used)
Definition: Dijkstra.h:62
ogdf::AdjElement::twinNode
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
Definition: Graph_d.h:175
ogdf::pq_internal::PrioritizedArrayQueueBase< E, P, std::less< P >, PairingHeap, HashArray< E, PrioritizedQueue< E, P, std::less< P >, PairingHeap >::Handle, DefHashFunc< E > > >::decrease
void decrease(const E &element, const P &priority)
Decreases the priority of the given element.
Definition: PriorityQueue.h:351
basic.h
Basic declarations, included by all source files.
ogdf::EdgeElement
Class for the representation of edges.
Definition: Graph_d.h:363
List.h
Declaration of doubly linked lists and iterators.
ogdf::RegisteredArray< GraphRegistry< Key >, Value, WithDefault, Graph >::init
void init(const Graph *base=nullptr)
Reinitializes the array. Associates the array with the matching registry of base.
Definition: RegisteredArray.h:858
ogdf::Dijkstra::callBound
void callBound(const Graph &G, const EdgeArray< T > &weight, node s, NodeArray< edge > &predecessor, NodeArray< T > &distance, bool directed, bool arcsReversed, node target, T maxLength=std::numeric_limits< T >::max())
Calculates, based on the graph G with corresponding edge costs and a source node s,...
Definition: Dijkstra.h:233
ogdf::EdgeElement::target
node target() const
Returns the target node of the edge.
Definition: Graph_d.h:401
ogdf::NodeElement
Class for the representation of nodes.
Definition: Graph_d.h:240
ogdf::List::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: List.h:1547
ogdf::internal::EdgeArrayBase2
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition: Graph_d.h:716