Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah_graph_concepts_test.cc
Go to the documentation of this file.
1// Self-containment check: must stay the first include (aleph-concepts.md ยง4.6).
2#include <ah-graph-concepts.H>
3
4#include <gtest/gtest.h>
5
6#include <Dijkstra.H>
7#include <Johnson.H>
8#include <K_Shortest_Paths.H>
9#include <io_graph.H>
10#include <Kruskal.H>
11#include <tpl_agraph.H>
12#include <tpl_graph.H>
13#include <tpl_indexGraph.H>
14#include <tpl_maxflow.H>
15#include <tpl_net.H>
16#include <tpl_sgraph.H>
17
18// Positive/negative checks for the graph concepts of Phase 3 of
19// aleph-concepts-plan.md, and for the algorithms they now constrain.
20
21using namespace Aleph;
22
23namespace
24{
32
33 struct NotAGraph
34 {
35 using Node = int;
36 };
37
38 // A distance without Distance_Type: fine for Kruskal (it only compares
39 // dist(a) < dist(b)) but not an ArcDistance.
40 struct PlainWeight
41 {
42 int operator()(LG::Arc * a) const { return a->get_info(); }
43 };
44
45 struct NonArithmeticCost
46 {
47 struct Cost
48 {
49 int v = 0;
50 };
51 using Distance_Type = Cost;
52 Cost operator()(LG::Arc *) const { return {}; }
53 };
54} // namespace
55
56// --- Concepts over the library graph types ---------------------------------
57
60static_assert(AlephGraph<const LG &>);
62
63static_assert(ArcFilter<Dft_Show_Arc<LG>, LG>);
64static_assert(NodeFilter<Dft_Show_Node<LG>, LG>);
65static_assert(not ArcFilter<Dft_Show_Node<LG>, LG>);
66static_assert(not NodeFilter<Dft_Show_Arc<LG>, LG>);
67
68static_assert(ArcDistance<Dft_Dist<LG>, LG>);
70
71static_assert(FlowNetwork<NG>);
72static_assert(not FlowNetwork<LG>);
73
74// --- Constrained algorithms --------------------------------------------------
75
76template <class G>
77concept can_dijkstra = requires { typename Dijkstra_Min_Paths<G>; };
78template <class D>
79concept can_dijkstra_with = requires { typename Dijkstra_Min_Paths<LG, D>; };
80template <class D>
81concept can_kruskal_with = requires { typename Kruskal_Min_Spanning_Tree<LG, D>; };
82template <class N>
83concept can_max_flow = requires(N & net) { dinic_maximum_flow(net); };
84template <class D>
85concept can_yen = requires(const LG & g, LG::Node * n, D d) {
86 yen_k_shortest_paths<LG, D>(g, n, n, 1, d);
87};
88
90static_assert(not can_dijkstra<NotAGraph>);
92// Kruskal keeps accepting distances without Distance_Type, as it always has.
95// Former static_assert, now a constraint on the entry point.
97
98// --- Constrained utilities of tpl_graph.H ------------------------------------
99
100template <class G>
101concept can_copy_graph = requires(G & t, const G & s) { copy_graph(t, s); };
102template <class G>
103concept can_clear_graph = requires(G & g) { clear_graph(g); };
104template <class G>
105concept can_compare_graphs = requires(const G & g) { are_equal(g, g); };
106template <class G>
107concept can_for_each_node = requires(const G & g) { for_each_node(g, [](auto *) {}); };
108template <class SA>
109concept can_filter_arcs_with = requires(const LG & g) { for_each_arc(g, [](LG::Arc *) {}, SA()); };
110template <class G>
111concept can_out_nodes = requires(typename G::Node * p) { out_nodes<G>(p); };
112
117// Filters are checked at the call: a node filter is not an arc filter.
120
121// Graph I/O: the graph and the node/arc filters are checked when naming IO_Graph.
122template <class G>
123concept can_io_graph = requires { typename IO_Graph<G>; };
124template <class NF>
128
133
135{
136 // These helpers never compiled: they called traverse_*_arcs and
137 // for_each_*_arc without <GT>, which cannot be deduced from a Node *.
138 LG g;
139 auto * a = g.insert_node(1);
140 auto * b = g.insert_node(2);
141 g.insert_arc(a, b, 4);
142 g.insert_arc(a, b, 7);
143 auto even = [](LG::Arc * arc) { return arc->get_info() % 2 == 0; };
144
147 EXPECT_EQ(search_in_arc<LG>(b, even)->get_info(), 4);
149 EXPECT_EQ((map_out_arcs<LG, int>(a, [](LG::Arc * arc) { return arc->get_info(); }).size()), 2u);
150 EXPECT_EQ((foldl_in_arcs<LG, int>(b, 0, [](const int & s, LG::Arc * arc)
151 { return s + arc->get_info(); })), 11);
152
153 // The one-argument form used to be ambiguous (two viable overloads).
155 EXPECT_EQ(in_degree<LG>(b), 2u);
156 EXPECT_EQ(in_degree<LG>(a), 0u);
157}
158
160{
161 LG g;
162 auto * a = g.insert_node(1);
163 auto * b = g.insert_node(2);
164 auto * c = g.insert_node(3);
165 g.insert_arc(a, b, 2);
166 g.insert_arc(b, c, 3);
167 g.insert_arc(a, c, 9);
168
169 Path<LG> path(g);
170 const auto d = Dijkstra_Min_Paths<LG>().find_min_path(g, a, c, path);
171 EXPECT_EQ(d, 5);
172
173 LG tree;
175 EXPECT_EQ(tree.get_num_arcs(), 2u);
176
177 const auto paths = yen_k_shortest_paths<LG>(g, a, c, 2);
178 EXPECT_EQ(paths.size(), 2u);
179}
Dijkstra's shortest path algorithm.
Johnson's algorithm for all-pairs shortest paths.
K-shortest path algorithms (Yen and Eppstein-style API).
Kruskal's minimum spanning tree algorithm.
C++20 concepts for the protocol shared by graph algorithms.
WeightedDigraph::Node Node
Generic directed graph (digraph) wrapper template.
Definition graph-dry.H:3960
Spanning tree calculation of all shortest paths from a given node according to Dijkstra's algorithm.
Definition Dijkstra.H:103
Arc for graphs implemented with simple adjacency lists.
Definition tpl_sgraph.H:197
Graph serialization and deserialization class.
Definition io_graph.H:320
Computes the minimum spanning tree of a graph using Kruskal's algorithm.
Definition Kruskal.H:92
Graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:429
_Graph_Node Node
The graph type.
Definition tpl_graph.H:433
Graph class implemented with singly-linked adjacency lists.
Definition tpl_sgraph.H:274
Path on a graph.
Definition tpl_graph.H:2772
ArcInfo & get_info() noexcept
Return a modifiable reference to the arc data.
Definition graph-dry.H:637
#define TEST(name)
#define N
Definition fib.C:294
void for_each_node(const GT &g, Op operation, SN sn=SN())
Traverse all the nodes of graph filtering some ones according to a condition and executing an operati...
Definition tpl_graph.H:1240
void clear_graph(GT &g) noexcept
Clean a graph: all its nodes and arcs are removed and freed.
Definition tpl_graph.H:3659
void for_each_arc(const GT &g, Op operation, SA sa=SA())
Traverse all the arcs of graph filtering some ones according to a condition and executing an operatio...
Definition tpl_graph.H:1259
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
void copy_graph(GT &gtgt, const GT &gsrc, bool cookie_map=false)
Explicit copy of graph.
Definition tpl_graph.H:3677
Graph serialization and deserialization utilities.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
size_t size(Node *root) noexcept
Net::Flow_Type dinic_maximum_flow(Net &net)
Compute maximum flow using Dinic's algorithm.
and
Check uniqueness with explicit hash + equality functors.
bool are_equal(const GT &g1, const GT &g2)
Fast graph comparison.
Default arc loading functor for binary and text modes.
Definition io_graph.H:258
Default arc storage functor for binary and text modes.
Definition io_graph.H:188
Default node storage functor for binary and text modes.
Definition io_graph.H:153
Arc of graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:223
Arc of a flow network implemented with adjacency lists.
Definition tpl_net.H:115
Flow network implemented with adjacency lists.
Definition tpl_net.H:261
Array-based graph implementation.
Generic graph and digraph implementations.
Graph indexing utilities for O(log n) node/arc lookup.
Advanced maximum flow algorithms.
Network flow graph structures.
Simple graph implementation with adjacency lists.