-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Pass vertex and edge id to writers * Added shortest path example * Link to example section in readme
- Loading branch information
Showing
12 changed files
with
215 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Examples | ||
This section contains example usages of the Graaf library. | ||
If there is a usecase you would like to see an example of, please open an issue in our [issue tracker](https://github.com/bobluppes/graaf/issues). | ||
|
||
- [Shortest path](./shortest_path/README.md) | ||
- [Dot serialization](./dot_serialization/README.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Shortest Path Example | ||
The shortest path algorithm implemented in `graaf::algorithm::get_shortest_path` can be used to compute the shortest path between any two vertices in a graph. | ||
|
||
Consider the following graph: | ||
|
||
<p align="center"> | ||
<img src="./graph.png"> | ||
</p> | ||
|
||
In order to compute the shortest path between *vertex 0* and *vertex 2*, we call: | ||
|
||
```c++ | ||
const auto maybe_shortest_path{get_shortest_path<edge_strategy::UNWEIGHTED>(graph, start, target)}; | ||
|
||
// Assert that we found a path at all | ||
assert(maybe_shortest_path.has_value()); | ||
auto shortest_path{maybe_shortest_path.value()}; | ||
``` | ||
## Visualizing the shortest path | ||
If we want to visualize the shortest path on the graph, we can create our own vertex and edge writers. These writers then determine the vertex and edge attributes based on whether the vertex or edge is contained in the shortest path. | ||
First, we create a datastructure of all edges on the shortest path such that we can query it in the edge writer: | ||
```c++ | ||
// We use a set here for O(1) time contains checks | ||
std::unordered_set<graaf::vertex_ids_t, graaf::vertex_ids_hash> edges_on_shortest_path{}; | ||
// Convert the list of vertices on the shortest path to edges | ||
graaf::vertex_id_t prev{shortest_path.vertices.front()}; | ||
shortest_path.vertices.pop_front(); | ||
for (const auto current : shortest_path.vertices) { | ||
edges_on_shortest_path.insert(std::make_pair(prev, current)); | ||
prev = current; | ||
} | ||
``` | ||
|
||
Now we can specify our custom writers: | ||
|
||
```c++ | ||
const auto vertex_writer{ | ||
[start, target](graaf::vertex_id_t vertex_id, int vertex) -> std::string { | ||
if (vertex_id == start) { | ||
return "label=start"; | ||
} else if (vertex_id == target) { | ||
return "label=target"; | ||
} | ||
return "label=\"\""; | ||
}}; | ||
|
||
const auto edge_writer{ | ||
[&edges_on_shortest_path](const graaf::vertex_ids_t& edge_id, int edge) -> std::string { | ||
if (edges_on_shortest_path.contains(edge_id)) { | ||
return "label=\"\", color=red"; | ||
} | ||
return "label=\"\", color=gray, style=dashed"; | ||
}}; | ||
``` | ||
This yields us the following visualization: | ||
|
||
<p align="center"> | ||
<img src="./shortest_path.png"> | ||
</p> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#include <fmt/core.h> | ||
#include <graaflib/algorithm/shortest_path.h> | ||
#include <graaflib/directed_graph.h> | ||
#include <graaflib/io/dot.h> | ||
#include <graaflib/types.h> | ||
|
||
#include <cassert> | ||
#include <filesystem> | ||
#include <string> | ||
#include <unordered_set> | ||
|
||
struct graph_with_start_and_target { | ||
graaf::directed_graph<int, int> graph{}; | ||
graaf::vertex_id_t start{}; | ||
graaf::vertex_id_t target{}; | ||
}; | ||
|
||
graph_with_start_and_target create_graph_with_start_and_target() { | ||
graaf::directed_graph<int, int> graph{}; | ||
|
||
const auto vertex_1{graph.add_vertex(10)}; | ||
const auto vertex_2{graph.add_vertex(20)}; | ||
const auto vertex_3{graph.add_vertex(30)}; | ||
const auto vertex_4{graph.add_vertex(40)}; | ||
const auto vertex_5{graph.add_vertex(50)}; | ||
const auto vertex_6{graph.add_vertex(60)}; | ||
|
||
graph.add_edge(vertex_1, vertex_2, 100); | ||
graph.add_edge(vertex_3, vertex_2, 200); | ||
graph.add_edge(vertex_3, vertex_5, 300); | ||
graph.add_edge(vertex_2, vertex_4, 400); | ||
graph.add_edge(vertex_4, vertex_3, 500); | ||
graph.add_edge(vertex_4, vertex_6, 600); | ||
graph.add_edge(vertex_6, vertex_3, 700); | ||
|
||
return {graph, vertex_1, vertex_3}; | ||
} | ||
|
||
int main() { | ||
const auto [graph, start, target]{create_graph_with_start_and_target()}; | ||
|
||
const auto maybe_shortest_path{graaf::algorithm::get_shortest_path< | ||
graaf::algorithm::edge_strategy::UNWEIGHTED>(graph, start, target)}; | ||
assert(maybe_shortest_path.has_value()); | ||
auto shortest_path{maybe_shortest_path.value()}; | ||
|
||
std::unordered_set<graaf::vertex_ids_t, graaf::vertex_ids_hash> | ||
edges_on_shortest_path{}; | ||
|
||
graaf::vertex_id_t prev{shortest_path.vertices.front()}; | ||
shortest_path.vertices.pop_front(); | ||
for (const auto current : shortest_path.vertices) { | ||
edges_on_shortest_path.insert(std::make_pair(prev, current)); | ||
prev = current; | ||
} | ||
|
||
const auto vertex_writer{ | ||
[start, target](graaf::vertex_id_t vertex_id, int vertex) -> std::string { | ||
if (vertex_id == start) { | ||
return "label=start, fillcolor=white, style=filled"; | ||
} else if (vertex_id == target) { | ||
return "label=target, fillcolor=white, style=filled"; | ||
} | ||
return "label=\"\", color=gray, fillcolor=white, style=filled"; | ||
}}; | ||
|
||
const auto edge_writer{ | ||
[&edges_on_shortest_path](const graaf::vertex_ids_t& edge_id, | ||
int edge) -> std::string { | ||
if (edges_on_shortest_path.contains(edge_id)) { | ||
return "label=\"\", color=red"; | ||
} | ||
return "label=\"\", color=gray, style=dashed"; | ||
}}; | ||
|
||
const std::filesystem::path output{"shortest_path.dot"}; | ||
graaf::io::to_dot(graph, output, vertex_writer, edge_writer); | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters