1 #include "../algorithm/graph/connectivity.hpp" 2 #include "../algorithm/graph/cycles.hpp" 3 #include "../utils/serialise.hpp" 4 #include "../utils/triple.hpp" 6 #include <EASTL/vector_map.h> 7 #include <EASTL/vector_set.h> 12 #define GRAPHTEMPLATE \ 13 template <class V, class E, class S, class D, class VP, class EP> 14 #define BG BaseGraph<V, E, S, D, VP, EP> 15 #define BASEGRAPH(...) GRAPHTEMPLATE __VA_ARGS__ BG 16 #define tBG typename BG 37 : boost_graph(), state(0), state_cached_components(0),
38 state_cached_cycles(0) {}
41 EdgeType eboost = edge_descriptors.left.at(e);
42 VertType source = boost::source(eboost, boost_graph);
43 return vertex_descriptors.right.at(source);
47 EdgeType eboost = edge_descriptors.left.at(e);
48 VertType target = boost::target(eboost, boost_graph);
49 return vertex_descriptors.right.at(target);
53 VertType vboost = boost::add_vertex(VP(), boost_graph);
54 vertex_descriptors.insert(v, vboost);
55 vertices.emplace_back(v);
56 predecessors.emplace(v, VertContain());
57 if (D::is_directed) successors.emplace(v, VertContain());
60 void AddEdge(
const V &u,
const V &v,
const E &e) {
63 VertType uboost = vertex_descriptors.left.at(u);
64 VertType vboost = vertex_descriptors.left.at(v);
66 boost::add_edge(uboost, vboost, EP(), boost_graph).first;
67 edge_descriptors.insert(e, eboost);
68 edges.emplace_back(e);
71 template <
typename Archive>
72 void save(Archive & archive,
const uint32_t)
const {
73 std::vector<std::pair<V, V>> vertex_edges;
74 vertex_edges.reserve(edges.size());
75 for (
const E &e : edges) {
76 vertex_edges.emplace_back(GetSourceVertex(e), GetTargetVertex(e));
85 template <
typename Archive>
void load(Archive & archive,
const uint32_t) {
86 VertContain input_vertices;
87 std::vector<std::pair<V, V>> input_vertex_edges;
88 EdgeContain input_edges;
94 for (V &v : input_vertices) AddVertex(v);
95 for (
size_t pos = 0; pos < input_edges.size(); ++pos) {
96 AddEdge(input_vertex_edges[pos].first, input_vertex_edges[pos].second,
105 BASEGRAPH(template <typename Archive>
void)::serialise(Archive &archive,
126 m_basedata->AddVertex(v);
134 std::tie(vi, vi_end) =
135 boost::inv_adjacent_vertices(vboost, m_basedata->boost_graph);
136 for (; vi != vi_end; ++vi) {
138 E e = GetE(boost::edge(vboost, *vi, m_basedata->boost_graph).first);
139 m_basedata->edge_descriptors.erase(e);
140 m_basedata->edges.erase(
141 std::find(m_basedata->edges.begin(), m_basedata->edges.end(), e));
144 if (D::is_directed) {
146 std::tie(vp, vp_end) =
147 boost::adjacent_vertices(vboost, m_basedata->boost_graph);
148 for (; vp != vp_end; ++vp) {
150 E e = GetE(boost::edge(*vp, vboost, m_basedata->boost_graph).first);
151 m_basedata->edge_descriptors.erase(e);
152 m_basedata->edges.erase(
153 std::find(m_basedata->edges.begin(), m_basedata->edges.end(), e));
157 m_basedata->vertex_descriptors.erase(v);
158 m_basedata->vertices.erase(
159 std::find(m_basedata->vertices.begin(), m_basedata->vertices.end(), v));
160 m_basedata->predecessors.erase(v);
161 if (D::is_directed) m_basedata->successors.erase(v);
162 boost::clear_vertex(vboost, m_basedata->boost_graph);
163 boost::remove_vertex(vboost, m_basedata->boost_graph);
166 BASEGRAPH(
void)::AddEdge(const V &u, const V &v, const E &e) {
168 if (!HasVertex(u)) AddVertex(u);
169 if (!HasVertex(v)) AddVertex(v);
170 m_basedata->AddEdge(u, v, e);
176 m_basedata->edge_descriptors.erase(eboost);
177 m_basedata->edges.erase(
178 std::find(m_basedata->edges.begin(), m_basedata->edges.end(), e));
179 boost::remove_edge(eboost, m_basedata->boost_graph);
188 return m_basedata->vertex_descriptors.left.find(v) !=
189 m_basedata->vertex_descriptors.left.end();
193 return m_basedata->edge_descriptors.left.find(e) !=
194 m_basedata->edge_descriptors.left.end();
197 BASEGRAPH(
bool)::HasEdge(const V &u, const V &v) const {
198 if (!HasVertex(u) || !HasVertex(v))
return false;
201 return boost::edge(u_, v_, m_basedata->boost_graph).second;
205 return boost::num_vertices(m_basedata->boost_graph);
209 return boost::num_edges(m_basedata->boost_graph);
213 return HasVertex(v) ? OutDegree(GetDescriptor(v)) : -1;
217 if (!HasVertex(v))
return -1;
218 if (D::is_directed)
return InDegree(GetDescriptor(v));
219 return OutDegree(GetDescriptor(v));
222 BASEGRAPH(
const tBG::VertContain &)::GetNeighbours(const V &v) {
223 static_assert(!D::is_directed,
"Requires an undirected graph.");
225 auto adjis = boost::adjacent_vertices(vboost, m_basedata->boost_graph);
226 m_basedata->predecessors.at(v).clear();
227 for (; adjis.first != adjis.second; ++adjis.first)
228 m_basedata->predecessors.at(v).emplace_back(GetV(*adjis.first));
229 return m_basedata->predecessors.at(v);
232 BASEGRAPH(
const tBG::VertContain &)::GetPredecessors(const V &v) {
233 static_assert(D::is_directed,
"Requires a directed graph.");
235 auto adjis = boost::inv_adjacent_vertices(vboost, m_basedata->boost_graph);
236 m_basedata->predecessors.at(v).clear();
237 for (; adjis.first != adjis.second; ++adjis.first)
238 m_basedata->predecessors.at(v).emplace_back(GetV(*adjis.first));
239 return m_basedata->predecessors.at(v);
242 BASEGRAPH(
const tBG::VertContain &)::GetSuccessors(const V &v) {
243 static_assert(D::is_directed,
"Requires a directed graph.");
245 auto adjis = boost::adjacent_vertices(vboost, m_basedata->boost_graph);
246 m_basedata->successors.at(v).clear();
247 for (; adjis.first != adjis.second; ++adjis.first)
248 m_basedata->successors.at(v).emplace_back(GetV(*adjis.first));
249 return m_basedata->successors.at(v);
252 BASEGRAPH(std::pair<V, V>)::GetVertices(const E &e) const {
254 VertType u = boost::source(eboost, m_basedata->boost_graph);
255 VertType v = boost::target(eboost, m_basedata->boost_graph);
256 return {GetV(u), GetV(v)};
259 BASEGRAPH(
const tBG::VertContain &)::GetVertices() const {
260 return m_basedata->vertices;
264 return m_basedata->edges;
271 boost::edge(uboost, vboost, m_basedata->boost_graph).first;
276 return m_basedata->GetSourceVertex(e);
280 return m_basedata->GetTargetVertex(e);
286 BASEGRAPH(tBG::VertType)::GetDescriptor(const V &v) const {
287 return m_basedata->vertex_descriptors.left.at(v);
291 return m_basedata->vertex_descriptors.right.at(v);
294 BASEGRAPH(tBG::EdgeType)::GetDescriptor(const E &e) const {
295 return m_basedata->edge_descriptors.left.at(e);
299 return m_basedata->edge_descriptors.right.at(e);
302 BASEGRAPH(int64_t)::OutDegree(
BG::VertType v) const {
303 return boost::out_degree(v, m_basedata->boost_graph);
306 BASEGRAPH(int64_t)::InDegree(
BG::VertType v) const {
307 return boost::in_degree(v, m_basedata->boost_graph);
316 GetConnectedComponents();
317 return m_basedata->cached_connected_components.size() == 1;
321 GetConnectedComponents();
322 return m_basedata->cached_connected_components.size();
325 BASEGRAPH(
const tBG::ComponentContain &)::GetConnectedComponents() {
326 if (m_basedata->state_cached_components == m_basedata->state)
327 return m_basedata->cached_connected_components;
329 m_basedata->cached_connected_components);
330 m_basedata->state_cached_components = m_basedata->state;
331 return m_basedata->cached_connected_components;
337 auto pos = std::find(m_basedata->cached_cyclic_vertices.begin(),
338 m_basedata->cached_cyclic_vertices.end(), v);
339 return pos != m_basedata->cached_cyclic_vertices.end();
343 if (!IsCyclic(v))
return false;
344 for (
auto &cyc : m_basedata->cached_cycles) {
345 if (cyc.size() > sz)
return false;
346 for (E &edge : cyc) {
347 V a = GetSourceVertex(edge);
348 V b = GetTargetVertex(edge);
349 if (a == v || b == v)
return true;
357 auto pos = std::find(m_basedata->cached_cyclic_edges.begin(),
358 m_basedata->cached_cyclic_edges.end(), e);
359 return pos != m_basedata->cached_cyclic_edges.end();
363 if (!IsCyclic(e))
return false;
364 for (
auto &cyc : m_basedata->cached_cycles) {
365 if (cyc.size() > sz)
return false;
366 for (E &edge : cyc) {
367 if (edge == e)
return true;
374 using VertSet = eastl::vector_set<V>;
375 using EdgeSet = eastl::vector_set<E>;
377 if (m_basedata->state == m_basedata->state_cached_cycles)
378 return m_basedata->cached_cycles;
381 cyclic_v.reserve(NumVertices());
383 cyclic_e.reserve(NumEdges());
385 for (
EdgeContain &cycle : m_basedata->cached_cycles) {
386 for (E &edge : cycle) {
387 cyclic_e.emplace(edge);
388 cyclic_v.emplace(GetSourceVertex(edge));
389 cyclic_v.emplace(GetTargetVertex(edge));
392 m_basedata->cached_cyclic_vertices.clear();
393 m_basedata->cached_cyclic_vertices.assign(cyclic_v.begin(), cyclic_v.end());
394 m_basedata->cached_cyclic_edges.clear();
395 m_basedata->cached_cyclic_edges.assign(cyclic_e.begin(), cyclic_e.end());
397 m_basedata->cached_cycles.begin(), m_basedata->cached_cycles.end(),
399 m_basedata->state_cached_cycles = m_basedata->state;
400 return m_basedata->cached_cycles;
405 return m_basedata->cached_cycles.size();
V GetTargetVertex(const E &e) const
Definition: base_graph_impl.hpp:46
void load(Archive &archive, const uint32_t)
Definition: base_graph_impl.hpp:85
EdgeContain cached_cyclic_edges
Definition: base_graph_impl.hpp:32
std::vector< CMGEdge > EdgeContain
Type for storing edges.
Definition: base_graph.hpp:92
Definition: assignment.hpp:16
BaseImpl()
Definition: base_graph_impl.hpp:36
void RemoveEdge(const V &u, const V &v)
Remove an edge from the graph.
Definition: base_graph_impl.hpp:182
State state_cached_components
Definition: base_graph_impl.hpp:29
void AddVertex(const V &v)
Definition: base_graph_impl.hpp:52
#define BASEGRAPH(...)
Definition: base_graph_impl.hpp:15
void AddEdge(const V &u, const V &v, const E &e)
Definition: base_graph_impl.hpp:60
CycleEdgeContain cached_cycles
Definition: base_graph_impl.hpp:33
#define INDIGOX_SERIAL_NVP(name, value)
Definition: serialise.hpp:66
VertContain cached_cyclic_vertices
Definition: base_graph_impl.hpp:31
void save(Archive &archive, const uint32_t) const
Definition: base_graph_impl.hpp:72
EdgeMap edge_descriptors
Definition: base_graph_impl.hpp:21
typename graph_type::inv_adjacency_iterator PredIter
Type for iterator over predecessors of a vertex descriptor.
Definition: base_graph.hpp:79
typename graph_type::vertex_descriptor VertType
Type of the graph vertex descriptor.
Definition: base_graph.hpp:73
uint32_t State
Definition: fwd_declares.hpp:45
V GetSourceVertex(const E &e) const
Definition: base_graph_impl.hpp:40
EdgeContain edges
Definition: base_graph_impl.hpp:23
VertContain vertices
Definition: base_graph_impl.hpp:22
State state
Definition: base_graph_impl.hpp:26
#define BG
Definition: base_graph_impl.hpp:14
int64_t ConnectedComponents(graph::BaseGraph< V, E, S, D, VP, EP > &G, Container &bits)
NbrsContain successors
Definition: base_graph_impl.hpp:25
ComponentContain cached_connected_components
Definition: base_graph_impl.hpp:28
NbrsContain predecessors
Definition: base_graph_impl.hpp:24
graph_type boost_graph
Definition: base_graph_impl.hpp:19
VertMap vertex_descriptors
Definition: base_graph_impl.hpp:20
State state_cached_cycles
Definition: base_graph_impl.hpp:34
int64_t AllCycles(graph::BaseGraph< V, E, S, D, VP, EP > &G, Container &ecycles)
typename graph_type::edge_descriptor EdgeType
Type of the graph edge descriptor.
Definition: base_graph.hpp:81
typename graph_type::adjacency_iterator NbrsIter
Type for iterator over neighbours of vertex descriptor.
Definition: base_graph.hpp:77
Definition: base_graph_impl.hpp:18