digiKam
Loading...
Searching...
No Matches
itemhistorygraph_boost.h
Go to the documentation of this file.
1/* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2010-10-22
7 * Description : Boost Graph Library: a graph class
8 *
9 * SPDX-FileCopyrightText: 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 *
13 * ============================================================ */
14
15#pragma once
16
17// To include pragma directives for MSVC
18
19#include "digikam_config.h"
20
21#ifdef Q_CC_MSVC
22# include <ciso646>
23# pragma warning(disable : 4267)
24#endif
25
26#if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU)
27# pragma GCC diagnostic push
28# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
29# pragma GCC diagnostic ignored "-Wunused-local-typedefs"
30#endif
31
32#if defined(Q_CC_CLANG)
33# pragma clang diagnostic push
34# pragma clang diagnostic ignored "-Wdeprecated-declarations"
35# pragma clang diagnostic ignored "-Wdeprecated-builtins"
36# pragma clang diagnostic ignored "-Wundef"
37# pragma clang diagnostic ignored "-Wunused-parameter"
38# pragma clang diagnostic ignored "-Wcast-align"
39# pragma clang diagnostic ignored "-Wunused-local-typedef"
40# pragma clang diagnostic ignored "-Wambiguous-reversed-operator"
41#endif
42
43// C++ includes
44
45#include <utility>
46#include <algorithm>
47#include <vector>
48#include <stdbool.h>
49#include <functional>
50
51// Boost includes
52
53// Prohibit boost using deprecated header files.
54
55#define BOOST_NO_HASH
56#define BOOST_BIND_GLOBAL_PLACEHOLDERS
57#define BOOST_ALLOW_DEPRECATED_HEADERS
58
59#include <boost/graph/transitive_closure.hpp>
60#include <boost/graph/adjacency_list.hpp>
61#include <boost/graph/topological_sort.hpp>
62#include <boost/graph/graph_utility.hpp>
63#include <boost/graph/dag_shortest_paths.hpp>
64#include <boost/graph/dijkstra_shortest_paths.hpp>
65#include <boost/graph/reverse_graph.hpp>
66#include <boost/graph/dominator_tree.hpp>
67#include <boost/graph/depth_first_search.hpp>
68#include <boost/graph/breadth_first_search.hpp>
69#include <boost/graph/transitive_reduction.hpp>
70
71// Local includes
72
73#include "digikam_debug.h"
74#include "digikam_export.h"
75
76// clazy:excludeall=missing-typeinfo,copyable-polymorphic,explicit
77
83
84namespace boost
85{
86 BOOST_INSTALL_PROPERTY(vertex, properties);
87 BOOST_INSTALL_PROPERTY(edge, properties);
88}
89
90namespace Digikam
91{
92
97template <typename Key, typename Value>
98class QMapForAdaptors : public QMap<Key, Value>
99{
100public:
101
102 typedef Key key_type;
103 typedef Value data_type;
104 typedef typename std::pair<const Key, Value> value_type;
105
106public:
107
108 QMapForAdaptors() = default;
109};
110
121
125template <class VertexProperties, class EdgeProperties>
126class DIGIKAM_DATABASE_EXPORT Graph
127{
128public:
129
130 typedef boost::adjacency_list<
131 boost::vecS,
132 boost::vecS,
133 boost::bidirectionalS,
134 boost::property<boost::vertex_index_t, int,
135 boost::property<vertex_properties_t, VertexProperties> >,
136 boost::property<edge_properties_t, EdgeProperties>
138
142 typedef typename boost::graph_traits<GraphContainer> graph_traits;
143
144 typedef typename graph_traits::vertex_descriptor vertex_t;
145 typedef typename graph_traits::edge_descriptor edge_t;
146
147 typedef typename graph_traits::vertex_iterator vertex_iter;
148 typedef typename graph_traits::edge_iterator edge_iter;
149 typedef typename graph_traits::adjacency_iterator adjacency_iter;
150 typedef typename graph_traits::out_edge_iterator out_edge_iter;
151 typedef typename graph_traits::in_edge_iterator in_edge_iter;
152 typedef typename boost::inv_adjacency_iterator_generator<GraphContainer,
153 vertex_t,
155
156 typedef typename graph_traits::degree_size_type degree_t;
157
158 typedef std::pair<adjacency_iter, adjacency_iter> adjacency_vertex_range_t;
159 typedef std::pair<inv_adjacency_iter, inv_adjacency_iter> inv_adjacency_vertex_range_t;
160 typedef std::pair<out_edge_iter, out_edge_iter> out_edge_range_t;
161 typedef std::pair<vertex_iter, vertex_iter> vertex_range_t;
162 typedef std::pair<edge_iter, edge_iter> edge_range_t;
163
164 typedef typename boost::property_map<GraphContainer, boost::vertex_index_t>::type vertex_index_map_t;
165 typedef typename boost::property_map<GraphContainer, boost::vertex_index_t>::const_type const_vertex_index_map_t;
166 typedef typename boost::property_map<GraphContainer, vertex_properties_t>::type vertex_property_map_t;
167 typedef typename boost::property_map<GraphContainer, vertex_properties_t>::const_type const_vertex_property_map_t;
168 typedef typename boost::property_map<GraphContainer, edge_properties_t>::type edge_property_map_t;
169 typedef typename boost::property_map<GraphContainer, edge_properties_t>::const_type const_edge_property_map_t;
170
175 class DIGIKAM_DATABASE_EXPORT Vertex
176 {
177 public:
178
180 : v(graph_traits::null_vertex())
181 {
182 }
183
184 // cppcheck-suppress noExplicitConstructor
185 Vertex(const vertex_t& vv) // krazy:exclude=explicit
186 : v(vv)
187 {
188 }
189
190 Vertex& operator=(const vertex_t& other)
191 {
192 v = other;
193
194 return *this;
195 }
196
197 operator const vertex_t&() const
198 {
199 return v;
200 }
201
202 operator vertex_t&()
203 {
204 return v;
205 }
206
207 bool operator==(const vertex_t& other) const
208 {
209 return (v == other);
210 }
211
212 bool operator!=(const vertex_t& other) const
213 {
214 return (v != other);
215 }
216
217 bool isNull() const
218 {
219 return (v == graph_traits::null_vertex());
220 }
221
222 protected:
223
225 };
226
227 class DIGIKAM_DATABASE_EXPORT Edge
228 {
229 public:
230
231 Edge() = default;
232
233 // cppcheck-suppress noExplicitConstructor
234 Edge(const edge_t& e) // krazy:exclude=explicit
235 : e (e),
236 null(false)
237 {
238 }
239
240 Edge& operator=(const edge_t& other)
241 {
242 e = other;
243 null = false;
244
245 return *this;
246 }
247
248 operator const edge_t&() const
249 {
250 return e;
251 }
252
253 operator edge_t&()
254 {
255 return e;
256 }
257
258 const edge_t& toEdge() const
259 {
260 return e;
261 }
262
264 {
265 return e;
266 }
267
268 bool operator==(const edge_t& other) const
269 {
270 return (e == other);
271 }
272
273 bool isNull() const
274 {
275 return null;
276 }
277
278 protected:
279
281
282 // NOTE: there is not null_edge, we must emulate it.
283
284 bool null = true;
285 };
286
287public:
288
289 typedef QPair<Vertex, Vertex> VertexPair;
290 typedef QPair<Edge, Edge> EdgePair;
291
294
295 typedef boost::associative_property_map<VertexVertexMap> VertexVertexMapAdaptor;
296 typedef boost::associative_property_map<VertexIntMap> VertexIntMapAdaptor;
297
298public:
299
300 explicit Graph(MeaningOfDirection dir = ParentToChild)
301 : direction(dir)
302 {
303 }
304
305 Graph(const Graph& g)
306 : graph (g.graph),
307 direction(g.direction)
308 {
309 }
310
311 virtual ~Graph() = default;
312
313 Graph& operator=(const Graph& other)
314 {
315 graph = other.graph;
316 direction = other.direction;
317
318 return *this;
319 }
320
322 {
323 return direction;
324 }
325
326 void clear()
327 {
328 graph.clear();
329 }
330
332 {
333 Vertex v = boost::add_vertex(graph);
334
335 return v;
336 }
337
338 Vertex addVertex(const VertexProperties& properties)
339 {
340 Vertex v = addVertex();
341 setProperties(v, properties);
342
343 return v;
344 }
345
346 void remove(const Vertex& v)
347 {
348 if (v.isNull())
349 {
350 return;
351 }
352
353 boost::clear_vertex(v, graph);
354 boost::remove_vertex(v, graph);
355 }
356
357 Edge addEdge(const Vertex& v1, const Vertex& v2)
358 {
359 Edge e = edge(v1, v2);
360
361 if (e.isNull())
362 {
363 e = boost::add_edge(v1, v2, graph).first;
364 }
365
366 return e;
367 }
368
369 Edge edge(const Vertex& v1, const Vertex& v2) const
370 {
371 std::pair<edge_t, bool> pair = boost::edge(v1, v2, graph);
372
373 if (pair.second)
374 {
375 return pair.first;
376 }
377
378 return Edge();
379 }
380
381 bool hasEdge(const Vertex& v1, const Vertex& v2) const
382 {
383 return boost::edge(v1, v2, graph).second;
384 }
385
386 // NOTE: Does not care for direction.
387
388 bool isConnected(const Vertex& v1, const Vertex& v2) const
389 {
390 if (boost::edge(v1, v2, graph).second)
391 {
392 return true;
393 }
394
395 if (boost::edge(v2, v1, graph).second)
396 {
397 return true;
398 }
399
400 return false;
401 }
402
403 void setProperties(const Vertex& v, const VertexProperties& props)
404 {
405 boost::put(vertex_properties, graph, v, props);
406 }
407
408 const VertexProperties& properties(const Vertex& v) const
409 {
410 return boost::get(vertex_properties, graph, v);
411 }
412
413 VertexProperties& properties(const Vertex& v)
414 {
415 return boost::get(vertex_properties, graph, v);
416 }
417
418 void setProperties(const Edge& e, const EdgeProperties& props)
419 {
420 boost::put(edge_properties, graph, e, props);
421 }
422
423 template <class T>
425 {
426 vertex_range_t range = boost::vertices(graph);
427
428 for (vertex_iter it = range.first ; it != range.second ; ++it)
429 {
430 const VertexProperties& props = properties(*it);
431
432 // Must implement operator==(const T&).
433
434 if (props == value)
435 {
436 return *it;
437 }
438 }
439
440 return Vertex();
441 }
442
443 EdgeProperties properties(const Vertex& v1, const Vertex& v2) const
444 {
445 Edge e = edge(v1, v2);
446
447 if (e.isNull())
448 {
449 return EdgeProperties();
450 }
451
452 return properties(e);
453 }
454
455 const EdgeProperties& properties(const Edge& e) const
456 {
457 return boost::get(edge_properties, graph, e);
458 }
459
460 EdgeProperties& properties(const Edge& e)
461 {
462 return boost::get(edge_properties, graph, e);
463 }
464
469 {
470 return graph;
471 }
472
473 QList<Vertex> vertices() const
474 {
475 return toVertexList(boost::vertices(graph));
476 }
477
479 {
480 OutboundEdges = 1 << 0,
481 InboundEdges = 1 << 1,
482
484
485 EdgesToLeaf = 1 << 2,
486 EdgesToRoot = 1 << 3,
487 AllEdges = InboundEdges | OutboundEdges
488 };
489
490 QList<Vertex> adjacentVertices(const Vertex& v, AdjacencyFlags flags = AllEdges) const
491 {
492 if (flags & EdgesToLeaf)
493 {
494 flags = (AdjacencyFlags)(flags | ((direction == ParentToChild) ? OutboundEdges
495 : InboundEdges));
496 }
497
498 if (flags & EdgesToRoot)
499 {
500 flags = (AdjacencyFlags)(flags | ((direction == ParentToChild) ? InboundEdges
501 : OutboundEdges));
502 }
503
504 QList<Vertex> verticesLst;
505
506 if (flags & OutboundEdges)
507 {
508 verticesLst << toVertexList(boost::adjacent_vertices(v, graph));
509 }
510
511 if (flags & InboundEdges)
512 {
513 verticesLst << toVertexList(boost::inv_adjacent_vertices(v, graph));
514 }
515
516 return verticesLst;
517 }
518
520
521 int vertexCount() const
522 {
523 return (int)boost::num_vertices(graph);
524 }
525
526 bool isEmpty() const
527 {
528 return isEmptyRange(boost::vertices(graph));
529 }
530
531 int outDegree(const Vertex& v) const
532 {
533 return (int)boost::out_degree(v, graph);
534 }
535
536 int inDegree(const Vertex& v) const
537 {
538 return boost::in_degree(v, graph);
539 }
540
541 bool isRoot(const Vertex& v) const
542 {
543 return !hasEdges(v, EdgesToRoot);
544 }
545
546 bool isLeaf(const Vertex& v) const
547 {
548 return !hasEdges(v, EdgesToLeaf);
549 }
550
551 Vertex source(const Edge& e) const
552 {
553 return boost::source(e.toEdge(), graph);
554 }
555
556 Vertex target(const Edge& e) const
557 {
558 return boost::target(e.toEdge(), graph);
559 }
560
561 QList<Edge> edges(const Vertex& v, AdjacencyFlags flags = AllEdges) const
562 {
563 if (flags & EdgesToLeaf)
564 {
565 flags = (AdjacencyFlags)(flags | ((direction == ParentToChild) ? OutboundEdges
566 : InboundEdges));
567 }
568
569 if (flags & EdgesToRoot)
570 {
571 flags = (AdjacencyFlags)(flags | ((direction == ParentToChild) ? InboundEdges
572 : OutboundEdges));
573 }
574
575 QList<Edge> es;
576
577 if (flags & OutboundEdges)
578 {
579 es << toEdgeList(boost::out_edges(v, graph));
580 }
581
582 if (flags & InboundEdges)
583 {
584 es << toEdgeList(boost::in_edges(v, graph));
585 }
586
587 return es;
588 }
589
590 int edgeCount() const
591 {
592 return boost::num_edges(graph);
593 }
594
595 bool hasEdges(const Vertex& v, AdjacencyFlags flags = AllEdges) const
596 {
597 if (flags & EdgesToLeaf)
598 {
599 flags = (AdjacencyFlags)(flags | ((direction == ParentToChild) ? OutboundEdges
600 : InboundEdges));
601 }
602
603 if (flags & EdgesToRoot)
604 {
605 flags = (AdjacencyFlags)(flags | ((direction == ParentToChild) ? InboundEdges
606 : OutboundEdges));
607 }
608
609 if (flags & OutboundEdges)
610 {
611 if (!isEmptyRange(boost::out_edges(v, graph)))
612 {
613 return true;
614 }
615 }
616
617 if (flags & InboundEdges)
618 {
619 if (!isEmptyRange(boost::in_edges(v, graph)))
620 {
621 return true;
622 }
623 }
624
625 return false;
626 }
627
628 bool hasEdges() const
629 {
630 return !isEmptyRange(boost::edges(graph));
631 }
632
633 QList<Edge> edges() const
634 {
635 return toEdgeList(boost::edges(graph));
636 }
637
638 QList<VertexPair> edgePairs() const
639 {
640 QList<VertexPair> pairs;
641 edge_range_t range = boost::edges(graph);
642
643 for (edge_iter it = range.first ; it != range.second ; ++it)
644 {
645 pairs << VertexPair(boost::source(*it, graph), boost::target(*it, graph));
646 }
647
648 return pairs;
649 }
650
651 /* ---- Algorithms ---- */
652
656 QList<Vertex> topologicalSort() const
657 {
658 std::list<Vertex> verticesLst;
659
660 try
661 {
662 boost::topological_sort(graph, std::back_inserter(verticesLst));
663 }
664 catch (boost::bad_graph& e)
665 {
666 qCDebug(DIGIKAM_DATABASE_LOG) << e.what();
667
668 return QList<Vertex>();
669 }
670
671 typedef typename std::list<Vertex>::iterator vertex_list_iter;
672
673 return toVertexList(std::pair<vertex_list_iter, vertex_list_iter>(verticesLst.begin(), verticesLst.end()));
674 }
675
677 {
678 CopyVertexProperties = 1 << 0,
679 CopyEdgeProperties = 1 << 1,
680 CopyAllProperties = CopyVertexProperties | CopyEdgeProperties
681 };
682
686 Graph transitiveClosure(GraphCopyFlags flags = CopyAllProperties) const
687 {
688 // make_iterator_property_map:
689 // 1. The second parameter, our verteX_index map, converts the key (Vertex) into an index.
690 // 2. The index is used to store the value (Vertex) in the first argument, which is our vector.
691
692 std::vector<vertex_t> copiedVertices(vertexCount(), Vertex());
693 Graph closure;
694
695 try
696 {
697 boost::transitive_closure(
698 graph,
699 closure.graph,
700 orig_to_copy(make_iterator_property_map(copiedVertices.begin(),
701 get(boost::vertex_index, graph)))
702 );
703 }
704 catch (boost::bad_graph& e)
705 {
706 qCDebug(DIGIKAM_DATABASE_LOG) << e.what();
707
708 return Graph();
709 }
710
711 copyProperties(closure, flags, copiedVertices);
712
713 return closure;
714 }
715
720 Graph transitiveReduction(QList<Edge>* removedEdges = 0, GraphCopyFlags flags = CopyAllProperties) const
721 {
722 std::vector<vertex_t> copiedVertices(vertexCount(), Vertex());
723 Graph reduction;
724
725 // NOTE: named parameters is not implemented.
726
727 try
728 {
729 boost::transitive_reduction(graph, reduction.graph,
730 make_iterator_property_map(copiedVertices.begin(), get(boost::vertex_index, graph)),
731 get(boost::vertex_index, graph));
732 }
733 catch (boost::bad_graph& e)
734 {
735 qCDebug(DIGIKAM_DATABASE_LOG) << e.what();
736
737 return Graph();
738 }
739
740 copyProperties(reduction, flags, copiedVertices);
741
742 if (removedEdges)
743 {
744 *removedEdges = edgeDifference(reduction, copiedVertices);
745 }
746
747 return reduction;
748 }
749
754 QList<Vertex> roots() const
755 {
756 return findZeroDegree(direction == ParentToChild ? true : false);
757 }
758
764 QList<Vertex> rootsOf(const Vertex& v) const
765 {
766 return findZeroDegreeFrom(v, direction == ParentToChild ? true : false);
767 }
768
773 QList<Vertex> leaves() const
774 {
775 return findZeroDegree((direction == ParentToChild) ? false : true);
776 }
777
778 QList<Vertex> leavesFrom(const Vertex& v) const
779 {
780 return findZeroDegreeFrom(v, (direction == ParentToChild) ? false : true);
781 }
782
783 template <typename T> static bool alwaysFalse(const T&, const T&)
784 {
785 return false;
786 }
787
794 QList<Vertex> longestPathTouching(const Vertex& v) const
795 {
796 return longestPathTouching(v, alwaysFalse<Vertex>);
797 }
798
799 template <typename LessThan>
800 QList<Vertex> longestPathTouching(const Vertex& v, LessThan lessThan) const
801 {
802 if (v.isNull())
803 {
804 return QList<Vertex>();
805 }
806
807 QList<Vertex> fromRoot;
808 QList<Vertex> toLeave;
809 Path path;
810
811 path.longestPath(boost::make_reverse_graph(graph), v);
812
813 QList<Vertex> rootCandidates = mostRemoteNodes(path.distances);
814
815 if (!rootCandidates.isEmpty())
816 {
817 std::stable_sort(rootCandidates.begin(), rootCandidates.end(), lessThan);
818 Vertex root = rootCandidates.first();
819 fromRoot << listPath(root, v, path.predecessors, ChildToParent);
820 }
821
822 path.longestPath(graph, v);
823
824 QList<Vertex> leaveCandidates = mostRemoteNodes(path.distances);
825
826 if (!leaveCandidates.isEmpty())
827 {
828 std::stable_sort(leaveCandidates.begin(), leaveCandidates.end(), lessThan);
829 Vertex leave = leaveCandidates.first();
830 toLeave << listPath(leave, v, path.predecessors);
831 }
832
833 if (direction == ParentToChild)
834 {
835 return (fromRoot << v << toLeave);
836 }
837 else
838 {
839 return (toLeave << v << fromRoot);
840 }
841 }
842
849 QList<Vertex> shortestPath(const Vertex& v1, const Vertex& v2) const
850 {
851 if (v1.isNull() || v2.isNull())
852 {
853 return QList<Vertex>();
854 }
855
856 QList<Vertex> verticesLst;
857
858 Path path;
859 path.shortestPath(graph, v1);
860
861 if (path.isReachable(v2))
862 {
863 verticesLst = listPath(v2, v1, path.predecessors, ChildToParent);
864 verticesLst.prepend(v1);
865 }
866 else
867 {
868 // Assume inverted parameters.
869
870 path.shortestPath(graph, v2);
871
872 if (path.isReachable(v1))
873 {
874 verticesLst = listPath(v1, v2, path.predecessors);
875 verticesLst.append(v2);
876 }
877 }
878
879 return verticesLst;
880 }
881
886 QMap<Vertex, int> shortestDistancesFrom(const Vertex& v) const
887 {
888 Path path;
889
890 if (direction == ParentToChild)
891 {
892 path.shortestPath(graph, v);
893 }
894 else
895 {
896 path.shortestPath(boost::make_reverse_graph(graph), v);
897 }
898
899 // Change 2147483647 to -1.
900
901 typename QMap<Vertex, int>::iterator it;
902
903 for (it = path.distances.begin() ; it != path.distances.end() ; ++it)
904 {
905 if (it.value() == std::numeric_limits<int>::max())
906 {
907 it.value() = -1;
908 }
909 }
910
911 return path.distances;
912 }
913
915 {
917 DepthFirstOrder
918 };
919
925 QList<Vertex> verticesDominatedBy(const Vertex& v,
926 const Vertex& root,
927 ReturnOrder order = BreadthFirstOrder) const
928 {
929 if (v.isNull() || isEmpty())
930 {
931 return QList<Vertex>();
932 }
933
934 GraphSearch search;
935
936 if (order == BreadthFirstOrder)
937 {
938 search.breadthFirstSearch(graph, root, (direction == ChildToParent));
939 }
940 else
941 {
942 search.depthFirstSearch(graph, root, (direction == ChildToParent));
943 }
944
945 return verticesDominatedBy(v, root, search.vertices);
946 }
947
953 template <typename LessThan>
955 const Vertex& root,
956 LessThan lessThan) const
957 {
958 return verticesDominatedBy(v, root, verticesDepthFirstSorted(root, lessThan));
959 }
960
968 QList<Vertex> verticesDominatedBy(const Vertex& v,
969 const Vertex& root,
970 const QList<Vertex>& presortedVertices) const
971 {
972 if (v.isNull() || isEmpty())
973 {
974 return QList<Vertex>();
975 }
976
977 DominatorTree tree;
978 tree.enter(graph, root, direction);
979
980 QList<Vertex> dominatedTree = treeFromPredecessors(v, tree.predecessors);
981
983
984 QList<Vertex> orderedTree;
985
986 for (const Vertex& vv : std::as_const(presortedVertices))
987 {
988 if (dominatedTree.contains(vv))
989 {
990 orderedTree << vv;
991 }
992 }
993
994 return orderedTree;
995 }
996
1002 QList<Vertex> verticesBreadthFirst(const Vertex& givenRef = Vertex()) const
1003 {
1004 if (isEmpty())
1005 {
1006 return QList<Vertex>();
1007 }
1008
1009 Vertex ref(givenRef);
1010
1011 if (ref.isNull())
1012 {
1013 ref = roots().first();
1014 }
1015
1016 QList<Vertex> verticesLst;
1017 verticesLst << rootsOf(ref);
1018
1019 if (verticesLst.size() == vertexCount())
1020 {
1021 return verticesLst;
1022 }
1023
1024 GraphSearch search;
1025 search.breadthFirstSearch(graph, verticesLst.first(), direction == ChildToParent);
1026 QList<Vertex> bfs = search.verticesLst;
1027
1028 for (const Vertex& v : std::as_const(verticesLst))
1029 {
1030 bfs.removeOne(v);
1031 }
1032
1033 verticesLst << bfs;
1034
1035 if (verticesLst.size() == vertexCount())
1036 {
1037 return verticesLst;
1038 }
1039
1040 // Sort in any so far unreachable nodes.
1041
1042 vertex_range_t range = boost::vertices(graph);
1043
1044 for (vertex_iter it = range.first ; it != range.second ; ++it)
1045 {
1046 if (!verticesLst.contains(*it))
1047 {
1048 GraphSearch childSearch;
1049 childSearch.breadthFirstSearch(graph, *it, direction == ChildToParent);
1050 QList<Vertex> childBfs = childSearch.vertices;
1051 QList<Vertex> toInsert;
1052
1053 // Any item reachable from *it should come after it.
1054
1055 int minIndex = verticesLst.size();
1056
1057 for (const Vertex& c : std::as_const(childBfs))
1058 {
1059 int foundAt = verticesLst.indexOf(c);
1060
1061 if (foundAt == -1)
1062 {
1063 toInsert << c;
1064 }
1065 else
1066 {
1067 minIndex = qMin(foundAt, minIndex);
1068 }
1069 }
1070
1071 for (const Vertex& c : std::as_const(toInsert))
1072 {
1073 verticesLst.insert(minIndex++, c);
1074 }
1075 }
1076 }
1077
1078 return verticesLst;
1079 }
1080
1087 template <typename LessThan>
1088 QList<Vertex> verticesDepthFirstSorted(const Vertex& givenRef, LessThan lessThan) const
1089 {
1090 if (isEmpty())
1091 {
1092 return QList<Vertex>();
1093 }
1094
1095 Vertex ref(givenRef);
1096
1097 if (ref.isNull())
1098 {
1099 ref = roots().first();
1100 }
1101
1102 QList<Vertex> verticesLst;
1103 verticesLst = rootsOf(ref);
1104
1105 if ((verticesLst.size() == vertexCount()) || verticesLst.isEmpty())
1106 {
1107 return verticesLst;
1108 }
1109
1110 GraphSearch search;
1111 search.depthFirstSearchSorted(graph, verticesLst.first(), direction == ChildToParent, lessThan);
1112 QList<Vertex> dfs = search.vertices;
1113
1114 for (const Vertex& v : std::as_const(verticesLst))
1115 {
1116 dfs.removeOne(v);
1117 }
1118
1119 verticesLst << dfs;
1120
1121 return search.vertices;
1122 }
1123
1124protected:
1125
1126 QList<Vertex> treeFromPredecessors(const Vertex& v, const VertexVertexMap& predecessors) const
1127 {
1128 QList<Vertex> verticesLst;
1129 verticesLst << v;
1130 treeFromPredecessorsRecursive(v, verticesLst, predecessors);
1131
1132 return verticesLst;
1133 }
1134
1136 QList<Vertex>& vertices,
1137 const VertexVertexMap& predecessors) const
1138 {
1139 QList<Vertex> children = predecessors.keys(v);
1140 vertices << children;
1141
1142 for (const Vertex& child : std::as_const(children))
1143 {
1144 treeFromPredecessorsRecursive(child, vertices, predecessors);
1145 }
1146 }
1147
1151 template <typename Value, typename range_t>
1152 static QList<Value> toList(const range_t& range)
1153 {
1154 typedef typename range_t::first_type iterator_t;
1155 QList<Value> list;
1156
1157 for (iterator_t it = range.first ; it != range.second ; ++it)
1158 {
1159 list << *it;
1160 }
1161
1162 return list;
1163 }
1164
1165 template <typename range_t> static QList<Vertex> toVertexList(const range_t& range)
1166 {
1167 return toList<Vertex, range_t>(range);
1168 }
1169
1170 template <typename range_t> static QList<Edge> toEdgeList(const range_t& range)
1171 {
1172 return toList<Edge, range_t>(range);
1173 }
1174
1175 template <typename range_t>
1176 static bool isEmptyRange(const range_t& range)
1177 {
1178 return (range.first == range.second);
1179 }
1180
1185 void copyProperties(Graph& other, GraphCopyFlags flags, const std::vector<vertex_t>& copiedVertices) const
1186 {
1187 other.direction = direction;
1188
1189 if (flags & CopyVertexProperties)
1190 {
1191 vertex_index_map_t indexMap = boost::get(boost::vertex_index, graph);
1192 vertex_range_t range = boost::vertices(graph);
1193
1194 for (vertex_iter it = range.first ; it != range.second ; ++it)
1195 {
1196 Vertex copiedVertex = copiedVertices[boost::get(indexMap, *it)];
1197
1198 if (copiedVertex.isNull())
1199 {
1200 continue;
1201 }
1202
1203 other.setProperties(copiedVertex, properties(*it));
1204 }
1205 }
1206
1207 if (flags & CopyEdgeProperties)
1208 {
1209 vertex_index_map_t indexMap = boost::get(boost::vertex_index, graph);
1210 edge_range_t range = boost::edges(graph);
1211
1212 for (edge_iter it = range.first ; it != range.second ; ++it)
1213 {
1214 Vertex s = boost::source(*it, graph);
1215 Vertex t = boost::target(*it, graph);
1216 Vertex copiedS = copiedVertices[boost::get(indexMap, s)];
1217 Vertex copiedT = copiedVertices[boost::get(indexMap, t)];
1218
1219 if (copiedS.isNull() || copiedT.isNull())
1220 {
1221 continue;
1222 }
1223
1224 Edge copiedEdge = other.edge(copiedS, copiedT);
1225
1226 if (!copiedEdge.isNull())
1227 {
1228 other.setProperties(copiedEdge, properties(s, t));
1229 }
1230 }
1231 }
1232 }
1233
1238 QList<Edge> edgeDifference(const Graph& other, const std::vector<vertex_t>& copiedVertices) const
1239 {
1240 QList<Edge> removed;
1241 vertex_index_map_t indexMap = boost::get(boost::vertex_index, graph);
1242 edge_range_t range = boost::edges(graph);
1243
1244 for (edge_iter it = range.first ; it != range.second ; ++it)
1245 {
1246 Vertex s = boost::source(*it, graph);
1247 Vertex t = boost::target(*it, graph);
1248 Vertex copiedS = copiedVertices[boost::get(indexMap, s)];
1249 Vertex copiedT = copiedVertices[boost::get(indexMap, t)];
1250
1251 if (copiedS.isNull() || copiedT.isNull())
1252 {
1253 continue;
1254 }
1255
1256 Edge copiedEdge = other.edge(copiedS, copiedT);
1257
1258 if (copiedEdge.isNull())
1259 {
1260 removed << *it;
1261 }
1262 }
1263
1264 return removed;
1265 }
1266
1270 QList<Vertex> findZeroDegree(bool inOrOut) const
1271 {
1272 QList<Vertex> verticesLst;
1273 vertex_range_t range = boost::vertices(graph);
1274
1275 for (vertex_iter it = range.first ; it != range.second ; ++it)
1276 {
1277 if ((inOrOut ? in_degree(*it, graph)
1278 : out_degree(*it, graph)) == 0)
1279 {
1280 verticesLst << *it;
1281 }
1282 }
1283
1284 return verticesLst;
1285 }
1286
1287 QList<Vertex> findZeroDegreeFrom(const Vertex& v, bool inOrOut) const
1288 {
1289 bool invertGraph = (direction == ChildToParent);
1290
1291 if (!inOrOut)
1292 {
1293 invertGraph = !invertGraph;
1294 }
1295
1296 GraphSearch search;
1297 search.breadthFirstSearch(graph, v, invertGraph);
1298
1299 QList<Vertex> verticesLst;
1300
1301 for (const Vertex& candidate : std::as_const(search.vertices))
1302 {
1303 if ((inOrOut ? in_degree(candidate, graph)
1304 : out_degree(candidate, graph)) == 0)
1305 {
1306 verticesLst << candidate;
1307 }
1308 }
1309
1310 return verticesLst;
1311 }
1312
1317 class Path
1318 {
1319 public:
1320
1321 template <class GraphType>
1322 void shortestPath(const GraphType& graph, const Vertex& v)
1323 {
1324 int weight = 1;
1325
1326 try
1327 {
1328 boost::dag_shortest_paths(
1329 graph, v,
1330
1332
1333 weight_map(boost::ref_property_map<typename boost::graph_traits<GraphType>::edge_descriptor,int>(weight)).
1334
1336
1337 distance_map(VertexIntMapAdaptor(distances)).
1338 predecessor_map(VertexVertexMapAdaptor(predecessors))
1339 );
1340 }
1341 catch (boost::bad_graph& e)
1342 {
1343 qCDebug(DIGIKAM_DATABASE_LOG) << e.what();
1344 }
1345 }
1346
1347 template <class GraphType>
1348 void longestPath(const GraphType& graph, const Vertex& v)
1349 {
1350 int weight = 1;
1351
1352 try
1353 {
1354 boost::dag_shortest_paths(
1355 graph, v,
1356
1358
1359 weight_map(boost::ref_property_map<typename boost::graph_traits<GraphType>::edge_descriptor,int>(weight)).
1360
1362
1363 distance_compare(std::greater<int>()).
1364
1366
1367 distance_inf(-1).
1368
1370
1371 distance_map(VertexIntMapAdaptor(distances)).
1372 predecessor_map(VertexVertexMapAdaptor(predecessors))
1373 );
1374 }
1375 catch (boost::bad_graph& e)
1376 {
1377 qCDebug(DIGIKAM_DATABASE_LOG) << e.what();
1378 }
1379 }
1380
1381 bool isReachable(const Vertex& v) const
1382 {
1383 return (predecessors.value(v, v) != v);
1384 }
1385
1388 };
1389
1391 {
1392 public:
1393
1394 template <class GraphType>
1395 void enter(const GraphType& graph, const Vertex& v, MeaningOfDirection direction = ParentToChild)
1396 {
1397 try
1398 {
1399 if (direction == ParentToChild)
1400 {
1401 boost::lengauer_tarjan_dominator_tree(graph, v, VertexVertexMapAdaptor(predecessors));
1402 }
1403 else
1404 {
1405 boost::lengauer_tarjan_dominator_tree(boost::make_reverse_graph(graph), v,
1406 VertexVertexMapAdaptor(predecessors));
1407 }
1408 }
1409 catch (boost::bad_graph& e)
1410 {
1411 qCDebug(DIGIKAM_DATABASE_LOG) << e.what();
1412 }
1413 }
1414
1416 };
1417
1419 {
1420 public:
1421
1422 template <class GraphType>
1423 void depthFirstSearch(const GraphType& graph, const Vertex& v, bool invertGraph)
1424 {
1425 // Remember that the visitor is passed by value.
1426
1427 DepthFirstSearchVisitor vis(this);
1428
1429 try
1430 {
1431 if (invertGraph)
1432 {
1433 boost::depth_first_search(boost::make_reverse_graph(graph), visitor(vis).root_vertex(v));
1434 }
1435 else
1436 {
1437 boost::depth_first_search(graph, visitor(vis).root_vertex(v));
1438 }
1439 }
1440 catch (boost::bad_graph& e)
1441 {
1442 qCDebug(DIGIKAM_DATABASE_LOG) << e.what();
1443 }
1444 }
1445
1446 template <class GraphType, typename LessThan>
1447 void depthFirstSearchSorted(const GraphType& graph, const Vertex& v, bool invertGraph, LessThan lessThan)
1448 {
1449 // Remember that the visitor is passed by value.
1450
1451 DepthFirstSearchVisitor vis(this);
1452 std::vector<boost::default_color_type> color_vec(boost::num_vertices(graph), boost::white_color);
1453
1454 try
1455 {
1456 if (invertGraph)
1457 {
1458 depth_first_search_sorted(boost::make_reverse_graph(graph), v, vis,
1459 make_iterator_property_map(color_vec.begin(), get(boost::vertex_index, graph)), lessThan);
1460 }
1461 else
1462 {
1463 depth_first_search_sorted(graph, v, vis,
1464 make_iterator_property_map(color_vec.begin(), get(boost::vertex_index, graph)), lessThan);
1465 }
1466 }
1467 catch (boost::bad_graph& e)
1468 {
1469 qCDebug(DIGIKAM_DATABASE_LOG) << e.what();
1470 }
1471 }
1472
1473 template <class GraphType>
1474 void breadthFirstSearch(const GraphType& graph, const Vertex& v, bool invertGraph)
1475 {
1476 BreadthFirstSearchVisitor vis(this);
1477
1478 try
1479 {
1480 if (invertGraph)
1481 {
1482 boost::breadth_first_search(boost::make_reverse_graph(graph), v, visitor(vis));
1483 }
1484 else
1485 {
1486 boost::breadth_first_search(graph, v, visitor(vis));
1487 }
1488 }
1489 catch (boost::bad_graph& e)
1490 {
1491 qCDebug(DIGIKAM_DATABASE_LOG) << e.what();
1492 }
1493 }
1494
1496 {
1497 protected:
1498
1499 explicit CommonVisitor(GraphSearch* const qq)
1500 : q(qq)
1501 {
1502 }
1503
1504 void record(const Vertex& v) const
1505 {
1506 q->vertices << v;
1507 }
1508
1509 GraphSearch* const q = nullptr;
1510 };
1511
1512 class DepthFirstSearchVisitor : public boost::default_dfs_visitor,
1513 public CommonVisitor
1514 {
1515 public:
1516
1518 : CommonVisitor(q)
1519 {
1520 }
1521
1522 template <typename VertexType, typename GraphType>
1523 void discover_vertex(VertexType u, const GraphType&) const
1524 {
1525 this->record(u);
1526 }
1527 };
1528
1529 class BreadthFirstSearchVisitor : public boost::default_bfs_visitor,
1530 public CommonVisitor
1531 {
1532 public:
1533
1535 : CommonVisitor(q)
1536 {
1537 }
1538
1539 template <typename VertexType, typename GraphType>
1540 void discover_vertex(VertexType u, const GraphType&) const
1541 {
1542 this->record(u);
1543 }
1544 };
1545
1546 QList<Vertex> vertices;
1547
1548 protected:
1549
1550 template <class GraphType, typename VertexLessThan>
1552 {
1553 typedef typename boost::graph_traits<GraphType>::edge_descriptor edge_descriptor;
1554
1555 public:
1556
1557 lessThanMapEdgeToTarget(const GraphType& gg, VertexLessThan vertexLessThan)
1558 : g (gg),
1559 vertexLessThan(vertexLessThan)
1560 {
1561 }
1562
1563 bool operator()(const edge_descriptor& a, const edge_descriptor& b)
1564 {
1565 return vertexLessThan(boost::target(a, g), boost::target(b, g));
1566 }
1567
1568 public:
1569
1570 const GraphType& g;
1571 VertexLessThan vertexLessThan;
1572 };
1573
1577 template <class IncidenceGraph, class DFSVisitor, class ColorMap, typename LessThan>
1578 void depth_first_search_sorted(const IncidenceGraph& g,
1579 Vertex u,
1580 DFSVisitor& vis,
1581 ColorMap color,
1582 LessThan lessThan)
1583 {
1584/*
1585 typedef std::pair<Vertex, QList<Edge> > VertexInfo;
1586*/
1587 typedef typename boost::graph_traits<IncidenceGraph>::edge_descriptor edge_descriptor;
1588 QList<edge_descriptor> outEdges;
1589/*
1590 std::vector<VertexInfo> stack;
1591*/
1592 boost::put(color, u, boost::gray_color);
1593 vis.discover_vertex(u, g);
1594
1595 outEdges = toList<edge_descriptor>(boost::out_edges(u, g));
1596
1601 std::sort(outEdges.begin(),
1602 outEdges.end(),
1604
1605 for (const edge_descriptor& e : std::as_const(outEdges))
1606 {
1607 Vertex v = boost::target(e, g);
1608 vis.examine_edge(e, g);
1609 boost::default_color_type v_color = boost::get(color, v);
1610
1611 if (v_color == boost::white_color)
1612 {
1613 vis.tree_edge(e, g);
1614 depth_first_search_sorted(g, v, vis, color, lessThan);
1615 }
1616 else if (v_color == boost::gray_color)
1617 {
1618 vis.back_edge(e, g);
1619 }
1620 else
1621 {
1622 vis.forward_or_cross_edge(e, g);
1623 }
1624 }
1625
1626 put(color, u, boost::black_color);
1627 vis.finish_vertex(u, g);
1628 }
1629 };
1630
1634 QList<Vertex> mostRemoteNodes(const VertexIntMap& distances) const
1635 {
1636 typename VertexIntMap::const_iterator it;
1637 int maxDist = 1;
1638 QList<Vertex> candidates;
1639
1640 for (it = distances.begin() ; it != distances.end() ; ++it)
1641 {
1642 if (it.value() > maxDist)
1643 {
1644 maxDist = it.value();
1645/*
1646 qDebug() << "Increasing maxDist to" << maxDist;
1647*/
1648 candidates.clear();
1649 }
1650
1651 if (it.value() >= maxDist)
1652 {
1653/*
1654 qDebug() << "Adding candidate" << id(it.key()) << "at distance" << maxDist;
1655*/
1656 candidates << it.key();
1657 }
1658
1659/*
1660 if (it.value() == -1)
1661 {
1662 qDebug() << id(it.key()) << "unreachable";
1663 }
1664 else
1665 {
1666 qDebug() << "Distance to" << id(it.key()) << "is" << it.value();
1667 }
1668*/
1669 }
1670
1671 return candidates;
1672 }
1673
1678 QList<Vertex> listPath(const Vertex& root,
1679 const Vertex& target,
1680 const VertexVertexMap& predecessors,
1681 MeaningOfDirection dir = ParentToChild) const
1682 {
1683 QList<Vertex> verticesLst;
1684
1685 for (Vertex v = root ; v != target ; v = predecessors.value(v))
1686 {
1687/*
1688 qDebug() << "Adding waypoint" << id(v);
1689*/
1690 if (dir == ParentToChild)
1691 {
1692 verticesLst.append(v);
1693 }
1694 else
1695 {
1696 verticesLst.prepend(v);
1697 }
1698
1699 // If a node is not reachable, it seems its entry in the predecessors map is itself.
1700 // Avoid endless loop.
1701
1702 if (predecessors.value(v) == v)
1703 {
1704 break;
1705 }
1706 }
1707
1708 return verticesLst;
1709 }
1710
1711protected:
1712
1715};
1716
1717} // namespace Digikam
1718
1719// Restore warnings.
1720
1721#if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU)
1722# pragma GCC diagnostic pop
1723#endif
1724
1725#if defined(Q_CC_CLANG)
1726# pragma clang diagnostic pop
1727#endif
Definition itemhistorygraph_boost.h:1391
VertexVertexMap predecessors
Definition itemhistorygraph_boost.h:1415
void enter(const GraphType &graph, const Vertex &v, MeaningOfDirection direction=ParentToChild)
Definition itemhistorygraph_boost.h:1395
Definition itemhistorygraph_boost.h:228
Edge(const edge_t &e)
Definition itemhistorygraph_boost.h:234
edge_t e
Definition itemhistorygraph_boost.h:280
bool operator==(const edge_t &other) const
Definition itemhistorygraph_boost.h:268
const edge_t & toEdge() const
Definition itemhistorygraph_boost.h:258
Edge & operator=(const edge_t &other)
Definition itemhistorygraph_boost.h:240
bool isNull() const
Definition itemhistorygraph_boost.h:273
edge_t & toEdge()
Definition itemhistorygraph_boost.h:263
Definition itemhistorygraph_boost.h:1531
void discover_vertex(VertexType u, const GraphType &) const
Definition itemhistorygraph_boost.h:1540
BreadthFirstSearchVisitor(GraphSearch *const q)
Definition itemhistorygraph_boost.h:1534
Definition itemhistorygraph_boost.h:1496
CommonVisitor(GraphSearch *const qq)
Definition itemhistorygraph_boost.h:1499
void record(const Vertex &v) const
Definition itemhistorygraph_boost.h:1504
Definition itemhistorygraph_boost.h:1514
void discover_vertex(VertexType u, const GraphType &) const
Definition itemhistorygraph_boost.h:1523
DepthFirstSearchVisitor(GraphSearch *const q)
Definition itemhistorygraph_boost.h:1517
Definition itemhistorygraph_boost.h:1552
VertexLessThan vertexLessThan
Definition itemhistorygraph_boost.h:1571
bool operator()(const edge_descriptor &a, const edge_descriptor &b)
Definition itemhistorygraph_boost.h:1563
lessThanMapEdgeToTarget(const GraphType &gg, VertexLessThan vertexLessThan)
Definition itemhistorygraph_boost.h:1557
const GraphType & g
Definition itemhistorygraph_boost.h:1570
Definition itemhistorygraph_boost.h:1419
void depth_first_search_sorted(const IncidenceGraph &g, Vertex u, DFSVisitor &vis, ColorMap color, LessThan lessThan)
Definition itemhistorygraph_boost.h:1578
QList< Vertex > vertices
Definition itemhistorygraph_boost.h:1546
void depthFirstSearchSorted(const GraphType &graph, const Vertex &v, bool invertGraph, LessThan lessThan)
Definition itemhistorygraph_boost.h:1447
void breadthFirstSearch(const GraphType &graph, const Vertex &v, bool invertGraph)
Definition itemhistorygraph_boost.h:1474
void depthFirstSearch(const GraphType &graph, const Vertex &v, bool invertGraph)
Definition itemhistorygraph_boost.h:1423
Definition itemhistorygraph_boost.h:1318
VertexIntMap distances
Definition itemhistorygraph_boost.h:1387
VertexVertexMap predecessors
Definition itemhistorygraph_boost.h:1386
void longestPath(const GraphType &graph, const Vertex &v)
Definition itemhistorygraph_boost.h:1348
bool isReachable(const Vertex &v) const
Definition itemhistorygraph_boost.h:1381
void shortestPath(const GraphType &graph, const Vertex &v)
Definition itemhistorygraph_boost.h:1322
Definition itemhistorygraph_boost.h:176
Vertex & operator=(const vertex_t &other)
Definition itemhistorygraph_boost.h:190
bool operator!=(const vertex_t &other) const
Definition itemhistorygraph_boost.h:212
Vertex()
Definition itemhistorygraph_boost.h:179
vertex_t v
Definition itemhistorygraph_boost.h:224
Vertex(const vertex_t &vv)
Definition itemhistorygraph_boost.h:185
bool operator==(const vertex_t &other) const
Definition itemhistorygraph_boost.h:207
bool isNull() const
Definition itemhistorygraph_boost.h:217
Definition itemhistorygraph_boost.h:127
std::pair< vertex_iter, vertex_iter > vertex_range_t
Definition itemhistorygraph_boost.h:161
void clear()
Definition itemhistorygraph_boost.h:326
boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, boost::property< boost::vertex_index_t, int, boost::property< vertex_properties_t, VertexProperties > >, boost::property< edge_properties_t, EdgeProperties > > GraphContainer
Definition itemhistorygraph_boost.h:137
QList< Vertex > findZeroDegreeFrom(const Vertex &v, bool inOrOut) const
Definition itemhistorygraph_boost.h:1287
QList< Vertex > longestPathTouching(const Vertex &v) const
Definition itemhistorygraph_boost.h:794
QMapForAdaptors< Vertex, Vertex > VertexVertexMap
Definition itemhistorygraph_boost.h:292
const EdgeProperties & properties(const Edge &e) const
Definition itemhistorygraph_boost.h:455
Graph(const Graph &g)
Definition itemhistorygraph_boost.h:305
QList< Vertex > verticesDominatedBy(const Vertex &v, const Vertex &root, const QList< Vertex > &presortedVertices) const
Definition itemhistorygraph_boost.h:968
QList< Vertex > roots() const
Definition itemhistorygraph_boost.h:754
QList< Vertex > verticesDepthFirstSorted(const Vertex &givenRef, LessThan lessThan) const
Definition itemhistorygraph_boost.h:1088
bool hasEdge(const Vertex &v1, const Vertex &v2) const
Definition itemhistorygraph_boost.h:381
boost::property_map< GraphContainer, edge_properties_t >::const_type const_edge_property_map_t
Definition itemhistorygraph_boost.h:169
bool isEmpty() const
Definition itemhistorygraph_boost.h:526
virtual ~Graph()=default
MeaningOfDirection meaningOfDirection() const
Definition itemhistorygraph_boost.h:321
QPair< Edge, Edge > EdgePair
Definition itemhistorygraph_boost.h:290
boost::inv_adjacency_iterator_generator< GraphContainer, vertex_t, in_edge_iter >::type inv_adjacency_iter
Definition itemhistorygraph_boost.h:154
QList< Vertex > topologicalSort() const
Definition itemhistorygraph_boost.h:656
void remove(const Vertex &v)
Definition itemhistorygraph_boost.h:346
Graph & operator=(const Graph &other)
Definition itemhistorygraph_boost.h:313
bool isLeaf(const Vertex &v) const
Definition itemhistorygraph_boost.h:546
Vertex target(const Edge &e) const
Definition itemhistorygraph_boost.h:556
std::pair< edge_iter, edge_iter > edge_range_t
Definition itemhistorygraph_boost.h:162
boost::property_map< GraphContainer, boost::vertex_index_t >::type vertex_index_map_t
Definition itemhistorygraph_boost.h:164
Graph(MeaningOfDirection dir=ParentToChild)
Definition itemhistorygraph_boost.h:300
AdjacencyFlags
Definition itemhistorygraph_boost.h:479
GraphCopyFlags
Definition itemhistorygraph_boost.h:677
const GraphContainer & getGraph() const
Definition itemhistorygraph_boost.h:468
graph_traits::vertex_descriptor vertex_t
Definition itemhistorygraph_boost.h:144
QList< Vertex > verticesDominatedBy(const Vertex &v, const Vertex &root, ReturnOrder order=BreadthFirstOrder) const
Definition itemhistorygraph_boost.h:925
static QList< Vertex > toVertexList(const range_t &range)
Definition itemhistorygraph_boost.h:1165
boost::graph_traits< GraphContainer > graph_traits
Definition itemhistorygraph_boost.h:142
QList< VertexPair > edgePairs() const
Definition itemhistorygraph_boost.h:638
void setProperties(const Vertex &v, const VertexProperties &props)
Definition itemhistorygraph_boost.h:403
int edgeCount() const
Definition itemhistorygraph_boost.h:590
boost::property_map< GraphContainer, vertex_properties_t >::const_type const_vertex_property_map_t
Definition itemhistorygraph_boost.h:167
boost::property_map< GraphContainer, boost::vertex_index_t >::const_type const_vertex_index_map_t
Definition itemhistorygraph_boost.h:165
QList< Vertex > listPath(const Vertex &root, const Vertex &target, const VertexVertexMap &predecessors, MeaningOfDirection dir=ParentToChild) const
Definition itemhistorygraph_boost.h:1678
int outDegree(const Vertex &v) const
Definition itemhistorygraph_boost.h:531
QList< Vertex > treeFromPredecessors(const Vertex &v, const VertexVertexMap &predecessors) const
Definition itemhistorygraph_boost.h:1126
Edge edge(const Vertex &v1, const Vertex &v2) const
Definition itemhistorygraph_boost.h:369
static QList< Value > toList(const range_t &range)
Definition itemhistorygraph_boost.h:1152
EdgeProperties properties(const Vertex &v1, const Vertex &v2) const
Definition itemhistorygraph_boost.h:443
QList< Vertex > mostRemoteNodes(const VertexIntMap &distances) const
Definition itemhistorygraph_boost.h:1634
graph_traits::vertex_iterator vertex_iter
Definition itemhistorygraph_boost.h:147
const VertexProperties & properties(const Vertex &v) const
Definition itemhistorygraph_boost.h:408
QMapForAdaptors< Vertex, int > VertexIntMap
Definition itemhistorygraph_boost.h:293
MeaningOfDirection direction
Definition itemhistorygraph_boost.h:1714
QList< Edge > edgeDifference(const Graph &other, const std::vector< vertex_t > &copiedVertices) const
Definition itemhistorygraph_boost.h:1238
bool isRoot(const Vertex &v) const
Definition itemhistorygraph_boost.h:541
void treeFromPredecessorsRecursive(const Vertex &v, QList< Vertex > &vertices, const VertexVertexMap &predecessors) const
Definition itemhistorygraph_boost.h:1135
static QList< Edge > toEdgeList(const range_t &range)
Definition itemhistorygraph_boost.h:1170
std::pair< inv_adjacency_iter, inv_adjacency_iter > inv_adjacency_vertex_range_t
Definition itemhistorygraph_boost.h:159
graph_traits::edge_iterator edge_iter
Definition itemhistorygraph_boost.h:148
QPair< Vertex, Vertex > VertexPair
Definition itemhistorygraph_boost.h:289
QList< Vertex > vertices() const
Definition itemhistorygraph_boost.h:473
bool hasEdges() const
Definition itemhistorygraph_boost.h:628
int inDegree(const Vertex &v) const
Definition itemhistorygraph_boost.h:536
Graph transitiveClosure(GraphCopyFlags flags=CopyAllProperties) const
Definition itemhistorygraph_boost.h:686
std::pair< out_edge_iter, out_edge_iter > out_edge_range_t
Definition itemhistorygraph_boost.h:160
QList< Vertex > rootsOf(const Vertex &v) const
Definition itemhistorygraph_boost.h:764
VertexProperties & properties(const Vertex &v)
Definition itemhistorygraph_boost.h:413
QList< Edge > edges(const Vertex &v, AdjacencyFlags flags=AllEdges) const
Definition itemhistorygraph_boost.h:561
graph_traits::out_edge_iterator out_edge_iter
Definition itemhistorygraph_boost.h:150
graph_traits::degree_size_type degree_t
Definition itemhistorygraph_boost.h:156
QList< Edge > edges() const
Definition itemhistorygraph_boost.h:633
void copyProperties(Graph &other, GraphCopyFlags flags, const std::vector< vertex_t > &copiedVertices) const
Definition itemhistorygraph_boost.h:1185
QList< Vertex > shortestPath(const Vertex &v1, const Vertex &v2) const
Definition itemhistorygraph_boost.h:849
int vertexCount() const
NOTE: for "hasAdjacentVertices", simply use hasEdges(v, flags).
Definition itemhistorygraph_boost.h:521
boost::property_map< GraphContainer, edge_properties_t >::type edge_property_map_t
Definition itemhistorygraph_boost.h:168
EdgeProperties & properties(const Edge &e)
Definition itemhistorygraph_boost.h:460
Vertex findVertexByProperties(const T &value) const
Definition itemhistorygraph_boost.h:424
std::pair< adjacency_iter, adjacency_iter > adjacency_vertex_range_t
Definition itemhistorygraph_boost.h:158
boost::associative_property_map< VertexIntMap > VertexIntMapAdaptor
Definition itemhistorygraph_boost.h:296
QMap< Vertex, int > shortestDistancesFrom(const Vertex &v) const
Definition itemhistorygraph_boost.h:886
QList< Vertex > longestPathTouching(const Vertex &v, LessThan lessThan) const
Definition itemhistorygraph_boost.h:800
Edge addEdge(const Vertex &v1, const Vertex &v2)
Definition itemhistorygraph_boost.h:357
ReturnOrder
Definition itemhistorygraph_boost.h:915
@ BreadthFirstOrder
Definition itemhistorygraph_boost.h:916
bool hasEdges(const Vertex &v, AdjacencyFlags flags=AllEdges) const
Definition itemhistorygraph_boost.h:595
bool isConnected(const Vertex &v1, const Vertex &v2) const
Definition itemhistorygraph_boost.h:388
void setProperties(const Edge &e, const EdgeProperties &props)
Definition itemhistorygraph_boost.h:418
static bool alwaysFalse(const T &, const T &)
Definition itemhistorygraph_boost.h:783
graph_traits::edge_descriptor edge_t
Definition itemhistorygraph_boost.h:145
GraphContainer graph
Definition itemhistorygraph_boost.h:1713
boost::associative_property_map< VertexVertexMap > VertexVertexMapAdaptor
Definition itemhistorygraph_boost.h:295
QList< Vertex > leaves() const
Definition itemhistorygraph_boost.h:773
graph_traits::in_edge_iterator in_edge_iter
Definition itemhistorygraph_boost.h:151
QList< Vertex > adjacentVertices(const Vertex &v, AdjacencyFlags flags=AllEdges) const
Definition itemhistorygraph_boost.h:490
static bool isEmptyRange(const range_t &range)
Definition itemhistorygraph_boost.h:1176
Vertex addVertex(const VertexProperties &properties)
Definition itemhistorygraph_boost.h:338
graph_traits::adjacency_iterator adjacency_iter
Definition itemhistorygraph_boost.h:149
boost::property_map< GraphContainer, vertex_properties_t >::type vertex_property_map_t
Definition itemhistorygraph_boost.h:166
QList< Vertex > findZeroDegree(bool inOrOut) const
Definition itemhistorygraph_boost.h:1270
Vertex addVertex()
Definition itemhistorygraph_boost.h:331
QList< Vertex > leavesFrom(const Vertex &v) const
Definition itemhistorygraph_boost.h:778
QList< Vertex > verticesBreadthFirst(const Vertex &givenRef=Vertex()) const
Definition itemhistorygraph_boost.h:1002
Graph transitiveReduction(QList< Edge > *removedEdges=0, GraphCopyFlags flags=CopyAllProperties) const
Definition itemhistorygraph_boost.h:720
Vertex source(const Edge &e) const
Definition itemhistorygraph_boost.h:551
QList< Vertex > verticesDominatedByDepthFirstSorted(const Vertex &v, const Vertex &root, LessThan lessThan) const
Definition itemhistorygraph_boost.h:954
Definition itemhistorygraph_boost.h:99
Key key_type
Definition itemhistorygraph_boost.h:102
Value data_type
Definition itemhistorygraph_boost.h:103
std::pair< const Key, Value > value_type
Definition itemhistorygraph_boost.h:104
edge_properties_t
Definition itemhistorygraph_boost.h:82
@ edge_properties
Definition itemhistorygraph_boost.h:82
vertex_properties_t
Definition itemhistorygraph_boost.h:81
@ vertex_properties
Definition itemhistorygraph_boost.h:81
qulonglong value
Definition itemviewutilities.cpp:585
#define T
Definition datefolderview.cpp:34
MeaningOfDirection
Definition itemhistorygraph_boost.h:117
@ ParentToChild
Edges are directed from a parent to its child.
Definition itemhistorygraph_boost.h:118
@ ChildToParent
Edges are direct from a child to its parent.
Definition itemhistorygraph_boost.h:119