Skip to content

Commit 5539241

Browse files
committed
incident_edges directed logic error fix
1 parent abef96d commit 5539241

18 files changed

Lines changed: 295 additions & 182 deletions

include/gl/algorithm/spanning_tree/prim_mst.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ template <traits::c_undirected_graph G>
5151
if (root_id == invalid_id)
5252
root_id = initial_id;
5353

54-
for (const auto& edge : graph.incident_edges(root_id))
54+
for (const auto& edge : graph.out_edges(root_id))
5555
edge_queue.emplace(edge);
5656

5757
// mark the root vertex as visited

include/gl/algorithm/templates/bfs.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ bool bfs(
5555
if (not visit(node.vertex_id, node.pred_id))
5656
return false;
5757

58-
for (const auto& edge : graph.incident_edges(node.vertex_id)) {
58+
for (const auto& edge : graph.out_edges(node.vertex_id)) {
5959
const auto target_vertex_id = edge.other(node.vertex_id);
6060
const auto enqueue = enqueue_vertex_pred(target_vertex_id, edge);
6161
if (enqueue == decision::abort)

include/gl/algorithm/templates/dfs.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ bool dfs(
5555
if (not visit(node.vertex_id, node.pred_id))
5656
return false;
5757

58-
for (const auto& edge : graph.incident_edges(node.vertex_id)) {
58+
for (const auto& edge : graph.out_edges(node.vertex_id)) {
5959
const auto target_vertex_id = edge.other(node.vertex_id);
6060
if (enqueue_vertex_pred(target_vertex_id, edge))
6161
s.emplace(target_vertex_id, node.vertex_id);
@@ -96,7 +96,7 @@ void r_dfs(
9696
visit(vertex_id, pred_id);
9797

9898
// recursively search vertices adjacent to the current vertex
99-
for (const auto& edge : graph.incident_edges(vertex_id)) {
99+
for (const auto& edge : graph.out_edges(vertex_id)) {
100100
const auto target_vertex_id = edge.other(vertex_id);
101101
if (enqueue_vertex_pred(target_vertex_id, edge))
102102
r_dfs(

include/gl/algorithm/templates/pfs.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bool pfs(
5959
if (not visit(node.vertex_id, node.pred_id))
6060
return false;
6161

62-
for (const auto& edge : graph.incident_edges(node.vertex_id)) {
62+
for (const auto& edge : graph.out_edges(node.vertex_id)) {
6363
const auto target_vertex_id = edge.other(node.vertex_id);
6464
const auto enqueue = enqueue_vertex_pred(target_vertex_id, edge);
6565
if (enqueue == decision::abort)

include/gl/graph.hpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ class graph final {
734734

735735
for (const auto& vertex : this->vertices()) {
736736
os << "- " << vertex << "\n incident edges:\n";
737-
for (const auto& edge : this->incident_edges(vertex.id()))
737+
for (const auto& edge : this->out_edges(vertex.id()))
738738
os << "\t- " << edge << '\n';
739739
}
740740
}
@@ -744,7 +744,7 @@ class graph final {
744744

745745
for (const auto& vertex : this->vertices()) {
746746
os << "- " << vertex << " :";
747-
for (const auto& edge : this->incident_edges(vertex.id()))
747+
for (const auto& edge : this->out_edges(vertex.id()))
748748
os << ' ' << edge;
749749
os << '\n';
750750
}
@@ -773,8 +773,8 @@ class graph final {
773773

774774
if constexpr (traits::c_writable<typename edge_type::properties_type>) {
775775
if (with_edge_properties) {
776-
const auto print_incident_edges = [this, &os](const id_type vertex_id) {
777-
for (const auto& edge : this->incident_edges(vertex_id)) {
776+
const auto print_out_edges = [this, &os](const id_type vertex_id) {
777+
for (const auto& edge : this->out_edges(vertex_id)) {
778778
if (edge.source() != vertex_id)
779779
continue; // vertex is not the source
780780
os << edge.source() << ' ' << edge.target() << ' ' << edge.properties()
@@ -783,22 +783,22 @@ class graph final {
783783
};
784784

785785
for (const auto vertex_id : this->vertex_ids())
786-
print_incident_edges(vertex_id);
786+
print_out_edges(vertex_id);
787787

788788
return;
789789
}
790790
}
791791

792-
const auto print_incident_edges = [this, &os](const id_type vertex_id) {
793-
for (const auto& edge : this->incident_edges(vertex_id)) {
792+
const auto print_out_edges = [this, &os](const id_type vertex_id) {
793+
for (const auto& edge : this->out_edges(vertex_id)) {
794794
if (edge.source() != vertex_id)
795795
continue; // vertex is not the source
796796
os << edge.source() << ' ' << edge.target() << '\n';
797797
}
798798
};
799799

800800
for (const auto vertex_id : this->vertex_ids())
801-
print_incident_edges(vertex_id);
801+
print_out_edges(vertex_id);
802802
}
803803

804804
void _gsf_read(std::istream& is) {

include/gl/impl/adjacency_list.hpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,9 @@ class adjacency_list final {
155155
[[nodiscard]] std::optional<edge_type> get_edge(id_type source_id, id_type target_id) const
156156
requires(traits::c_has_empty_properties<edge_type>)
157157
{
158-
const auto& incident_edges = this->_list[to_idx(source_id)];
159-
const auto item_it = std::ranges::find(incident_edges, target_id, &item_type::vertex_id);
160-
if (item_it == incident_edges.cend())
158+
const auto& out_edges = this->_list[to_idx(source_id)];
159+
const auto item_it = std::ranges::find(out_edges, target_id, &item_type::vertex_id);
160+
if (item_it == out_edges.cend())
161161
return std::nullopt;
162162
return std::make_optional<edge_type>(item_it->edge_id, source_id, target_id);
163163
}
@@ -167,11 +167,11 @@ class adjacency_list final {
167167
) const
168168
requires(traits::c_has_non_empty_properties<edge_type>)
169169
{
170-
const auto& incident_edges = this->_list[to_idx(source_id)];
171-
const auto item_it = std::ranges::find(incident_edges, target_id, [](const auto& item) {
170+
const auto& out_edges = this->_list[to_idx(source_id)];
171+
const auto item_it = std::ranges::find(out_edges, target_id, [](const auto& item) {
172172
return item.vertex_id;
173173
});
174-
if (item_it == incident_edges.cend())
174+
if (item_it == out_edges.cend())
175175
return std::nullopt;
176176
return std::make_optional<edge_type>(
177177
item_it->edge_id, source_id, target_id, *edge_properties_map[to_idx(item_it->edge_id)]
@@ -209,15 +209,15 @@ class adjacency_list final {
209209
[[nodiscard]] gl_attr_force_inline auto incident_edges(id_type vertex_id) const
210210
requires(traits::c_has_empty_properties<edge_type>)
211211
{
212-
return this->out_edges(vertex_id);
212+
return specialized_impl::incident_edges(*this, vertex_id);
213213
}
214214

215215
[[nodiscard]] gl_attr_force_inline auto incident_edges(
216216
id_type vertex_id, const auto& edge_properties_map
217217
) const
218218
requires(traits::c_has_non_empty_properties<edge_type>)
219219
{
220-
return this->out_edges(vertex_id, edge_properties_map);
220+
return specialized_impl::incident_edges(*this, vertex_id, edge_properties_map);
221221
}
222222

223223
[[nodiscard]] gl_attr_force_inline auto in_edges(id_type vertex_id) const
@@ -275,14 +275,14 @@ class adjacency_list final {
275275
[[nodiscard]] gl_attr_force_inline auto at(id_type vertex_id) const
276276
requires(traits::c_has_empty_properties<edge_type>)
277277
{
278-
return this->incident_edges(vertex_id);
278+
return this->out_edges(vertex_id);
279279
}
280280

281281
[[nodiscard]] gl_attr_force_inline auto at(id_type vertex_id, const auto& edge_properties_map)
282282
const
283283
requires(traits::c_has_non_empty_properties<edge_type>)
284284
{
285-
return this->incident_edges(vertex_id, edge_properties_map);
285+
return this->out_edges(vertex_id, edge_properties_map);
286286
}
287287

288288
// --- comparison ---

include/gl/impl/adjacency_matrix.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,15 +200,15 @@ class adjacency_matrix final {
200200
[[nodiscard]] gl_attr_force_inline auto incident_edges(id_type vertex_id) const
201201
requires(traits::c_has_empty_properties<edge_type>)
202202
{
203-
return this->out_edges(vertex_id);
203+
return specialized_impl::incident_edges(*this, vertex_id);
204204
}
205205

206206
[[nodiscard]] gl_attr_force_inline auto incident_edges(
207207
id_type vertex_id, const auto& edge_properties_map
208208
) const
209209
requires(traits::c_has_non_empty_properties<edge_type>)
210210
{
211-
return this->out_edges(vertex_id, edge_properties_map);
211+
return specialized_impl::incident_edges(*this, vertex_id, edge_properties_map);
212212
}
213213

214214
[[nodiscard]] gl_attr_force_inline auto in_edges(id_type vertex_id) const

include/gl/impl/specialized/adjacency_list.hpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ struct directed_adjacency_list {
118118

119119
[[nodiscard]] static size_type in_degree(const impl_type& self, id_type vertex_id) {
120120
size_type in_deg = 0uz;
121-
for (const auto& incident_edges : self._list)
121+
for (const auto& out_edges : self._list)
122122
in_deg += static_cast<size_type>(
123-
std::ranges::count(incident_edges, vertex_id, &item_type::vertex_id)
123+
std::ranges::count(out_edges, vertex_id, &item_type::vertex_id)
124124
);
125125

126126
return in_deg;
@@ -191,6 +191,21 @@ struct directed_adjacency_list {
191191

192192
// --- edge getters ---
193193

194+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
195+
const impl_type& self, id_type vertex_id
196+
) {
197+
return util::concat(self.in_edges(vertex_id), self.out_edges(vertex_id));
198+
}
199+
200+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
201+
const impl_type& self, id_type vertex_id, const auto& edge_properties_map
202+
) {
203+
return util::concat(
204+
self.in_edges(vertex_id, edge_properties_map),
205+
self.out_edges(vertex_id, edge_properties_map)
206+
);
207+
}
208+
194209
[[nodiscard]] static auto in_edges(const impl_type& self, id_type vertex_id) {
195210
std::vector<item_type> in_edges;
196211
for (id_type src_id = initial_id; src_id < self._list.size(); ++src_id) {
@@ -337,6 +352,18 @@ struct undirected_adjacency_list {
337352

338353
// --- edge getters ---
339354

355+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
356+
const impl_type& self, id_type vertex_id
357+
) {
358+
return self.out_edges(vertex_id);
359+
}
360+
361+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
362+
const impl_type& self, id_type vertex_id, const auto& edge_properties_map
363+
) {
364+
return self.out_edges(vertex_id, edge_properties_map);
365+
}
366+
340367
[[nodiscard]] gl_attr_force_inline static auto in_edges(
341368
const impl_type& self, id_type vertex_id
342369
) {

include/gl/impl/specialized/adjacency_matrix.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,23 @@ struct directed_adjacency_matrix {
225225
gl_attr_force_inline static void remove_edge(impl_type& self, const edge_type& edge) {
226226
detail::strict_get(self._matrix, edge) = invalid_id;
227227
}
228+
229+
// --- edge getters ---
230+
231+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
232+
const impl_type& self, id_type vertex_id
233+
) {
234+
return util::concat(self.in_edges(vertex_id), self.out_edges(vertex_id));
235+
}
236+
237+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
238+
const impl_type& self, id_type vertex_id, const auto& edge_properties_map
239+
) {
240+
return util::concat(
241+
self.in_edges(vertex_id, edge_properties_map),
242+
self.out_edges(vertex_id, edge_properties_map)
243+
);
244+
}
228245
};
229246

230247
template <traits::c_instantiation_of<adjacency_matrix> AdjacencyMatrix>
@@ -396,6 +413,20 @@ struct undirected_adjacency_matrix {
396413
self._matrix[to_idx(edge.target())][to_idx(edge.source())] = invalid_id;
397414
}
398415
}
416+
417+
// --- edge getters ---
418+
419+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
420+
const impl_type& self, id_type vertex_id
421+
) {
422+
return self.out_edges(vertex_id);
423+
}
424+
425+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
426+
const impl_type& self, id_type vertex_id, const auto& edge_properties_map
427+
) {
428+
return self.out_edges(vertex_id, edge_properties_map);
429+
}
399430
};
400431

401432
template <traits::c_instantiation_of<adjacency_matrix> AdjacencyMatrix>

include/gl/impl/specialized/flat_adjacency_list.hpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,21 @@ struct directed_flat_adjacency_list {
154154

155155
// --- edge getters ---
156156

157+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
158+
const impl_type& self, id_type vertex_id
159+
) {
160+
return util::concat(self.in_edges(vertex_id), self.out_edges(vertex_id));
161+
}
162+
163+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
164+
const impl_type& self, id_type vertex_id, const auto& edge_properties_map
165+
) {
166+
return util::concat(
167+
self.in_edges(vertex_id, edge_properties_map),
168+
self.out_edges(vertex_id, edge_properties_map)
169+
);
170+
}
171+
157172
[[nodiscard]] static auto in_edges(const impl_type& self, id_type vertex_id) {
158173
std::vector<item_type> in_edges;
159174
for (id_type src_id = initial_id; src_id < self._list.size(); ++src_id) {
@@ -318,6 +333,18 @@ struct undirected_flat_adjacency_list {
318333

319334
// --- edge getters ---
320335

336+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
337+
const impl_type& self, id_type vertex_id
338+
) {
339+
return self.out_edges(vertex_id);
340+
}
341+
342+
[[nodiscard]] gl_attr_force_inline static auto incident_edges(
343+
const impl_type& self, id_type vertex_id, const auto& edge_properties_map
344+
) {
345+
return self.out_edges(vertex_id, edge_properties_map);
346+
}
347+
321348
[[nodiscard]] gl_attr_force_inline static auto in_edges(
322349
const impl_type& self, id_type vertex_id
323350
) {

0 commit comments

Comments
 (0)