Skip to content

Commit 47d7f12

Browse files
committed
edges store only vertex ids
1 parent 06c7258 commit 47d7f12

24 files changed

Lines changed: 273 additions & 414 deletions

include/gl/algorithm/coloring.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ template <
2626
coloring_opt.emplace(graph.n_vertices(), bin_color_value::unset);
2727
auto& coloring = coloring_opt.value();
2828

29-
for (const auto root_vertex : graph.vertices()) {
30-
const auto root_id = root_vertex.id();
29+
for (const auto root_id : graph.vertex_ids()) {
3130
if (coloring[root_id].is_set())
3231
continue;
3332

@@ -44,7 +43,7 @@ template <
4443
if (in_edge.is_loop())
4544
return false;
4645

47-
const auto pred_id = in_edge.incident_vertex(vertex_id).id();
46+
const auto pred_id = in_edge.incident_vertex(vertex_id);
4847

4948
if (coloring[vertex_id] == coloring[pred_id])
5049
return predicate_result::unknown; // graph is not bipartite

include/gl/algorithm/dijkstra.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ template <
9494
algorithm::empty_callback{}, // visit callback
9595
[&paths, &negative_edge](const types::id_type vertex_id, const edge_type& in_edge)
9696
-> predicate_result { // enqueue predicate
97-
const auto pred_id = in_edge.incident_vertex(vertex_id).id();
97+
const auto pred_id = in_edge.incident_vertex(vertex_id);
9898

9999
const auto edge_weight = get_weight<GraphType>(in_edge);
100100
if (edge_weight < constants::zero) {
@@ -118,8 +118,8 @@ template <
118118
const auto& edge = negative_edge.value().get();
119119
throw std::invalid_argument(std::format(
120120
"[alg::dijkstra_shortest_paths] Found an edge with a negative weight: [{}, {} | w={}]",
121-
edge.first().id(),
122-
edge.second().id(),
121+
edge.first(),
122+
edge.second(),
123123
get_weight<GraphType>(edge)
124124
));
125125
}

include/gl/algorithm/impl/bfs.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ bool bfs(
5656
return false;
5757

5858
for (const auto& edge : graph.adjacent_edges(vinfo.id)) {
59-
const auto incident_vertex_id = edge.incident_vertex(vinfo.id).id();
59+
const auto incident_vertex_id = edge.incident_vertex(vinfo.id);
6060

6161
const auto enqueue = enqueue_vertex_pred(incident_vertex_id, edge);
6262
if (enqueue == predicate_result::unknown)

include/gl/algorithm/impl/dfs.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void dfs(
5252
visit(vinfo.id, vinfo.pred_id);
5353

5454
for (const auto& edge : graph.adjacent_edges(vinfo.id)) {
55-
const auto incident_vertex_id = edge.incident_vertex(vinfo.id).id();
55+
const auto incident_vertex_id = edge.incident_vertex(vinfo.id);
5656
if (enqueue_vertex_pred(incident_vertex_id, edge))
5757
vertex_stack.emplace(incident_vertex_id, vinfo.id);
5858
}
@@ -91,7 +91,7 @@ void r_dfs(
9191

9292
// recursively search vertices adjacent to the current vertex
9393
for (const auto& edge : graph.adjacent_edges(vertex_id)) {
94-
const auto& incident_vertex_id = edge.incident_vertex(vertex_id).id();
94+
const auto& incident_vertex_id = edge.incident_vertex(vertex_id);
9595
if (enqueue_vertex_pred(incident_vertex_id, edge))
9696
r_dfs(
9797
graph,

include/gl/algorithm/impl/pfs.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bool pfs(
5959
return false;
6060

6161
for (const auto& edge : graph.adjacent_edges(vinfo.id)) {
62-
const auto incident_vertex_id = edge.incident_vertex(vinfo.id).id();
62+
const auto incident_vertex_id = edge.incident_vertex(vinfo.id);
6363

6464
const auto enqueue = enqueue_vertex_pred(incident_vertex_id, edge);
6565
if (enqueue == predicate_result::unknown)

include/gl/algorithm/mst.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ template <type_traits::c_undirected_graph GraphType>
7272
const auto& min_edge = min_edge_info.edge.get();
7373
const auto min_weight = get_weight<GraphType>(min_edge);
7474

75-
const auto& target_id = min_edge.incident_vertex(min_edge_info.source_id).id();
75+
const auto& target_id = min_edge.incident_vertex(min_edge_info.source_id);
7676
if (visited[target_id])
7777
continue;
7878

@@ -85,7 +85,7 @@ template <type_traits::c_undirected_graph GraphType>
8585

8686
// enqueue all edges adjacent to the `target` vertex if they lead to unvisited verties
8787
for (const auto& edge : graph.adjacent_edges(target_id))
88-
if (not visited[edge.incident_vertex(target_id).id()])
88+
if (not visited[edge.incident_vertex(target_id)])
8989
edge_queue.emplace(edge, target_id);
9090
}
9191

@@ -141,7 +141,7 @@ requires type_traits::c_has_numeric_limits_max<types::vertex_distance_type<Graph
141141
// Update adjacent vertices
142142
for (const auto& edge : graph.adjacent_edges(vertex_id)) {
143143
const auto edge_weight = get_weight<GraphType>(edge);
144-
const auto incident_vertex_id = edge.incident_vertex(vertex_id).id();
144+
const auto incident_vertex_id = edge.incident_vertex(vertex_id);
145145

146146
if (not in_mst[incident_vertex_id] && edge_weight < min_cost[incident_vertex_id]) {
147147
min_cost[incident_vertex_id] = edge_weight;

include/gl/edge_descriptor.hpp

Lines changed: 28 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@
1111
namespace gl {
1212

1313
template <
14-
type_traits::c_instantiation_of<vertex_descriptor> VertexType,
1514
type_traits::c_edge_directional_tag DirectionalTag = directed_t,
1615
type_traits::c_properties Properties = types::empty_properties>
1716
class edge_descriptor final {
1817
public:
19-
using type = edge_descriptor<VertexType, DirectionalTag, Properties>;
20-
using vertex_type = VertexType;
18+
using type = edge_descriptor<DirectionalTag, Properties>;
2119
using directional_tag = DirectionalTag;
2220
using properties_type = Properties;
2321
using properties_ref_type = std::conditional_t<
@@ -34,14 +32,14 @@ class edge_descriptor final {
3432
edge_descriptor(const edge_descriptor&) = delete;
3533
edge_descriptor& operator=(const edge_descriptor&) = delete;
3634

37-
explicit edge_descriptor(const vertex_type first, const vertex_type& second)
38-
: _vertices(std::move(first), std::move(second)) {}
35+
explicit edge_descriptor(const types::id_type first, const types::id_type second)
36+
: _vertices(first, second) {}
3937

4038
explicit edge_descriptor(
41-
const vertex_type first, const vertex_type second, properties_type properties
39+
const types::id_type first, const types::id_type second, properties_type properties
4240
)
4341
requires(not type_traits::is_default_properties_type_v<properties_type>)
44-
: _vertices(std::move(first), std::move(second)), _properties(properties) {}
42+
: _vertices(first, second), _properties(properties) {}
4543

4644
edge_descriptor(edge_descriptor&&) = default;
4745
edge_descriptor& operator=(edge_descriptor&&) = default;
@@ -59,68 +57,45 @@ class edge_descriptor final {
5957
// clang-format off
6058
// gl_attr_force_inline misplacement
6159

62-
[[nodiscard]] gl_attr_force_inline
63-
const types::homogeneous_pair<const vertex_type>& incident_vertices() const {
60+
[[nodiscard]] gl_attr_force_inline types::homogeneous_pair<const types::id_type> incident_vertices() const {
6461
return this->_vertices;
6562
}
6663

67-
[[nodiscard]] gl_attr_force_inline const types::homogeneous_pair<types::id_type> incident_vertex_ids() const {
68-
return std::make_pair(this->_vertices.first.id(), this->_vertices.second.id());
69-
}
70-
71-
[[nodiscard]] gl_attr_force_inline const vertex_type& first() const {
64+
[[nodiscard]] gl_attr_force_inline const types::id_type first() const {
7265
return this->_vertices.first;
7366
}
7467

75-
[[nodiscard]] gl_attr_force_inline const vertex_type& second() const {
68+
[[nodiscard]] gl_attr_force_inline const types::id_type second() const {
7669
return this->_vertices.second;
7770
}
7871

7972
// clang-format on
8073

8174
// returns the `other` vertex or throws error if the given vertex is not incident with the edge
82-
[[nodiscard]] const vertex_type incident_vertex(const types::id_type vertex_id) const {
83-
if (vertex_id == this->_vertices.first.id())
75+
[[nodiscard]] const types::id_type incident_vertex(const types::id_type vertex_id) const {
76+
if (vertex_id == this->_vertices.first)
8477
return this->_vertices.second;
8578

86-
if (vertex_id == this->_vertices.second.id())
79+
if (vertex_id == this->_vertices.second)
8780
return this->_vertices.first;
8881

8982
throw std::invalid_argument(std::format("Got invalid vertex id: {}", vertex_id));
9083
}
9184

92-
[[nodiscard]] const vertex_type incident_vertex(const vertex_type& vertex) const {
93-
return this->incident_vertex(vertex.id());
94-
}
95-
9685
[[nodiscard]] gl_attr_force_inline bool is_incident_with(const types::id_type vertex_id) const {
97-
return vertex_id == this->_vertices.first.id() or vertex_id == this->_vertices.second.id();
98-
}
99-
100-
[[nodiscard]] gl_attr_force_inline bool is_incident_with(const vertex_type& vertex) const {
101-
return this->is_incident_with(vertex.id());
86+
return vertex_id == this->_vertices.first or vertex_id == this->_vertices.second;
10287
}
10388

10489
// true if the given vertex is the `source` of the edge
10590
[[nodiscard]] gl_attr_force_inline bool is_incident_from(const types::id_type vertex_id) const {
10691
return directional_tag::is_incident_from(*this, vertex_id);
10792
}
10893

109-
// true if the given vertex is the `source` of the edge
110-
[[nodiscard]] gl_attr_force_inline bool is_incident_from(const vertex_type& vertex) const {
111-
return this->is_incident_from(vertex.id());
112-
}
113-
11494
// true if the given vertex is the `target` vertex of the edge
11595
[[nodiscard]] gl_attr_force_inline bool is_incident_to(const types::id_type vertex_id) const {
11696
return directional_tag::is_incident_to(*this, vertex_id);
11797
}
11898

119-
// true if the given vertex is the `target` vertex of the edge
120-
[[nodiscard]] gl_attr_force_inline bool is_incident_to(const vertex_type& vertex) const {
121-
return this->is_incident_to(vertex.id());
122-
}
123-
12499
[[nodiscard]] gl_attr_force_inline bool is_loop() const {
125100
return this->_vertices.first == this->_vertices.second;
126101
}
@@ -135,75 +110,49 @@ class edge_descriptor final {
135110
}
136111

137112
private:
138-
class vertex_writer {
139-
public:
140-
vertex_writer(const vertex_type& vertex, bool within_context)
141-
: _vertex_ref(vertex), _within_context(within_context) {}
142-
143-
friend std::ostream& operator<<(std::ostream& os, const vertex_writer& vw) {
144-
if (vw._within_context)
145-
os << vw._vertex_ref.id();
146-
else
147-
os << vw._vertex_ref;
148-
return os;
149-
}
150-
151-
private:
152-
const vertex_type& _vertex_ref;
153-
bool _within_context;
154-
};
155-
156-
void _write(std::ostream& os, bool within_context = false) const {
113+
void _write(std::ostream& os) const {
157114
if constexpr (not type_traits::c_writable<properties_type>) {
158-
this->_write_no_properties(os, within_context);
115+
this->_write_no_properties(os);
159116
return;
160117
}
161118
else {
162119
if (not io::is_option_set(os, io::graph_option::with_edge_properties)) {
163-
this->_write_no_properties(os, within_context);
120+
this->_write_no_properties(os);
164121
return;
165122
}
166123

167124
if (io::is_option_set(os, io::graph_option::verbose)) {
168-
os << "[first: " << vertex_writer(this->first(), within_context)
169-
<< ", second: " << vertex_writer(this->second(), within_context)
125+
os << "[first: " << this->_vertices.first << ", second: " << this->_vertices.second
170126
<< " | properties: " << this->_properties << "]";
171127
}
172128
else {
173-
os << "[" << vertex_writer(this->first(), within_context) << ", "
174-
<< vertex_writer(this->second(), within_context) << " | " << this->_properties
175-
<< "]";
129+
os << "[" << this->_vertices.first << ", " << this->_vertices.second << " | "
130+
<< this->_properties << "]";
176131
}
177132
}
178133
}
179134

180-
void _write_no_properties(std::ostream& os, bool within_context = false) const {
135+
void _write_no_properties(std::ostream& os) const {
181136
if (io::is_option_set(os, io::graph_option::verbose))
182-
os << "[first: " << vertex_writer(this->first(), within_context)
183-
<< ", second: " << vertex_writer(this->second(), within_context) << "]";
137+
os << "[first: " << this->_vertices.first << ", second: " << this->_vertices.first
138+
<< "]";
184139
else
185-
os << "[" << vertex_writer(this->first(), within_context) << ", "
186-
<< vertex_writer(this->second(), within_context) << "]";
140+
os << "[" << this->_vertices.first << ", " << this->_vertices.second << "]";
187141
}
188142

189-
types::homogeneous_pair<const vertex_type> _vertices;
143+
types::homogeneous_pair<types::id_type> _vertices;
190144
[[no_unique_address]] mutable properties_type _properties{};
191145
};
192146

193147
template <
194-
type_traits::c_instantiation_of<vertex_descriptor> VertexType,
195148
type_traits::c_edge_directional_tag DirectionalTag = directed_t,
196149
type_traits::c_properties Properties = types::empty_properties>
197-
using edge = edge_descriptor<VertexType, DirectionalTag, Properties>;
150+
using edge = edge_descriptor<DirectionalTag, Properties>;
198151

199-
template <
200-
type_traits::c_instantiation_of<vertex_descriptor> VertexType,
201-
type_traits::c_properties Properties = types::empty_properties>
202-
using directed_edge = edge_descriptor<VertexType, directed_t, Properties>;
152+
template <type_traits::c_properties Properties = types::empty_properties>
153+
using directed_edge = edge_descriptor<directed_t, Properties>;
203154

204-
template <
205-
type_traits::c_instantiation_of<vertex_descriptor> VertexType,
206-
type_traits::c_properties Properties = types::empty_properties>
207-
using undirected_edge = edge_descriptor<VertexType, undirected_t, Properties>;
155+
template <type_traits::c_properties Properties = types::empty_properties>
156+
using undirected_edge = edge_descriptor<undirected_t, Properties>;
208157

209158
} // namespace gl

include/gl/edge_tags.hpp

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,7 @@ concept c_edge_directional_tag = c_one_of<T, directed_t, undirected_t>;
2121

2222
} // namespace type_traits
2323

24-
template <type_traits::c_properties Properties>
25-
class vertex_descriptor;
26-
27-
template <
28-
type_traits::c_instantiation_of<vertex_descriptor> VertexType,
29-
type_traits::c_edge_directional_tag EdgeTag,
30-
type_traits::c_properties Properties>
24+
template <type_traits::c_edge_directional_tag EdgeTag, type_traits::c_properties Properties>
3125
class edge_descriptor;
3226

3327
namespace type_traits {
@@ -58,16 +52,16 @@ struct directed_t {
5852
template <type_traits::c_instantiation_of<edge_descriptor> EdgeType>
5953
requires(type_traits::is_directed_v<EdgeType>)
6054
[[nodiscard]] gl_attr_force_inline static edge_ptr_type<EdgeType> make(
61-
const typename EdgeType::vertex_type& first, const typename EdgeType::vertex_type& second
55+
const types::id_type first, const types::id_type second
6256
) {
6357
return std::make_unique<EdgeType>(first, second);
6458
}
6559

6660
template <type_traits::c_instantiation_of<edge_descriptor> EdgeType>
6761
requires(type_traits::is_directed_v<EdgeType>)
6862
[[nodiscard]] gl_attr_force_inline static edge_ptr_type<EdgeType> make(
69-
const typename EdgeType::vertex_type& first,
70-
const typename EdgeType::vertex_type& second,
63+
const types::id_type first,
64+
const types::id_type second,
7165
const typename EdgeType::properties_type& properties
7266
) {
7367
return std::make_unique<EdgeType>(first, second, properties);
@@ -78,15 +72,15 @@ struct directed_t {
7872
[[nodiscard]] gl_attr_force_inline static bool is_incident_from(
7973
const EdgeType& edge, const types::id_type vertex_id
8074
) {
81-
return vertex_id == edge._vertices.first.id();
75+
return vertex_id == edge._vertices.first;
8276
}
8377

8478
template <type_traits::c_instantiation_of<edge_descriptor> EdgeType>
8579
requires(type_traits::is_directed_v<EdgeType>)
8680
[[nodiscard]] gl_attr_force_inline static bool is_incident_to(
8781
const EdgeType& edge, const types::id_type vertex_id
8882
) {
89-
return vertex_id == edge._vertices.second.id();
83+
return vertex_id == edge._vertices.second;
9084
}
9185
};
9286

@@ -100,16 +94,16 @@ struct undirected_t {
10094
template <type_traits::c_instantiation_of<edge_descriptor> EdgeType>
10195
requires(type_traits::is_undirected_v<EdgeType>)
10296
[[nodiscard]] gl_attr_force_inline static edge_ptr_type<EdgeType> make(
103-
const typename EdgeType::vertex_type& first, const typename EdgeType::vertex_type& second
97+
const types::id_type first, const types::id_type second
10498
) {
10599
return std::make_shared<EdgeType>(first, second);
106100
}
107101

108102
template <type_traits::c_instantiation_of<edge_descriptor> EdgeType>
109103
requires(type_traits::is_undirected_v<EdgeType>)
110104
[[nodiscard]] gl_attr_force_inline static edge_ptr_type<EdgeType> make(
111-
const typename EdgeType::vertex_type& first,
112-
const typename EdgeType::vertex_type& second,
105+
const types::id_type first,
106+
const types::id_type second,
113107
const typename EdgeType::properties_type& properties
114108
) {
115109
return std::make_shared<EdgeType>(first, second, properties);
@@ -143,15 +137,15 @@ namespace detail {
143137

144138
template <type_traits::c_instantiation_of<edge_descriptor> EdgeType>
145139
[[nodiscard]] gl_attr_force_inline types::edge_ptr_type<EdgeType> make_edge(
146-
const typename EdgeType::vertex_type& first, const typename EdgeType::vertex_type& second
140+
const types::id_type first, const types::id_type second
147141
) {
148142
return EdgeType::directional_tag::template make<EdgeType>(first, second);
149143
}
150144

151145
template <type_traits::c_instantiation_of<edge_descriptor> EdgeType>
152146
[[nodiscard]] gl_attr_force_inline types::edge_ptr_type<EdgeType> make_edge(
153-
const typename EdgeType::vertex_type& first,
154-
const typename EdgeType::vertex_type& second,
147+
const types::id_type first,
148+
const types::id_type second,
155149
const typename EdgeType::properties_type& properties
156150
) {
157151
return EdgeType::directional_tag::template make<EdgeType>(first, second, properties);

0 commit comments

Comments
 (0)