Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Floyd-Warshall algorithm #98

Merged
merged 47 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3fe9e21
- added DFS cycle detection for directed and undirected graph
Hromz Jul 24, 2023
a629352
- corrected code according to comments
Hromz Jul 25, 2023
99f77cd
Apply suggestions from code review
bobluppes Jul 25, 2023
956eac3
Merge branch 'bobluppes:main' into main
Hromz Jul 28, 2023
3ec396d
Merge branch 'bobluppes:main' into main
Hromz Jul 29, 2023
3ba348d
Merge branch 'bobluppes:main' into main
Hromz Aug 1, 2023
432b6b4
- First example of potential use of the library
Hromz Aug 1, 2023
97ccea7
- small fixes
Hromz Aug 1, 2023
3e55e23
Update transport-example.md
Hromz Aug 2, 2023
286e9ce
Merge remote-tracking branch 'upstream/main'
bobluppes Aug 5, 2023
419b663
clang format fix
bobluppes Aug 5, 2023
2408835
Merge remote-tracking branch 'upstream/main'
bobluppes Aug 5, 2023
7e459bf
reflect breaking changes on main
bobluppes Aug 5, 2023
6fc3af0
clang format fix
bobluppes Aug 5, 2023
767a532
- corrected according to git comments
Hromz Aug 12, 2023
8ebb5f4
small fixes
Hromz Aug 12, 2023
ffe4553
small fixes
Hromz Aug 12, 2023
bb28f8c
Merge remote-tracking branch 'upstream/main'
bobluppes Aug 13, 2023
ce5df25
fix issues after merge
bobluppes Aug 13, 2023
1c82f04
fix syntax highlighting code blocks
bobluppes Aug 13, 2023
1c644a0
clang format
bobluppes Aug 13, 2023
a0fde77
Merge branch 'bobluppes:main' into main
Hromz Aug 13, 2023
2ae7d97
Merge branch 'bobluppes:main' into main
Hromz Aug 13, 2023
a3a3b31
Merge branch 'bobluppes:main' into main
Hromz Aug 15, 2023
c05cd27
- Added MST algorithm
Hromz Aug 18, 2023
b5db653
clang style correction
Hromz Aug 18, 2023
057ee77
Apply suggestions from code review
bobluppes Aug 31, 2023
9e92f3f
Merge remote-tracking branch 'upstream/main'
bobluppes Aug 31, 2023
665a484
Merge branch 'bobluppes:main' into main
Hromz Sep 1, 2023
5dce08b
Added topological sort algorithm DFS-based
Hromz Sep 5, 2023
03200f7
Merge branch 'main' into main
Hromz Sep 5, 2023
f8cd4fb
small fixes
Hromz Sep 5, 2023
21cde40
Merge branch 'main' of https://github.com/Hromz/graaf
Hromz Sep 5, 2023
14f0b8d
clang format fix
Hromz Sep 5, 2023
7efd134
added test
Hromz Sep 5, 2023
0bcad82
more tests
Hromz Sep 5, 2023
f96849a
Minor fixes
Hromz Sep 10, 2023
57d3c47
Clang format
Hromz Sep 10, 2023
c5ddba1
Update topological-sort.md
Hromz Sep 10, 2023
3c94ab6
Merge branch 'bobluppes:main' into main
Hromz Sep 13, 2023
19ea438
DOCS for DFS based cycle detection
Hromz Sep 14, 2023
68c2c2b
small fixes
Hromz Sep 14, 2023
55d3972
Update dfs-based.md
Hromz Sep 18, 2023
39487bd
Merge branch 'bobluppes:main' into main
Hromz Sep 19, 2023
da97d62
Added Floyd-WArshall algorithm
Hromz Sep 24, 2023
7a1ca3c
clang tidy
Hromz Sep 24, 2023
4a43bce
removed redundant negative cicle check and according tests, added two…
Hromz Sep 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions docs/docs/algorithms/shortest-path/floyd-warshall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
sidebar_position: 5
---

# Floyd-Warshall algorithm

