Skip to content

Commit 6f64f55

Browse files
committed
hyperedge list alignment
1 parent afa3fc9 commit 6f64f55

6 files changed

Lines changed: 176 additions & 65 deletions

File tree

include/hgl/hypergraph.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ class hypergraph final {
368368
this->_n_vertices--;
369369
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
370370
this->_vertex_properties.erase(this->_vertex_properties.begin() + vertex_id);
371+
// TODO: impl::remove_vertex(vertex_id)
371372
}
372373

373374
// --- hyperedge methods ---

include/hgl/hypergraph_traits.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ template <
3737
type_traits::c_hypergraph_directional_tag DirectionalTag = undirected_t,
3838
type_traits::c_properties VertexProperties = types::empty_properties,
3939
type_traits::c_properties HyperedgeProperties = types::empty_properties>
40-
using adjacency_list_hg_traits =
41-
hypergraph_traits<DirectionalTag, VertexProperties, HyperedgeProperties, impl::adjacency_list_t>;
40+
using vertex_list_hg_traits =
41+
hypergraph_traits<DirectionalTag, VertexProperties, HyperedgeProperties, impl::vertex_list_t>;
4242

4343
template <
4444
type_traits::c_hypergraph_directional_tag DirectionalTag = undirected_t,
@@ -69,9 +69,9 @@ concept c_hyperedge_list_hg_traits =
6969
and std::same_as<typename TraitsType::implementation_tag, impl::hyperedge_list_t>;
7070

7171
template <typename TraitsType>
72-
concept c_adjacency_list_hg_traits =
72+
concept c_vertex_list_hg_traits =
7373
c_instantiation_of<TraitsType, hypergraph_traits>
74-
and std::same_as<typename TraitsType::implementation_tag, impl::adjacency_list_t>;
74+
and std::same_as<typename TraitsType::implementation_tag, impl::vertex_list_t>;
7575

7676
template <typename TraitsType>
7777
concept c_incidence_matrix_hg_traits =

include/hgl/impl/hyperedge_list.hpp

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "hgl/types/types.hpp"
88

99
#include <algorithm>
10+
#include <ranges>
1011
#include <vector>
1112

