Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
MixedGraph.hpp
Go to the documentation of this file.
1
6// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
7
8#pragma once
9
10#include <alib/map>
11#include <alib/tuple>
12#include <alib/set>
13#include <alib/vector>
14#include <functional>
15#include <alib/pair>
16#include <object/Object.h>
17#include <core/normalize.hpp>
18
19#include <common/Normalize.hpp>
22
23namespace graph {
24
25template<typename TNode, typename TEdge>
26class MixedGraph : public GraphInterface<TNode, TEdge> {
27// ---------------------------------------------------------------------------------------------------------------------
28 public:
29 using node_type = TNode;
30 using edge_type = TEdge;
31
32// ---------------------------------------------------------------------------------------------------------------------
33
34 protected:
35 // Container for edge
37
38 // Two containers for arc
41
42// =====================================================================================================================
43// Constructor, Destructor, Operators
44 public:
45
46// ---------------------------------------------------------------------------------------------------------------------
47
49 ext::map<TNode, ext::map<TNode, TEdge>> &&getAdjacencyList() &&;
50
51 const ext::map<TNode, ext::map<TNode, TEdge>> &getSuccessorList() const &;
52 ext::map<TNode, ext::map<TNode, TEdge>> &&getSuccessorList() &&;
53
54 const ext::map<TNode, ext::map<TNode, TEdge>> &getPredecessorList() const &;
55 ext::map<TNode, ext::map<TNode, TEdge>> &&getPredecessorList() &&;
56
57// ---------------------------------------------------------------------------------------------------------------------
58
59// =====================================================================================================================
60// GraphBase interface
61 public:
62 auto operator <=> ( const MixedGraph & other ) const {
63 return std::tie(m_adjacency_list, m_succ_list, m_pred_list) <=> std::tie(other.getAdjacencyList(), other.getSuccessorList(), other.getPredecessorList());
64 }
65
66 bool operator == ( const MixedGraph & other ) const {
68 }
69
70 void operator>>(ext::ostream &ostream) const override;
71
72// =====================================================================================================================
73// Graph interface
74
75 public:
76 void addNode(const TNode &n);
77 void addNode(TNode &&n);
78 template<typename ... Params>
79 void addNode(Params &&... params);
80
81// ---------------------------------------------------------------------------------------------------------------------
82
83 bool addEdge(const TEdge &e);
84 bool addEdge(TEdge &&e);
85 template<typename ... Params>
86 bool addEdge(Params &&... params);
87
88 bool addArc(const TEdge &e);
89 bool addArc(TEdge &&e);
90 template<typename ... Params>
91 bool addArc(Params &&... params);
92
93// ---------------------------------------------------------------------------------------------------------------------
94
95// =====================================================================================================================
96// GraphInterface interface
97
98 size_t nodeCount() const override;
99 size_t edgeCount() const override;
100
101// ---------------------------------------------------------------------------------------------------------------------
102
103 ext::set<TNode> getNodes() const override;
104 ext::vector<TEdge> getEdges() const override;
105
106// ---------------------------------------------------------------------------------------------------------------------
107
108 ext::set<TNode> successors(const TNode &n) const override;
109 ext::vector<TEdge> successorEdges(const TNode &n) const override;
110 ext::set<TNode> predecessors(const TNode &n) const override;
111 ext::vector<TEdge> predecessorEdges(const TNode &n) const override;
112
113// ---------------------------------------------------------------------------------------------------------------------
114
115 std::string name() const override;
116
117// ---------------------------------------------------------------------------------------------------------------------
118
119};
120
121// =====================================================================================================================
122
123template<typename TNode, typename TEdge>
125 return m_adjacency_list;
126}
127
128template<typename TNode, typename TEdge>
130 return std::move(m_adjacency_list);
131}
132
133template<typename TNode, typename TEdge>
135 return m_succ_list;
136}
137
138template<typename TNode, typename TEdge>
140 return std::move(m_succ_list);
141}
142
143template<typename TNode, typename TEdge>
145 return m_pred_list;
146}
147
148template<typename TNode, typename TEdge>
150 return std::move(m_pred_list);
151}
152
153// ---------------------------------------------------------------------------------------------------------------------
154
155template<typename TNode, typename TEdge>
157 m_adjacency_list[n];
158 m_succ_list[n];
159 m_pred_list[n];
160}
161
162template<typename TNode, typename TEdge>
164 m_adjacency_list[n];
165 m_succ_list[n];
166 m_pred_list[std::forward<TNode>(n)];
167}
168
169template<typename TNode, typename TEdge>
170template<typename... Params>
171void MixedGraph<TNode, TEdge>::addNode(Params &&... params) {
172 addNode(TNode(std::forward<Params>(params) ...));
173}
174
175// ---------------------------------------------------------------------------------------------------------------------
176
177template<typename TNode, typename TEdge>
179 auto search_succ = m_succ_list.find(e.first);
180 auto search_pred = m_pred_list.find(e.first);
181
182 if (search_succ != m_succ_list.end() && search_succ->second.find(e.second) != search_succ->second.end()) {
183 return false;
184 } else if (search_pred != m_pred_list.end() && search_pred->second.find(e.second) != search_pred->second.end()) {
185 return false;
186 }
187
188 // Check if edge doesn't already exists
189 if (m_adjacency_list.find(e.first) != m_adjacency_list.end()
190 && m_adjacency_list[e.first].find(e.second) != m_adjacency_list[e.first].end()) {
191 return false;
192 }
193
194 addNode(e.first); // because of consistency
195 addNode(e.second); // because of consistency
196 m_adjacency_list[e.first].insert(ext::make_pair(e.second, e));
197 m_adjacency_list[e.second].insert(ext::make_pair(e.first, e));
198
199 return true;
200}
201
202template<typename TNode, typename TEdge>
204 auto search_succ = m_succ_list.find(e.first);
205 auto search_pred = m_pred_list.find(e.first);
206
207 if (search_succ != m_succ_list.end() && search_succ->second.find(e.second) != search_succ->second.end()) {
208 return false;
209 } else if (search_pred != m_pred_list.end() && search_pred->second.find(e.second) != search_pred->second.end()) {
210 return false;
211 }
212
213 // Check if edge doesn't already exists
214 if (m_adjacency_list.find(e.first) != m_adjacency_list.end()
215 && m_adjacency_list[e.first].find(e.second) != m_adjacency_list[e.first].end()) {
216 return false;
217 }
218
219 addNode(e.first); // because of consistency
220 addNode(e.second); // because of consistency
221 m_adjacency_list[e.first].insert(ext::make_pair(e.second, e));
222 m_adjacency_list[e.second].insert(ext::make_pair(e.first, std::forward<TEdge>(e)));
223
224 return true;
225}
226
227template<typename TNode, typename TEdge>
228template<typename... Params>
229bool MixedGraph<TNode, TEdge>::addEdge(Params &&... params) {
230 return addEdge(TEdge(std::forward<Params>(params) ...));
231}
232
233template<typename TNode, typename TEdge>
235 // Check if edge doesn't already exists
236 if (m_adjacency_list.find(e.first) != m_adjacency_list.end()
237 && m_adjacency_list[e.first].find(e.second) != m_adjacency_list[e.first].end()) {
238 return false;
239 }
240
241 // Check if arc doesn't already exits
242 auto search_succ = m_succ_list.find(e.first);
243 if (search_succ != m_succ_list.end() && search_succ->second.find(e.second) != search_succ->second.end()) {
244 return false;
245 }
246
247 addNode(e.first); // because of consistency
248 addNode(e.second); // because of consistency
249 m_succ_list[e.first].insert(ext::make_pair(e.second, e));
250 m_pred_list[e.second].insert(ext::make_pair(e.first, e));
251
252 return true;
253}
254
255template<typename TNode, typename TEdge>
257 // Check if edge doesn't already exists
258 if (m_adjacency_list.find(e.first) != m_adjacency_list.end()
259 && m_adjacency_list[e.first].find(e.second) != m_adjacency_list[e.first].end()) {
260 return false;
261 }
262
263 // Check if arc doesn't already exits
264 auto search_succ = m_succ_list.find(e.first);
265 if (search_succ != m_succ_list.end() && search_succ->second.find(e.second) != search_succ->second.end()) {
266 return false;
267 }
268
269 addNode(e.first); // because of consistency
270 addNode(e.second); // because of consistency
271 m_succ_list[e.first].insert(ext::make_pair(e.second, e));
272 m_pred_list[e.second].insert(ext::make_pair(e.first, std::forward<TEdge>(e)));
273
274 return true;
275}
276
277template<typename TNode, typename TEdge>
278template<typename... Params>
279bool MixedGraph<TNode, TEdge>::addArc(Params &&... params) {
280 return addArc(TEdge(std::forward<Params>(params)...));
281}
282
283// ---------------------------------------------------------------------------------------------------------------------
284
285template<typename TNode, typename TEdge>
287 return m_adjacency_list.size();
288}
289template<typename TNode, typename TEdge>
291 size_t cnt = 0;
292
293 for (const auto &i: m_adjacency_list) {
294 cnt += i.second.size();
295 }
296
297 cnt /= 2;
298
299 for (const auto &i: m_succ_list) {
300 cnt += i.second.size();
301 }
302
303 return cnt;
304}
305
306// ---------------------------------------------------------------------------------------------------------------------
307
308template<typename TNode, typename TEdge>
310 ext::set<TNode> set;
311
312 for (const auto &i: m_adjacency_list) {
313 set.insert(i.first);
314 }
315
316 return set;
317}
318
319template<typename TNode, typename TEdge>
322
323 for (const auto &i: m_adjacency_list) {
324 for (const auto &j : i.second) {
325 vec.push_back(j.second);
326 }
327 }
328
329 for (const auto &i: m_succ_list) {
330 for (const auto &j : i.second) {
331 vec.push_back(j.second);
332 }
333 }
334
335 return vec;
336}
337
338// ---------------------------------------------------------------------------------------------------------------------
339
340template<typename TNode, typename TEdge>
342 ext::set<TNode> set;
343
344 if (m_adjacency_list.count(n) == 0) {
345 return set;
346 }
347
348 for (const auto &i: m_adjacency_list.at(n)) {
349 set.insert(i.first);
350 }
351
352 for (const auto &i: m_succ_list.at(n)) {
353 set.insert(i.first);
354 }
355
356 return set;
357}
358
359template<typename TNode, typename TEdge>
362
363 if (m_succ_list.count(n) == 0) {
364 return vec;
365 }
366
367 for (const auto &i: m_adjacency_list.at(n)) {
368 vec.push_back(i.second);
369 }
370
371 for (const auto &i: m_succ_list.at(n)) {
372 vec.push_back(i.second);
373 }
374
375 return vec;
376}
377
378template<typename TNode, typename TEdge>
380 ext::set<TNode> set;
381
382 if (m_pred_list.count(n) == 0) {
383 return set;
384 }
385
386 for (const auto &i: m_adjacency_list.at(n)) {
387 set.insert(i.first);
388 }
389
390 for (const auto &i: m_pred_list.at(n)) {
391 set.insert(i.first);
392 }
393
394 return set;
395}
396
397template<typename TNode, typename TEdge>
400
401 if (m_pred_list.count(n) == 0) {
402 return vec;
403 }
404
405 for (const auto &i: m_adjacency_list.at(n)) {
406 vec.push_back(i.second);
407 }
408
409 for (const auto &i: m_pred_list.at(n)) {
410 vec.push_back(i.second);
411 }
412
413 return vec;
414}
415
416// ---------------------------------------------------------------------------------------------------------------------
417
418template<typename TNode, typename TEdge>
420 return "MixedGraph";
421}
422
423// ---------------------------------------------------------------------------------------------------------------------
424
425template<typename TNode, typename TEdge>
427 ostream << "(" << name() << " ";
428 for (const auto &i : m_adjacency_list) {
429 ostream << i.first << " <-->" << std::endl;
430
431 for (const auto &j : i.second) {
432 ostream << "\t\t" << j.first << " " << j.second << std::endl;
433 }
434
435 ostream << i.first << " -->" << std::endl;
436 for (const auto &j : m_succ_list.at(i.first)) {
437 ostream << "\t\t" << j.first << " " << j.second << std::endl;
438 }
439 }
440 ostream << ")";
441}
442
443// ---------------------------------------------------------------------------------------------------------------------
444
445} // namespace graph
446
447// =====================================================================================================================
448
449namespace core {
450
457template<typename TNode, typename TEdge>
458struct normalize < graph::MixedGraph < TNode, TEdge > > {
461
462 // Create edges
463 for (auto &&i: ext::make_mover(std::move(value).getAdjacencyList())) {
465 for (auto &&j: i.second) {
468
469 graph.addNode(first);
470 graph.addNode(second);
471 graph.addEdge(edge);
472 }
473 }
474
475 // Create successor
476 for (auto &&i: ext::make_mover(std::move(value).getSuccessorList())) {
478 for (auto &&j: i.second) {
481
482 graph.addNode(first);
483 graph.addNode(second);
484 graph.addEdge(edge);
485 }
486 }
487
488 // Create predecessors
489 for (auto &&i: ext::make_mover(std::move(value).getPredecessorList())) {
491 for (auto &&j: i.second) {
494
495 graph.addNode(first);
496 graph.addNode(second);
497 graph.addEdge(edge);
498 }
499 }
500
501 return graph;
502 }
503};
504
505}
506
507// =====================================================================================================================
Class extending the map class from the standard library. Original reason is to allow printing of the ...
Definition: map.hpp:48
Definition: ostream.h:14
Class extending the pair class from the standard library. Original reason is to allow printing of the...
Definition: pair.hpp:43
Definition: set.hpp:44
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
Definition: GraphInterface.hpp:19
TEdge edge_type
Definition: GraphInterface.hpp:23
TNode node_type
Definition: GraphInterface.hpp:22
static DefaultNodeType normalizeNode(TNode &&node)
Definition: Normalize.hpp:47
static DefaultEdgeType normalizeEdge(TEdge &&edge)
Definition: Normalize.hpp:52
Definition: MixedGraph.hpp:26
bool addArc(TEdge &&e)
Definition: MixedGraph.hpp:256
std::string name() const override
Definition: MixedGraph.hpp:419
bool addArc(Params &&... params)
Definition: MixedGraph.hpp:279
ext::map< TNode, ext::map< TNode, TEdge > > m_succ_list
Definition: MixedGraph.hpp:39
ext::vector< TEdge > getEdges() const override
Definition: MixedGraph.hpp:320
size_t nodeCount() const override
Definition: MixedGraph.hpp:286
void operator>>(ext::ostream &ostream) const override
Definition: MixedGraph.hpp:426
ext::set< TNode > successors(const TNode &n) const override
Definition: MixedGraph.hpp:341
bool addEdge(const TEdge &e)
Definition: MixedGraph.hpp:178
ext::vector< TEdge > successorEdges(const TNode &n) const override
Definition: MixedGraph.hpp:360
bool addArc(const TEdge &e)
Definition: MixedGraph.hpp:234
void addNode(TNode &&n)
Definition: MixedGraph.hpp:163
bool operator==(const MixedGraph &other) const
Definition: MixedGraph.hpp:66
size_t edgeCount() const override
Definition: MixedGraph.hpp:290
void addNode(Params &&... params)
Definition: MixedGraph.hpp:171
ext::set< TNode > predecessors(const TNode &n) const override
Definition: MixedGraph.hpp:379
bool addEdge(Params &&... params)
Definition: MixedGraph.hpp:229
ext::vector< TEdge > predecessorEdges(const TNode &n) const override
Definition: MixedGraph.hpp:398
ext::map< TNode, ext::map< TNode, TEdge > > m_adjacency_list
Definition: MixedGraph.hpp:36
ext::map< TNode, ext::map< TNode, TEdge > > m_pred_list
Definition: MixedGraph.hpp:40
const ext::map< TNode, ext::map< TNode, TEdge > > & getPredecessorList() const &
Definition: MixedGraph.hpp:144
ext::set< TNode > getNodes() const override
Definition: MixedGraph.hpp:309
void addNode(const TNode &n)
Definition: MixedGraph.hpp:156
const ext::map< TNode, ext::map< TNode, TEdge > > & getAdjacencyList() const &
Definition: MixedGraph.hpp:124
bool addEdge(TEdge &&e)
Definition: MixedGraph.hpp:203
const ext::map< TNode, ext::map< TNode, TEdge > > & getSuccessorList() const &
Definition: MixedGraph.hpp:134
Definition: Object.h:16
p second
Definition: ToRegExpAlgebraic.h:126
int i
Definition: AllEpsilonClosure.h:118
Definition: normalize.hpp:10
Definition: CapacityEdge.hpp:18
Definition: sigHandler.cpp:20
constexpr tuple< Elements &... > tie(Elements &... args) noexcept
Helper of extended tuple of references construction. The tuple is constructed to reffer to values in ...
Definition: tuple.hpp:218
reference_mover< T > make_mover(T &param)
Move adaptor construction function specialized to lvalue reference parameter.
Definition: iterator.hpp:468
constexpr auto make_pair(T1 &&x, T2 &&y)
Definition: pair.hpp:79
Definition: ReconstructPath.hpp:14
static graph::MixedGraph eval(graph::MixedGraph< TNode, TEdge > &&value)
Definition: MixedGraph.hpp:459
Definition: normalize.hpp:13