Floyd-Warshall algorithm computes the shortest path between any two vertices in a graph, both directed and undirected.
The algorithm does not work for graphs with negative weight cycles.
The key idea of the algorithm is to relax the weighted shortest path between any two vertices, using any vertex as an
intermediate one.
Advantage of the algorithm is that it processes vertices instead of edges. This advantage can be used when the number of
edges is large enough, aka a dense graph.
Runtime of the algorithm is O(|V<sup>3</sup>|) and memory consumption is O(|V<sup>2</sup>|).

[wikipedia](https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm)

## Syntax

Calculates the shortest path between any two vertices.

```cpp
template <typename V, typename E, graph_type T,
typename WEIGHT_T = decltype(get_weight(std::declval<E>()))>
std::vector<std::vector<WEIGHT_T>> floyd_warshall_shortest_paths(
const graph<V, E, T>& graph);
```

- **graph** The graph to extract the shortest path from.
- **return** Returns a 2D vector of the shortest path. If a path doesn't exist between two vertices, mark it as
TYPE_MAX.
30 changes: 30 additions & 0 deletions include/graaflib/algorithm/shortest_path/floyd_warshall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include <graaflib/graph.h>
#include <graaflib/types.h>

namespace graaf::algorithm {
/**
* @brief Floyd-Warshall Algorithm
*
* This function computes the shortest paths between all pairs of vertices in a
* given weighted graph. It works for graphs with negative weight edges as well,
* but not for graphs with negative weight cycles. The function returns an
* adjacency matrix representing the shortest distances.
*
* @tparam V The type of a graph vertex
* @tparam E The type of a graph edge
* @tparam T the graph type (DIRECTED or UNDIRECTED)
* @tparam WEIGHT_T The weight type of an edge in the graph
* @param graph The graph object
* @return A 2D vector where element at [i][j] is the shortest distance from
* vertex i to vertex j.
*/
template <typename V, typename E, graph_type T,
typename WEIGHT_T = decltype(get_weight(std::declval<E>()))>
std::vector<std::vector<WEIGHT_T>> floyd_warshall_shortest_paths(
const graph<V, E, T>& graph);

}; // namespace graaf::algorithm

#include "floyd_warshall.tpp"
51 changes: 51 additions & 0 deletions include/graaflib/algorithm/shortest_path/floyd_warshall.tpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma once

#include <graaflib/algorithm/shortest_path/floyd_warshall.h>

#include <limits>
#include <vector>

namespace graaf::algorithm {

template <typename V, typename E, graph_type T, typename WEIGHT_T>
std::vector<std::vector<WEIGHT_T>> floyd_warshall_shortest_paths(
const graph<V, E, T>& graph) {
WEIGHT_T ZERO{};
std::size_t n = graph.vertex_count();
auto INF = std::numeric_limits<WEIGHT_T>::max();

std::vector<std::vector<WEIGHT_T>> shortest_paths(
n, std::vector<WEIGHT_T>(n, INF));

for (std::size_t vertex = 0; vertex < n; ++vertex) {
shortest_paths[vertex][vertex] = ZERO;
}

// Initial weights between vertices
for (std::size_t from_vertex = 0; from_vertex < n; ++from_vertex) {
for (const auto& to_vertex : graph.get_neighbors(from_vertex)) {
shortest_paths[from_vertex][to_vertex] =
std::min(shortest_paths[from_vertex][to_vertex],
get_weight(graph.get_edge(from_vertex, to_vertex)));
}
}

for (std::size_t through_vertex = 0; through_vertex < n; ++through_vertex) {
for (std::size_t start_vertex = 0; start_vertex < n; ++start_vertex) {
if (shortest_paths[start_vertex][through_vertex] < INF) {
for (std::size_t end_vertex = 0; end_vertex < n; ++end_vertex) {
if (shortest_paths[through_vertex][end_vertex] < INF) {
shortest_paths[start_vertex][end_vertex] =
std::min(shortest_paths[start_vertex][end_vertex],
shortest_paths[start_vertex][through_vertex] +
shortest_paths[through_vertex][end_vertex]);
}
}
}
}
}

return shortest_paths;
}

Check warning on line 49 in include/graaflib/algorithm/shortest_path/floyd_warshall.tpp

View check run for this annotation

Codecov / codecov/patch

include/graaflib/algorithm/shortest_path/floyd_warshall.tpp#L49

Added line #L49 was not covered by tests

}; // namespace graaf::algorithm
Loading