1213
#ifdef HGL_TESTING
@@ -45,11 +46,36 @@ class undirected_hyperedge_list final {
4546

4647
// --- vertex methods ---
4748

48-
gl_attr_force_inline void add_vertices(const types::size_type) const noexcept {}
49+
// clang-format off
50+
51+
gl_attr_force_inline void add_vertices([[maybe_unused]] const types::size_type) const noexcept {}
52+
53+
// clang-format on
4954

5055
void remove_vertex(const types::id_type vertex_id) noexcept {
51-
for (auto& hyperedge_vertices : this->_storage)
52-
this->_unbind_impl(hyperedge_vertices, vertex_id);
56+
for (auto& hyperedge : this->_storage) {
57+
auto vertex_it = std::ranges::lower_bound(hyperedge, vertex_id);
58+
if (vertex_it != hyperedge.end() and *vertex_it == vertex_id)
59+
vertex_it = hyperedge.erase(vertex_it); // unbind the vertex
60+
while (vertex_it != hyperedge.end())
61+
--(*vertex_it++); // decrement ids > vertex_id
62+
}
63+
}
64+
65+
[[nodiscard]] gl_attr_force_inline auto incident_hyperedges(const types::id_type vertex_id
66+
) const noexcept {
67+
return std::views::iota(0uz, this->_storage.size())
68+
| std::views::filter([this, vertex_id](types::id_type hid) {
69+
return this->_are_bound_impl(this->_storage[hid], vertex_id);
70+
});
71+
}
72+
73+
[[nodiscard]] types::size_type degree(const types::id_type vertex_id) const noexcept {
74+
types::size_type deg = 0uz;
75+
for (const auto& hyperedge : this->_storage)
76+
if (this->_are_bound_impl(hyperedge, vertex_id))
77+
++deg;
78+
return deg;
5379
}
5480

5581
// --- hyperedge methods ---
@@ -62,52 +88,53 @@ class undirected_hyperedge_list final {
6288
this->_storage.erase(this->_storage.begin() + hyperedge_id);
6389
}
6490

65-
[[nodiscard]] gl_attr_force_inline types::size_type hyperedge_size(
66-
const types::id_type hyperedge_id
91+
[[nodiscard]] gl_attr_force_inline auto incident_vertices(const types::id_type hyperedge_id
6792
) const noexcept {
68-
return this->_storage[hyperedge_id].size();
93+
return std::views::all(this->_storage[hyperedge_id]);
6994
}
7095

71-
[[nodiscard]] gl_attr_force_inline auto hyperedge_vertices(const types::id_type hyperedge_id
96+
[[nodiscard]] gl_attr_force_inline types::size_type hyperedge_size(
97+
const types::id_type hyperedge_id
7298
) const noexcept {
73-
return std::views::all(this->_storage[hyperedge_id]);
99+
return this->_storage[hyperedge_id].size();
74100
}
75101

76102
// --- binding methods ---
77103

78-
void bind(const types::id_type hyperedge_id, const types::id_type vertex_id) noexcept {
79-
auto& hyperedge_vertices = this->_storage[hyperedge_id];
104+
void bind(const types::id_type vertex_id, const types::id_type hyperedge_id) noexcept {
105+
auto& hyperedge = this->_storage[hyperedge_id];
80106

81107
// insert the id at the correct position to keep the vertex-id collection sorted
82-
const auto it = std::ranges::lower_bound(hyperedge_vertices, vertex_id);
83-
if (it == hyperedge_vertices.end() or *it != vertex_id)
84-
hyperedge_vertices.insert(it, vertex_id);
108+
const auto it = std::ranges::lower_bound(hyperedge, vertex_id);
109+
if (it == hyperedge.end() or *it != vertex_id)
110+
hyperedge.insert(it, vertex_id);
85111
}
86112

87113
gl_attr_force_inline void unbind(
88-
const types::id_type hyperedge_id, const types::id_type vertex_id
114+
const types::id_type vertex_id, const types::id_type hyperedge_id
89115
) noexcept {
90-
this->_unbind_impl(this->_storage[hyperedge_id], vertex_id);
116+
auto& hyperedge = this->_storage[hyperedge_id];
117+
const auto vertex_it = std::ranges::lower_bound(hyperedge, vertex_id);
118+
if (vertex_it != hyperedge.end() and *vertex_it == vertex_id)
119+
hyperedge.erase(vertex_it);
91120
}
92121

93-
[[nodiscard]] bool are_bound(const types::id_type hyperedge_id, const types::id_type vertex_id)
94-
const noexcept {
95-
auto& hyperedge_vertices = this->_storage[hyperedge_id];
96-
const auto vertex_it = std::ranges::lower_bound(hyperedge_vertices, vertex_id);
97-
return vertex_it != hyperedge_vertices.end() and *vertex_it == vertex_id;
122+
[[nodiscard]] gl_attr_force_inline bool are_bound(
123+
const types::id_type vertex_id, const types::id_type hyperedge_id
124+
) const noexcept {
125+
return this->_are_bound_impl(this->_storage[hyperedge_id], vertex_id);
98126
}
99127

100128
#ifdef HGL_TESTING
101129
friend struct hgl_testing::test_hyperedge_list;
102130
#endif
103131

104132
private:
105-
void _unbind_impl(
106-
hyperedge_storage_type& hyperedge_vertices, const types::id_type vertex_id
107-
) noexcept {
108-
const auto vertex_it = std::ranges::lower_bound(hyperedge_vertices, vertex_id);
109-
if (vertex_it != hyperedge_vertices.end() and *vertex_it == vertex_id)
110-
hyperedge_vertices.erase(vertex_it);
133+
[[nodiscard]] bool _are_bound_impl(
134+
const hyperedge_storage_type& hyperedge, const types::id_type vertex_id
135+
) const noexcept {
136+
const auto vertex_it = std::ranges::lower_bound(hyperedge, vertex_id);
137+
return vertex_it != hyperedge.end() and *vertex_it == vertex_id;
111138
}
112139

113140
hypergraph_storage_type _storage;

include/hgl/impl/impl_tags.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace impl {
1212

1313
struct hyperedge_list_t {};
1414

15-
struct adjacency_list_t {};
15+
struct vertex_list_t {};
1616

1717
struct incidence_matrix_t {};
1818

@@ -22,7 +22,7 @@ namespace type_traits {
2222

2323
template <typename T>
2424
concept c_hypergraph_impl_tag =
25-
c_one_of<T, impl::hyperedge_list_t, impl::adjacency_list_t, impl::incidence_matrix_t>;
25+
c_one_of<T, impl::hyperedge_list_t, impl::vertex_list_t, impl::incidence_matrix_t>;
2626

2727
} // namespace type_traits
2828

0 commit comments

Comments
 (0)