Skip to content

Commit

Permalink
Merge pull request #100 from stdgraph/bfs
Browse files Browse the repository at this point in the history
Add find_negative_cycle for Bellman-Ford
Move Topological Sort to Traversal section
  • Loading branch information
pratzl authored Aug 29, 2024
2 parents 23a53a3 + 7e9eefd commit dbb8b52
Show file tree
Hide file tree
Showing 14 changed files with 244 additions and 162 deletions.
10 changes: 6 additions & 4 deletions D3128_Algorithms/src/bellman_shortest_dists.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ template <index_adjacency_list G,
class Visitor = bellman_visitor_base<G>,
class Compare = less<ranges::range_value_t<Distances>>,
class Combine = plus<ranges::range_value_t<Distances>>>
requires is_arithmetic_v<ranges::range_value_t<Distances>> && //
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine> &&
requires is_arithmetic_v<ranges::range_value_t<Distances>> &&
ranges::sized_range<Distances> &&
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine> &&
bellman_visitor<G, Visitor>
bool bellman_ford_shortest_distances(
optional<vertex_id_t<G>> bellman_ford_shortest_distances(
G& g,
const vertex_id_t<G> source,
Distances& distances,
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
WF&& weight =
[](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); }, // default weight(uv) -> 1
Visitor&& visitor = bellman_visitor_base<G>(),
Compare&& compare = less<ranges::range_value_t<Distances>>(),
Combine&& combine = plus<ranges::range_value_t<Distances>>());
13 changes: 8 additions & 5 deletions D3128_Algorithms/src/bellman_shortest_dists_multi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ template <index_adjacency_list G,
class Visitor = bellman_visitor_base<G>,
class Compare = less<ranges::range_value_t<Distances>>,
class Combine = plus<ranges::range_value_t<Distances>>>
requires convertible_to<ranges::range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<ranges::range_value_t<Distances>> &&
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine>
bool bellman_ford_shortest_distances(
requires convertible_to<ranges::range_value_t<Sources>, vertex_id_t<G>> && //
is_arithmetic_v<ranges::range_value_t<Distances>> && //
ranges::sized_range<Distances> && //
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine> &&
bellman_visitor<G, Visitor>
optional<vertex_id_t<G>> bellman_ford_shortest_distances(
G& g,
const Sources& sources,
Distances& distances,
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
WF&& weight =
[](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); }, // default weight(uv) -> 1
Visitor&& visitor = bellman_visitor_base<G>(),
Compare&& compare = less<ranges::range_value_t<Distances>>(),
Combine&& combine = plus<ranges::range_value_t<Distances>>());
11 changes: 7 additions & 4 deletions D3128_Algorithms/src/bellman_shortest_paths.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ template <index_adjacency_list G,
class Visitor = bellman_visitor_base<G>,
class Compare = less<ranges::range_value_t<Distances>>,
class Combine = plus<ranges::range_value_t<Distances>>>
requires is_arithmetic_v<ranges::range_value_t<Distances>> &&
convertible_to<vertex_id_t<G>, ranges::range_value_t<Predecessors>> &&
requires is_arithmetic_v<ranges::range_value_t<Distances>> &&
convertible_to<vertex_id_t<G>, ranges::range_value_t<Predecessors>> &&
ranges::sized_range<Distances> &&
ranges::sized_range<Predecessors> &&
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine> &&
bellman_visitor<G, Visitor>
bool bellman_ford_shortest_paths(
optional<vertex_id_t<G>> bellman_ford_shortest_paths(
G& g,
const vertex_id_t<G> source,
Distances& distances,
Predecessors& predecessor,
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
WF&& weight =
[](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); }, // default weight(uv) -> 1
Visitor&& visitor = bellman_visitor_base<G>(),
Compare&& compare = less<ranges::range_value_t<Distances>>(),
Combine&& combine = plus<ranges::range_value_t<Distances>>());
16 changes: 10 additions & 6 deletions D3128_Algorithms/src/bellman_shortest_paths_multi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ template <index_adjacency_list G,
class Visitor = bellman_visitor_base<G>,
class Compare = less<ranges::range_value_t<Distances>>,
class Combine = plus<ranges::range_value_t<Distances>>>
requires convertible_to<ranges::range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<ranges::range_value_t<Distances>> &&
convertible_to<vertex_id_t<G>, ranges::range_value_t<Predecessors>> &&
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine>
bool bellman_ford_shortest_paths(
requires convertible_to<ranges::range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<ranges::range_value_t<Distances>> &&
convertible_to<vertex_id_t<G>, ranges::range_value_t<Predecessors>> &&
ranges::sized_range<Distances> &&
ranges::sized_range<Predecessors> &&
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine> &&
bellman_visitor<G, Visitor>
optional<vertex_id_t<G>> bellman_ford_shortest_paths(
G& g,
const Sources& sources,
Distances& distances,
Predecessors& predecessor,
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
WF&& weight =
[](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); }, // default weight(uv) -> 1
Visitor&& visitor = bellman_visitor_base<G>(),
Compare&& compare = less<ranges::range_value_t<Distances>>(),
Combine&& combine = plus<ranges::range_value_t<Distances>>());
5 changes: 1 addition & 4 deletions D3128_Algorithms/src/breadth_first_search_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,5 @@ constexpr void init_breadth_first_search(Distances& distances) {

template <class Predecessors>
constexpr void init_breadth_first_search(Predecessors& predecessors) {
// exposition only
size_t i = 0;
for(auto& pred : predecessors)
pred = i++;
ranges::iota(predecessors, 0); // exposition only
}
3 changes: 2 additions & 1 deletion D3128_Algorithms/src/dijkstra_shortest_dists.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ template <index_adjacency_list G,
class Compare = less<ranges::range_value_t<Distances>>,
class Combine = plus<ranges::range_value_t<Distances>>>
requires is_arithmetic_v<ranges::range_value_t<Distances>> && //
ranges::sized_range<Distances> && //
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine> &&
dijkstra_visitor<G, Visitor>
void dijkstra_shortest_distances(
G& g,
const vertex_id_t<G> source,
Distances& distances,
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
Visitor&& visitor = dijkstra_visitor_base<G>(),
Compare&& compare = less<ranges::range_value_t<Distances>>(),
Combine&& combine = plus<ranges::range_value_t<Distances>>());
10 changes: 6 additions & 4 deletions D3128_Algorithms/src/dijkstra_shortest_dists_multi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ template <index_adjacency_list G,
class Visitor = dijkstra_visitor_base<G>,
class Compare = less<ranges::range_value_t<Distances>>,
class Combine = plus<ranges::range_value_t<Distances>>>
requires convertible_to<ranges::range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<ranges::range_value_t<Distances>> &&
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine>
requires convertible_to<ranges::range_value_t<Sources>, vertex_id_t<G>> && //
ranges::sized_range<Distances> && //
is_arithmetic_v<ranges::range_value_t<Distances>> && //
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine> &&
dijkstra_visitor<G, Visitor>
void dijkstra_shortest_distances(
G& g,
const Sources& sources,
Distances& distances,
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
Visitor&& visitor = dijkstra_visitor_base<G>(),
Compare&& compare = less<ranges::range_value_t<Distances>>(),
Combine&& combine = plus<ranges::range_value_t<Distances>>());
8 changes: 5 additions & 3 deletions D3128_Algorithms/src/dijkstra_shortest_paths.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
template <index_adjacency_list G,
ranges::random_access_range Distances,
ranges::random_access_range Predecessors,
class WF = function<ranges::range_value_t<Distances>(edge_reference_t<G>)>,
class WF = std::function<ranges::range_value_t<Distances>(edge_reference_t<G>)>,
class Visitor = dijkstra_visitor_base<G>,
class Compare = less<ranges::range_value_t<Distances>>,
class Combine = plus<ranges::range_value_t<Distances>>>
requires is_arithmetic_v<ranges::range_value_t<Distances>> && //
requires is_arithmetic_v<ranges::range_value_t<Distances>> &&
ranges::sized_range<Distances> &&
ranges::sized_range<Predecessors> &&
convertible_to<vertex_id_t<G>, ranges::range_value_t<Predecessors>> &&
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine> &&
dijkstra_visitor<G, Visitor>
Expand All @@ -14,7 +16,7 @@ void dijkstra_shortest_paths(
const vertex_id_t<G> source,
Distances& distances,
Predecessors& predecessor,
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
Visitor&& visitor = dijkstra_visitor_base<G>(),
Compare&& compare = less<ranges::range_value_t<Distances>>(),
Combine&& combine = plus<ranges::range_value_t<Distances>>());
13 changes: 8 additions & 5 deletions D3128_Algorithms/src/dijkstra_shortest_paths_multi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@ template <index_adjacency_list G,
ranges::input_range Sources,
ranges::random_access_range Distances,
ranges::random_access_range Predecessors,
class WF = function<ranges::range_value_t<Distances>(edge_reference_t<G>)>,
class WF = std::function<ranges::range_value_t<Distances>(edge_reference_t<G>)>,
class Visitor = dijkstra_visitor_base<G>,
class Compare = less<ranges::range_value_t<Distances>>,
class Combine = plus<ranges::range_value_t<Distances>>>
requires convertible_to<ranges::range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<ranges::range_value_t<Distances>> &&
requires convertible_to<ranges::range_value_t<Sources>, vertex_id_t<G>> &&
is_arithmetic_v<ranges::range_value_t<Distances>> &&
ranges::sized_range<Distances> &&
ranges::sized_range<Predecessors> &&
convertible_to<vertex_id_t<G>, ranges::range_value_t<Predecessors>> &&
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine>
basic_edge_weight_function<G, WF, ranges::range_value_t<Distances>, Compare, Combine> &&
dijkstra_visitor<G, Visitor>
void dijkstra_shortest_paths(
G& g,
const Sources& sources,
Distances& distances,
Predecessors& predecessor,
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
WF&& weight = [](edge_reference_t<G> uv) { return ranges::range_value_t<Distances>(1); },
Visitor&& visitor = dijkstra_visitor_base<G>(),
Compare&& compare = less<ranges::range_value_t<Distances>>(),
Combine&& combine = plus<ranges::range_value_t<Distances>>());
6 changes: 6 additions & 0 deletions D3128_Algorithms/src/find_negative_cycle.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
template <index_adjacency_list G, ranges::forward_range Predecessors, class OutputIterator>
requires output_iterator<OutputIterator, vertex_id_t<G>>
void find_negative_cycle(G& g,
const Predecessors& predecessor,
const optional<vertex_id_t<G>>& cycle_vertex_id,
OutputIterator out_cycle);
4 changes: 1 addition & 3 deletions D3128_Algorithms/src/shortest_paths_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,5 @@ template <class Distances, class Predecessors>
constexpr void init_shortest_paths(Distances& distances, Predecessors& predecessors) {
// exposition only
init_shortest_paths_distances(distances);
size_t i = 0;
for(auto& pred : predecessors)
pred = i++;
ranges::iota(predecessors, 0);
}
Loading

0 comments on commit dbb8b52

Please sign in to comment.