Skip to content

Commit 2f2f9e1

Browse files
committed
docs: extracted section tutorial.algorithms
1 parent 8e56bc4 commit 2f2f9e1

File tree

2 files changed

+59
-56
lines changed

2 files changed

+59
-56
lines changed

doc/tutorial/algorithms.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Algorithms
2+
==========
3+
4+
This library offers a number of generic algorithms.
5+
Due to the nature of graph algorithms, the way they communicate the results requires some additional code.
6+
7+
Let's use the following graph representation, naively recognized by this library,
8+
that is able to store a weight for each edge:
9+
10+
```c++
11+
std::vector<std::vector<std::tuple<int, double>>> g {
12+
/*0*/ { {(1), 9.1}, {(3), 1.1} }, // 9.1 2.2
13+
/*1*/ { {(0), 9.1}, {(2), 2.2}, {(4), 3.5} }, // (0)-------(1)-------(2)
14+
/*2*/ { {(1), 2.2}, {(5), 1.0} }, // | | |
15+
/*3*/ { {(0), 1.1}, {(4), 2.0} }, // |1.1 |3.5 |1.0
16+
/*4*/ { {(1), 3.5}, {(3), 2.0} }, // | 2.0 | | 0.5
17+
/*5*/ { {(2), 1.0}, {(6), 0.5} }, // (3)-------(4) (5)-------(6)
18+
/*6*/ { {(5), 0.5} } //
19+
};
20+
```
21+
22+
Now, let's use Dijkstra's Shortest Paths algorithm to determine the distance from vertex `0` to each vertex in `g`, and also to determine these paths. The paths are not obtained directly, but instead the list of predecessors is returned for each vertex:
23+
24+
```c++
25+
auto weight = [](std::tuple<int, double> const& uv) {
26+
return std::get<1>(uv);
27+
};
28+
29+
std::vector<double> distances(g.size()); // we will store the distance to each vertex here
30+
std::vector<int> predecessors(g.size()); // we will store the predecessor of each vertex here
31+
32+
// fill `distances` with `infinity`
33+
// fill `predecessors` at index `i` with value `i`
34+
graph::init_shortest_paths(distances, predecessors);
35+
36+
graph::dijkstra_shortest_paths(g, 0, distances, predecessors, weight); // from vertex 0
37+
38+
assert((distances == std::vector{0.0, 6.6, 8.8, 1.1, 3.1, 9.8, 10.3}));
39+
assert((predecessors == std::vector{0, 4, 1, 0, 3, 2, 5}));
40+
```
41+
42+
If you need to know the sequence of vertices in the path from, say, `0` to `5`, you have to compute it yourself:
43+
44+
```c++
45+
auto path = [&predecessors](int from, int to)
46+
{
47+
std::vector<int> result;
48+
for (; to != from; to = predecessors[to]) {
49+
assert(to < predecessors.size());
50+
result.push_back(to);
51+
}
52+
std::reverse(result.begin(), result.end());
53+
return result;
54+
};
55+
56+
assert((path(0, 5) == std::vector{3, 4, 1, 2, 5}));
57+
```
58+
59+
The algorithms from this library are described in section [Algorithms](../reference/algorithms.md).

doc/tutorial/tutorial_other.md

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -124,62 +124,6 @@ int main()
124124
}
125125
```
126126

127-
## Algorithms
128-
129-
This library offers also full fledged algorithms.
130-
However, due to the nature of graph algorithms, the way they communicate the results requires some additional code.
131-
Let's, reuse the same graph topology, but use a different adjacency-list representation that is also able to store a weight for each edge:
132-
133-
```c++
134-
std::vector<std::vector<std::tuple<int, double>>> g {
135-
/*0*/ { {(1), 9.1}, {(3), 1.1} }, // 9.1 2.2
136-
/*1*/ { {(0), 9.1}, {(2), 2.2}, {(4), 3.5} }, // (0)-------(1)-------(2)
137-
/*2*/ { {(1), 2.2}, {(5), 1.0} }, // | | |
138-
/*3*/ { {(0), 1.1}, {(4), 2.0} }, // |1.1 |3.5 |1.0
139-
/*4*/ { {(1), 3.5}, {(3), 2.0} }, // | 2.0 | | 0.5
140-
/*5*/ { {(2), 1.0}, {(6), 0.5} }, // (3)-------(4) (5)-------(6)
141-
/*6*/ { {(5), 0.5} } //
142-
};
143-
```
144-
145-
Now, let's use Dijkstra's Shortest Paths algorithm to determine the distance from vertex `0` to each vertex in `g`, and also to determine these paths. The paths are not obtained directly, but instead the list of predecessors is returned for each vertex:
146-
147-
```c++
148-
auto weight = [](std::tuple<int, double> const& uv) {
149-
return std::get<1>(uv);
150-
};
151-
152-
std::vector<double> distances(g.size()); // we will store the distance to each vertex here
153-
std::vector<int> predecessors(g.size()); // we will store the predecessor of each vertex here
154-
155-
// fill `distances` with `infinity`
156-
// fill `predecessors` at index `i` with value `i`
157-
graph::init_shortest_paths(distances, predecessors);
158-
159-
graph::dijkstra_shortest_paths(g, 0, distances, predecessors, weight); // from vertex 0
160-
161-
assert((distances == std::vector{0.0, 6.6, 8.8, 1.1, 3.1, 9.8, 10.3}));
162-
assert((predecessors == std::vector{0, 4, 1, 0, 3, 2, 5}));
163-
```
164-
165-
If you need to know the sequence of vertices in the path from, say, `0` to `5`, you have to compute it yourself:
166-
167-
```c++
168-
auto path = [&predecessors](int from, int to)
169-
{
170-
std::vector<int> result;
171-
for (; to != from; to = predecessors[to]) {
172-
assert(to < predecessors.size());
173-
result.push_back(to);
174-
}
175-
std::reverse(result.begin(), result.end());
176-
return result;
177-
};
178-
179-
assert((path(0, 5) == std::vector{3, 4, 1, 2, 5}));
180-
```
181-
The algorithms in this library are described in section [Algorithms](./algorithms.md).
182-
183127

184128

185129
## Containers

0 commit comments

Comments
 (0)