Skip to content

Commit ef60922

Browse files
committed
aligned algorithms to use vertex ids instead of vertex objects
1 parent f6cff87 commit ef60922

15 files changed

Lines changed: 151 additions & 214 deletions

include/gl/algorithm/breadth_first_search.hpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ namespace gl::algorithm {
1313
template <
1414
result_discriminator ResultDiscriminator = algorithm::ret,
1515
type_traits::c_graph GraphType,
16-
type_traits::c_optional_vertex_callback<GraphType, void> PreVisitCallback =
17-
algorithm::empty_callback,
18-
type_traits::c_optional_vertex_callback<GraphType, void> PostVisitCallback =
19-
algorithm::empty_callback>
16+
type_traits::c_optional_id_callback<void> PreVisitCallback = algorithm::empty_callback,
17+
type_traits::c_optional_id_callback<void> PostVisitCallback = algorithm::empty_callback>
2018
impl::alg_return_type<ResultDiscriminator, predecessors_descriptor> breadth_first_search(
2119
const GraphType& graph,
2220
const std::optional<types::id_type>& root_vertex_id_opt = no_root_vertex,
@@ -35,8 +33,8 @@ impl::alg_return_type<ResultDiscriminator, predecessors_descriptor> breadth_firs
3533
impl::bfs(
3634
graph,
3735
impl::init_range(root_vertex_id_opt.value()),
38-
impl::default_visit_vertex_predicate<GraphType>(visited),
39-
impl::default_visit_callback<GraphType, ResultDiscriminator>(visited, pd),
36+
impl::default_visit_vertex_predicate(visited),
37+
impl::default_visit_callback<ResultDiscriminator>(visited, pd),
4038
impl::default_enqueue_vertex_predicate<GraphType, true>(visited),
4139
pre_visit,
4240
post_visit
@@ -47,8 +45,8 @@ impl::alg_return_type<ResultDiscriminator, predecessors_descriptor> breadth_firs
4745
impl::bfs(
4846
graph,
4947
impl::init_range(root_id),
50-
impl::default_visit_vertex_predicate<GraphType>(visited),
51-
impl::default_visit_callback<GraphType, ResultDiscriminator>(visited, pd),
48+
impl::default_visit_vertex_predicate(visited),
49+
impl::default_visit_callback<ResultDiscriminator>(visited, pd),
5250
impl::default_enqueue_vertex_predicate<GraphType, true>(visited),
5351
pre_visit,
5452
post_visit

include/gl/algorithm/coloring.hpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ using bicoloring_type = std::vector<types::binary_color>;
1212

1313
template <
1414
type_traits::c_graph GraphType,
15-
type_traits::c_optional_vertex_callback<GraphType, void> PreVisitCallback =
16-
algorithm::empty_callback,
17-
type_traits::c_optional_vertex_callback<GraphType, void> PostVisitCallback =
18-
algorithm::empty_callback>
15+
type_traits::c_optional_id_callback<void> PreVisitCallback = algorithm::empty_callback,
16+
type_traits::c_optional_id_callback<void> PostVisitCallback = algorithm::empty_callback>
1917
[[nodiscard]] std::optional<bicoloring_type> bipartite_coloring(
2018
const GraphType& graph,
2119
const PreVisitCallback& pre_visit = {},
@@ -41,19 +39,18 @@ template <
4139
impl::init_range(root_id),
4240
algorithm::empty_callback{}, // visit predicate
4341
algorithm::empty_callback{}, // visit callback
44-
[&coloring](const vertex_type& vertex, const edge_type& in_edge)
42+
[&coloring](const types::id_type vertex_id, const edge_type& in_edge)
4543
-> predicate_result { // enqueue predicate
4644
if (in_edge.is_loop())
4745
return false;
4846

49-
const auto vertex_id = vertex.id();
50-
const auto source_id = in_edge.incident_vertex(vertex).id();
47+
const auto pred_id = in_edge.incident_vertex(vertex_id).id();
5148

52-
if (coloring[vertex_id] == coloring[source_id])
49+
if (coloring[vertex_id] == coloring[pred_id])
5350
return predicate_result::unknown; // graph is not bipartite
5451

55-
if (not coloring[vertex.id()].is_set()) {
56-
coloring[vertex.id()] = coloring[source_id].next();
52+
if (not coloring[vertex_id].is_set()) {
53+
coloring[vertex_id] = coloring[pred_id].next();
5754
return true;
5855
}
5956

include/gl/algorithm/depth_first_search.hpp

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ namespace gl::algorithm {
1212
template <
1313
result_discriminator ResultDiscriminator = algorithm::ret,
1414
type_traits::c_graph GraphType,
15-
type_traits::c_optional_vertex_callback<GraphType, void> PreVisitCallback =
16-
algorithm::empty_callback,
17-
type_traits::c_optional_vertex_callback<GraphType, void> PostVisitCallback =
18-
algorithm::empty_callback>
15+
type_traits::c_optional_id_callback<void> PreVisitCallback = algorithm::empty_callback,
16+
type_traits::c_optional_id_callback<void> PostVisitCallback = algorithm::empty_callback>
1917
impl::alg_return_type<ResultDiscriminator, predecessors_descriptor> depth_first_search(
2018
const GraphType& graph,
2119
const std::optional<types::id_type>& root_vertex_id_opt = no_root_vertex,
@@ -33,21 +31,21 @@ impl::alg_return_type<ResultDiscriminator, predecessors_descriptor> depth_first_
3331
if (root_vertex_id_opt) {
3432
impl::dfs(
3533
graph,
36-
graph.get_vertex(root_vertex_id_opt.value()),
37-
impl::default_visit_vertex_predicate<GraphType>(visited),
38-
impl::default_visit_callback<GraphType, ResultDiscriminator>(visited, pd),
34+
root_vertex_id_opt.value(),
35+
impl::default_visit_vertex_predicate(visited),
36+
impl::default_visit_callback<ResultDiscriminator>(visited, pd),
3937
impl::default_enqueue_vertex_predicate<GraphType>(visited),
4038
pre_visit,
4139
post_visit
4240
);
4341
}
4442
else {
45-
for (const auto& root_vertex : graph.vertices())
43+
for (const auto root_vertex_id : graph.vertex_ids())
4644
impl::dfs(
4745
graph,
48-
root_vertex,
49-
impl::default_visit_vertex_predicate<GraphType>(visited),
50-
impl::default_visit_callback<GraphType, ResultDiscriminator>(visited, pd),
46+
root_vertex_id,
47+
impl::default_visit_vertex_predicate(visited),
48+
impl::default_visit_callback<ResultDiscriminator>(visited, pd),
5149
impl::default_enqueue_vertex_predicate<GraphType>(visited),
5250
pre_visit,
5351
post_visit
@@ -61,10 +59,8 @@ impl::alg_return_type<ResultDiscriminator, predecessors_descriptor> depth_first_
6159
template <
6260
result_discriminator ResultDiscriminator = algorithm::ret,
6361
type_traits::c_graph GraphType,
64-
type_traits::c_optional_vertex_callback<GraphType, void> PreVisitCallback =
65-
algorithm::empty_callback,
66-
type_traits::c_optional_vertex_callback<GraphType, void> PostVisitCallback =
67-
algorithm::empty_callback>
62+
type_traits::c_optional_id_callback<void> PreVisitCallback = algorithm::empty_callback,
63+
type_traits::c_optional_id_callback<void> PostVisitCallback = algorithm::empty_callback>
6864
impl::alg_return_type<ResultDiscriminator, predecessors_descriptor> recursive_depth_first_search(
6965
const GraphType& graph,
7066
const std::optional<types::id_type>& root_vertex_id_opt = no_root_vertex,
@@ -83,23 +79,23 @@ impl::alg_return_type<ResultDiscriminator, predecessors_descriptor> recursive_de
8379
const auto root_id = root_vertex_id_opt.value();
8480
impl::r_dfs(
8581
graph,
86-
graph.get_vertex(root_id),
8782
root_id,
88-
impl::default_visit_vertex_predicate<GraphType>(visited),
89-
impl::default_visit_callback<GraphType, ResultDiscriminator>(visited, pd),
83+
root_id, // pred_id
84+
impl::default_visit_vertex_predicate(visited),
85+
impl::default_visit_callback<ResultDiscriminator>(visited, pd),
9086
impl::default_enqueue_vertex_predicate<GraphType>(visited),
9187
pre_visit,
9288
post_visit
9389
);
9490
}
9591
else {
96-
for (const auto& root_vertex : graph.vertices())
92+
for (const auto& root_id : graph.vertex_ids())
9793
impl::r_dfs(
9894
graph,
99-
root_vertex,
100-
root_vertex.id(),
101-
impl::default_visit_vertex_predicate<GraphType>(visited),
102-
impl::default_visit_callback<GraphType, ResultDiscriminator>(visited, pd),
95+
root_id,
96+
root_id, // pred_id
97+
impl::default_visit_vertex_predicate(visited),
98+
impl::default_visit_callback<ResultDiscriminator>(visited, pd),
10399
impl::default_enqueue_vertex_predicate<GraphType>(visited),
104100
pre_visit,
105101
post_visit

include/gl/algorithm/dijkstra.hpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,8 @@ template <type_traits::c_graph GraphType>
6565

6666
template <
6767
type_traits::c_graph GraphType,
68-
type_traits::c_optional_vertex_callback<GraphType, void> PreVisitCallback =
69-
algorithm::empty_callback,
70-
type_traits::c_optional_vertex_callback<GraphType, void> PostVisitCallback =
71-
algorithm::empty_callback>
68+
type_traits::c_optional_id_callback<void> PreVisitCallback = algorithm::empty_callback,
69+
type_traits::c_optional_id_callback<void> PostVisitCallback = algorithm::empty_callback>
7270
[[nodiscard]] paths_descriptor_type<GraphType> dijkstra_shortest_paths(
7371
const GraphType& graph,
7472
const types::id_type source_id,
@@ -94,22 +92,21 @@ template <
9492
impl::init_range(source_id),
9593
algorithm::empty_callback{}, // visit predicate
9694
algorithm::empty_callback{}, // visit callback
97-
[&paths, &negative_edge](const vertex_type& vertex, const edge_type& in_edge)
95+
[&paths, &negative_edge](const types::id_type vertex_id, const edge_type& in_edge)
9896
-> predicate_result { // enqueue predicate
99-
const auto vertex_id = vertex.id();
100-
const auto source_id = in_edge.incident_vertex(vertex).id();
97+
const auto pred_id = in_edge.incident_vertex(vertex_id).id();
10198

10299
const auto edge_weight = get_weight<GraphType>(in_edge);
103100
if (edge_weight < constants::zero) {
104101
negative_edge = std::cref(in_edge);
105102
return predicate_result::unknown;
106103
}
107104

108-
const auto new_distance = paths.distances[source_id] + edge_weight;
105+
const auto new_distance = paths.distances[pred_id] + edge_weight;
109106
if (not paths.predecessors[vertex_id].has_value()
110107
or new_distance < paths.distances[vertex_id]) {
111108
paths.distances[vertex_id] = new_distance;
112-
paths.predecessors[vertex_id].emplace(source_id);
109+
paths.predecessors[vertex_id].emplace(pred_id);
113110
return true;
114111
}
115112

include/gl/algorithm/impl/bfs.hpp

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,11 @@ template <
1414
type_traits::c_graph GraphType,
1515
type_traits::c_sized_range_of<algorithm::vertex_info> InitQueueRangeType =
1616
std::vector<algorithm::vertex_info>,
17-
type_traits::c_optional_vertex_callback<GraphType, bool> VisitVertexPredicate,
18-
type_traits::c_optional_vertex_callback<GraphType, bool, types::id_type> VisitCallback,
19-
type_traits::c_vertex_callback<GraphType, predicate_result, const typename GraphType::edge_type&>
20-
EnqueueVertexPred,
21-
type_traits::c_optional_vertex_callback<GraphType, void> PreVisitCallback =
22-
algorithm::empty_callback,
23-
type_traits::c_optional_vertex_callback<GraphType, void> PostVisitCallback =
24-
algorithm::empty_callback>
17+
type_traits::c_optional_id_callback<bool> VisitVertexPredicate,
18+
type_traits::c_optional_id_callback<bool, types::id_type> VisitCallback,
19+
type_traits::c_id_callback<predicate_result, const typename GraphType::edge_type&> EnqueueVertexPred,
20+
type_traits::c_optional_id_callback<void> PreVisitCallback = algorithm::empty_callback,
21+
type_traits::c_optional_id_callback<void> PostVisitCallback = algorithm::empty_callback>
2522
bool bfs(
2623
const GraphType& graph,
2724
const InitQueueRangeType& initial_queue_content,
@@ -46,31 +43,30 @@ bool bfs(
4643
const algorithm::vertex_info vinfo = vertex_queue.front();
4744
vertex_queue.pop();
4845

49-
const auto& vertex = graph.get_vertex(vinfo.id);
5046
if constexpr (not type_traits::c_empty_callback<VisitVertexPredicate>)
51-
if (not visit_vertex_pred(vertex))
47+
if (not visit_vertex_pred(vinfo.id))
5248
continue;
5349

5450
if constexpr (not type_traits::c_empty_callback<PreVisitCallback>)
55-
pre_visit(vertex);
51+
pre_visit(vinfo.id);
5652

5753
if constexpr (not type_traits::c_empty_callback<VisitCallback>)
58-
if (not visit(vertex, vinfo.source_id))
54+
if (not visit(vinfo.id, vinfo.pred_id))
5955
return false;
6056

6157
for (const auto& edge : graph.adjacent_edges(vinfo.id)) {
62-
const auto& incident_vertex = edge.incident_vertex(vertex);
58+
const auto incident_vertex_id = edge.incident_vertex(vinfo.id).id();
6359

64-
const auto enqueue = enqueue_vertex_pred(incident_vertex, edge);
60+
const auto enqueue = enqueue_vertex_pred(incident_vertex_id, edge);
6561
if (enqueue == predicate_result::unknown)
6662
return false;
6763

6864
if (enqueue)
69-
vertex_queue.emplace(incident_vertex.id(), vinfo.id);
65+
vertex_queue.emplace(incident_vertex_id, vinfo.id);
7066
}
7167

7268
if constexpr (not type_traits::c_empty_callback<PostVisitCallback>)
73-
post_visit(vertex);
69+
post_visit(vinfo.id);
7470
}
7571

7672
return true;

include/gl/algorithm/impl/common.hpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,21 @@ template <
3030
return InitRangeType{algorithm::vertex_info{root_vertex_id}};
3131
}
3232

33-
template <type_traits::c_graph GraphType>
3433
[[nodiscard]] gl_attr_force_inline auto default_visit_vertex_predicate(std::vector<bool>& visited) {
35-
return [&](const typename GraphType::vertex_type& vertex) -> bool {
36-
return not visited[vertex.id()];
34+
return [&](const types::id_type vertex_id) -> bool {
35+
return not visited[vertex_id];
3736
};
3837
}
3938

40-
template <type_traits::c_graph GraphType, result_discriminator ResultDiscriminator>
39+
template <result_discriminator ResultDiscriminator>
4140
[[nodiscard]] gl_attr_force_inline auto default_visit_callback(
4241
std::vector<bool>& visited,
4342
alg_return_type_non_void<ResultDiscriminator, predecessors_descriptor>& pd
4443
) {
45-
return [&](const typename GraphType::vertex_type& vertex, const types::id_type source_id) {
46-
const auto vertex_id = vertex.id();
44+
return [&](const types::id_type vertex_id, const types::id_type pred_id) {
4745
visited[vertex_id] = true;
4846
if constexpr (ResultDiscriminator == algorithm::ret)
49-
pd[vertex_id].emplace(source_id);
47+
pd[vertex_id].emplace(pred_id);
5048
return true;
5149
};
5250
}
@@ -56,9 +54,8 @@ template <type_traits::c_graph GraphType, bool AsResult = false>
5654
) {
5755
using return_type = std::conditional_t<AsResult, predicate_result, bool>;
5856

59-
return [&](const typename GraphType::vertex_type& vertex,
60-
const typename GraphType::edge_type& in_edge) -> return_type {
61-
return not visited[vertex.id()];
57+
return [&](const types::id_type vertex_id, const typename GraphType::edge_type& in_edge) -> return_type {
58+
return not visited[vertex_id];
6259
};
6360
}
6461

0 commit comments

Comments
 (0)