diff --git a/D3126_Overview/tex/overview.tex b/D3126_Overview/tex/overview.tex index d5596ed..c6a83bc 100644 --- a/D3126_Overview/tex/overview.tex +++ b/D3126_Overview/tex/overview.tex @@ -254,6 +254,9 @@ \section{Freestanding} Additionally, \tcode{stack} and \tcode{queue} require memory allocation which could throw a \tcode{bad_alloc} exception. +\section{Language Requirements} +The library targets C++20 as its baseline. The topological sort safe view factories (\tcode{vertices_topological_sort_safe}, \tcode{edges_topological_sort_safe}) use \tcode{std::expected} from C++23. The reference implementation provides backward compatibility to C++20 via an external \tcode{expected} library (e.g., \tcode{tl::expected}), switching to \tcode{std::expected} when C++23 or later is available. + \section{Namespaces} Graph containers and their views and algorithms are not interchangeable with existing containers and algorithms. Additionally, there are some domain-specific terms that may clash with existing or future names, such as diff --git a/D3128_Algorithms/src/bellman_shortest_dists.hpp b/D3128_Algorithms/src/bellman_shortest_dists.hpp index 4b01fdd..f0e28ca 100644 --- a/D3128_Algorithms/src/bellman_shortest_dists.hpp +++ b/D3128_Algorithms/src/bellman_shortest_dists.hpp @@ -1,18 +1,19 @@ -template (const remove_reference_t&, - const edge_t&)>, +template (const remove_reference_t&, + const edge_t&)>, class Visitor = empty_visitor, - class Compare = less>, - class Combine = plus>> -requires is_arithmetic_v> && sized_range && - basic_edge_weight_function, Compare, Combine> + class Compare = less>, + class Combine = plus>> +requires vertex_property_map_for && + is_arithmetic_v> && + basic_edge_weight_function, Compare, Combine> [[nodiscard]] constexpr optional> bellman_ford_shortest_distances( G&& g, const vertex_id_t& source, Distances& distances, WF&& weight = [](const auto&, - const edge_t& uv) { return range_value_t(1); }, + const edge_t& uv) { return vertex_property_map_value_t(1); }, Visitor&& visitor = empty_visitor(), - Compare&& compare = less>(), - Combine&& combine = plus>()); + Compare&& compare = less>(), + Combine&& combine = plus>()); diff --git a/D3128_Algorithms/src/bellman_shortest_dists_multi.hpp b/D3128_Algorithms/src/bellman_shortest_dists_multi.hpp index dfea973..7656388 100644 --- a/D3128_Algorithms/src/bellman_shortest_dists_multi.hpp +++ b/D3128_Algorithms/src/bellman_shortest_dists_multi.hpp @@ -1,20 +1,21 @@ -template (const remove_reference_t&, - const edge_t&)>, +template (const remove_reference_t&, + const edge_t&)>, class Visitor = empty_visitor, - class Compare = less>, - class Combine = plus>> -requires convertible_to, vertex_id_t> && - is_arithmetic_v> && sized_range && - basic_edge_weight_function, Compare, Combine> + class Compare = less>, + class Combine = plus>> +requires vertex_property_map_for && + convertible_to, vertex_id_t> && + is_arithmetic_v> && + basic_edge_weight_function, Compare, Combine> [[nodiscard]] constexpr optional> bellman_ford_shortest_distances( G&& g, const Sources& sources, Distances& distances, WF&& weight = [](const auto&, - const edge_t& uv) { return range_value_t(1); }, + const edge_t& uv) { return vertex_property_map_value_t(1); }, Visitor&& visitor = empty_visitor(), - Compare&& compare = less>(), - Combine&& combine = plus>()); + Compare&& compare = less>(), + Combine&& combine = plus>()); diff --git a/D3128_Algorithms/src/bellman_shortest_paths.hpp b/D3128_Algorithms/src/bellman_shortest_paths.hpp index 75d1b37..e4bb496 100644 --- a/D3128_Algorithms/src/bellman_shortest_paths.hpp +++ b/D3128_Algorithms/src/bellman_shortest_paths.hpp @@ -1,22 +1,23 @@ -template (const remove_reference_t&, - const edge_t&)>, +template (const remove_reference_t&, + const edge_t&)>, class Visitor = empty_visitor, - class Compare = less>, - class Combine = plus>> -requires is_arithmetic_v> && - convertible_to, range_value_t> && - sized_range && sized_range && - basic_edge_weight_function, Compare, Combine> + class Compare = less>, + class Combine = plus>> +requires vertex_property_map_for && + vertex_property_map_for && + is_arithmetic_v> && + convertible_to, vertex_property_map_value_t> && + basic_edge_weight_function, Compare, Combine> [[nodiscard]] constexpr optional> bellman_ford_shortest_paths( G&& g, const vertex_id_t& source, Distances& distances, Predecessors& predecessor, WF&& weight = [](const auto&, - const edge_t& uv) { return range_value_t(1); }, + const edge_t& uv) { return vertex_property_map_value_t(1); }, Visitor&& visitor = empty_visitor(), - Compare&& compare = less>(), - Combine&& combine = plus>()); + Compare&& compare = less>(), + Combine&& combine = plus>()); diff --git a/D3128_Algorithms/src/bellman_shortest_paths_multi.hpp b/D3128_Algorithms/src/bellman_shortest_paths_multi.hpp index 6d11401..0f58806 100644 --- a/D3128_Algorithms/src/bellman_shortest_paths_multi.hpp +++ b/D3128_Algorithms/src/bellman_shortest_paths_multi.hpp @@ -1,24 +1,25 @@ -template (const remove_reference_t&, - const edge_t&)>, +template (const remove_reference_t&, + const edge_t&)>, class Visitor = empty_visitor, - class Compare = less>, - class Combine = plus>> -requires convertible_to, vertex_id_t> && - is_arithmetic_v> && - convertible_to, range_value_t> && - sized_range && sized_range && - basic_edge_weight_function, Compare, Combine> + class Compare = less>, + class Combine = plus>> +requires vertex_property_map_for && + vertex_property_map_for && + convertible_to, vertex_id_t> && + is_arithmetic_v> && + convertible_to, vertex_property_map_value_t> && + basic_edge_weight_function, Compare, Combine> [[nodiscard]] constexpr optional> bellman_ford_shortest_paths( G&& g, const Sources& sources, Distances& distances, Predecessors& predecessor, WF&& weight = [](const auto&, - const edge_t& uv) { return range_value_t(1); }, + const edge_t& uv) { return vertex_property_map_value_t(1); }, Visitor&& visitor = empty_visitor(), - Compare&& compare = less>(), - Combine&& combine = plus>()); + Compare&& compare = less>(), + Combine&& combine = plus>()); diff --git a/D3128_Algorithms/src/breadth_first_search.hpp b/D3128_Algorithms/src/breadth_first_search.hpp index 7c6f2d2..21d8ffa 100644 --- a/D3128_Algorithms/src/breadth_first_search.hpp +++ b/D3128_Algorithms/src/breadth_first_search.hpp @@ -1,4 +1,4 @@ -template +template void breadth_first_search( G&& g, // graph vertex_id_t source, // starting vertex\_id diff --git a/D3128_Algorithms/src/breadth_first_search_multi.hpp b/D3128_Algorithms/src/breadth_first_search_multi.hpp index a600ee7..ab43b62 100644 --- a/D3128_Algorithms/src/breadth_first_search_multi.hpp +++ b/D3128_Algorithms/src/breadth_first_search_multi.hpp @@ -1,4 +1,4 @@ -template +template requires convertible_to, vertex_id_t> void breadth_first_search(G&& g, // graph const Sources& sources, diff --git a/D3128_Algorithms/src/connected_components.hpp b/D3128_Algorithms/src/connected_components.hpp index e734288..23dfb62 100644 --- a/D3128_Algorithms/src/connected_components.hpp +++ b/D3128_Algorithms/src/connected_components.hpp @@ -1,36 +1,41 @@ /* * Hopcroft-Tarjan Articulation Points */ -template +template requires output_iterator> void articulation_points(G&& g, Iter cut_vertices); /* * Hopcroft-Tarjan Biconnected Components */ -template +template void biconnected_components(G&& g, OuterContainer& components); /* * Connected Components */ -template +template +requires vertex_property_map_for size_t connected_components(G&& g, Component& component); /* * Afforest Connected Components */ -template +template +requires vertex_property_map_for void afforest(G&& g, Component& component, const size_t neighbor_rounds = 2); -template +template +requires vertex_property_map_for void afforest(G&& g, GT&& g_t, Component& component, const size_t neighbor_rounds = 2); /* * Kosaraju Strongly Connected Components */ -template +template +requires vertex_property_map_for void kosaraju(G&& g, GT&& g_t, Component& component); -template +template +requires vertex_property_map_for void kosaraju(G&& g, Component& component); diff --git a/D3128_Algorithms/src/depth_first_search.hpp b/D3128_Algorithms/src/depth_first_search.hpp index 1e73268..052f2d1 100644 --- a/D3128_Algorithms/src/depth_first_search.hpp +++ b/D3128_Algorithms/src/depth_first_search.hpp @@ -1,4 +1,4 @@ -template +template void depth_first_search( G&& g, // graph vertex_id_t source, // starting vertex\_id diff --git a/D3128_Algorithms/src/dijkstra_example_mapped.hpp b/D3128_Algorithms/src/dijkstra_example_mapped.hpp new file mode 100644 index 0000000..974e51f --- /dev/null +++ b/D3128_Algorithms/src/dijkstra_example_mapped.hpp @@ -0,0 +1,29 @@ +// Example: Dijkstra on a mapped graph (string vertex IDs, double edge weights) + +#include +#include +#include +#include +using namespace graph; +using namespace graph::adj_list; + +using Traits = container::uov_graph_traits; +using G = container::dynamic_graph; + +G g({{"a", "b", 4.0}, {"a", "c", 2.0}, + {"b", "d", 5.0}, + {"c", "b", 1.0}, {"c", "d", 8.0}}); + +constexpr double inf = std::numeric_limits::max(); + +auto dist = make_vertex_property_map(g, inf); +auto pred = make_vertex_property_map>(g, vertex_id_t{}); +for (auto&& [uid, u] : views::vertexlist(g)) + pred[uid] = uid; + +dijkstra_shortest_paths(g, std::string{"a"}, dist, pred, + [](const auto& g, const edge_t& e) { return edge_value(g, e); }); + +// Shortest a to d: a to c (2) to b (1) to d (5) = 8 +// dist["d"] == 8 + diff --git a/D3128_Algorithms/src/dijkstra_shortest_dists.hpp b/D3128_Algorithms/src/dijkstra_shortest_dists.hpp index f1b9156..03404d8 100644 --- a/D3128_Algorithms/src/dijkstra_shortest_dists.hpp +++ b/D3128_Algorithms/src/dijkstra_shortest_dists.hpp @@ -1,18 +1,19 @@ -template (const remove_reference_t&, - const edge_t&)>, +template (const remove_reference_t&, + const edge_t&)>, class Visitor = empty_visitor, - class Compare = less>, - class Combine = plus>> -requires is_arithmetic_v> && sized_range && - basic_edge_weight_function, Compare, Combine> + class Compare = less>, + class Combine = plus>> +requires vertex_property_map_for && + is_arithmetic_v> && + basic_edge_weight_function, Compare, Combine> constexpr void dijkstra_shortest_distances( G&& g, const vertex_id_t& source, Distances& distances, WF&& weight = [](const auto&, - const edge_t& uv) { return range_value_t(1); }, + const edge_t& uv) { return vertex_property_map_value_t(1); }, Visitor&& visitor = empty_visitor(), - Compare&& compare = less>(), - Combine&& combine = plus>()); + Compare&& compare = less>(), + Combine&& combine = plus>()); diff --git a/D3128_Algorithms/src/dijkstra_shortest_dists_multi.hpp b/D3128_Algorithms/src/dijkstra_shortest_dists_multi.hpp index 1ed16e4..365c4f4 100644 --- a/D3128_Algorithms/src/dijkstra_shortest_dists_multi.hpp +++ b/D3128_Algorithms/src/dijkstra_shortest_dists_multi.hpp @@ -1,20 +1,21 @@ -template (const remove_reference_t&, - const edge_t&)>, +template (const remove_reference_t&, + const edge_t&)>, class Visitor = empty_visitor, - class Compare = less>, - class Combine = plus>> -requires convertible_to, vertex_id_t> && sized_range && - is_arithmetic_v> && - basic_edge_weight_function, Compare, Combine> + class Compare = less>, + class Combine = plus>> +requires vertex_property_map_for && + convertible_to, vertex_id_t> && + is_arithmetic_v> && + basic_edge_weight_function, Compare, Combine> constexpr void dijkstra_shortest_distances( G&& g, const Sources& sources, Distances& distances, WF&& weight = [](const auto&, - const edge_t& uv) { return range_value_t(1); }, + const edge_t& uv) { return vertex_property_map_value_t(1); }, Visitor&& visitor = empty_visitor(), - Compare&& compare = less>(), - Combine&& combine = plus>()); + Compare&& compare = less>(), + Combine&& combine = plus>()); diff --git a/D3128_Algorithms/src/dijkstra_shortest_paths.hpp b/D3128_Algorithms/src/dijkstra_shortest_paths.hpp index 245b90c..f5d9b53 100644 --- a/D3128_Algorithms/src/dijkstra_shortest_paths.hpp +++ b/D3128_Algorithms/src/dijkstra_shortest_paths.hpp @@ -1,22 +1,23 @@ -template (const remove_reference_t&, - const edge_t&)>, +template (const remove_reference_t&, + const edge_t&)>, class Visitor = empty_visitor, - class Compare = less>, - class Combine = plus>> -requires is_arithmetic_v> && sized_range && - sized_range && - convertible_to, range_value_t> && - basic_edge_weight_function, Compare, Combine> + class Compare = less>, + class Combine = plus>> +requires vertex_property_map_for && + vertex_property_map_for && + is_arithmetic_v> && + convertible_to, vertex_property_map_value_t> && + basic_edge_weight_function, Compare, Combine> constexpr void dijkstra_shortest_paths( G&& g, const vertex_id_t& source, Distances& distances, Predecessors& predecessor, WF&& weight = [](const auto&, - const edge_t& uv) { return range_value_t(1); }, + const edge_t& uv) { return vertex_property_map_value_t(1); }, Visitor&& visitor = empty_visitor(), - Compare&& compare = less>(), - Combine&& combine = plus>()); + Compare&& compare = less>(), + Combine&& combine = plus>()); diff --git a/D3128_Algorithms/src/dijkstra_shortest_paths_multi.hpp b/D3128_Algorithms/src/dijkstra_shortest_paths_multi.hpp index 77a295d..3f765b0 100644 --- a/D3128_Algorithms/src/dijkstra_shortest_paths_multi.hpp +++ b/D3128_Algorithms/src/dijkstra_shortest_paths_multi.hpp @@ -1,24 +1,25 @@ -template (const remove_reference_t&, - const edge_t&)>, +template (const remove_reference_t&, + const edge_t&)>, class Visitor = empty_visitor, - class Compare = less>, - class Combine = plus>> -requires convertible_to, vertex_id_t> && - is_arithmetic_v> && sized_range && - sized_range && - convertible_to, range_value_t> && - basic_edge_weight_function, Compare, Combine> + class Compare = less>, + class Combine = plus>> +requires vertex_property_map_for && + vertex_property_map_for && + convertible_to, vertex_id_t> && + is_arithmetic_v> && + convertible_to, vertex_property_map_value_t> && + basic_edge_weight_function, Compare, Combine> constexpr void dijkstra_shortest_paths( G&& g, const Sources& sources, Distances& distances, Predecessors& predecessor, WF&& weight = [](const auto&, - const edge_t& uv) { return range_value_t(1); }, + const edge_t& uv) { return vertex_property_map_value_t(1); }, Visitor&& visitor = empty_visitor(), - Compare&& compare = less>(), - Combine&& combine = plus>()); + Compare&& compare = less>(), + Combine&& combine = plus>()); diff --git a/D3128_Algorithms/src/find_negative_cycle.hpp b/D3128_Algorithms/src/find_negative_cycle.hpp index 9adaaa8..12f44cf 100644 --- a/D3128_Algorithms/src/find_negative_cycle.hpp +++ b/D3128_Algorithms/src/find_negative_cycle.hpp @@ -1,4 +1,4 @@ -template +template requires output_iterator> void find_negative_cycle(const G& g, const Predecessors& predecessor, diff --git a/D3128_Algorithms/src/jaccard.hpp b/D3128_Algorithms/src/jaccard.hpp index 49366fa..68c4a85 100644 --- a/D3128_Algorithms/src/jaccard.hpp +++ b/D3128_Algorithms/src/jaccard.hpp @@ -1,6 +1,6 @@ /* * Jaccard Coefficient Algorithm */ -template +template requires invocable, vertex_id_t, edge_t&, T> void jaccard_coefficient(G&& g, OutOp out); diff --git a/D3128_Algorithms/src/lp.hpp b/D3128_Algorithms/src/lp.hpp index 88db3bc..58f0413 100644 --- a/D3128_Algorithms/src/lp.hpp +++ b/D3128_Algorithms/src/lp.hpp @@ -1,25 +1,27 @@ /* * Label Propagation Algorithm */ -template -requires equality_comparable> && +requires vertex_property_map_for && + equality_comparable> && uniform_random_bit_generator> void label_propagation(G&& g, Label& label, Gen&& rng = default_random_engine{}, T max_iters = numeric_limits::max()); -template -requires equality_comparable> && +requires vertex_property_map_for && + equality_comparable> && uniform_random_bit_generator> -void label_propagation(G&& g, - Label& label, - range_value_t