Skip to content

Commit 4627cf1

Browse files
committed
split forward and backward search algorithms + dfs versions
1 parent 065f931 commit 4627cf1

6 files changed

Lines changed: 489 additions & 50 deletions

File tree

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright (c) 2024-2026 Jakub Musiał
2+
// This file is part of the CPP-GL project (https://github.com/SpectraL519/cpp-gl).
3+
// Licensed under the MIT License. See the LICENSE file in the project root for full license information.
4+
5+
#pragma once
6+
7+
#include "hgl/algorithm/core.hpp"
8+
#include "hgl/algorithm/templates/bfs.hpp"
9+
#include "hgl/algorithm/templates/dfs.hpp"
10+
#include "hgl/algorithm/util.hpp"
11+
#include "hgl/hypergraph.hpp"
12+
13+
namespace hgl::algorithm {
14+
15+
template <
16+
result_discriminator Result = ret,
17+
hgl::traits::c_bf_directed_hypergraph H,
18+
traits::c_forward_range_of<typename H::id_type> RootRange = std::vector<typename H::id_type>,
19+
gl::traits::c_optional_callback<void, const search_node<H>&> PreVisitCallback = empty_callback,
20+
gl::traits::c_optional_callback<void, const search_node<H>&> PostVisitCallback = empty_callback>
21+
return_type<Result, search_tree<H>> backward_bfs(
22+
const H& hypergraph,
23+
const RootRange& root_vertices,
24+
const PreVisitCallback& pre_visit = {},
25+
const PostVisitCallback& post_visit = {}
26+
) {
27+
using id_type = typename H::id_type;
28+
29+
std::vector<bool> visited_vertices(hypergraph.order(), false);
30+
auto tail_unvisited = hypergraph.tail_size_map() | std::ranges::to<std::vector>();
31+
32+
auto stree = init_search_tree<Result>(hypergraph);
33+
auto root_queue =
34+
root_vertices
35+
| std::views::transform([](const id_type root_id) { return search_node<H>{root_id}; });
36+
37+
const auto traverse_hyperedge_pred = [&tail_unvisited](id_type he_id, id_type) {
38+
return static_cast<decision>(--tail_unvisited[gl::to_idx(he_id)] == 0uz);
39+
};
40+
41+
// clang-format off
42+
43+
bfs<traversal_direction::forward>(
44+
hypergraph,
45+
root_queue,
46+
default_visit_vertex_predicate<H>(visited_vertices),
47+
default_visit_callback<H, Result>(visited_vertices, stree),
48+
traverse_hyperedge_pred,
49+
default_enqueue_vertex_predicate<H, true>(visited_vertices),
50+
pre_visit,
51+
post_visit
52+
);
53+
54+
// clang-format on
55+
56+
if constexpr (Result == ret)
57+
return stree;
58+
}
59+
60+
template <
61+
result_discriminator Result = ret,
62+
hgl::traits::c_bf_directed_hypergraph H,
63+
traits::c_forward_range_of<typename H::id_type> RootRange = std::vector<typename H::id_type>,
64+
gl::traits::c_optional_callback<void, const search_node<H>&> PreVisitCallback = empty_callback,
65+
gl::traits::c_optional_callback<void, const search_node<H>&> PostVisitCallback = empty_callback>
66+
return_type<Result, search_tree<H>> backward_dfs(
67+
const H& hypergraph,
68+
const RootRange& root_vertices,
69+
const PreVisitCallback& pre_visit = {},
70+
const PostVisitCallback& post_visit = {}
71+
) {
72+
using id_type = typename H::id_type;
73+
74+
std::vector<bool> visited_vertices(hypergraph.order(), false);
75+
auto tail_unvisited = hypergraph.tail_size_map() | std::ranges::to<std::vector>();
76+
77+
auto stree = init_search_tree<Result>(hypergraph);
78+
auto root_queue =
79+
root_vertices
80+
| std::views::transform([](const id_type root_id) { return search_node<H>{root_id}; });
81+
82+
const auto traverse_hyperedge_pred = [&tail_unvisited](id_type he_id, id_type) {
83+
return static_cast<decision>(--tail_unvisited[gl::to_idx(he_id)] == 0uz);
84+
};
85+
86+
// clang-format off
87+
88+
dfs<traversal_direction::forward>(
89+
hypergraph,
90+
root_queue,
91+
default_visit_vertex_predicate<H>(visited_vertices),
92+
default_visit_callback<H, Result>(visited_vertices, stree),
93+
traverse_hyperedge_pred,
94+
default_enqueue_vertex_predicate<H, true>(visited_vertices),
95+
pre_visit,
96+
post_visit
97+
);
98+
99+
// clang-format on
100+
101+
if constexpr (Result == ret)
102+
return stree;
103+
}
104+
105+
} // namespace hgl::algorithm

