Skip to content

Commit ed6d3ce

Browse files
authored
Add distance predecessor support to shortest path algorithms (#126)
1 parent eef9fa1 commit ed6d3ce

14 files changed

Lines changed: 380 additions & 367 deletions
Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
template <adjacency_list G,
2-
class Distances,
3-
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
4-
const edge_t<G>&)>,
2+
class DistanceFn,
3+
class WF = function<distance_fn_value_t<DistanceFn, G>(const remove_reference_t<G>&,
4+
const edge_t<G>&)>,
55
class Visitor = empty_visitor,
6-
class Compare = less<vertex_property_map_value_t<Distances>>,
7-
class Combine = plus<vertex_property_map_value_t<Distances>>>
8-
requires vertex_property_map_for<Distances, G> &&
9-
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
10-
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
6+
class Compare = less<distance_fn_value_t<DistanceFn, G>>,
7+
class Combine = plus<distance_fn_value_t<DistanceFn, G>>>
8+
requires distance_fn_for<DistanceFn, G> &&
9+
basic_edge_weight_function<G, WF, distance_fn_value_t<DistanceFn, G>, Compare, Combine>
1110
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_distances(
1211
G&& g,
1312
const vertex_id_t<G>& source,
14-
Distances& distances,
13+
DistanceFn&& distance,
1514
WF&& weight = [](const auto&,
16-
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
15+
const edge_t<G>& uv) { return distance_fn_value_t<DistanceFn, G>(1); },
1716
Visitor&& visitor = empty_visitor(),
18-
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
19-
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
17+
Compare&& compare = less<distance_fn_value_t<DistanceFn, G>>(),
18+
Combine&& combine = plus<distance_fn_value_t<DistanceFn, G>>());
Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
template <adjacency_list G,
22
input_range Sources,
3-
class Distances,
4-
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
5-
const edge_t<G>&)>,
3+
class DistanceFn,
4+
class WF = function<distance_fn_value_t<DistanceFn, G>(const remove_reference_t<G>&,
5+
const edge_t<G>&)>,
66
class Visitor = empty_visitor,
7-
class Compare = less<vertex_property_map_value_t<Distances>>,
8-
class Combine = plus<vertex_property_map_value_t<Distances>>>
9-
requires vertex_property_map_for<Distances, G> &&
7+
class Compare = less<distance_fn_value_t<DistanceFn, G>>,
8+
class Combine = plus<distance_fn_value_t<DistanceFn, G>>>
9+
requires distance_fn_for<DistanceFn, G> &&
1010
convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
11-
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
12-
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
11+
basic_edge_weight_function<G, WF, distance_fn_value_t<DistanceFn, G>, Compare, Combine>
1312
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_distances(
1413
G&& g,
1514
const Sources& sources,
16-
Distances& distances,
15+
DistanceFn&& distance,
1716
WF&& weight = [](const auto&,
18-
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
17+
const edge_t<G>& uv) { return distance_fn_value_t<DistanceFn, G>(1); },
1918
Visitor&& visitor = empty_visitor(),
20-
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
21-
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
19+
Compare&& compare = less<distance_fn_value_t<DistanceFn, G>>(),
20+
Combine&& combine = plus<distance_fn_value_t<DistanceFn, G>>());
Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
template <adjacency_list G,
2-
class Distances,
3-
class Predecessors,
4-
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
5-
const edge_t<G>&)>,
2+
class DistanceFn,
3+
class PredecessorFn,
4+
class WF = function<distance_fn_value_t<DistanceFn, G>(const remove_reference_t<G>&,
5+
const edge_t<G>&)>,
66
class Visitor = empty_visitor,
7-
class Compare = less<vertex_property_map_value_t<Distances>>,
8-
class Combine = plus<vertex_property_map_value_t<Distances>>>
9-
requires vertex_property_map_for<Distances, G> &&
10-
vertex_property_map_for<Predecessors, G> &&
11-
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
12-
convertible_to<vertex_id_t<G>, vertex_property_map_value_t<Predecessors>> &&
13-
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
7+
class Compare = less<distance_fn_value_t<DistanceFn, G>>,
8+
class Combine = plus<distance_fn_value_t<DistanceFn, G>>>
9+
requires distance_fn_for<DistanceFn, G> &&
10+
predecessor_fn_for<PredecessorFn, G> &&
11+
basic_edge_weight_function<G, WF, distance_fn_value_t<DistanceFn, G>, Compare, Combine>
1412
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_paths(
1513
G&& g,
1614
const vertex_id_t<G>& source,
17-
Distances& distances,
18-
Predecessors& predecessor,
15+
DistanceFn&& distance,
16+
PredecessorFn&& predecessor,
1917
WF&& weight = [](const auto&,
20-
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
18+
const edge_t<G>& uv) { return distance_fn_value_t<DistanceFn, G>(1); },
2119
Visitor&& visitor = empty_visitor(),
22-
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
23-
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
20+
Compare&& compare = less<distance_fn_value_t<DistanceFn, G>>(),
21+
Combine&& combine = plus<distance_fn_value_t<DistanceFn, G>>());
Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
template <adjacency_list G,
22
input_range Sources,
3-
class Distances,
4-
class Predecessors,
5-
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
6-
const edge_t<G>&)>,
3+
class DistanceFn,
4+
class PredecessorFn,
5+
class WF = function<distance_fn_value_t<DistanceFn, G>(const remove_reference_t<G>&,
6+
const edge_t<G>&)>,
77
class Visitor = empty_visitor,
8-
class Compare = less<vertex_property_map_value_t<Distances>>,
9-
class Combine = plus<vertex_property_map_value_t<Distances>>>
10-
requires vertex_property_map_for<Distances, G> &&
11-
vertex_property_map_for<Predecessors, G> &&
8+
class Compare = less<distance_fn_value_t<DistanceFn, G>>,
9+
class Combine = plus<distance_fn_value_t<DistanceFn, G>>>
10+
requires distance_fn_for<DistanceFn, G> &&
11+
predecessor_fn_for<PredecessorFn, G> &&
1212
convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
13-
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
14-
convertible_to<vertex_id_t<G>, vertex_property_map_value_t<Predecessors>> &&
15-
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
13+
basic_edge_weight_function<G, WF, distance_fn_value_t<DistanceFn, G>, Compare, Combine>
1614
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_paths(
17-
G&& g,
18-
const Sources& sources,
19-
Distances& distances,
20-
Predecessors& predecessor,
21-
WF&& weight = [](const auto&,
22-
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
23-
Visitor&& visitor = empty_visitor(),
24-
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
25-
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
15+
G&& g,
16+
const Sources& sources,
17+
DistanceFn&& distance,
18+
PredecessorFn&& predecessor,
19+
WF&& weight = [](const auto&,
20+
const edge_t<G>& uv) { return distance_fn_value_t<DistanceFn, G>(1); },
21+
Visitor&& visitor = empty_visitor(),
22+
Compare&& compare = less<distance_fn_value_t<DistanceFn, G>>(),
23+
Combine&& combine = plus<distance_fn_value_t<DistanceFn, G>>());

D3128_Algorithms/src/connected_components.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ void biconnected_components(G&& g, OuterContainer& components);
1414
/*
1515
* Connected Components
1616
*/
17-
template <adjacency_list G, class Component>
18-
requires vertex_property_map_for<Component, G>
19-
size_t connected_components(G&& g, Component& component);
17+
template <adjacency_list G, class ComponentFn>
18+
requires vertex_property_fn_for<ComponentFn, G>
19+
size_t connected_components(G&& g, ComponentFn&& component);
2020

2121
/*
2222
* Afforest Connected Components
@@ -32,10 +32,10 @@ void afforest(G&& g, GT&& g_t, Component& component, const size_t neighbor_round
3232
/*
3333
* Kosaraju Strongly Connected Components
3434
*/
35-
template <adjacency_list G, adjacency_list GT, class Component>
36-
requires vertex_property_map_for<Component, G>
37-
void kosaraju(G&& g, GT&& g_t, Component& component);
35+
template <adjacency_list G, adjacency_list GT, class ComponentFn>
36+
requires vertex_property_fn_for<ComponentFn, G>
37+
void kosaraju(G&& g, GT&& g_t, ComponentFn&& component);
3838

39-
template <bidirectional_adjacency_list G, class Component>
40-
requires vertex_property_map_for<Component, G>
41-
void kosaraju(G&& g, Component& component);
39+
template <bidirectional_adjacency_list G, class ComponentFn>
40+
requires vertex_property_fn_for<ComponentFn, G>
41+
void kosaraju(G&& g, ComponentFn&& component);

D3128_Algorithms/src/dijkstra_example_mapped.hpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@ G g({{"a", "b", 4.0}, {"a", "c", 2.0},
1616

1717
constexpr double inf = std::numeric_limits<double>::max();
1818

19-
auto dist = make_vertex_property_map<G, double>(g, inf);
20-
auto pred = make_vertex_property_map<G, vertex_id_t<G>>(g, vertex_id_t<G>{});
21-
for (auto&& [uid, u] : views::vertexlist(g))
22-
pred[uid] = uid;
23-
24-
dijkstra_shortest_paths(g, std::string{"a"}, dist, pred,
19+
std::unordered_map<std::string, double> dist_map;
20+
std::unordered_map<std::string, std::string> pred_map;
21+
for (auto&& [uid, u] : views::vertexlist(g)) {
22+
dist_map[uid] = inf;
23+
pred_map[uid] = uid;
24+
}
25+
26+
dijkstra_shortest_paths(g, std::string{"a"},
27+
[&dist_map](const auto&, const auto& uid) -> double& { return dist_map[uid]; },
28+
[&pred_map](const auto&, const auto& uid) -> std::string& { return pred_map[uid]; },
2529
[](const auto& g, const edge_t<G>& e) { return edge_value(g, e); });
2630

2731
// Shortest a to d: a to c (2) to b (1) to d (5) = 8
28-
// dist["d"] == 8
32+
// dist\_map["d"] == 8
2933

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
template <adjacency_list G,
2-
class Distances,
3-
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
4-
const edge_t<G>&)>,
2+
class DistanceFn,
3+
class WF = function<distance_fn_value_t<DistanceFn, G>(const remove_reference_t<G>&,
4+
const edge_t<G>&)>,
55
class Visitor = empty_visitor,
6-
class Compare = less<vertex_property_map_value_t<Distances>>,
7-
class Combine = plus<vertex_property_map_value_t<Distances>>>
8-
requires vertex_property_map_for<Distances, G> &&
9-
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
10-
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
6+
class Compare = less<distance_fn_value_t<DistanceFn, G>>,
7+
class Combine = plus<distance_fn_value_t<DistanceFn, G>>>
8+
requires distance_fn_for<DistanceFn, G> &&
9+
basic_edge_weight_function<G, WF, distance_fn_value_t<DistanceFn, G>, Compare, Combine>
1110
constexpr void dijkstra_shortest_distances(
1211
G&& g,
1312
const vertex_id_t<G>& source,
14-
Distances& distances,
13+
DistanceFn&& distance,
1514
WF&& weight = [](const auto&,
16-
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
15+
const edge_t<G>& uv) { return distance_fn_value_t<DistanceFn, G>(1); },
1716
Visitor&& visitor = empty_visitor(),
18-
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
19-
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
17+
Compare&& compare = less<distance_fn_value_t<DistanceFn, G>>(),
18+
Combine&& combine = plus<distance_fn_value_t<DistanceFn, G>>());
Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
template <adjacency_list G,
22
input_range Sources,
3-
class Distances,
4-
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
5-
const edge_t<G>&)>,
3+
class DistanceFn,
4+
class WF = function<distance_fn_value_t<DistanceFn, G>(const remove_reference_t<G>&,
5+
const edge_t<G>&)>,
66
class Visitor = empty_visitor,
7-
class Compare = less<vertex_property_map_value_t<Distances>>,
8-
class Combine = plus<vertex_property_map_value_t<Distances>>>
9-
requires vertex_property_map_for<Distances, G> &&
7+
class Compare = less<distance_fn_value_t<DistanceFn, G>>,
8+
class Combine = plus<distance_fn_value_t<DistanceFn, G>>>
9+
requires distance_fn_for<DistanceFn, G> &&
1010
convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
11-
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
12-
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
11+
basic_edge_weight_function<G, WF, distance_fn_value_t<DistanceFn, G>, Compare, Combine>
1312
constexpr void dijkstra_shortest_distances(
1413
G&& g,
1514
const Sources& sources,
16-
Distances& distances,
15+
DistanceFn&& distance,
1716
WF&& weight = [](const auto&,
18-
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
17+
const edge_t<G>& uv) { return distance_fn_value_t<DistanceFn, G>(1); },
1918
Visitor&& visitor = empty_visitor(),
20-
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
21-
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
19+
Compare&& compare = less<distance_fn_value_t<DistanceFn, G>>(),
20+
Combine&& combine = plus<distance_fn_value_t<DistanceFn, G>>());
Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
template <adjacency_list G,
2-
class Distances,
3-
class Predecessors,
4-
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
5-
const edge_t<G>&)>,
2+
class DistanceFn,
3+
class PredecessorFn,
4+
class WF = function<distance_fn_value_t<DistanceFn, G>(const remove_reference_t<G>&,
5+
const edge_t<G>&)>,
66
class Visitor = empty_visitor,
7-
class Compare = less<vertex_property_map_value_t<Distances>>,
8-
class Combine = plus<vertex_property_map_value_t<Distances>>>
9-
requires vertex_property_map_for<Distances, G> &&
10-
vertex_property_map_for<Predecessors, G> &&
11-
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
12-
convertible_to<vertex_id_t<G>, vertex_property_map_value_t<Predecessors>> &&
13-
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
7+
class Compare = less<distance_fn_value_t<DistanceFn, G>>,
8+
class Combine = plus<distance_fn_value_t<DistanceFn, G>>>
9+
requires distance_fn_for<DistanceFn, G> &&
10+
predecessor_fn_for<PredecessorFn, G> &&
11+
basic_edge_weight_function<G, WF, distance_fn_value_t<DistanceFn, G>, Compare, Combine>
1412
constexpr void dijkstra_shortest_paths(
1513
G&& g,
1614
const vertex_id_t<G>& source,
17-
Distances& distances,
18-
Predecessors& predecessor,
15+
DistanceFn&& distance,
16+
PredecessorFn&& predecessor,
1917
WF&& weight = [](const auto&,
20-
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
18+
const edge_t<G>& uv) { return distance_fn_value_t<DistanceFn, G>(1); },
2119
Visitor&& visitor = empty_visitor(),
22-
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
23-
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
20+
Compare&& compare = less<distance_fn_value_t<DistanceFn, G>>(),
21+
Combine&& combine = plus<distance_fn_value_t<DistanceFn, G>>());

0 commit comments

Comments
 (0)