1 #ifndef GL_FLOYD_WARSHALL_HPP
2 #define GL_FLOYD_WARSHALL_HPP
4 #include "../gl_base.hpp"
17 template <
class Graph>
92 template <class
Graph>
95 template <
class Graph>
101 template <
class Graph>
110 for (
int i = 0; i < graph.
numNodes(); ++i)
112 for (
int j = 0; j < graph.
numNodes(); ++j)
114 if (!graph.
hasEdge(i,j))
continue;
119 GL_ASSERT(weight >= 0,
"FloydWarshall::compute | Graph is undirected and contains negative weights")
121 dist[i*numNodes+j].setDistance(weight);
122 next[i*numNodes+j] = j;
126 for (
idx_t i = 0; i < numNodes; ++i)
128 dist[i*numNodes+i].setDistance(0);
129 next[i*numNodes+i] = i;
132 for (k = 0; k < numNodes; ++k) {
133 for (j = 0; j < numNodes; ++j) {
134 for (i = 0; i < numNodes; ++i) {
135 if (k == i || k == j)
137 if (dist[i*numNodes+k] + dist[k*numNodes+j] < dist[i*numNodes+j])
139 dist[i*numNodes+j] = dist[i*numNodes+k] + dist[k*numNodes+j];
140 next[i*numNodes+j] = next[i*numNodes+k];
146 for (
idx_t i = 0; i < numNodes; ++i)
148 if (!dist[i*numNodes+i].isZero())
150 negativePath_ = {
true,i};
156 isInitialized_ =
true;
159 template <
class Graph>
161 GL_ASSERT(isInitialized_,
"FloydWarshall::hasNegativePath | FloydWarshall has not been initialized with a graph.")
163 return negativePath_.first;
166 template <
class Graph>
168 GL_ASSERT(isInitialized_,
"FloydWarshall::pathLength | FloydWarshall has not been initialized with a graph.")
169 graph_.checkRange(src,dest);
170 GL_ASSERT(!negativePath_.first,std::string(
"FloydWarshall::pathLength | The input graph has a negative cycle at node ")+std::to_string(negativePath_.second))
172 return dist_[src*graph_.numNodes()+dest];
175 template <
class Graph>
177 GL_ASSERT(isInitialized_,
"FloydWarshall::getPath | FloydWarshall has not been initialized with a graph.")
178 graph_.checkRange(src,dest);
179 GL_ASSERT(!negativePath_.first,std::string(
"FloydWarshall::getPath | The input graph has a negative cycle at node ")+std::to_string(negativePath_.second))
182 if (dist_[src*graph_.numNodes()+dest].isInfinite())
190 u = next_[u*graph_.numNodes()+dest];
196 template <
class Graph>
199 GL_ASSERT(isInitialized_,
"FloydWarshall::getSPT | FloydWarshall has not been initialized with a graph.")
200 graph_.checkRange(src);
201 GL_ASSERT(!negativePath_.first,std::string(
"FloydWarshall::getSPT | The input graph has a negative cycle at node ")+std::to_string(negativePath_.second))
203 Graph result(graph_.numNodes(),std::string(std::string(
"SPT of node ")+std::to_string(src)+std::string(
" in ")+graph_.getGraphLabel()));
204 for (
idx_t i = 0; i < graph_.numNodes(); ++i)
206 auto path = getPath(src,i);
209 for (
idx_t j = i+1; j < path.second.size(); ++i, ++j)
211 if (!result.
hasEdge(path.second[i],path.second[j]))
213 result.
setEdge(path.second[i],path.second[j],graph_.getEdgeWeight(path.second[i],path.second[j]));
221 template <
class Graph>
224 GL_ASSERT(isInitialized_,
"FloydWarshall::closenessCentrality | FloydWarshall has not been initialized with a graph.")
225 graph_.checkRange(
id);
226 GL_ASSERT(!negativePath_.first,std::string(
"FloydWarshall::closenessCentrality | The input graph has a negative cycle at node ")+std::to_string(negativePath_.second))
231 for (
idx_t i = 0; i < graph_.numNodes(); ++i)
233 if (
id == i)
continue;
234 distance = pathLength(i,
id);
240 return static_cast<double>((graph_.numNodes()-1)/result);
243 template <
class Graph>
246 GL_ASSERT(isInitialized_,
"FloydWarshall::closenessCentrality | FloydWarshall has not been initialized with a graph.")
247 graph_.checkRange(
id);
248 GL_ASSERT(!negativePath_.first,std::string(
"FloydWarshall::closenessCentrality | The input graph has a negative cycle at node ")+std::to_string(negativePath_.second))
253 for (
idx_t i = 0; i < graph_.numNodes(); ++i)
255 if (
id == i)
continue;
256 distance = pathLength(i,
id);
262 return static_cast<double>(result/(graph_.numNodes()-1));
268 #endif // GL_FLOYD_WARSHALL_HPP
SCALAR val_t
Value type.
Definition: Graph.hpp:43
Graph getSPT(const idx_t src) const
Returns a graph that only contains the edges of the SPT (Shortest Path Tree) starting at 'src'...
Definition: FloydWarshall.hpp:197
std::vector< idx_t > idx_list_t
Index List type.
Definition: Graph.hpp:48
gl::index_type idx_t
Index type.
Definition: Graph.hpp:44
std::vector< Distance< val_t >> distance_matrix_t
Definition: FloydWarshall.hpp:21
void setEdge(const idx_t &start, const idx_t &end, const val_t &weight=1, const Color &color=Color())
Sets an edge including start/end points and weight.
Definition: Graph.hpp:510
Stores and implements a Graph.
Definition: Graph.hpp:39
typename Graph::idx_t idx_t
Definition: FloydWarshall.hpp:19
bool isInfinite() const
Checks whether the distance is infinite.
Definition: Distance.hpp:108
bool hasEdge(const idx_t &start, const idx_t &end) const
Checks whether an edge exists from start to end.
Definition: Graph.hpp:818
Graph graph_
Reference to graph.
Definition: FloydWarshall.hpp:83
distance_matrix_t dist_
Shortest Path lengths.
Definition: FloydWarshall.hpp:84
double closenessCentrality(const idx_t id) const
Computes the closeness centrality of node 'id'.
Definition: FloydWarshall.hpp:222
bool isDirected() const
Returns true if the graph is directed, false if not.
Definition: Graph.hpp:426
#define GL_ASSERT(EXPR, ERROR_MSG)
Custom assert that supports attaching a message.
Definition: gl_assert.hpp:14
FloydWarshall()
Default constructor.
Definition: FloydWarshall.hpp:93
idx_t numNodes() const
Returns the number of nodes currently in the graph.
Definition: Graph.hpp:406
bool hasNegativePath() const
Checks whether the input graph has negative cycles.
Definition: FloydWarshall.hpp:160
void compute(const Graph &graph)
Computation. This is where the shortest distances and the successors of each node pair gets computed...
Definition: FloydWarshall.hpp:102
std::pair< bool, idx_list_t > getPath(const idx_t src, const idx_t dest) const
Computes the node sequence that represents the shortest path from 'src' to 'dest'.
Definition: FloydWarshall.hpp:176
idx_list_t next_
Shortest Path successors.
Definition: FloydWarshall.hpp:85
Implements a numerical distance that supports "infinite distance".
Definition: Distance.hpp:13
#define GL_INF(ValueType)
Definition: gl_base.hpp:7
std::pair< bool, idx_t > negativePath_
Boolean storing info on negative path in graph.
Definition: FloydWarshall.hpp:82
bool isInitialized_
Boolean storing initialization status.
Definition: FloydWarshall.hpp:81
Distance< val_t > pathLength(const idx_t src, const idx_t dest) const
Computes the shortest path length from 'src' to 'dest'.
Definition: FloydWarshall.hpp:167
Class computes that Shortest Paths for all pairs of nodes in the graph using the Floyd-Warshall algor...
Definition: FloydWarshall.hpp:18
typename Graph::idx_list_t idx_list_t
Definition: FloydWarshall.hpp:22
SCALAR scalarDistance() const
Gets the numerical value of the distance. If the distance is infinite, returns the maximum value of t...
Definition: Distance.hpp:90
val_t getEdgeWeight(const idx_t &start, const idx_t &end) const
Finds the weight of the edge going from start to end.
Definition: Graph.hpp:858
typename Graph::val_t val_t
Definition: FloydWarshall.hpp:20
double harmonicCentrality(const idx_t id) const
Computes the harmonic centrality of node 'id'.
Definition: FloydWarshall.hpp:244