69 |
69 |
70 ///Creates convenience typedefs for the undirected graph types and iterators |
70 ///Creates convenience typedefs for the undirected graph types and iterators |
71 |
71 |
72 ///This \c \#define creates the same convenience typedefs as defined by |
72 ///This \c \#define creates the same convenience typedefs as defined by |
73 ///\ref GRAPH_TYPEDEFS(Graph) and three more, namely it creates |
73 ///\ref GRAPH_TYPEDEFS(Graph) and three more, namely it creates |
74 ///\c UndirEdge, \c UndirEdgeIt, \c IncEdgeIt, |
74 ///\c UEdge, \c UEdgeIt, \c IncEdgeIt, |
75 ///\c BoolUndirEdgeMap, \c IntUndirEdgeMap, \c DoubleUndirEdgeMap. |
75 ///\c BoolUEdgeMap, \c IntUEdgeMap, \c DoubleUEdgeMap. |
76 /// |
76 /// |
77 ///\note If \c G it a template parameter, it should be used in this way. |
77 ///\note If \c G it a template parameter, it should be used in this way. |
78 ///\code |
78 ///\code |
79 /// UNDIRGRAPH_TYPEDEFS(typename G) |
79 /// UNDIRGRAPH_TYPEDEFS(typename G) |
80 ///\endcode |
80 ///\endcode |
81 /// |
81 /// |
82 ///\warning There are no typedefs for the graph maps because of the lack of |
82 ///\warning There are no typedefs for the graph maps because of the lack of |
83 ///template typedefs in C++. |
83 ///template typedefs in C++. |
84 #define UNDIRGRAPH_TYPEDEFS(Graph) \ |
84 #define UNDIRGRAPH_TYPEDEFS(Graph) \ |
85 GRAPH_TYPEDEFS(Graph) \ |
85 GRAPH_TYPEDEFS(Graph) \ |
86 typedef Graph:: UndirEdge UndirEdge; \ |
86 typedef Graph:: UEdge UEdge; \ |
87 typedef Graph:: UndirEdgeIt UndirEdgeIt; \ |
87 typedef Graph:: UEdgeIt UEdgeIt; \ |
88 typedef Graph:: IncEdgeIt IncEdgeIt; |
88 typedef Graph:: IncEdgeIt IncEdgeIt; |
89 // typedef Graph::template UndirEdgeMap<bool> BoolUndirEdgeMap; |
89 // typedef Graph::template UEdgeMap<bool> BoolUEdgeMap; |
90 // typedef Graph::template UndirEdgeMap<int> IntUndirEdgeMap; |
90 // typedef Graph::template UEdgeMap<int> IntUEdgeMap; |
91 // typedef Graph::template UndirEdgeMap<double> DoubleUndirEdgeMap; |
91 // typedef Graph::template UEdgeMap<double> DoubleUEdgeMap; |
92 |
92 |
93 |
93 |
94 |
94 |
95 /// \brief Function to count the items in the graph. |
95 /// \brief Function to count the items in the graph. |
96 /// |
96 /// |
160 // Undirected edge counting: |
160 // Undirected edge counting: |
161 |
161 |
162 template <typename Graph> |
162 template <typename Graph> |
163 inline |
163 inline |
164 typename enable_if<typename Graph::EdgeNumTag, int>::type |
164 typename enable_if<typename Graph::EdgeNumTag, int>::type |
165 _countUndirEdges(const Graph &g) { |
165 _countUEdges(const Graph &g) { |
166 return g.undirEdgeNum(); |
166 return g.uEdgeNum(); |
167 } |
167 } |
168 |
168 |
169 template <typename Graph> |
169 template <typename Graph> |
170 inline int _countUndirEdges(Wrap<Graph> w) { |
170 inline int _countUEdges(Wrap<Graph> w) { |
171 return countItems<Graph, typename Graph::UndirEdgeIt>(w.value); |
171 return countItems<Graph, typename Graph::UEdgeIt>(w.value); |
172 } |
172 } |
173 |
173 |
174 /// \brief Function to count the undirected edges in the graph. |
174 /// \brief Function to count the undirected edges in the graph. |
175 /// |
175 /// |
176 /// This function counts the undirected edges in the graph. |
176 /// This function counts the undirected edges in the graph. |
177 /// The complexity of the function is O(e) but for some |
177 /// The complexity of the function is O(e) but for some |
178 /// graph structures it is specialized to run in O(1). |
178 /// graph structures it is specialized to run in O(1). |
179 |
179 |
180 template <typename Graph> |
180 template <typename Graph> |
181 inline int countUndirEdges(const Graph& g) { |
181 inline int countUEdges(const Graph& g) { |
182 return _countUndirEdges<Graph>(g); |
182 return _countUEdges<Graph>(g); |
183 } |
183 } |
184 |
184 |
185 |
185 |
186 |
186 |
187 template <typename Graph, typename DegIt> |
187 template <typename Graph, typename DegIt> |
323 |
323 |
324 template <typename Graph> |
324 template <typename Graph> |
325 inline |
325 inline |
326 typename enable_if< |
326 typename enable_if< |
327 typename Graph::FindEdgeTag, |
327 typename Graph::FindEdgeTag, |
328 typename Graph::UndirEdge>::type |
328 typename Graph::UEdge>::type |
329 _findUndirEdge(const Graph &g, |
329 _findUEdge(const Graph &g, |
330 typename Graph::Node u, typename Graph::Node v, |
330 typename Graph::Node u, typename Graph::Node v, |
331 typename Graph::UndirEdge prev = INVALID) { |
331 typename Graph::UEdge prev = INVALID) { |
332 return g.findUndirEdge(u, v, prev); |
332 return g.findUEdge(u, v, prev); |
333 } |
333 } |
334 |
334 |
335 template <typename Graph> |
335 template <typename Graph> |
336 inline typename Graph::UndirEdge |
336 inline typename Graph::UEdge |
337 _findUndirEdge(Wrap<Graph> w, |
337 _findUEdge(Wrap<Graph> w, |
338 typename Graph::Node u, |
338 typename Graph::Node u, |
339 typename Graph::Node v, |
339 typename Graph::Node v, |
340 typename Graph::UndirEdge prev = INVALID) { |
340 typename Graph::UEdge prev = INVALID) { |
341 const Graph& g = w.value; |
341 const Graph& g = w.value; |
342 if (prev == INVALID) { |
342 if (prev == INVALID) { |
343 typename Graph::OutEdgeIt e(g, u); |
343 typename Graph::OutEdgeIt e(g, u); |
344 while (e != INVALID && g.target(e) != v) ++e; |
344 while (e != INVALID && g.target(e) != v) ++e; |
345 return e; |
345 return e; |
348 while (e != INVALID && g.target(e) != v) ++e; |
348 while (e != INVALID && g.target(e) != v) ++e; |
349 return e; |
349 return e; |
350 } |
350 } |
351 } |
351 } |
352 |
352 |
353 /// \brief Finds an undir edge between two nodes of a graph. |
353 /// \brief Finds an uedge between two nodes of a graph. |
354 /// |
354 /// |
355 /// Finds an undir edge from node \c u to node \c v in graph \c g. |
355 /// Finds an uedge from node \c u to node \c v in graph \c g. |
356 /// |
356 /// |
357 /// If \c prev is \ref INVALID (this is the default value), then |
357 /// If \c prev is \ref INVALID (this is the default value), then |
358 /// it finds the first edge from \c u to \c v. Otherwise it looks for |
358 /// it finds the first edge from \c u to \c v. Otherwise it looks for |
359 /// the next edge from \c u to \c v after \c prev. |
359 /// the next edge from \c u to \c v after \c prev. |
360 /// \return The found edge or \ref INVALID if there is no such an edge. |
360 /// \return The found edge or \ref INVALID if there is no such an edge. |
361 /// |
361 /// |
362 /// Thus you can iterate through each edge from \c u to \c v as it follows. |
362 /// Thus you can iterate through each edge from \c u to \c v as it follows. |
363 /// \code |
363 /// \code |
364 /// for(UndirEdge e = findUndirEdge(g,u,v); e != INVALID; |
364 /// for(UEdge e = findUEdge(g,u,v); e != INVALID; |
365 /// e = findUndirEdge(g,u,v,e)) { |
365 /// e = findUEdge(g,u,v,e)) { |
366 /// ... |
366 /// ... |
367 /// } |
367 /// } |
368 /// \endcode |
368 /// \endcode |
369 // /// \todo We may want to use the "GraphBase" |
369 // /// \todo We may want to use the "GraphBase" |
370 // /// interface here... |
370 // /// interface here... |
371 template <typename Graph> |
371 template <typename Graph> |
372 inline typename Graph::UndirEdge |
372 inline typename Graph::UEdge |
373 findUndirEdge(const Graph &g, |
373 findUEdge(const Graph &g, |
374 typename Graph::Node u, |
374 typename Graph::Node u, |
375 typename Graph::Node v, |
375 typename Graph::Node v, |
376 typename Graph::UndirEdge prev = INVALID) { |
376 typename Graph::UEdge prev = INVALID) { |
377 return _findUndirEdge<Graph>(g, u, v, prev); |
377 return _findUEdge<Graph>(g, u, v, prev); |
378 } |
378 } |
379 |
379 |
380 /// \brief Iterator for iterating on undir edges connected the same nodes. |
380 /// \brief Iterator for iterating on uedges connected the same nodes. |
381 /// |
381 /// |
382 /// Iterator for iterating on undir edges connected the same nodes. It is |
382 /// Iterator for iterating on uedges connected the same nodes. It is |
383 /// higher level interface for the findUndirEdge() function. You can |
383 /// higher level interface for the findUEdge() function. You can |
384 /// use it the following way: |
384 /// use it the following way: |
385 /// \code |
385 /// \code |
386 /// for (ConUndirEdgeIt<Graph> it(g, src, trg); it != INVALID; ++it) { |
386 /// for (ConUEdgeIt<Graph> it(g, src, trg); it != INVALID; ++it) { |
387 /// ... |
387 /// ... |
388 /// } |
388 /// } |
389 /// \endcode |
389 /// \endcode |
390 /// |
390 /// |
391 /// \author Balazs Dezso |
391 /// \author Balazs Dezso |
392 template <typename _Graph> |
392 template <typename _Graph> |
393 class ConUndirEdgeIt : public _Graph::UndirEdge { |
393 class ConUEdgeIt : public _Graph::UEdge { |
394 public: |
394 public: |
395 |
395 |
396 typedef _Graph Graph; |
396 typedef _Graph Graph; |
397 typedef typename Graph::UndirEdge Parent; |
397 typedef typename Graph::UEdge Parent; |
398 |
398 |
399 typedef typename Graph::UndirEdge UndirEdge; |
399 typedef typename Graph::UEdge UEdge; |
400 typedef typename Graph::Node Node; |
400 typedef typename Graph::Node Node; |
401 |
401 |
402 /// \brief Constructor. |
402 /// \brief Constructor. |
403 /// |
403 /// |
404 /// Construct a new ConUndirEdgeIt iterating on the edges which |
404 /// Construct a new ConUEdgeIt iterating on the edges which |
405 /// connects the \c u and \c v node. |
405 /// connects the \c u and \c v node. |
406 ConUndirEdgeIt(const Graph& g, Node u, Node v) : graph(g) { |
406 ConUEdgeIt(const Graph& g, Node u, Node v) : graph(g) { |
407 Parent::operator=(findUndirEdge(graph, u, v)); |
407 Parent::operator=(findUEdge(graph, u, v)); |
408 } |
408 } |
409 |
409 |
410 /// \brief Constructor. |
410 /// \brief Constructor. |
411 /// |
411 /// |
412 /// Construct a new ConUndirEdgeIt which continues the iterating from |
412 /// Construct a new ConUEdgeIt which continues the iterating from |
413 /// the \c e edge. |
413 /// the \c e edge. |
414 ConUndirEdgeIt(const Graph& g, UndirEdge e) : Parent(e), graph(g) {} |
414 ConUEdgeIt(const Graph& g, UEdge e) : Parent(e), graph(g) {} |
415 |
415 |
416 /// \brief Increment operator. |
416 /// \brief Increment operator. |
417 /// |
417 /// |
418 /// It increments the iterator and gives back the next edge. |
418 /// It increments the iterator and gives back the next edge. |
419 ConUndirEdgeIt& operator++() { |
419 ConUEdgeIt& operator++() { |
420 Parent::operator=(findUndirEdge(graph, graph.source(*this), |
420 Parent::operator=(findUEdge(graph, graph.source(*this), |
421 graph.target(*this), *this)); |
421 graph.target(*this), *this)); |
422 return *this; |
422 return *this; |
423 } |
423 } |
424 private: |
424 private: |
425 const Graph& graph; |
425 const Graph& graph; |
594 } |
594 } |
595 |
595 |
596 /// \brief Class to copy an undirected graph. |
596 /// \brief Class to copy an undirected graph. |
597 /// |
597 /// |
598 /// Class to copy an undirected graph to an other graph (duplicate a graph). |
598 /// Class to copy an undirected graph to an other graph (duplicate a graph). |
599 /// The simplest way of using it is through the \c copyUndirGraph() function. |
599 /// The simplest way of using it is through the \c copyUGraph() function. |
600 template <typename Target, typename Source> |
600 template <typename Target, typename Source> |
601 class UndirGraphCopy { |
601 class UGraphCopy { |
602 public: |
602 public: |
603 typedef typename Source::Node Node; |
603 typedef typename Source::Node Node; |
604 typedef typename Source::NodeIt NodeIt; |
604 typedef typename Source::NodeIt NodeIt; |
605 typedef typename Source::Edge Edge; |
605 typedef typename Source::Edge Edge; |
606 typedef typename Source::EdgeIt EdgeIt; |
606 typedef typename Source::EdgeIt EdgeIt; |
607 typedef typename Source::UndirEdge UndirEdge; |
607 typedef typename Source::UEdge UEdge; |
608 typedef typename Source::UndirEdgeIt UndirEdgeIt; |
608 typedef typename Source::UEdgeIt UEdgeIt; |
609 |
609 |
610 typedef typename Source:: |
610 typedef typename Source:: |
611 template NodeMap<typename Target::Node> NodeRefMap; |
611 template NodeMap<typename Target::Node> NodeRefMap; |
612 |
612 |
613 typedef typename Source:: |
613 typedef typename Source:: |
614 template UndirEdgeMap<typename Target::UndirEdge> UndirEdgeRefMap; |
614 template UEdgeMap<typename Target::UEdge> UEdgeRefMap; |
615 |
615 |
616 private: |
616 private: |
617 |
617 |
618 struct EdgeRefMap { |
618 struct EdgeRefMap { |
619 EdgeRefMap(UndirGraphCopy& _gc) : gc(_gc) {} |
619 EdgeRefMap(UGraphCopy& _gc) : gc(_gc) {} |
620 typedef typename Source::Edge Key; |
620 typedef typename Source::Edge Key; |
621 typedef typename Target::Edge Value; |
621 typedef typename Target::Edge Value; |
622 |
622 |
623 Value operator[](const Key& key) { |
623 Value operator[](const Key& key) { |
624 return gc.target.direct(gc.undirEdgeRef[key], |
624 return gc.target.direct(gc.uEdgeRef[key], |
625 gc.target.direction(key)); |
625 gc.target.direction(key)); |
626 } |
626 } |
627 |
627 |
628 UndirGraphCopy& gc; |
628 UGraphCopy& gc; |
629 }; |
629 }; |
630 |
630 |
631 public: |
631 public: |
632 |
632 |
633 /// \brief Constructor for the UndirGraphCopy. |
633 /// \brief Constructor for the UGraphCopy. |
634 /// |
634 /// |
635 /// It copies the content of the \c _source graph into the |
635 /// It copies the content of the \c _source graph into the |
636 /// \c _target graph. It creates also two references, one beetween |
636 /// \c _target graph. It creates also two references, one beetween |
637 /// the two nodeset and one beetween the two edgesets. |
637 /// the two nodeset and one beetween the two edgesets. |
638 UndirGraphCopy(Target& _target, const Source& _source) |
638 UGraphCopy(Target& _target, const Source& _source) |
639 : source(_source), target(_target), |
639 : source(_source), target(_target), |
640 nodeRefMap(_source), edgeRefMap(*this), undirEdgeRefMap(_source) { |
640 nodeRefMap(_source), edgeRefMap(*this), uEdgeRefMap(_source) { |
641 for (NodeIt it(source); it != INVALID; ++it) { |
641 for (NodeIt it(source); it != INVALID; ++it) { |
642 nodeRefMap[it] = target.addNode(); |
642 nodeRefMap[it] = target.addNode(); |
643 } |
643 } |
644 for (UndirEdgeIt it(source); it != INVALID; ++it) { |
644 for (UEdgeIt it(source); it != INVALID; ++it) { |
645 undirEdgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], |
645 uEdgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], |
646 nodeRefMap[source.target(it)]); |
646 nodeRefMap[source.target(it)]); |
647 } |
647 } |
648 } |
648 } |
649 |
649 |
650 /// \brief Copies the node references into the given map. |
650 /// \brief Copies the node references into the given map. |
651 /// |
651 /// |
652 /// Copies the node references into the given map. |
652 /// Copies the node references into the given map. |
653 template <typename NodeRef> |
653 template <typename NodeRef> |
654 const UndirGraphCopy& nodeRef(NodeRef& map) const { |
654 const UGraphCopy& nodeRef(NodeRef& map) const { |
655 for (NodeIt it(source); it != INVALID; ++it) { |
655 for (NodeIt it(source); it != INVALID; ++it) { |
656 map.set(it, nodeRefMap[it]); |
656 map.set(it, nodeRefMap[it]); |
657 } |
657 } |
658 return *this; |
658 return *this; |
659 } |
659 } |
660 |
660 |
661 /// \brief Reverse and copies the node references into the given map. |
661 /// \brief Reverse and copies the node references into the given map. |
662 /// |
662 /// |
663 /// Reverse and copies the node references into the given map. |
663 /// Reverse and copies the node references into the given map. |
664 template <typename NodeRef> |
664 template <typename NodeRef> |
665 const UndirGraphCopy& nodeCrossRef(NodeRef& map) const { |
665 const UGraphCopy& nodeCrossRef(NodeRef& map) const { |
666 for (NodeIt it(source); it != INVALID; ++it) { |
666 for (NodeIt it(source); it != INVALID; ++it) { |
667 map.set(nodeRefMap[it], it); |
667 map.set(nodeRefMap[it], it); |
668 } |
668 } |
669 return *this; |
669 return *this; |
670 } |
670 } |
671 |
671 |
672 /// \brief Copies the edge references into the given map. |
672 /// \brief Copies the edge references into the given map. |
673 /// |
673 /// |
674 /// Copies the edge references into the given map. |
674 /// Copies the edge references into the given map. |
675 template <typename EdgeRef> |
675 template <typename EdgeRef> |
676 const UndirGraphCopy& edgeRef(EdgeRef& map) const { |
676 const UGraphCopy& edgeRef(EdgeRef& map) const { |
677 for (EdgeIt it(source); it != INVALID; ++it) { |
677 for (EdgeIt it(source); it != INVALID; ++it) { |
678 map.set(edgeRefMap[it], it); |
678 map.set(edgeRefMap[it], it); |
679 } |
679 } |
680 return *this; |
680 return *this; |
681 } |
681 } |
683 /// \brief Reverse and copies the undirected edge references into the |
683 /// \brief Reverse and copies the undirected edge references into the |
684 /// given map. |
684 /// given map. |
685 /// |
685 /// |
686 /// Reverse and copies the undirected edge references into the given map. |
686 /// Reverse and copies the undirected edge references into the given map. |
687 template <typename EdgeRef> |
687 template <typename EdgeRef> |
688 const UndirGraphCopy& edgeCrossRef(EdgeRef& map) const { |
688 const UGraphCopy& edgeCrossRef(EdgeRef& map) const { |
689 for (EdgeIt it(source); it != INVALID; ++it) { |
689 for (EdgeIt it(source); it != INVALID; ++it) { |
690 map.set(it, edgeRefMap[it]); |
690 map.set(it, edgeRefMap[it]); |
691 } |
691 } |
692 return *this; |
692 return *this; |
693 } |
693 } |
694 |
694 |
695 /// \brief Copies the undirected edge references into the given map. |
695 /// \brief Copies the undirected edge references into the given map. |
696 /// |
696 /// |
697 /// Copies the undirected edge references into the given map. |
697 /// Copies the undirected edge references into the given map. |
698 template <typename EdgeRef> |
698 template <typename EdgeRef> |
699 const UndirGraphCopy& undirEdgeRef(EdgeRef& map) const { |
699 const UGraphCopy& uEdgeRef(EdgeRef& map) const { |
700 for (UndirEdgeIt it(source); it != INVALID; ++it) { |
700 for (UEdgeIt it(source); it != INVALID; ++it) { |
701 map.set(it, undirEdgeRefMap[it]); |
701 map.set(it, uEdgeRefMap[it]); |
702 } |
702 } |
703 return *this; |
703 return *this; |
704 } |
704 } |
705 |
705 |
706 /// \brief Reverse and copies the undirected edge references into the |
706 /// \brief Reverse and copies the undirected edge references into the |
707 /// given map. |
707 /// given map. |
708 /// |
708 /// |
709 /// Reverse and copies the undirected edge references into the given map. |
709 /// Reverse and copies the undirected edge references into the given map. |
710 template <typename EdgeRef> |
710 template <typename EdgeRef> |
711 const UndirGraphCopy& undirEdgeCrossRef(EdgeRef& map) const { |
711 const UGraphCopy& uEdgeCrossRef(EdgeRef& map) const { |
712 for (UndirEdgeIt it(source); it != INVALID; ++it) { |
712 for (UEdgeIt it(source); it != INVALID; ++it) { |
713 map.set(undirEdgeRefMap[it], it); |
713 map.set(uEdgeRefMap[it], it); |
714 } |
714 } |
715 return *this; |
715 return *this; |
716 } |
716 } |
717 |
717 |
718 /// \brief Make copy of the given map. |
718 /// \brief Make copy of the given map. |