include/hgl/algorithm/traversal/bf_search.hpp renamed to include/hgl/algorithm/traversal/forward_search.hpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "hgl/algorithm/core.hpp"
88
#include "hgl/algorithm/templates/bfs.hpp"
9+
#include "hgl/algorithm/templates/dfs.hpp"
910
#include "hgl/algorithm/util.hpp"
1011
#include "hgl/hypergraph.hpp"
1112

@@ -17,7 +18,7 @@ template <
1718
traits::c_forward_range_of<typename H::id_type> RootRange = std::vector<typename H::id_type>,
1819
gl::traits::c_optional_callback<void, const search_node<H>&> PreVisitCallback = empty_callback,
1920
gl::traits::c_optional_callback<void, const search_node<H>&> PostVisitCallback = empty_callback>
20-
return_type<Result, search_tree<H>> backward_search(
21+
return_type<Result, search_tree<H>> forward_bfs(
2122
const H& hypergraph,
2223
const RootRange& root_vertices,
2324
const PreVisitCallback& pre_visit = {},
@@ -26,20 +27,20 @@ return_type<Result, search_tree<H>> backward_search(
2627
using id_type = typename H::id_type;
2728

2829
std::vector<bool> visited_vertices(hypergraph.order(), false);
29-
auto tail_unvisited = hypergraph.tail_size_map() | std::ranges::to<std::vector>();
30+
auto head_unvisited = hypergraph.head_size_map() | std::ranges::to<std::vector>();
3031

3132
auto stree = init_search_tree<Result>(hypergraph);
3233
auto root_queue =
3334
root_vertices
3435
| std::views::transform([](const id_type root_id) { return search_node<H>{root_id}; });
3536

36-
const auto traverse_hyperedge_pred = [&tail_unvisited](id_type he_id, id_type) {
37-
return static_cast<decision>(--tail_unvisited[gl::to_idx(he_id)] == 0uz);
37+
const auto traverse_hyperedge_pred = [&head_unvisited](id_type he_id, id_type) {
38+
return static_cast<decision>(--head_unvisited[gl::to_idx(he_id)] == 0uz);
3839
};
3940

4041
// clang-format off
4142

42-
bfs(
43+
bfs<traversal_direction::backward>(
4344
hypergraph,
4445
root_queue,
4546
default_visit_vertex_predicate<H>(visited_vertices),
@@ -62,7 +63,7 @@ template <
6263
traits::c_forward_range_of<typename H::id_type> RootRange = std::vector<typename H::id_type>,
6364
gl::traits::c_optional_callback<void, const search_node<H>&> PreVisitCallback = empty_callback,
6465
gl::traits::c_optional_callback<void, const search_node<H>&> PostVisitCallback = empty_callback>
65-
return_type<Result, search_tree<H>> forward_search(
66+
return_type<Result, search_tree<H>> forward_dfs(
6667
const H& hypergraph,
6768
const RootRange& root_vertices,
6869
const PreVisitCallback& pre_visit = {},
@@ -84,7 +85,7 @@ return_type<Result, search_tree<H>> forward_search(
8485

8586
// clang-format off
8687

87-
bfs<traversal_direction::backward>(
88+
dfs<traversal_direction::backward>(
8889
hypergraph,
8990
root_queue,
9091
default_visit_vertex_predicate<H>(visited_vertices),

0 commit comments

Comments
 (0)