discrete-modulus (C++)
Reference implementations of discrete modulus algorithms (C++)
Loading...
Searching...
No Matches
graphs.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include <cmath>
10#include <map>
11#include <random>
12#include <vector>
13
14#include <boost/graph/adjacency_list.hpp>
15#include <boost/graph/connected_components.hpp>
16#include <boost/graph/filtered_graph.hpp>
17
18namespace discrete_modulus {
19
20// Confined to this namespace only, so downstream code that includes this
21// header does not get `boost`'s names injected into its own namespace.
22using namespace boost;
23
24//----------------------------------------------------------------
25// Main graph type
26//----------------------------------------------------------------
27
29using Traits = adjacency_list_traits<vecS, vecS, undirectedS>;
30
41using Graph = adjacency_list<
42 vecS, vecS, undirectedS, property<vertex_name_t, Traits::vertex_descriptor>,
43 property<edge_index_t, int, property<edge_weight_t, long>>>;
44
45using Vertex = graph_traits<Graph>::vertex_descriptor;
46using Edge = graph_traits<Graph>::edge_descriptor;
47using VertexIterator = graph_traits<Graph>::vertex_iterator;
48using EdgeIterator = graph_traits<Graph>::edge_iterator;
49
50//----------------------------------------------------------------
51// Flow graph type
52//----------------------------------------------------------------
53
55using FlowTraits = adjacency_list_traits<vecS, vecS, directedS>;
56using FlowVertex = FlowTraits::vertex_descriptor;
57using FlowEdge = FlowTraits::edge_descriptor;
58
66using FlowGraph = adjacency_list<
67 vecS, vecS, directedS, no_property,
68 property<edge_capacity_t, long,
69 property<edge_residual_capacity_t, long, property<edge_reverse_t, FlowTraits::edge_descriptor>>>>;
70
78template <typename G>
79Graph subgraph(const G& g, std::vector<Vertex> v) {
80 Graph sg;
81
82 std::map<Vertex, Vertex> local_to_global;
83 std::map<Vertex, Vertex> global_to_local;
84
85 for (std::size_t i = 0; i < v.size(); ++i) {
86 Vertex v_new = add_vertex(get(vertex_name, g, v[i]), sg);
87 local_to_global.insert({v_new, v[i]});
88 global_to_local.insert({v[i], v_new});
89 }
90
91 typename graph_traits<G>::vertex_iterator vi, vi_end;
92 for (boost::tie(vi, vi_end) = vertices(sg); vi != vi_end; ++vi) {
93 Vertex vv = local_to_global[*vi];
94 typename graph_traits<G>::out_edge_iterator ei, ei_end;
95 for (boost::tie(ei, ei_end) = out_edges(vv, g); ei != ei_end; ++ei) {
96 Vertex uu = target(*ei, g);
97 auto u = global_to_local.find(uu);
98 if (u != global_to_local.end() && !edge(*vi, u->second, sg).second) {
99 add_edge(*vi, u->second, sg);
100 }
101 }
102 }
103
104 return sg;
105}
106
108template <typename G>
109std::vector<Graph> connected_component_graphs(const G& g) {
110 std::vector<Graph> components;
111
112 std::vector<int> component(num_vertices(g));
113 int num_components = connected_components(g, &component[0]);
114
115 std::vector<std::vector<Vertex>> component_v(num_components);
116 int i = 0;
117 typename graph_traits<G>::vertex_iterator vi, vi_end;
118 for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++i) {
119 component_v[component[i]].push_back(*vi);
120 }
121
122 for (const auto& vs : component_v) {
123 components.push_back(subgraph(g, vs));
124 }
125
126 return components;
127}
128
131 NonCriticalEdge() = default;
132 explicit NonCriticalEdge(std::set<Edge> a) : m_A(std::move(a)) {}
133 bool operator()(const Edge& e) const { return m_A.count(e) == 0; }
134 std::set<Edge> m_A;
135};
136
141inline std::vector<Graph> induced_components(Graph& g, const std::set<Edge>& A) {
142 NonCriticalEdge filter(A);
143 filtered_graph<Graph, NonCriticalEdge> fg(g, filter);
145}
146
165template <typename G>
166bool is_simple_graph(const G& g) {
167 std::set<std::pair<typename graph_traits<G>::vertex_descriptor, typename graph_traits<G>::vertex_descriptor>>
168 seen;
169 typename graph_traits<G>::edge_iterator ei, ei_end;
170 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
171 auto u = source(*ei, g);
172 auto v = target(*ei, g);
173 if (u == v) {
174 return false;
175 }
176 if (v < u) {
177 std::swap(u, v);
178 }
179 if (!seen.insert({u, v}).second) {
180 return false;
181 }
182 }
183 return true;
184}
185
186//----------------------------------------------------------------
187// Demo graphs
188//----------------------------------------------------------------
189
192 Graph g(n);
193 for (int i = 0; i < n; ++i) {
194 add_edge(i, (i + 1) % n, g);
195 }
196 add_edge(1, n - 1, g);
197 return g;
198}
199
201inline Graph complete_graph(int n) {
202 Graph g(n);
203 for (int i = 0; i < n - 1; ++i) {
204 for (int j = i + 1; j < n; ++j) {
205 add_edge(i, j, g);
206 }
207 }
208 return g;
209}
210
212inline Graph wheel_graph(int n) {
213 Graph g(n);
214 for (int i = 0; i < n - 1; ++i) {
215 add_edge(i, (i + 1) % (n - 1), g);
216 add_edge(i, n - 1, g);
217 }
218 return g;
219}
220
225inline Graph growing_multipartite(int n_layers) {
226 const int n = (n_layers * (n_layers + 1)) / 2;
227 Graph g(n);
228
229 int offset = 0;
230 for (int i = 1; i < n_layers; ++i) {
231 int prev_offset = offset;
232 offset += i;
233 for (int src_i = 0; src_i < i + 1; ++src_i) {
234 for (int tgt_i = 0; tgt_i < i; ++tgt_i) {
235 add_edge(src_i + offset, tgt_i + prev_offset, g);
236 }
237 }
238 }
239
240 return g;
241}
242
245 Graph g(n);
246 for (int i = 0; i < n - 2; ++i) {
247 for (int j = i + 1; j < n - 1; ++j) {
248 add_edge(i + 1, j + 1, g);
249 }
250 }
251 add_edge(0, 1, g);
252 add_edge(0, 2, g);
253 return g;
254}
255
257inline Graph permuted_graph(const Graph& g, const std::vector<int>& perm) {
258 int n = num_vertices(g);
259 Graph pg(n);
260
261 EdgeIterator ei, ei_end;
262 for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
263 Vertex u = perm[source(*ei, g)], v = perm[target(*ei, g)];
264 add_edge(u, v, pg);
265 }
266
267 return pg;
268}
269
272 Graph g(6);
273 add_edge(0, 1, g);
274 add_edge(1, 2, g);
275 add_edge(2, 0, g);
276 add_edge(3, 4, g);
277 add_edge(4, 5, g);
278 add_edge(5, 3, g);
279 return g;
280}
281
283inline Graph random_gnp_graph(int n, double p, int seed) {
284 std::default_random_engine rg(seed);
285 Graph g(n);
286
287 std::uniform_real_distribution<double> distribution(0.0, 1.0);
288 for (int i = 0; i < n - 1; ++i) {
289 for (int j = i + 1; j < n; ++j) {
290 if (distribution(rg) < p) {
291 add_edge(i, j, g);
292 }
293 }
294 }
295
296 return g;
297}
298
300inline Graph random_geometric_graph(int n, double r, int seed = 381928) {
301 std::default_random_engine rg(seed);
302 Graph g(n);
303
304 std::uniform_real_distribution<double> distribution(0.0, 1.0);
305 std::vector<double> x(n), y(n);
306 for (int i = 0; i < n; ++i) {
307 x[i] = distribution(rg);
308 y[i] = distribution(rg);
309 }
310
311 for (int i = 0; i < n; ++i) {
312 for (int j = i + 1; j < n; ++j) {
313 double d = std::sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
314 if (d < r) {
315 add_edge(i, j, g);
316 }
317 }
318 }
319
320 return g;
321}
322
323} // namespace discrete_modulus
Definition cunningham.hpp:50
Graph random_gnp_graph(int n, double p, int seed)
An Erdos-Renyi G(n,p) random graph.
Definition graphs.hpp:283
adjacency_list< vecS, vecS, undirectedS, property< vertex_name_t, Traits::vertex_descriptor >, property< edge_index_t, int, property< edge_weight_t, long > > > Graph
The undirected graph type used throughout this library.
Definition graphs.hpp:43
bool is_simple_graph(const G &g)
Checks whether g is a simple graph: no self-loops, no parallel edges between the same pair of vertice...
Definition graphs.hpp:166
Graph wheel_graph(int n)
The wheel graph: a cycle on n-1 vertices plus one hub vertex n-1.
Definition graphs.hpp:212
Graph complete_graph(int n)
The complete graph on n vertices.
Definition graphs.hpp:201
adjacency_list< vecS, vecS, directedS, no_property, property< edge_capacity_t, long, property< edge_residual_capacity_t, long, property< edge_reverse_t, FlowTraits::edge_descriptor > > > > FlowGraph
The directed, capacitated graph type used for the max-flow subproblem in Cunningham's algorithm (see ...
Definition graphs.hpp:69
std::vector< Graph > connected_component_graphs(const G &g)
Splits g into one Graph per connected component.
Definition graphs.hpp:109
std::vector< Graph > induced_components(Graph &g, const std::set< Edge > &A)
Splits g into connected components after removing the critical edge set A.
Definition graphs.hpp:141
Graph cycle_plus_triangle(int n)
A cycle on n vertices plus one extra chord (between vertices 1 and n-1).
Definition graphs.hpp:191
adjacency_list_traits< vecS, vecS, undirectedS > Traits
Traits for Graph.
Definition graphs.hpp:29
FlowTraits::vertex_descriptor FlowVertex
Definition graphs.hpp:56
Graph subgraph(const G &g, std::vector< Vertex > v)
Builds the subgraph of g induced by the given vertices.
Definition graphs.hpp:79
graph_traits< Graph >::edge_descriptor Edge
Definition graphs.hpp:46
FlowTraits::edge_descriptor FlowEdge
Definition graphs.hpp:57
graph_traits< Graph >::vertex_iterator VertexIterator
Definition graphs.hpp:47
graph_traits< Graph >::vertex_descriptor Vertex
Definition graphs.hpp:45
graph_traits< Graph >::edge_iterator EdgeIterator
Definition graphs.hpp:48
Graph growing_multipartite(int n_layers)
A multipartite graph with growing layer sizes (1, 2, ..., n_layers) and complete bipartite connection...
Definition graphs.hpp:225
Graph permuted_graph(const Graph &g, const std::vector< int > &perm)
g with vertices relabeled according to perm.
Definition graphs.hpp:257
Graph random_geometric_graph(int n, double r, int seed=381928)
A random geometric graph: n uniform points in the unit square, connected within radius r.
Definition graphs.hpp:300
Graph disconnected_graph()
Two disjoint triangles: a minimal example of a disconnected graph.
Definition graphs.hpp:271
Graph complete_plus_triangle(int n)
The complete graph on n-1 vertices, plus one extra vertex attached to two of them.
Definition graphs.hpp:244
adjacency_list_traits< vecS, vecS, directedS > FlowTraits
Traits for FlowGraph.
Definition graphs.hpp:55
Edge filter selecting edges not in a given critical/tight set.
Definition graphs.hpp:130
NonCriticalEdge(std::set< Edge > a)
Definition graphs.hpp:132
bool operator()(const Edge &e) const
Definition graphs.hpp:133
std::set< Edge > m_A
Definition graphs.hpp:134