alpar@100: /* -*- C++ -*- alpar@100: * alpar@100: * This file is a part of LEMON, a generic C++ optimization library alpar@100: * alpar@100: * Copyright (C) 2003-2008 alpar@100: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@100: * (Egervary Research Group on Combinatorial Optimization, EGRES). alpar@100: * alpar@100: * Permission to use, modify and distribute this software is granted alpar@100: * provided that this copyright notice appears in all copies. For alpar@100: * precise terms see the accompanying LICENSE file. alpar@100: * alpar@100: * This software is provided "AS IS" with no warranty of any kind, alpar@100: * express or implied, and with no claim as to its suitability for any alpar@100: * purpose. alpar@100: * alpar@100: */ alpar@100: alpar@100: #ifndef LEMON_GRAPH_UTILS_H alpar@100: #define LEMON_GRAPH_UTILS_H alpar@100: alpar@100: #include alpar@100: #include alpar@100: #include alpar@100: #include alpar@100: #include alpar@100: alpar@100: #include alpar@100: #include alpar@100: #include alpar@100: #include alpar@100: alpar@100: #include alpar@100: #include alpar@100: alpar@100: ///\ingroup gutils alpar@100: ///\file alpar@100: ///\brief Digraph utilities. alpar@100: alpar@100: namespace lemon { alpar@100: alpar@100: /// \addtogroup gutils alpar@100: /// @{ alpar@100: alpar@100: ///Creates convenience typedefs for the digraph types and iterators alpar@100: alpar@100: ///This \c \#define creates convenience typedefs for the following types alpar@100: ///of \c Digraph: \c Node, \c NodeIt, \c Arc, \c ArcIt, \c InArcIt, alpar@100: ///\c OutArcIt alpar@100: ///\note If \c G it a template parameter, it should be used in this way. alpar@100: ///\code alpar@100: /// GRAPH_TYPEDEFS(typename G); alpar@100: ///\endcode alpar@100: /// alpar@100: ///\warning There are no typedefs for the digraph maps because of the lack of alpar@100: ///template typedefs in C++. alpar@100: #define GRAPH_TYPEDEFS(Digraph) \ alpar@100: typedef Digraph:: Node Node; \ alpar@100: typedef Digraph:: NodeIt NodeIt; \ alpar@100: typedef Digraph:: Arc Arc; \ alpar@100: typedef Digraph:: ArcIt ArcIt; \ alpar@100: typedef Digraph:: InArcIt InArcIt; \ alpar@100: typedef Digraph::OutArcIt OutArcIt alpar@100: alpar@100: ///Creates convenience typedefs for the graph types and iterators alpar@100: alpar@100: ///This \c \#define creates the same convenience typedefs as defined by alpar@100: ///\ref GRAPH_TYPEDEFS(Digraph) and three more, namely it creates alpar@100: ///\c Edge, \c EdgeIt, \c IncArcIt, alpar@100: /// alpar@100: ///\note If \c G it a template parameter, it should be used in this way. alpar@100: ///\code alpar@100: /// UGRAPH_TYPEDEFS(typename G); alpar@100: ///\endcode alpar@100: /// alpar@100: ///\warning There are no typedefs for the digraph maps because of the lack of alpar@100: ///template typedefs in C++. alpar@100: #define UGRAPH_TYPEDEFS(Digraph) \ alpar@100: GRAPH_TYPEDEFS(Digraph); \ alpar@100: typedef Digraph:: Edge Edge; \ alpar@100: typedef Digraph:: EdgeIt EdgeIt; \ alpar@100: typedef Digraph:: IncArcIt IncArcIt alpar@100: alpar@100: ///\brief Creates convenience typedefs for the bipartite digraph alpar@100: ///types and iterators alpar@100: alpar@100: ///This \c \#define creates the same convenience typedefs as defined by alpar@100: ///\ref UGRAPH_TYPEDEFS(Digraph) and two more, namely it creates alpar@100: ///\c RedIt, \c BlueIt, alpar@100: /// alpar@100: ///\note If \c G it a template parameter, it should be used in this way. alpar@100: ///\code alpar@100: /// BPUGRAPH_TYPEDEFS(typename G); alpar@100: ///\endcode alpar@100: /// alpar@100: ///\warning There are no typedefs for the digraph maps because of the lack of alpar@100: ///template typedefs in C++. alpar@100: #define BPUGRAPH_TYPEDEFS(Digraph) \ alpar@100: UGRAPH_TYPEDEFS(Digraph); \ alpar@100: typedef Digraph::Red Red; \ alpar@100: typedef Digraph::Blue Blue; \ alpar@100: typedef Digraph::RedIt RedIt; \ alpar@100: typedef Digraph::BlueIt BlueIt alpar@100: alpar@100: /// \brief Function to count the items in the digraph. alpar@100: /// alpar@100: /// This function counts the items (nodes, arcs etc) in the digraph. alpar@100: /// The complexity of the function is O(n) because alpar@100: /// it iterates on all of the items. alpar@100: alpar@100: template alpar@100: inline int countItems(const Digraph& g) { alpar@100: typedef typename ItemSetTraits::ItemIt ItemIt; alpar@100: int num = 0; alpar@100: for (ItemIt it(g); it != INVALID; ++it) { alpar@100: ++num; alpar@100: } alpar@100: return num; alpar@100: } alpar@100: alpar@100: // Node counting: alpar@100: alpar@100: namespace _digraph_utils_bits { alpar@100: alpar@100: template alpar@100: struct CountNodesSelector { alpar@100: static int count(const Digraph &g) { alpar@100: return countItems(g); alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct CountNodesSelector< alpar@100: Digraph, typename alpar@100: enable_if::type> alpar@100: { alpar@100: static int count(const Digraph &g) { alpar@100: return g.nodeNum(); alpar@100: } alpar@100: }; alpar@100: } alpar@100: alpar@100: /// \brief Function to count the nodes in the digraph. alpar@100: /// alpar@100: /// This function counts the nodes in the digraph. alpar@100: /// The complexity of the function is O(n) but for some alpar@100: /// digraph structures it is specialized to run in O(1). alpar@100: /// alpar@100: /// If the digraph contains a \e nodeNum() member function and a alpar@100: /// \e NodeNumTag tag then this function calls directly the member alpar@100: /// function to query the cardinality of the node set. alpar@100: template alpar@100: inline int countNodes(const Digraph& g) { alpar@100: return _digraph_utils_bits::CountNodesSelector::count(g); alpar@100: } alpar@100: alpar@100: namespace _digraph_utils_bits { alpar@100: alpar@100: template alpar@100: struct CountRedsSelector { alpar@100: static int count(const Digraph &g) { alpar@100: return countItems(g); alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct CountRedsSelector< alpar@100: Digraph, typename alpar@100: enable_if::type> alpar@100: { alpar@100: static int count(const Digraph &g) { alpar@100: return g.redNum(); alpar@100: } alpar@100: }; alpar@100: } alpar@100: alpar@100: /// \brief Function to count the reds in the digraph. alpar@100: /// alpar@100: /// This function counts the reds in the digraph. alpar@100: /// The complexity of the function is O(an) but for some alpar@100: /// digraph structures it is specialized to run in O(1). alpar@100: /// alpar@100: /// If the digraph contains an \e redNum() member function and a alpar@100: /// \e NodeNumTag tag then this function calls directly the member alpar@100: /// function to query the cardinality of the A-node set. alpar@100: template alpar@100: inline int countReds(const Digraph& g) { alpar@100: return _digraph_utils_bits::CountRedsSelector::count(g); alpar@100: } alpar@100: alpar@100: namespace _digraph_utils_bits { alpar@100: alpar@100: template alpar@100: struct CountBluesSelector { alpar@100: static int count(const Digraph &g) { alpar@100: return countItems(g); alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct CountBluesSelector< alpar@100: Digraph, typename alpar@100: enable_if::type> alpar@100: { alpar@100: static int count(const Digraph &g) { alpar@100: return g.blueNum(); alpar@100: } alpar@100: }; alpar@100: } alpar@100: alpar@100: /// \brief Function to count the blues in the digraph. alpar@100: /// alpar@100: /// This function counts the blues in the digraph. alpar@100: /// The complexity of the function is O(bn) but for some alpar@100: /// digraph structures it is specialized to run in O(1). alpar@100: /// alpar@100: /// If the digraph contains a \e blueNum() member function and a alpar@100: /// \e NodeNumTag tag then this function calls directly the member alpar@100: /// function to query the cardinality of the B-node set. alpar@100: template alpar@100: inline int countBlues(const Digraph& g) { alpar@100: return _digraph_utils_bits::CountBluesSelector::count(g); alpar@100: } alpar@100: alpar@100: alpar@100: // Arc counting: alpar@100: alpar@100: namespace _digraph_utils_bits { alpar@100: alpar@100: template alpar@100: struct CountArcsSelector { alpar@100: static int count(const Digraph &g) { alpar@100: return countItems(g); alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct CountArcsSelector< alpar@100: Digraph, alpar@100: typename enable_if::type> alpar@100: { alpar@100: static int count(const Digraph &g) { alpar@100: return g.arcNum(); alpar@100: } alpar@100: }; alpar@100: } alpar@100: alpar@100: /// \brief Function to count the arcs in the digraph. alpar@100: /// alpar@100: /// This function counts the arcs in the digraph. alpar@100: /// The complexity of the function is O(e) but for some alpar@100: /// digraph structures it is specialized to run in O(1). alpar@100: /// alpar@100: /// If the digraph contains a \e arcNum() member function and a alpar@100: /// \e ArcNumTag tag then this function calls directly the member alpar@100: /// function to query the cardinality of the arc set. alpar@100: template alpar@100: inline int countArcs(const Digraph& g) { alpar@100: return _digraph_utils_bits::CountArcsSelector::count(g); alpar@100: } alpar@100: alpar@100: // Undirected arc counting: alpar@100: namespace _digraph_utils_bits { alpar@100: alpar@100: template alpar@100: struct CountEdgesSelector { alpar@100: static int count(const Digraph &g) { alpar@100: return countItems(g); alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct CountEdgesSelector< alpar@100: Digraph, alpar@100: typename enable_if::type> alpar@100: { alpar@100: static int count(const Digraph &g) { alpar@100: return g.edgeNum(); alpar@100: } alpar@100: }; alpar@100: } alpar@100: alpar@100: /// \brief Function to count the edges in the digraph. alpar@100: /// alpar@100: /// This function counts the edges in the digraph. alpar@100: /// The complexity of the function is O(e) but for some alpar@100: /// digraph structures it is specialized to run in O(1). alpar@100: /// alpar@100: /// If the digraph contains a \e edgeNum() member function and a alpar@100: /// \e ArcNumTag tag then this function calls directly the member alpar@100: /// function to query the cardinality of the edge set. alpar@100: template alpar@100: inline int countEdges(const Digraph& g) { alpar@100: return _digraph_utils_bits::CountEdgesSelector::count(g); alpar@100: alpar@100: } alpar@100: alpar@100: alpar@100: template alpar@100: inline int countNodeDegree(const Digraph& _g, const typename Digraph::Node& _n) { alpar@100: int num = 0; alpar@100: for (DegIt it(_g, _n); it != INVALID; ++it) { alpar@100: ++num; alpar@100: } alpar@100: return num; alpar@100: } alpar@100: alpar@100: /// \brief Function to count the number of the out-arcs from node \c n. alpar@100: /// alpar@100: /// This function counts the number of the out-arcs from node \c n alpar@100: /// in the digraph. alpar@100: template alpar@100: inline int countOutArcs(const Digraph& _g, const typename Digraph::Node& _n) { alpar@100: return countNodeDegree(_g, _n); alpar@100: } alpar@100: alpar@100: /// \brief Function to count the number of the in-arcs to node \c n. alpar@100: /// alpar@100: /// This function counts the number of the in-arcs to node \c n alpar@100: /// in the digraph. alpar@100: template alpar@100: inline int countInArcs(const Digraph& _g, const typename Digraph::Node& _n) { alpar@100: return countNodeDegree(_g, _n); alpar@100: } alpar@100: alpar@100: /// \brief Function to count the number of the inc-arcs to node \c n. alpar@100: /// alpar@100: /// This function counts the number of the inc-arcs to node \c n alpar@100: /// in the digraph. alpar@100: template alpar@100: inline int countIncArcs(const Digraph& _g, const typename Digraph::Node& _n) { alpar@100: return countNodeDegree(_g, _n); alpar@100: } alpar@100: alpar@100: namespace _digraph_utils_bits { alpar@100: alpar@100: template alpar@100: struct FindArcSelector { alpar@100: typedef typename Digraph::Node Node; alpar@100: typedef typename Digraph::Arc Arc; alpar@100: static Arc find(const Digraph &g, Node u, Node v, Arc e) { alpar@100: if (e == INVALID) { alpar@100: g.firstOut(e, u); alpar@100: } else { alpar@100: g.nextOut(e); alpar@100: } alpar@100: while (e != INVALID && g.target(e) != v) { alpar@100: g.nextOut(e); alpar@100: } alpar@100: return e; alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct FindArcSelector< alpar@100: Digraph, alpar@100: typename enable_if::type> alpar@100: { alpar@100: typedef typename Digraph::Node Node; alpar@100: typedef typename Digraph::Arc Arc; alpar@100: static Arc find(const Digraph &g, Node u, Node v, Arc prev) { alpar@100: return g.findArc(u, v, prev); alpar@100: } alpar@100: }; alpar@100: } alpar@100: alpar@100: /// \brief Finds an arc between two nodes of a digraph. alpar@100: /// alpar@100: /// Finds an arc from node \c u to node \c v in digraph \c g. alpar@100: /// alpar@100: /// If \c prev is \ref INVALID (this is the default value), then alpar@100: /// it finds the first arc from \c u to \c v. Otherwise it looks for alpar@100: /// the next arc from \c u to \c v after \c prev. alpar@100: /// \return The found arc or \ref INVALID if there is no such an arc. alpar@100: /// alpar@100: /// Thus you can iterate through each arc from \c u to \c v as it follows. alpar@100: ///\code alpar@100: /// for(Arc e=findArc(g,u,v);e!=INVALID;e=findArc(g,u,v,e)) { alpar@100: /// ... alpar@100: /// } alpar@100: ///\endcode alpar@100: /// alpar@100: ///\sa ArcLookUp alpar@100: ///\sa AllArcLookUp alpar@100: ///\sa DynArcLookUp alpar@100: ///\sa ConArcIt alpar@100: template alpar@100: inline typename Digraph::Arc alpar@100: findArc(const Digraph &g, typename Digraph::Node u, typename Digraph::Node v, alpar@100: typename Digraph::Arc prev = INVALID) { alpar@100: return _digraph_utils_bits::FindArcSelector::find(g, u, v, prev); alpar@100: } alpar@100: alpar@100: /// \brief Iterator for iterating on arcs connected the same nodes. alpar@100: /// alpar@100: /// Iterator for iterating on arcs connected the same nodes. It is alpar@100: /// higher level interface for the findArc() function. You can alpar@100: /// use it the following way: alpar@100: ///\code alpar@100: /// for (ConArcIt it(g, src, trg); it != INVALID; ++it) { alpar@100: /// ... alpar@100: /// } alpar@100: ///\endcode alpar@100: /// alpar@100: ///\sa findArc() alpar@100: ///\sa ArcLookUp alpar@100: ///\sa AllArcLookUp alpar@100: ///\sa DynArcLookUp alpar@100: /// alpar@100: /// \author Balazs Dezso alpar@100: template alpar@100: class ConArcIt : public _Digraph::Arc { alpar@100: public: alpar@100: alpar@100: typedef _Digraph Digraph; alpar@100: typedef typename Digraph::Arc Parent; alpar@100: alpar@100: typedef typename Digraph::Arc Arc; alpar@100: typedef typename Digraph::Node Node; alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Construct a new ConArcIt iterating on the arcs which alpar@100: /// connects the \c u and \c v node. alpar@100: ConArcIt(const Digraph& g, Node u, Node v) : digraph(g) { alpar@100: Parent::operator=(findArc(digraph, u, v)); alpar@100: } alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Construct a new ConArcIt which continues the iterating from alpar@100: /// the \c e arc. alpar@100: ConArcIt(const Digraph& g, Arc e) : Parent(e), digraph(g) {} alpar@100: alpar@100: /// \brief Increment operator. alpar@100: /// alpar@100: /// It increments the iterator and gives back the next arc. alpar@100: ConArcIt& operator++() { alpar@100: Parent::operator=(findArc(digraph, digraph.source(*this), alpar@100: digraph.target(*this), *this)); alpar@100: return *this; alpar@100: } alpar@100: private: alpar@100: const Digraph& digraph; alpar@100: }; alpar@100: alpar@100: namespace _digraph_utils_bits { alpar@100: alpar@100: template alpar@100: struct FindEdgeSelector { alpar@100: typedef typename Digraph::Node Node; alpar@100: typedef typename Digraph::Edge Edge; alpar@100: static Edge find(const Digraph &g, Node u, Node v, Edge e) { alpar@100: bool b; alpar@100: if (u != v) { alpar@100: if (e == INVALID) { alpar@100: g.firstInc(e, b, u); alpar@100: } else { alpar@100: b = g.source(e) == u; alpar@100: g.nextInc(e, b); alpar@100: } alpar@100: while (e != INVALID && (b ? g.target(e) : g.source(e)) != v) { alpar@100: g.nextInc(e, b); alpar@100: } alpar@100: } else { alpar@100: if (e == INVALID) { alpar@100: g.firstInc(e, b, u); alpar@100: } else { alpar@100: b = true; alpar@100: g.nextInc(e, b); alpar@100: } alpar@100: while (e != INVALID && (!b || g.target(e) != v)) { alpar@100: g.nextInc(e, b); alpar@100: } alpar@100: } alpar@100: return e; alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct FindEdgeSelector< alpar@100: Digraph, alpar@100: typename enable_if::type> alpar@100: { alpar@100: typedef typename Digraph::Node Node; alpar@100: typedef typename Digraph::Edge Edge; alpar@100: static Edge find(const Digraph &g, Node u, Node v, Edge prev) { alpar@100: return g.findEdge(u, v, prev); alpar@100: } alpar@100: }; alpar@100: } alpar@100: alpar@100: /// \brief Finds an edge between two nodes of a digraph. alpar@100: /// alpar@100: /// Finds an edge from node \c u to node \c v in digraph \c g. alpar@100: /// If the node \c u and node \c v is equal then each loop arc alpar@100: /// will be enumerated. alpar@100: /// alpar@100: /// If \c prev is \ref INVALID (this is the default value), then alpar@100: /// it finds the first arc from \c u to \c v. Otherwise it looks for alpar@100: /// the next arc from \c u to \c v after \c prev. alpar@100: /// \return The found arc or \ref INVALID if there is no such an arc. alpar@100: /// alpar@100: /// Thus you can iterate through each arc from \c u to \c v as it follows. alpar@100: ///\code alpar@100: /// for(Edge e = findEdge(g,u,v); e != INVALID; alpar@100: /// e = findEdge(g,u,v,e)) { alpar@100: /// ... alpar@100: /// } alpar@100: ///\endcode alpar@100: /// alpar@100: ///\sa ConArcIt alpar@100: alpar@100: template alpar@100: inline typename Digraph::Edge alpar@100: findEdge(const Digraph &g, typename Digraph::Node u, typename Digraph::Node v, alpar@100: typename Digraph::Edge p = INVALID) { alpar@100: return _digraph_utils_bits::FindEdgeSelector::find(g, u, v, p); alpar@100: } alpar@100: alpar@100: /// \brief Iterator for iterating on edges connected the same nodes. alpar@100: /// alpar@100: /// Iterator for iterating on edges connected the same nodes. It is alpar@100: /// higher level interface for the findEdge() function. You can alpar@100: /// use it the following way: alpar@100: ///\code alpar@100: /// for (ConEdgeIt it(g, src, trg); it != INVALID; ++it) { alpar@100: /// ... alpar@100: /// } alpar@100: ///\endcode alpar@100: /// alpar@100: ///\sa findEdge() alpar@100: /// alpar@100: /// \author Balazs Dezso alpar@100: template alpar@100: class ConEdgeIt : public _Digraph::Edge { alpar@100: public: alpar@100: alpar@100: typedef _Digraph Digraph; alpar@100: typedef typename Digraph::Edge Parent; alpar@100: alpar@100: typedef typename Digraph::Edge Edge; alpar@100: typedef typename Digraph::Node Node; alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Construct a new ConEdgeIt iterating on the arcs which alpar@100: /// connects the \c u and \c v node. alpar@100: ConEdgeIt(const Digraph& g, Node u, Node v) : digraph(g) { alpar@100: Parent::operator=(findEdge(digraph, u, v)); alpar@100: } alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Construct a new ConEdgeIt which continues the iterating from alpar@100: /// the \c e arc. alpar@100: ConEdgeIt(const Digraph& g, Edge e) : Parent(e), digraph(g) {} alpar@100: alpar@100: /// \brief Increment operator. alpar@100: /// alpar@100: /// It increments the iterator and gives back the next arc. alpar@100: ConEdgeIt& operator++() { alpar@100: Parent::operator=(findEdge(digraph, digraph.source(*this), alpar@100: digraph.target(*this), *this)); alpar@100: return *this; alpar@100: } alpar@100: private: alpar@100: const Digraph& digraph; alpar@100: }; alpar@100: alpar@100: /// \brief Copy a map. alpar@100: /// alpar@100: /// This function copies the \c from map to the \c to map. It uses the alpar@100: /// given iterator to iterate on the data structure and it uses the \c ref alpar@100: /// mapping to convert the from's keys to the to's keys. alpar@100: template alpar@100: void copyMap(To& to, const From& from, alpar@100: ItemIt it, const Ref& ref) { alpar@100: for (; it != INVALID; ++it) { alpar@100: to[ref[it]] = from[it]; alpar@100: } alpar@100: } alpar@100: alpar@100: /// \brief Copy the from map to the to map. alpar@100: /// alpar@100: /// Copy the \c from map to the \c to map. It uses the given iterator alpar@100: /// to iterate on the data structure. alpar@100: template alpar@100: void copyMap(To& to, const From& from, ItemIt it) { alpar@100: for (; it != INVALID; ++it) { alpar@100: to[it] = from[it]; alpar@100: } alpar@100: } alpar@100: alpar@100: namespace _digraph_utils_bits { alpar@100: alpar@100: template alpar@100: class MapCopyBase { alpar@100: public: alpar@100: virtual void copy(const Digraph& from, const RefMap& refMap) = 0; alpar@100: alpar@100: virtual ~MapCopyBase() {} alpar@100: }; alpar@100: alpar@100: template alpar@100: class MapCopy : public MapCopyBase { alpar@100: public: alpar@100: alpar@100: MapCopy(ToMap& tmap, const FromMap& map) alpar@100: : _tmap(tmap), _map(map) {} alpar@100: alpar@100: virtual void copy(const Digraph& digraph, const RefMap& refMap) { alpar@100: typedef typename ItemSetTraits::ItemIt ItemIt; alpar@100: for (ItemIt it(digraph); it != INVALID; ++it) { alpar@100: _tmap.set(refMap[it], _map[it]); alpar@100: } alpar@100: } alpar@100: alpar@100: private: alpar@100: ToMap& _tmap; alpar@100: const FromMap& _map; alpar@100: }; alpar@100: alpar@100: template alpar@100: class ItemCopy : public MapCopyBase { alpar@100: public: alpar@100: alpar@100: ItemCopy(It& it, const Item& item) : _it(it), _item(item) {} alpar@100: alpar@100: virtual void copy(const Digraph&, const RefMap& refMap) { alpar@100: _it = refMap[_item]; alpar@100: } alpar@100: alpar@100: private: alpar@100: It& _it; alpar@100: Item _item; alpar@100: }; alpar@100: alpar@100: template alpar@100: class RefCopy : public MapCopyBase { alpar@100: public: alpar@100: alpar@100: RefCopy(Ref& map) : _map(map) {} alpar@100: alpar@100: virtual void copy(const Digraph& digraph, const RefMap& refMap) { alpar@100: typedef typename ItemSetTraits::ItemIt ItemIt; alpar@100: for (ItemIt it(digraph); it != INVALID; ++it) { alpar@100: _map.set(it, refMap[it]); alpar@100: } alpar@100: } alpar@100: alpar@100: private: alpar@100: Ref& _map; alpar@100: }; alpar@100: alpar@100: template alpar@100: class CrossRefCopy : public MapCopyBase { alpar@100: public: alpar@100: alpar@100: CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {} alpar@100: alpar@100: virtual void copy(const Digraph& digraph, const RefMap& refMap) { alpar@100: typedef typename ItemSetTraits::ItemIt ItemIt; alpar@100: for (ItemIt it(digraph); it != INVALID; ++it) { alpar@100: _cmap.set(refMap[it], it); alpar@100: } alpar@100: } alpar@100: alpar@100: private: alpar@100: CrossRef& _cmap; alpar@100: }; alpar@100: alpar@100: template alpar@100: struct DigraphCopySelector { alpar@100: template alpar@100: static void copy(Digraph &to, const From& from, alpar@100: NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) { alpar@100: for (typename From::NodeIt it(from); it != INVALID; ++it) { alpar@100: nodeRefMap[it] = to.addNode(); alpar@100: } alpar@100: for (typename From::ArcIt it(from); it != INVALID; ++it) { alpar@100: arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)], alpar@100: nodeRefMap[from.target(it)]); alpar@100: } alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct DigraphCopySelector< alpar@100: Digraph, alpar@100: typename enable_if::type> alpar@100: { alpar@100: template alpar@100: static void copy(Digraph &to, const From& from, alpar@100: NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) { alpar@100: to.build(from, nodeRefMap, arcRefMap); alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct GraphCopySelector { alpar@100: template alpar@100: static void copy(Graph &to, const From& from, alpar@100: NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { alpar@100: for (typename From::NodeIt it(from); it != INVALID; ++it) { alpar@100: nodeRefMap[it] = to.addNode(); alpar@100: } alpar@100: for (typename From::EdgeIt it(from); it != INVALID; ++it) { alpar@100: edgeRefMap[it] = to.addArc(nodeRefMap[from.source(it)], alpar@100: nodeRefMap[from.target(it)]); alpar@100: } alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct GraphCopySelector< alpar@100: Graph, alpar@100: typename enable_if::type> alpar@100: { alpar@100: template alpar@100: static void copy(Graph &to, const From& from, alpar@100: NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { alpar@100: to.build(from, nodeRefMap, edgeRefMap); alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct BpGraphCopySelector { alpar@100: template alpar@100: static void copy(BpGraph &to, const From& from, alpar@100: RedRefMap& redRefMap, BlueRefMap& blueRefMap, alpar@100: EdgeRefMap& edgeRefMap) { alpar@100: for (typename From::RedIt it(from); it != INVALID; ++it) { alpar@100: redRefMap[it] = to.addRed(); alpar@100: } alpar@100: for (typename From::BlueIt it(from); it != INVALID; ++it) { alpar@100: blueRefMap[it] = to.addBlue(); alpar@100: } alpar@100: for (typename From::EdgeIt it(from); it != INVALID; ++it) { alpar@100: edgeRefMap[it] = to.addArc(redRefMap[from.red(it)], alpar@100: blueRefMap[from.blue(it)]); alpar@100: } alpar@100: } alpar@100: }; alpar@100: alpar@100: template alpar@100: struct BpGraphCopySelector< alpar@100: BpGraph, alpar@100: typename enable_if::type> alpar@100: { alpar@100: template alpar@100: static void copy(BpGraph &to, const From& from, alpar@100: RedRefMap& redRefMap, BlueRefMap& blueRefMap, alpar@100: EdgeRefMap& edgeRefMap) { alpar@100: to.build(from, redRefMap, blueRefMap, edgeRefMap); alpar@100: } alpar@100: }; alpar@100: alpar@100: alpar@100: } alpar@100: alpar@100: /// \brief Class to copy a digraph. alpar@100: /// alpar@100: /// Class to copy a digraph to another digraph (duplicate a digraph). The alpar@100: /// simplest way of using it is through the \c copyDigraph() function. alpar@100: template alpar@100: class DigraphCopy { alpar@100: private: alpar@100: alpar@100: typedef typename From::Node Node; alpar@100: typedef typename From::NodeIt NodeIt; alpar@100: typedef typename From::Arc Arc; alpar@100: typedef typename From::ArcIt ArcIt; alpar@100: alpar@100: typedef typename To::Node TNode; alpar@100: typedef typename To::Arc TArc; alpar@100: alpar@100: typedef typename From::template NodeMap NodeRefMap; alpar@100: typedef typename From::template ArcMap ArcRefMap; alpar@100: alpar@100: alpar@100: public: alpar@100: alpar@100: alpar@100: /// \brief Constructor for the DigraphCopy. alpar@100: /// alpar@100: /// It copies the content of the \c _from digraph into the alpar@100: /// \c _to digraph. alpar@100: DigraphCopy(To& _to, const From& _from) alpar@100: : from(_from), to(_to) {} alpar@100: alpar@100: /// \brief Destructor of the DigraphCopy alpar@100: /// alpar@100: /// Destructor of the DigraphCopy alpar@100: ~DigraphCopy() { alpar@100: for (int i = 0; i < int(nodeMapCopies.size()); ++i) { alpar@100: delete nodeMapCopies[i]; alpar@100: } alpar@100: for (int i = 0; i < int(arcMapCopies.size()); ++i) { alpar@100: delete arcMapCopies[i]; alpar@100: } alpar@100: alpar@100: } alpar@100: alpar@100: /// \brief Copies the node references into the given map. alpar@100: /// alpar@100: /// Copies the node references into the given map. alpar@100: template alpar@100: DigraphCopy& nodeRef(NodeRef& map) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the node cross references into the given map. alpar@100: /// alpar@100: /// Copies the node cross references (reverse references) into alpar@100: /// the given map. alpar@100: template alpar@100: DigraphCopy& nodeCrossRef(NodeCrossRef& map) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's node type, alpar@100: /// and the copied map's key type is the from digraph's node alpar@100: /// type. alpar@100: template alpar@100: DigraphCopy& nodeMap(ToMap& tmap, const FromMap& map) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make a copy of the given node. alpar@100: /// alpar@100: /// Make a copy of the given node. alpar@100: DigraphCopy& node(TNode& tnode, const Node& snode) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::ItemCopy(tnode, snode)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the arc references into the given map. alpar@100: /// alpar@100: /// Copies the arc references into the given map. alpar@100: template alpar@100: DigraphCopy& arcRef(ArcRef& map) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the arc cross references into the given map. alpar@100: /// alpar@100: /// Copies the arc cross references (reverse references) into alpar@100: /// the given map. alpar@100: template alpar@100: DigraphCopy& arcCrossRef(ArcCrossRef& map) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's arc type, alpar@100: /// and the copied map's key type is the from digraph's arc alpar@100: /// type. alpar@100: template alpar@100: DigraphCopy& arcMap(ToMap& tmap, const FromMap& map) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make a copy of the given arc. alpar@100: /// alpar@100: /// Make a copy of the given arc. alpar@100: DigraphCopy& arc(TArc& tarc, const Arc& sarc) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::ItemCopy(tarc, sarc)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Executes the copies. alpar@100: /// alpar@100: /// Executes the copies. alpar@100: void run() { alpar@100: NodeRefMap nodeRefMap(from); alpar@100: ArcRefMap arcRefMap(from); alpar@100: _digraph_utils_bits::DigraphCopySelector:: alpar@100: copy(to, from, nodeRefMap, arcRefMap); alpar@100: for (int i = 0; i < int(nodeMapCopies.size()); ++i) { alpar@100: nodeMapCopies[i]->copy(from, nodeRefMap); alpar@100: } alpar@100: for (int i = 0; i < int(arcMapCopies.size()); ++i) { alpar@100: arcMapCopies[i]->copy(from, arcRefMap); alpar@100: } alpar@100: } alpar@100: alpar@100: protected: alpar@100: alpar@100: alpar@100: const From& from; alpar@100: To& to; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: nodeMapCopies; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: arcMapCopies; alpar@100: alpar@100: }; alpar@100: alpar@100: /// \brief Copy a digraph to another digraph. alpar@100: /// alpar@100: /// Copy a digraph to another digraph. alpar@100: /// The usage of the function: alpar@100: /// alpar@100: ///\code alpar@100: /// copyDigraph(trg, src).nodeRef(nr).arcCrossRef(ecr).run(); alpar@100: ///\endcode alpar@100: /// alpar@100: /// After the copy the \c nr map will contain the mapping from the alpar@100: /// nodes of the \c from digraph to the nodes of the \c to digraph and alpar@100: /// \c ecr will contain the mapping from the arcs of the \c to digraph alpar@100: /// to the arcs of the \c from digraph. alpar@100: /// alpar@100: /// \see DigraphCopy alpar@100: template alpar@100: DigraphCopy copyDigraph(To& to, const From& from) { alpar@100: return DigraphCopy(to, from); alpar@100: } alpar@100: alpar@100: /// \brief Class to copy an graph. alpar@100: /// alpar@100: /// Class to copy an graph to another digraph (duplicate a digraph). alpar@100: /// The simplest way of using it is through the \c copyGraph() function. alpar@100: template alpar@100: class GraphCopy { alpar@100: private: alpar@100: alpar@100: typedef typename From::Node Node; alpar@100: typedef typename From::NodeIt NodeIt; alpar@100: typedef typename From::Arc Arc; alpar@100: typedef typename From::ArcIt ArcIt; alpar@100: typedef typename From::Edge Edge; alpar@100: typedef typename From::EdgeIt EdgeIt; alpar@100: alpar@100: typedef typename To::Node TNode; alpar@100: typedef typename To::Arc TArc; alpar@100: typedef typename To::Edge TEdge; alpar@100: alpar@100: typedef typename From::template NodeMap NodeRefMap; alpar@100: typedef typename From::template EdgeMap EdgeRefMap; alpar@100: alpar@100: struct ArcRefMap { alpar@100: ArcRefMap(const To& _to, const From& _from, alpar@100: const EdgeRefMap& _edge_ref, const NodeRefMap& _node_ref) alpar@100: : to(_to), from(_from), alpar@100: edge_ref(_edge_ref), node_ref(_node_ref) {} alpar@100: alpar@100: typedef typename From::Arc Key; alpar@100: typedef typename To::Arc Value; alpar@100: alpar@100: Value operator[](const Key& key) const { alpar@100: bool forward = alpar@100: (from.direction(key) == alpar@100: (node_ref[from.source(static_cast(key))] == alpar@100: to.source(edge_ref[static_cast(key)]))); alpar@100: return to.direct(edge_ref[key], forward); alpar@100: } alpar@100: alpar@100: const To& to; alpar@100: const From& from; alpar@100: const EdgeRefMap& edge_ref; alpar@100: const NodeRefMap& node_ref; alpar@100: }; alpar@100: alpar@100: alpar@100: public: alpar@100: alpar@100: alpar@100: /// \brief Constructor for the DigraphCopy. alpar@100: /// alpar@100: /// It copies the content of the \c _from digraph into the alpar@100: /// \c _to digraph. alpar@100: GraphCopy(To& _to, const From& _from) alpar@100: : from(_from), to(_to) {} alpar@100: alpar@100: /// \brief Destructor of the DigraphCopy alpar@100: /// alpar@100: /// Destructor of the DigraphCopy alpar@100: ~GraphCopy() { alpar@100: for (int i = 0; i < int(nodeMapCopies.size()); ++i) { alpar@100: delete nodeMapCopies[i]; alpar@100: } alpar@100: for (int i = 0; i < int(arcMapCopies.size()); ++i) { alpar@100: delete arcMapCopies[i]; alpar@100: } alpar@100: for (int i = 0; i < int(edgeMapCopies.size()); ++i) { alpar@100: delete edgeMapCopies[i]; alpar@100: } alpar@100: alpar@100: } alpar@100: alpar@100: /// \brief Copies the node references into the given map. alpar@100: /// alpar@100: /// Copies the node references into the given map. alpar@100: template alpar@100: GraphCopy& nodeRef(NodeRef& map) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the node cross references into the given map. alpar@100: /// alpar@100: /// Copies the node cross references (reverse references) into alpar@100: /// the given map. alpar@100: template alpar@100: GraphCopy& nodeCrossRef(NodeCrossRef& map) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's node type, alpar@100: /// and the copied map's key type is the from digraph's node alpar@100: /// type. alpar@100: template alpar@100: GraphCopy& nodeMap(ToMap& tmap, const FromMap& map) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make a copy of the given node. alpar@100: /// alpar@100: /// Make a copy of the given node. alpar@100: GraphCopy& node(TNode& tnode, const Node& snode) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::ItemCopy(tnode, snode)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the arc references into the given map. alpar@100: /// alpar@100: /// Copies the arc references into the given map. alpar@100: template alpar@100: GraphCopy& arcRef(ArcRef& map) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the arc cross references into the given map. alpar@100: /// alpar@100: /// Copies the arc cross references (reverse references) into alpar@100: /// the given map. alpar@100: template alpar@100: GraphCopy& arcCrossRef(ArcCrossRef& map) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's arc type, alpar@100: /// and the copied map's key type is the from digraph's arc alpar@100: /// type. alpar@100: template alpar@100: GraphCopy& arcMap(ToMap& tmap, const FromMap& map) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make a copy of the given arc. alpar@100: /// alpar@100: /// Make a copy of the given arc. alpar@100: GraphCopy& arc(TArc& tarc, const Arc& sarc) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::ItemCopy(tarc, sarc)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the edge references into the given map. alpar@100: /// alpar@100: /// Copies the edge references into the given map. alpar@100: template alpar@100: GraphCopy& edgeRef(EdgeRef& map) { alpar@100: edgeMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the edge cross references into the given map. alpar@100: /// alpar@100: /// Copies the edge cross references (reverse alpar@100: /// references) into the given map. alpar@100: template alpar@100: GraphCopy& edgeCrossRef(EdgeCrossRef& map) { alpar@100: edgeMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's edge type, alpar@100: /// and the copied map's key type is the from digraph's edge alpar@100: /// type. alpar@100: template alpar@100: GraphCopy& edgeMap(ToMap& tmap, const FromMap& map) { alpar@100: edgeMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make a copy of the given edge. alpar@100: /// alpar@100: /// Make a copy of the given edge. alpar@100: GraphCopy& edge(TEdge& tedge, const Edge& sedge) { alpar@100: edgeMapCopies.push_back(new _digraph_utils_bits::ItemCopy(tedge, sedge)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Executes the copies. alpar@100: /// alpar@100: /// Executes the copies. alpar@100: void run() { alpar@100: NodeRefMap nodeRefMap(from); alpar@100: EdgeRefMap edgeRefMap(from); alpar@100: ArcRefMap arcRefMap(to, from, edgeRefMap, nodeRefMap); alpar@100: _digraph_utils_bits::GraphCopySelector:: alpar@100: copy(to, from, nodeRefMap, edgeRefMap); alpar@100: for (int i = 0; i < int(nodeMapCopies.size()); ++i) { alpar@100: nodeMapCopies[i]->copy(from, nodeRefMap); alpar@100: } alpar@100: for (int i = 0; i < int(edgeMapCopies.size()); ++i) { alpar@100: edgeMapCopies[i]->copy(from, edgeRefMap); alpar@100: } alpar@100: for (int i = 0; i < int(arcMapCopies.size()); ++i) { alpar@100: arcMapCopies[i]->copy(from, arcRefMap); alpar@100: } alpar@100: } alpar@100: alpar@100: private: alpar@100: alpar@100: const From& from; alpar@100: To& to; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: nodeMapCopies; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: arcMapCopies; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: edgeMapCopies; alpar@100: alpar@100: }; alpar@100: alpar@100: /// \brief Copy an graph to another digraph. alpar@100: /// alpar@100: /// Copy an graph to another digraph. alpar@100: /// The usage of the function: alpar@100: /// alpar@100: ///\code alpar@100: /// copyGraph(trg, src).nodeRef(nr).arcCrossRef(ecr).run(); alpar@100: ///\endcode alpar@100: /// alpar@100: /// After the copy the \c nr map will contain the mapping from the alpar@100: /// nodes of the \c from digraph to the nodes of the \c to digraph and alpar@100: /// \c ecr will contain the mapping from the arcs of the \c to digraph alpar@100: /// to the arcs of the \c from digraph. alpar@100: /// alpar@100: /// \see GraphCopy alpar@100: template alpar@100: GraphCopy alpar@100: copyGraph(To& to, const From& from) { alpar@100: return GraphCopy(to, from); alpar@100: } alpar@100: alpar@100: /// \brief Class to copy a bipartite digraph. alpar@100: /// alpar@100: /// Class to copy a bipartite digraph to another digraph alpar@100: /// (duplicate a digraph). The simplest way of using it is through alpar@100: /// the \c copyBpGraph() function. alpar@100: template alpar@100: class BpGraphCopy { alpar@100: private: alpar@100: alpar@100: typedef typename From::Node Node; alpar@100: typedef typename From::Red Red; alpar@100: typedef typename From::Blue Blue; alpar@100: typedef typename From::NodeIt NodeIt; alpar@100: typedef typename From::Arc Arc; alpar@100: typedef typename From::ArcIt ArcIt; alpar@100: typedef typename From::Edge Edge; alpar@100: typedef typename From::EdgeIt EdgeIt; alpar@100: alpar@100: typedef typename To::Node TNode; alpar@100: typedef typename To::Arc TArc; alpar@100: typedef typename To::Edge TEdge; alpar@100: alpar@100: typedef typename From::template RedMap RedRefMap; alpar@100: typedef typename From::template BlueMap BlueRefMap; alpar@100: typedef typename From::template EdgeMap EdgeRefMap; alpar@100: alpar@100: struct NodeRefMap { alpar@100: NodeRefMap(const From& _from, const RedRefMap& _red_ref, alpar@100: const BlueRefMap& _blue_ref) alpar@100: : from(_from), red_ref(_red_ref), blue_ref(_blue_ref) {} alpar@100: alpar@100: typedef typename From::Node Key; alpar@100: typedef typename To::Node Value; alpar@100: alpar@100: Value operator[](const Key& key) const { alpar@100: return from.red(key) ? red_ref[key] : blue_ref[key]; alpar@100: } alpar@100: alpar@100: const From& from; alpar@100: const RedRefMap& red_ref; alpar@100: const BlueRefMap& blue_ref; alpar@100: }; alpar@100: alpar@100: struct ArcRefMap { alpar@100: ArcRefMap(const To& _to, const From& _from, alpar@100: const EdgeRefMap& _edge_ref, const NodeRefMap& _node_ref) alpar@100: : to(_to), from(_from), alpar@100: edge_ref(_edge_ref), node_ref(_node_ref) {} alpar@100: alpar@100: typedef typename From::Arc Key; alpar@100: typedef typename To::Arc Value; alpar@100: alpar@100: Value operator[](const Key& key) const { alpar@100: bool forward = alpar@100: (from.direction(key) == alpar@100: (node_ref[from.source(static_cast(key))] == alpar@100: to.source(edge_ref[static_cast(key)]))); alpar@100: return to.direct(edge_ref[key], forward); alpar@100: } alpar@100: alpar@100: const To& to; alpar@100: const From& from; alpar@100: const EdgeRefMap& edge_ref; alpar@100: const NodeRefMap& node_ref; alpar@100: }; alpar@100: alpar@100: public: alpar@100: alpar@100: alpar@100: /// \brief Constructor for the DigraphCopy. alpar@100: /// alpar@100: /// It copies the content of the \c _from digraph into the alpar@100: /// \c _to digraph. alpar@100: BpGraphCopy(To& _to, const From& _from) alpar@100: : from(_from), to(_to) {} alpar@100: alpar@100: /// \brief Destructor of the DigraphCopy alpar@100: /// alpar@100: /// Destructor of the DigraphCopy alpar@100: ~BpGraphCopy() { alpar@100: for (int i = 0; i < int(redMapCopies.size()); ++i) { alpar@100: delete redMapCopies[i]; alpar@100: } alpar@100: for (int i = 0; i < int(blueMapCopies.size()); ++i) { alpar@100: delete blueMapCopies[i]; alpar@100: } alpar@100: for (int i = 0; i < int(nodeMapCopies.size()); ++i) { alpar@100: delete nodeMapCopies[i]; alpar@100: } alpar@100: for (int i = 0; i < int(arcMapCopies.size()); ++i) { alpar@100: delete arcMapCopies[i]; alpar@100: } alpar@100: for (int i = 0; i < int(edgeMapCopies.size()); ++i) { alpar@100: delete edgeMapCopies[i]; alpar@100: } alpar@100: alpar@100: } alpar@100: alpar@100: /// \brief Copies the A-node references into the given map. alpar@100: /// alpar@100: /// Copies the A-node references into the given map. alpar@100: template alpar@100: BpGraphCopy& redRef(RedRef& map) { alpar@100: redMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the A-node cross references into the given map. alpar@100: /// alpar@100: /// Copies the A-node cross references (reverse references) into alpar@100: /// the given map. alpar@100: template alpar@100: BpGraphCopy& redCrossRef(RedCrossRef& map) { alpar@100: redMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given A-node map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's node type, alpar@100: /// and the copied map's key type is the from digraph's node alpar@100: /// type. alpar@100: template alpar@100: BpGraphCopy& redMap(ToMap& tmap, const FromMap& map) { alpar@100: redMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the B-node references into the given map. alpar@100: /// alpar@100: /// Copies the B-node references into the given map. alpar@100: template alpar@100: BpGraphCopy& blueRef(BlueRef& map) { alpar@100: blueMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the B-node cross references into the given map. alpar@100: /// alpar@100: /// Copies the B-node cross references (reverse references) into alpar@100: /// the given map. alpar@100: template alpar@100: BpGraphCopy& blueCrossRef(BlueCrossRef& map) { alpar@100: blueMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given B-node map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's node type, alpar@100: /// and the copied map's key type is the from digraph's node alpar@100: /// type. alpar@100: template alpar@100: BpGraphCopy& blueMap(ToMap& tmap, const FromMap& map) { alpar@100: blueMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: /// \brief Copies the node references into the given map. alpar@100: /// alpar@100: /// Copies the node references into the given map. alpar@100: template alpar@100: BpGraphCopy& nodeRef(NodeRef& map) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the node cross references into the given map. alpar@100: /// alpar@100: /// Copies the node cross references (reverse references) into alpar@100: /// the given map. alpar@100: template alpar@100: BpGraphCopy& nodeCrossRef(NodeCrossRef& map) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's node type, alpar@100: /// and the copied map's key type is the from digraph's node alpar@100: /// type. alpar@100: template alpar@100: BpGraphCopy& nodeMap(ToMap& tmap, const FromMap& map) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make a copy of the given node. alpar@100: /// alpar@100: /// Make a copy of the given node. alpar@100: BpGraphCopy& node(TNode& tnode, const Node& snode) { alpar@100: nodeMapCopies.push_back(new _digraph_utils_bits::ItemCopy(tnode, snode)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the arc references into the given map. alpar@100: /// alpar@100: /// Copies the arc references into the given map. alpar@100: template alpar@100: BpGraphCopy& arcRef(ArcRef& map) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the arc cross references into the given map. alpar@100: /// alpar@100: /// Copies the arc cross references (reverse references) into alpar@100: /// the given map. alpar@100: template alpar@100: BpGraphCopy& arcCrossRef(ArcCrossRef& map) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's arc type, alpar@100: /// and the copied map's key type is the from digraph's arc alpar@100: /// type. alpar@100: template alpar@100: BpGraphCopy& arcMap(ToMap& tmap, const FromMap& map) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make a copy of the given arc. alpar@100: /// alpar@100: /// Make a copy of the given arc. alpar@100: BpGraphCopy& arc(TArc& tarc, const Arc& sarc) { alpar@100: arcMapCopies.push_back(new _digraph_utils_bits::ItemCopy(tarc, sarc)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the edge references into the given map. alpar@100: /// alpar@100: /// Copies the edge references into the given map. alpar@100: template alpar@100: BpGraphCopy& edgeRef(EdgeRef& map) { alpar@100: edgeMapCopies.push_back(new _digraph_utils_bits::RefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Copies the edge cross references into the given map. alpar@100: /// alpar@100: /// Copies the edge cross references (reverse alpar@100: /// references) into the given map. alpar@100: template alpar@100: BpGraphCopy& edgeCrossRef(EdgeCrossRef& map) { alpar@100: edgeMapCopies.push_back(new _digraph_utils_bits::CrossRefCopy(map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make copy of the given map. alpar@100: /// alpar@100: /// Makes copy of the given map for the newly created digraph. alpar@100: /// The new map's key type is the to digraph's edge type, alpar@100: /// and the copied map's key type is the from digraph's edge alpar@100: /// type. alpar@100: template alpar@100: BpGraphCopy& edgeMap(ToMap& tmap, const FromMap& map) { alpar@100: edgeMapCopies.push_back(new _digraph_utils_bits::MapCopy(tmap, map)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Make a copy of the given edge. alpar@100: /// alpar@100: /// Make a copy of the given edge. alpar@100: BpGraphCopy& edge(TEdge& tedge, const Edge& sedge) { alpar@100: edgeMapCopies.push_back(new _digraph_utils_bits::ItemCopy(tedge, sedge)); alpar@100: return *this; alpar@100: } alpar@100: alpar@100: /// \brief Executes the copies. alpar@100: /// alpar@100: /// Executes the copies. alpar@100: void run() { alpar@100: RedRefMap redRefMap(from); alpar@100: BlueRefMap blueRefMap(from); alpar@100: NodeRefMap nodeRefMap(from, redRefMap, blueRefMap); alpar@100: EdgeRefMap edgeRefMap(from); alpar@100: ArcRefMap arcRefMap(to, from, edgeRefMap, nodeRefMap); alpar@100: _digraph_utils_bits::BpGraphCopySelector:: alpar@100: copy(to, from, redRefMap, blueRefMap, edgeRefMap); alpar@100: for (int i = 0; i < int(redMapCopies.size()); ++i) { alpar@100: redMapCopies[i]->copy(from, redRefMap); alpar@100: } alpar@100: for (int i = 0; i < int(blueMapCopies.size()); ++i) { alpar@100: blueMapCopies[i]->copy(from, blueRefMap); alpar@100: } alpar@100: for (int i = 0; i < int(nodeMapCopies.size()); ++i) { alpar@100: nodeMapCopies[i]->copy(from, nodeRefMap); alpar@100: } alpar@100: for (int i = 0; i < int(edgeMapCopies.size()); ++i) { alpar@100: edgeMapCopies[i]->copy(from, edgeRefMap); alpar@100: } alpar@100: for (int i = 0; i < int(arcMapCopies.size()); ++i) { alpar@100: arcMapCopies[i]->copy(from, arcRefMap); alpar@100: } alpar@100: } alpar@100: alpar@100: private: alpar@100: alpar@100: const From& from; alpar@100: To& to; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: redMapCopies; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: blueMapCopies; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: nodeMapCopies; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: arcMapCopies; alpar@100: alpar@100: std::vector<_digraph_utils_bits::MapCopyBase* > alpar@100: edgeMapCopies; alpar@100: alpar@100: }; alpar@100: alpar@100: /// \brief Copy a bipartite digraph to another digraph. alpar@100: /// alpar@100: /// Copy a bipartite digraph to another digraph. alpar@100: /// The usage of the function: alpar@100: /// alpar@100: ///\code alpar@100: /// copyBpGraph(trg, src).redRef(anr).arcCrossRef(ecr).run(); alpar@100: ///\endcode alpar@100: /// alpar@100: /// After the copy the \c nr map will contain the mapping from the alpar@100: /// nodes of the \c from digraph to the nodes of the \c to digraph and alpar@100: /// \c ecr will contain the mapping from the arcs of the \c to digraph alpar@100: /// to the arcs of the \c from digraph. alpar@100: /// alpar@100: /// \see BpGraphCopy alpar@100: template alpar@100: BpGraphCopy alpar@100: copyBpGraph(To& to, const From& from) { alpar@100: return BpGraphCopy(to, from); alpar@100: } alpar@100: alpar@100: alpar@100: /// @} alpar@100: alpar@100: /// \addtogroup digraph_maps alpar@100: /// @{ alpar@100: alpar@100: /// Provides an immutable and unique id for each item in the digraph. alpar@100: alpar@100: /// The IdMap class provides a unique and immutable id for each item of the alpar@100: /// same type (e.g. node) in the digraph. This id is
  • \b unique: alpar@100: /// different items (nodes) get different ids
  • \b immutable: the id of an alpar@100: /// item (node) does not change (even if you delete other nodes).
alpar@100: /// Through this map you get access (i.e. can read) the inner id values of alpar@100: /// the items stored in the digraph. This map can be inverted with its member alpar@100: /// class \c InverseMap. alpar@100: /// alpar@100: template alpar@100: class IdMap { alpar@100: public: alpar@100: typedef _Digraph Digraph; alpar@100: typedef int Value; alpar@100: typedef _Item Item; alpar@100: typedef _Item Key; alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Constructor of the map. alpar@100: explicit IdMap(const Digraph& _digraph) : digraph(&_digraph) {} alpar@100: alpar@100: /// \brief Gives back the \e id of the item. alpar@100: /// alpar@100: /// Gives back the immutable and unique \e id of the item. alpar@100: int operator[](const Item& item) const { return digraph->id(item);} alpar@100: alpar@100: /// \brief Gives back the item by its id. alpar@100: /// alpar@100: /// Gives back the item by its id. alpar@100: Item operator()(int id) { return digraph->fromId(id, Item()); } alpar@100: alpar@100: private: alpar@100: const Digraph* digraph; alpar@100: alpar@100: public: alpar@100: alpar@100: /// \brief The class represents the inverse of its owner (IdMap). alpar@100: /// alpar@100: /// The class represents the inverse of its owner (IdMap). alpar@100: /// \see inverse() alpar@100: class InverseMap { alpar@100: public: alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Constructor for creating an id-to-item map. alpar@100: explicit InverseMap(const Digraph& _digraph) : digraph(&_digraph) {} alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Constructor for creating an id-to-item map. alpar@100: explicit InverseMap(const IdMap& idMap) : digraph(idMap.digraph) {} alpar@100: alpar@100: /// \brief Gives back the given item from its id. alpar@100: /// alpar@100: /// Gives back the given item from its id. alpar@100: /// alpar@100: Item operator[](int id) const { return digraph->fromId(id, Item());} alpar@100: alpar@100: private: alpar@100: const Digraph* digraph; alpar@100: }; alpar@100: alpar@100: /// \brief Gives back the inverse of the map. alpar@100: /// alpar@100: /// Gives back the inverse of the IdMap. alpar@100: InverseMap inverse() const { return InverseMap(*digraph);} alpar@100: alpar@100: }; alpar@100: alpar@100: alpar@100: /// \brief General invertable digraph-map type. alpar@100: alpar@100: /// This type provides simple invertable digraph-maps. alpar@100: /// The InvertableMap wraps an arbitrary ReadWriteMap alpar@100: /// and if a key is set to a new value then store it alpar@100: /// in the inverse map. alpar@100: /// alpar@100: /// The values of the map can be accessed alpar@100: /// with stl compatible forward iterator. alpar@100: /// alpar@100: /// \param _Digraph The digraph type. alpar@100: /// \param _Item The item type of the digraph. alpar@100: /// \param _Value The value type of the map. alpar@100: /// alpar@100: /// \see IterableValueMap alpar@100: template alpar@100: class InvertableMap : protected DefaultMap<_Digraph, _Item, _Value> { alpar@100: private: alpar@100: alpar@100: typedef DefaultMap<_Digraph, _Item, _Value> Map; alpar@100: typedef _Digraph Digraph; alpar@100: alpar@100: typedef std::map<_Value, _Item> Container; alpar@100: Container invMap; alpar@100: alpar@100: public: alpar@100: alpar@100: /// The key type of InvertableMap (Node, Arc, Edge). alpar@100: typedef typename Map::Key Key; alpar@100: /// The value type of the InvertableMap. alpar@100: typedef typename Map::Value Value; alpar@100: alpar@100: alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Construct a new InvertableMap for the digraph. alpar@100: /// alpar@100: explicit InvertableMap(const Digraph& digraph) : Map(digraph) {} alpar@100: alpar@100: /// \brief Forward iterator for values. alpar@100: /// alpar@100: /// This iterator is an stl compatible forward alpar@100: /// iterator on the values of the map. The values can alpar@100: /// be accessed in the [beginValue, endValue) range. alpar@100: /// alpar@100: class ValueIterator alpar@100: : public std::iterator { alpar@100: friend class InvertableMap; alpar@100: private: alpar@100: ValueIterator(typename Container::const_iterator _it) alpar@100: : it(_it) {} alpar@100: public: alpar@100: alpar@100: ValueIterator() {} alpar@100: alpar@100: ValueIterator& operator++() { ++it; return *this; } alpar@100: ValueIterator operator++(int) { alpar@100: ValueIterator tmp(*this); alpar@100: operator++(); alpar@100: return tmp; alpar@100: } alpar@100: alpar@100: const Value& operator*() const { return it->first; } alpar@100: const Value* operator->() const { return &(it->first); } alpar@100: alpar@100: bool operator==(ValueIterator jt) const { return it == jt.it; } alpar@100: bool operator!=(ValueIterator jt) const { return it != jt.it; } alpar@100: alpar@100: private: alpar@100: typename Container::const_iterator it; alpar@100: }; alpar@100: alpar@100: /// \brief Returns an iterator to the first value. alpar@100: /// alpar@100: /// Returns an stl compatible iterator to the alpar@100: /// first value of the map. The values of the alpar@100: /// map can be accessed in the [beginValue, endValue) alpar@100: /// range. alpar@100: ValueIterator beginValue() const { alpar@100: return ValueIterator(invMap.begin()); alpar@100: } alpar@100: alpar@100: /// \brief Returns an iterator after the last value. alpar@100: /// alpar@100: /// Returns an stl compatible iterator after the alpar@100: /// last value of the map. The values of the alpar@100: /// map can be accessed in the [beginValue, endValue) alpar@100: /// range. alpar@100: ValueIterator endValue() const { alpar@100: return ValueIterator(invMap.end()); alpar@100: } alpar@100: alpar@100: /// \brief The setter function of the map. alpar@100: /// alpar@100: /// Sets the mapped value. alpar@100: void set(const Key& key, const Value& val) { alpar@100: Value oldval = Map::operator[](key); alpar@100: typename Container::iterator it = invMap.find(oldval); alpar@100: if (it != invMap.end() && it->second == key) { alpar@100: invMap.erase(it); alpar@100: } alpar@100: invMap.insert(make_pair(val, key)); alpar@100: Map::set(key, val); alpar@100: } alpar@100: alpar@100: /// \brief The getter function of the map. alpar@100: /// alpar@100: /// It gives back the value associated with the key. alpar@100: typename MapTraits::ConstReturnValue alpar@100: operator[](const Key& key) const { alpar@100: return Map::operator[](key); alpar@100: } alpar@100: alpar@100: /// \brief Gives back the item by its value. alpar@100: /// alpar@100: /// Gives back the item by its value. alpar@100: Key operator()(const Value& key) const { alpar@100: typename Container::const_iterator it = invMap.find(key); alpar@100: return it != invMap.end() ? it->second : INVALID; alpar@100: } alpar@100: alpar@100: protected: alpar@100: alpar@100: /// \brief Erase the key from the map. alpar@100: /// alpar@100: /// Erase the key to the map. It is called by the alpar@100: /// \c AlterationNotifier. alpar@100: virtual void erase(const Key& key) { alpar@100: Value val = Map::operator[](key); alpar@100: typename Container::iterator it = invMap.find(val); alpar@100: if (it != invMap.end() && it->second == key) { alpar@100: invMap.erase(it); alpar@100: } alpar@100: Map::erase(key); alpar@100: } alpar@100: alpar@100: /// \brief Erase more keys from the map. alpar@100: /// alpar@100: /// Erase more keys from the map. It is called by the alpar@100: /// \c AlterationNotifier. alpar@100: virtual void erase(const std::vector& keys) { alpar@100: for (int i = 0; i < int(keys.size()); ++i) { alpar@100: Value val = Map::operator[](keys[i]); alpar@100: typename Container::iterator it = invMap.find(val); alpar@100: if (it != invMap.end() && it->second == keys[i]) { alpar@100: invMap.erase(it); alpar@100: } alpar@100: } alpar@100: Map::erase(keys); alpar@100: } alpar@100: alpar@100: /// \brief Clear the keys from the map and inverse map. alpar@100: /// alpar@100: /// Clear the keys from the map and inverse map. It is called by the alpar@100: /// \c AlterationNotifier. alpar@100: virtual void clear() { alpar@100: invMap.clear(); alpar@100: Map::clear(); alpar@100: } alpar@100: alpar@100: public: alpar@100: alpar@100: /// \brief The inverse map type. alpar@100: /// alpar@100: /// The inverse of this map. The subscript operator of the map alpar@100: /// gives back always the item what was last assigned to the value. alpar@100: class InverseMap { alpar@100: public: alpar@100: /// \brief Constructor of the InverseMap. alpar@100: /// alpar@100: /// Constructor of the InverseMap. alpar@100: explicit InverseMap(const InvertableMap& _inverted) alpar@100: : inverted(_inverted) {} alpar@100: alpar@100: /// The value type of the InverseMap. alpar@100: typedef typename InvertableMap::Key Value; alpar@100: /// The key type of the InverseMap. alpar@100: typedef typename InvertableMap::Value Key; alpar@100: alpar@100: /// \brief Subscript operator. alpar@100: /// alpar@100: /// Subscript operator. It gives back always the item alpar@100: /// what was last assigned to the value. alpar@100: Value operator[](const Key& key) const { alpar@100: return inverted(key); alpar@100: } alpar@100: alpar@100: private: alpar@100: const InvertableMap& inverted; alpar@100: }; alpar@100: alpar@100: /// \brief It gives back the just readable inverse map. alpar@100: /// alpar@100: /// It gives back the just readable inverse map. alpar@100: InverseMap inverse() const { alpar@100: return InverseMap(*this); alpar@100: } alpar@100: alpar@100: alpar@100: alpar@100: }; alpar@100: alpar@100: /// \brief Provides a mutable, continuous and unique descriptor for each alpar@100: /// item in the digraph. alpar@100: /// alpar@100: /// The DescriptorMap class provides a unique and continuous (but mutable) alpar@100: /// descriptor (id) for each item of the same type (e.g. node) in the alpar@100: /// digraph. This id is
  • \b unique: different items (nodes) get alpar@100: /// different ids
  • \b continuous: the range of the ids is the set of alpar@100: /// integers between 0 and \c n-1, where \c n is the number of the items of alpar@100: /// this type (e.g. nodes) (so the id of a node can change if you delete an alpar@100: /// other node, i.e. this id is mutable).
This map can be inverted alpar@100: /// with its member class \c InverseMap. alpar@100: /// alpar@100: /// \param _Digraph The digraph class the \c DescriptorMap belongs to. alpar@100: /// \param _Item The Item is the Key of the Map. It may be Node, Arc or alpar@100: /// Edge. alpar@100: template alpar@100: class DescriptorMap : protected DefaultMap<_Digraph, _Item, int> { alpar@100: alpar@100: typedef _Item Item; alpar@100: typedef DefaultMap<_Digraph, _Item, int> Map; alpar@100: alpar@100: public: alpar@100: /// The digraph class of DescriptorMap. alpar@100: typedef _Digraph Digraph; alpar@100: alpar@100: /// The key type of DescriptorMap (Node, Arc, Edge). alpar@100: typedef typename Map::Key Key; alpar@100: /// The value type of DescriptorMap. alpar@100: typedef typename Map::Value Value; alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Constructor for descriptor map. alpar@100: explicit DescriptorMap(const Digraph& _digraph) : Map(_digraph) { alpar@100: Item it; alpar@100: const typename Map::Notifier* nf = Map::notifier(); alpar@100: for (nf->first(it); it != INVALID; nf->next(it)) { alpar@100: Map::set(it, invMap.size()); alpar@100: invMap.push_back(it); alpar@100: } alpar@100: } alpar@100: alpar@100: protected: alpar@100: alpar@100: /// \brief Add a new key to the map. alpar@100: /// alpar@100: /// Add a new key to the map. It is called by the alpar@100: /// \c AlterationNotifier. alpar@100: virtual void add(const Item& item) { alpar@100: Map::add(item); alpar@100: Map::set(item, invMap.size()); alpar@100: invMap.push_back(item); alpar@100: } alpar@100: alpar@100: /// \brief Add more new keys to the map. alpar@100: /// alpar@100: /// Add more new keys to the map. It is called by the alpar@100: /// \c AlterationNotifier. alpar@100: virtual void add(const std::vector& items) { alpar@100: Map::add(items); alpar@100: for (int i = 0; i < int(items.size()); ++i) { alpar@100: Map::set(items[i], invMap.size()); alpar@100: invMap.push_back(items[i]); alpar@100: } alpar@100: } alpar@100: alpar@100: /// \brief Erase the key from the map. alpar@100: /// alpar@100: /// Erase the key from the map. It is called by the alpar@100: /// \c AlterationNotifier. alpar@100: virtual void erase(const Item& item) { alpar@100: Map::set(invMap.back(), Map::operator[](item)); alpar@100: invMap[Map::operator[](item)] = invMap.back(); alpar@100: invMap.pop_back(); alpar@100: Map::erase(item); alpar@100: } alpar@100: alpar@100: /// \brief Erase more keys from the map. alpar@100: /// alpar@100: /// Erase more keys from the map. It is called by the alpar@100: /// \c AlterationNotifier. alpar@100: virtual void erase(const std::vector& items) { alpar@100: for (int i = 0; i < int(items.size()); ++i) { alpar@100: Map::set(invMap.back(), Map::operator[](items[i])); alpar@100: invMap[Map::operator[](items[i])] = invMap.back(); alpar@100: invMap.pop_back(); alpar@100: } alpar@100: Map::erase(items); alpar@100: } alpar@100: alpar@100: /// \brief Build the unique map. alpar@100: /// alpar@100: /// Build the unique map. It is called by the alpar@100: /// \c AlterationNotifier. alpar@100: virtual void build() { alpar@100: Map::build(); alpar@100: Item it; alpar@100: const typename Map::Notifier* nf = Map::notifier(); alpar@100: for (nf->first(it); it != INVALID; nf->next(it)) { alpar@100: Map::set(it, invMap.size()); alpar@100: invMap.push_back(it); alpar@100: } alpar@100: } alpar@100: alpar@100: /// \brief Clear the keys from the map. alpar@100: /// alpar@100: /// Clear the keys from the map. It is called by the alpar@100: /// \c AlterationNotifier. alpar@100: virtual void clear() { alpar@100: invMap.clear(); alpar@100: Map::clear(); alpar@100: } alpar@100: alpar@100: public: alpar@100: alpar@100: /// \brief Returns the maximal value plus one. alpar@100: /// alpar@100: /// Returns the maximal value plus one in the map. alpar@100: unsigned int size() const { alpar@100: return invMap.size(); alpar@100: } alpar@100: alpar@100: /// \brief Swaps the position of the two items in the map. alpar@100: /// alpar@100: /// Swaps the position of the two items in the map. alpar@100: void swap(const Item& p, const Item& q) { alpar@100: int pi = Map::operator[](p); alpar@100: int qi = Map::operator[](q); alpar@100: Map::set(p, qi); alpar@100: invMap[qi] = p; alpar@100: Map::set(q, pi); alpar@100: invMap[pi] = q; alpar@100: } alpar@100: alpar@100: /// \brief Gives back the \e descriptor of the item. alpar@100: /// alpar@100: /// Gives back the mutable and unique \e descriptor of the map. alpar@100: int operator[](const Item& item) const { alpar@100: return Map::operator[](item); alpar@100: } alpar@100: alpar@100: /// \brief Gives back the item by its descriptor. alpar@100: /// alpar@100: /// Gives back th item by its descriptor. alpar@100: Item operator()(int id) const { alpar@100: return invMap[id]; alpar@100: } alpar@100: alpar@100: private: alpar@100: alpar@100: typedef std::vector Container; alpar@100: Container invMap; alpar@100: alpar@100: public: alpar@100: /// \brief The inverse map type of DescriptorMap. alpar@100: /// alpar@100: /// The inverse map type of DescriptorMap. alpar@100: class InverseMap { alpar@100: public: alpar@100: /// \brief Constructor of the InverseMap. alpar@100: /// alpar@100: /// Constructor of the InverseMap. alpar@100: explicit InverseMap(const DescriptorMap& _inverted) alpar@100: : inverted(_inverted) {} alpar@100: alpar@100: alpar@100: /// The value type of the InverseMap. alpar@100: typedef typename DescriptorMap::Key Value; alpar@100: /// The key type of the InverseMap. alpar@100: typedef typename DescriptorMap::Value Key; alpar@100: alpar@100: /// \brief Subscript operator. alpar@100: /// alpar@100: /// Subscript operator. It gives back the item alpar@100: /// that the descriptor belongs to currently. alpar@100: Value operator[](const Key& key) const { alpar@100: return inverted(key); alpar@100: } alpar@100: alpar@100: /// \brief Size of the map. alpar@100: /// alpar@100: /// Returns the size of the map. alpar@100: unsigned int size() const { alpar@100: return inverted.size(); alpar@100: } alpar@100: alpar@100: private: alpar@100: const DescriptorMap& inverted; alpar@100: }; alpar@100: alpar@100: /// \brief Gives back the inverse of the map. alpar@100: /// alpar@100: /// Gives back the inverse of the map. alpar@100: const InverseMap inverse() const { alpar@100: return InverseMap(*this); alpar@100: } alpar@100: }; alpar@100: alpar@100: /// \brief Returns the source of the given arc. alpar@100: /// alpar@100: /// The SourceMap gives back the source Node of the given arc. alpar@100: /// \see TargetMap alpar@100: /// \author Balazs Dezso alpar@100: template alpar@100: class SourceMap { alpar@100: public: alpar@100: alpar@100: typedef typename Digraph::Node Value; alpar@100: typedef typename Digraph::Arc Key; alpar@100: alpar@100: /// \brief Constructor alpar@100: /// alpar@100: /// Constructor alpar@100: /// \param _digraph The digraph that the map belongs to. alpar@100: explicit SourceMap(const Digraph& _digraph) : digraph(_digraph) {} alpar@100: alpar@100: /// \brief The subscript operator. alpar@100: /// alpar@100: /// The subscript operator. alpar@100: /// \param arc The arc alpar@100: /// \return The source of the arc alpar@100: Value operator[](const Key& arc) const { alpar@100: return digraph.source(arc); alpar@100: } alpar@100: alpar@100: private: alpar@100: const Digraph& digraph; alpar@100: }; alpar@100: alpar@100: /// \brief Returns a \ref SourceMap class. alpar@100: /// alpar@100: /// This function just returns an \ref SourceMap class. alpar@100: /// \relates SourceMap alpar@100: template alpar@100: inline SourceMap sourceMap(const Digraph& digraph) { alpar@100: return SourceMap(digraph); alpar@100: } alpar@100: alpar@100: /// \brief Returns the target of the given arc. alpar@100: /// alpar@100: /// The TargetMap gives back the target Node of the given arc. alpar@100: /// \see SourceMap alpar@100: /// \author Balazs Dezso alpar@100: template alpar@100: class TargetMap { alpar@100: public: alpar@100: alpar@100: typedef typename Digraph::Node Value; alpar@100: typedef typename Digraph::Arc Key; alpar@100: alpar@100: /// \brief Constructor alpar@100: /// alpar@100: /// Constructor alpar@100: /// \param _digraph The digraph that the map belongs to. alpar@100: explicit TargetMap(const Digraph& _digraph) : digraph(_digraph) {} alpar@100: alpar@100: /// \brief The subscript operator. alpar@100: /// alpar@100: /// The subscript operator. alpar@100: /// \param e The arc alpar@100: /// \return The target of the arc alpar@100: Value operator[](const Key& e) const { alpar@100: return digraph.target(e); alpar@100: } alpar@100: alpar@100: private: alpar@100: const Digraph& digraph; alpar@100: }; alpar@100: alpar@100: /// \brief Returns a \ref TargetMap class. alpar@100: /// alpar@100: /// This function just returns a \ref TargetMap class. alpar@100: /// \relates TargetMap alpar@100: template alpar@100: inline TargetMap targetMap(const Digraph& digraph) { alpar@100: return TargetMap(digraph); alpar@100: } alpar@100: alpar@100: /// \brief Returns the "forward" directed arc view of an edge. alpar@100: /// alpar@100: /// Returns the "forward" directed arc view of an edge. alpar@100: /// \see BackwardMap alpar@100: /// \author Balazs Dezso alpar@100: template alpar@100: class ForwardMap { alpar@100: public: alpar@100: alpar@100: typedef typename Digraph::Arc Value; alpar@100: typedef typename Digraph::Edge Key; alpar@100: alpar@100: /// \brief Constructor alpar@100: /// alpar@100: /// Constructor alpar@100: /// \param _digraph The digraph that the map belongs to. alpar@100: explicit ForwardMap(const Digraph& _digraph) : digraph(_digraph) {} alpar@100: alpar@100: /// \brief The subscript operator. alpar@100: /// alpar@100: /// The subscript operator. alpar@100: /// \param key An edge alpar@100: /// \return The "forward" directed arc view of edge alpar@100: Value operator[](const Key& key) const { alpar@100: return digraph.direct(key, true); alpar@100: } alpar@100: alpar@100: private: alpar@100: const Digraph& digraph; alpar@100: }; alpar@100: alpar@100: /// \brief Returns a \ref ForwardMap class. alpar@100: /// alpar@100: /// This function just returns an \ref ForwardMap class. alpar@100: /// \relates ForwardMap alpar@100: template alpar@100: inline ForwardMap forwardMap(const Digraph& digraph) { alpar@100: return ForwardMap(digraph); alpar@100: } alpar@100: alpar@100: /// \brief Returns the "backward" directed arc view of an edge. alpar@100: /// alpar@100: /// Returns the "backward" directed arc view of an edge. alpar@100: /// \see ForwardMap alpar@100: /// \author Balazs Dezso alpar@100: template alpar@100: class BackwardMap { alpar@100: public: alpar@100: alpar@100: typedef typename Digraph::Arc Value; alpar@100: typedef typename Digraph::Edge Key; alpar@100: alpar@100: /// \brief Constructor alpar@100: /// alpar@100: /// Constructor alpar@100: /// \param _digraph The digraph that the map belongs to. alpar@100: explicit BackwardMap(const Digraph& _digraph) : digraph(_digraph) {} alpar@100: alpar@100: /// \brief The subscript operator. alpar@100: /// alpar@100: /// The subscript operator. alpar@100: /// \param key An edge alpar@100: /// \return The "backward" directed arc view of edge alpar@100: Value operator[](const Key& key) const { alpar@100: return digraph.direct(key, false); alpar@100: } alpar@100: alpar@100: private: alpar@100: const Digraph& digraph; alpar@100: }; alpar@100: alpar@100: /// \brief Returns a \ref BackwardMap class alpar@100: alpar@100: /// This function just returns a \ref BackwardMap class. alpar@100: /// \relates BackwardMap alpar@100: template alpar@100: inline BackwardMap backwardMap(const Digraph& digraph) { alpar@100: return BackwardMap(digraph); alpar@100: } alpar@100: alpar@100: /// \brief Potential difference map alpar@100: /// alpar@100: /// If there is an potential map on the nodes then we alpar@100: /// can get an arc map as we get the substraction of the alpar@100: /// values of the target and source. alpar@100: template alpar@100: class PotentialDifferenceMap { alpar@100: public: alpar@100: typedef typename Digraph::Arc Key; alpar@100: typedef typename NodeMap::Value Value; alpar@100: alpar@100: /// \brief Constructor alpar@100: /// alpar@100: /// Contructor of the map alpar@100: explicit PotentialDifferenceMap(const Digraph& _digraph, alpar@100: const NodeMap& _potential) alpar@100: : digraph(_digraph), potential(_potential) {} alpar@100: alpar@100: /// \brief Const subscription operator alpar@100: /// alpar@100: /// Const subscription operator alpar@100: Value operator[](const Key& arc) const { alpar@100: return potential[digraph.target(arc)] - potential[digraph.source(arc)]; alpar@100: } alpar@100: alpar@100: private: alpar@100: const Digraph& digraph; alpar@100: const NodeMap& potential; alpar@100: }; alpar@100: alpar@100: /// \brief Returns a PotentialDifferenceMap. alpar@100: /// alpar@100: /// This function just returns a PotentialDifferenceMap. alpar@100: /// \relates PotentialDifferenceMap alpar@100: template alpar@100: PotentialDifferenceMap alpar@100: potentialDifferenceMap(const Digraph& digraph, const NodeMap& potential) { alpar@100: return PotentialDifferenceMap(digraph, potential); alpar@100: } alpar@100: alpar@100: /// \brief Map of the node in-degrees. alpar@100: /// alpar@100: /// This map returns the in-degree of a node. Once it is constructed, alpar@100: /// the degrees are stored in a standard NodeMap, so each query is done alpar@100: /// in constant time. On the other hand, the values are updated automatically alpar@100: /// whenever the digraph changes. alpar@100: /// alpar@100: /// \warning Besides addNode() and addArc(), a digraph structure may provide alpar@100: /// alternative ways to modify the digraph. The correct behavior of InDegMap alpar@100: /// is not guarantied if these additional features are used. For example alpar@100: /// the functions \ref ListDigraph::changeSource() "changeSource()", alpar@100: /// \ref ListDigraph::changeTarget() "changeTarget()" and alpar@100: /// \ref ListDigraph::reverseArc() "reverseArc()" alpar@100: /// of \ref ListDigraph will \e not update the degree values correctly. alpar@100: /// alpar@100: /// \sa OutDegMap alpar@100: alpar@100: template alpar@100: class InDegMap alpar@100: : protected ItemSetTraits<_Digraph, typename _Digraph::Arc> alpar@100: ::ItemNotifier::ObserverBase { alpar@100: alpar@100: public: alpar@100: alpar@100: typedef _Digraph Digraph; alpar@100: typedef int Value; alpar@100: typedef typename Digraph::Node Key; alpar@100: alpar@100: typedef typename ItemSetTraits<_Digraph, typename _Digraph::Arc> alpar@100: ::ItemNotifier::ObserverBase Parent; alpar@100: alpar@100: private: alpar@100: alpar@100: class AutoNodeMap : public DefaultMap<_Digraph, Key, int> { alpar@100: public: alpar@100: alpar@100: typedef DefaultMap<_Digraph, Key, int> Parent; alpar@100: typedef typename Parent::Digraph Digraph; alpar@100: alpar@100: AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {} alpar@100: alpar@100: virtual void add(const Key& key) { alpar@100: Parent::add(key); alpar@100: Parent::set(key, 0); alpar@100: } alpar@100: alpar@100: virtual void add(const std::vector& keys) { alpar@100: Parent::add(keys); alpar@100: for (int i = 0; i < int(keys.size()); ++i) { alpar@100: Parent::set(keys[i], 0); alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void build() { alpar@100: Parent::build(); alpar@100: Key it; alpar@100: typename Parent::Notifier* nf = Parent::notifier(); alpar@100: for (nf->first(it); it != INVALID; nf->next(it)) { alpar@100: Parent::set(it, 0); alpar@100: } alpar@100: } alpar@100: }; alpar@100: alpar@100: public: alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Constructor for creating in-degree map. alpar@100: explicit InDegMap(const Digraph& _digraph) : digraph(_digraph), deg(_digraph) { alpar@100: Parent::attach(digraph.notifier(typename _Digraph::Arc())); alpar@100: alpar@100: for(typename _Digraph::NodeIt it(digraph); it != INVALID; ++it) { alpar@100: deg[it] = countInArcs(digraph, it); alpar@100: } alpar@100: } alpar@100: alpar@100: /// Gives back the in-degree of a Node. alpar@100: int operator[](const Key& key) const { alpar@100: return deg[key]; alpar@100: } alpar@100: alpar@100: protected: alpar@100: alpar@100: typedef typename Digraph::Arc Arc; alpar@100: alpar@100: virtual void add(const Arc& arc) { alpar@100: ++deg[digraph.target(arc)]; alpar@100: } alpar@100: alpar@100: virtual void add(const std::vector& arcs) { alpar@100: for (int i = 0; i < int(arcs.size()); ++i) { alpar@100: ++deg[digraph.target(arcs[i])]; alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void erase(const Arc& arc) { alpar@100: --deg[digraph.target(arc)]; alpar@100: } alpar@100: alpar@100: virtual void erase(const std::vector& arcs) { alpar@100: for (int i = 0; i < int(arcs.size()); ++i) { alpar@100: --deg[digraph.target(arcs[i])]; alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void build() { alpar@100: for(typename _Digraph::NodeIt it(digraph); it != INVALID; ++it) { alpar@100: deg[it] = countInArcs(digraph, it); alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void clear() { alpar@100: for(typename _Digraph::NodeIt it(digraph); it != INVALID; ++it) { alpar@100: deg[it] = 0; alpar@100: } alpar@100: } alpar@100: private: alpar@100: alpar@100: const _Digraph& digraph; alpar@100: AutoNodeMap deg; alpar@100: }; alpar@100: alpar@100: /// \brief Map of the node out-degrees. alpar@100: /// alpar@100: /// This map returns the out-degree of a node. Once it is constructed, alpar@100: /// the degrees are stored in a standard NodeMap, so each query is done alpar@100: /// in constant time. On the other hand, the values are updated automatically alpar@100: /// whenever the digraph changes. alpar@100: /// alpar@100: /// \warning Besides addNode() and addArc(), a digraph structure may provide alpar@100: /// alternative ways to modify the digraph. The correct behavior of OutDegMap alpar@100: /// is not guarantied if these additional features are used. For example alpar@100: /// the functions \ref ListDigraph::changeSource() "changeSource()", alpar@100: /// \ref ListDigraph::changeTarget() "changeTarget()" and alpar@100: /// \ref ListDigraph::reverseArc() "reverseArc()" alpar@100: /// of \ref ListDigraph will \e not update the degree values correctly. alpar@100: /// alpar@100: /// \sa InDegMap alpar@100: alpar@100: template alpar@100: class OutDegMap alpar@100: : protected ItemSetTraits<_Digraph, typename _Digraph::Arc> alpar@100: ::ItemNotifier::ObserverBase { alpar@100: alpar@100: public: alpar@100: alpar@100: typedef typename ItemSetTraits<_Digraph, typename _Digraph::Arc> alpar@100: ::ItemNotifier::ObserverBase Parent; alpar@100: alpar@100: typedef _Digraph Digraph; alpar@100: typedef int Value; alpar@100: typedef typename Digraph::Node Key; alpar@100: alpar@100: private: alpar@100: alpar@100: class AutoNodeMap : public DefaultMap<_Digraph, Key, int> { alpar@100: public: alpar@100: alpar@100: typedef DefaultMap<_Digraph, Key, int> Parent; alpar@100: typedef typename Parent::Digraph Digraph; alpar@100: alpar@100: AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {} alpar@100: alpar@100: virtual void add(const Key& key) { alpar@100: Parent::add(key); alpar@100: Parent::set(key, 0); alpar@100: } alpar@100: virtual void add(const std::vector& keys) { alpar@100: Parent::add(keys); alpar@100: for (int i = 0; i < int(keys.size()); ++i) { alpar@100: Parent::set(keys[i], 0); alpar@100: } alpar@100: } alpar@100: virtual void build() { alpar@100: Parent::build(); alpar@100: Key it; alpar@100: typename Parent::Notifier* nf = Parent::notifier(); alpar@100: for (nf->first(it); it != INVALID; nf->next(it)) { alpar@100: Parent::set(it, 0); alpar@100: } alpar@100: } alpar@100: }; alpar@100: alpar@100: public: alpar@100: alpar@100: /// \brief Constructor. alpar@100: /// alpar@100: /// Constructor for creating out-degree map. alpar@100: explicit OutDegMap(const Digraph& _digraph) : digraph(_digraph), deg(_digraph) { alpar@100: Parent::attach(digraph.notifier(typename _Digraph::Arc())); alpar@100: alpar@100: for(typename _Digraph::NodeIt it(digraph); it != INVALID; ++it) { alpar@100: deg[it] = countOutArcs(digraph, it); alpar@100: } alpar@100: } alpar@100: alpar@100: /// Gives back the out-degree of a Node. alpar@100: int operator[](const Key& key) const { alpar@100: return deg[key]; alpar@100: } alpar@100: alpar@100: protected: alpar@100: alpar@100: typedef typename Digraph::Arc Arc; alpar@100: alpar@100: virtual void add(const Arc& arc) { alpar@100: ++deg[digraph.source(arc)]; alpar@100: } alpar@100: alpar@100: virtual void add(const std::vector& arcs) { alpar@100: for (int i = 0; i < int(arcs.size()); ++i) { alpar@100: ++deg[digraph.source(arcs[i])]; alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void erase(const Arc& arc) { alpar@100: --deg[digraph.source(arc)]; alpar@100: } alpar@100: alpar@100: virtual void erase(const std::vector& arcs) { alpar@100: for (int i = 0; i < int(arcs.size()); ++i) { alpar@100: --deg[digraph.source(arcs[i])]; alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void build() { alpar@100: for(typename _Digraph::NodeIt it(digraph); it != INVALID; ++it) { alpar@100: deg[it] = countOutArcs(digraph, it); alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void clear() { alpar@100: for(typename _Digraph::NodeIt it(digraph); it != INVALID; ++it) { alpar@100: deg[it] = 0; alpar@100: } alpar@100: } alpar@100: private: alpar@100: alpar@100: const _Digraph& digraph; alpar@100: AutoNodeMap deg; alpar@100: }; alpar@100: alpar@100: alpar@100: ///Dynamic arc look up between given endpoints. alpar@100: alpar@100: ///\ingroup gutils alpar@100: ///Using this class, you can find an arc in a digraph from a given alpar@100: ///source to a given target in amortized time O(log d), alpar@100: ///where d is the out-degree of the source node. alpar@100: /// alpar@100: ///It is possible to find \e all parallel arcs between two nodes with alpar@100: ///the \c findFirst() and \c findNext() members. alpar@100: /// alpar@100: ///See the \ref ArcLookUp and \ref AllArcLookUp classes if your alpar@100: ///digraph do not changed so frequently. alpar@100: /// alpar@100: ///This class uses a self-adjusting binary search tree, Sleator's alpar@100: ///and Tarjan's Splay tree for guarantee the logarithmic amortized alpar@100: ///time bound for arc lookups. This class also guarantees the alpar@100: ///optimal time bound in a constant factor for any distribution of alpar@100: ///queries. alpar@100: /// alpar@100: ///\param G The type of the underlying digraph. alpar@100: /// alpar@100: ///\sa ArcLookUp alpar@100: ///\sa AllArcLookUp alpar@100: template alpar@100: class DynArcLookUp alpar@100: : protected ItemSetTraits::ItemNotifier::ObserverBase alpar@100: { alpar@100: public: alpar@100: typedef typename ItemSetTraits alpar@100: ::ItemNotifier::ObserverBase Parent; alpar@100: alpar@100: GRAPH_TYPEDEFS(typename G); alpar@100: typedef G Digraph; alpar@100: alpar@100: protected: alpar@100: alpar@100: class AutoNodeMap : public DefaultMap { alpar@100: public: alpar@100: alpar@100: typedef DefaultMap Parent; alpar@100: alpar@100: AutoNodeMap(const G& digraph) : Parent(digraph, INVALID) {} alpar@100: alpar@100: virtual void add(const Node& node) { alpar@100: Parent::add(node); alpar@100: Parent::set(node, INVALID); alpar@100: } alpar@100: alpar@100: virtual void add(const std::vector& nodes) { alpar@100: Parent::add(nodes); alpar@100: for (int i = 0; i < int(nodes.size()); ++i) { alpar@100: Parent::set(nodes[i], INVALID); alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void build() { alpar@100: Parent::build(); alpar@100: Node it; alpar@100: typename Parent::Notifier* nf = Parent::notifier(); alpar@100: for (nf->first(it); it != INVALID; nf->next(it)) { alpar@100: Parent::set(it, INVALID); alpar@100: } alpar@100: } alpar@100: }; alpar@100: alpar@100: const Digraph &_g; alpar@100: AutoNodeMap _head; alpar@100: typename Digraph::template ArcMap _parent; alpar@100: typename Digraph::template ArcMap _left; alpar@100: typename Digraph::template ArcMap _right; alpar@100: alpar@100: class ArcLess { alpar@100: const Digraph &g; alpar@100: public: alpar@100: ArcLess(const Digraph &_g) : g(_g) {} alpar@100: bool operator()(Arc a,Arc b) const alpar@100: { alpar@100: return g.target(a)& arcs) { alpar@100: for (int i = 0; i < int(arcs.size()); ++i) { alpar@100: insert(arcs[i]); alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void erase(const Arc& arc) { alpar@100: remove(arc); alpar@100: } alpar@100: alpar@100: virtual void erase(const std::vector& arcs) { alpar@100: for (int i = 0; i < int(arcs.size()); ++i) { alpar@100: remove(arcs[i]); alpar@100: } alpar@100: } alpar@100: alpar@100: virtual void build() { alpar@100: refresh(); alpar@100: } alpar@100: alpar@100: virtual void clear() { alpar@100: for(NodeIt n(_g);n!=INVALID;++n) { alpar@100: _head.set(n, INVALID); alpar@100: } alpar@100: } alpar@100: alpar@100: void insert(Arc arc) { alpar@100: Node s = _g.source(arc); alpar@100: Node t = _g.target(arc); alpar@100: _left.set(arc, INVALID); alpar@100: _right.set(arc, INVALID); alpar@100: alpar@100: Arc e = _head[s]; alpar@100: if (e == INVALID) { alpar@100: _head.set(s, arc); alpar@100: _parent.set(arc, INVALID); alpar@100: return; alpar@100: } alpar@100: while (true) { alpar@100: if (t < _g.target(e)) { alpar@100: if (_left[e] == INVALID) { alpar@100: _left.set(e, arc); alpar@100: _parent.set(arc, e); alpar@100: splay(arc); alpar@100: return; alpar@100: } else { alpar@100: e = _left[e]; alpar@100: } alpar@100: } else { alpar@100: if (_right[e] == INVALID) { alpar@100: _right.set(e, arc); alpar@100: _parent.set(arc, e); alpar@100: splay(arc); alpar@100: return; alpar@100: } else { alpar@100: e = _right[e]; alpar@100: } alpar@100: } alpar@100: } alpar@100: } alpar@100: alpar@100: void remove(Arc arc) { alpar@100: if (_left[arc] == INVALID) { alpar@100: if (_right[arc] != INVALID) { alpar@100: _parent.set(_right[arc], _parent[arc]); alpar@100: } alpar@100: if (_parent[arc] != INVALID) { alpar@100: if (_left[_parent[arc]] == arc) { alpar@100: _left.set(_parent[arc], _right[arc]); alpar@100: } else { alpar@100: _right.set(_parent[arc], _right[arc]); alpar@100: } alpar@100: } else { alpar@100: _head.set(_g.source(arc), _right[arc]); alpar@100: } alpar@100: } else if (_right[arc] == INVALID) { alpar@100: _parent.set(_left[arc], _parent[arc]); alpar@100: if (_parent[arc] != INVALID) { alpar@100: if (_left[_parent[arc]] == arc) { alpar@100: _left.set(_parent[arc], _left[arc]); alpar@100: } else { alpar@100: _right.set(_parent[arc], _left[arc]); alpar@100: } alpar@100: } else { alpar@100: _head.set(_g.source(arc), _left[arc]); alpar@100: } alpar@100: } else { alpar@100: Arc e = _left[arc]; alpar@100: if (_right[e] != INVALID) { alpar@100: e = _right[e]; alpar@100: while (_right[e] != INVALID) { alpar@100: e = _right[e]; alpar@100: } alpar@100: Arc s = _parent[e]; alpar@100: _right.set(_parent[e], _left[e]); alpar@100: if (_left[e] != INVALID) { alpar@100: _parent.set(_left[e], _parent[e]); alpar@100: } alpar@100: alpar@100: _left.set(e, _left[arc]); alpar@100: _parent.set(_left[arc], e); alpar@100: _right.set(e, _right[arc]); alpar@100: _parent.set(_right[arc], e); alpar@100: alpar@100: _parent.set(e, _parent[arc]); alpar@100: if (_parent[arc] != INVALID) { alpar@100: if (_left[_parent[arc]] == arc) { alpar@100: _left.set(_parent[arc], e); alpar@100: } else { alpar@100: _right.set(_parent[arc], e); alpar@100: } alpar@100: } alpar@100: splay(s); alpar@100: } else { alpar@100: _right.set(e, _right[arc]); alpar@100: _parent.set(_right[arc], e); alpar@100: alpar@100: if (_parent[arc] != INVALID) { alpar@100: if (_left[_parent[arc]] == arc) { alpar@100: _left.set(_parent[arc], e); alpar@100: } else { alpar@100: _right.set(_parent[arc], e); alpar@100: } alpar@100: } else { alpar@100: _head.set(_g.source(arc), e); alpar@100: } alpar@100: } alpar@100: } alpar@100: } alpar@100: alpar@100: Arc refreshRec(std::vector &v,int a,int b) alpar@100: { alpar@100: int m=(a+b)/2; alpar@100: Arc me=v[m]; alpar@100: if (a < m) { alpar@100: Arc left = refreshRec(v,a,m-1); alpar@100: _left.set(me, left); alpar@100: _parent.set(left, me); alpar@100: } else { alpar@100: _left.set(me, INVALID); alpar@100: } alpar@100: if (m < b) { alpar@100: Arc right = refreshRec(v,m+1,b); alpar@100: _right.set(me, right); alpar@100: _parent.set(right, me); alpar@100: } else { alpar@100: _right.set(me, INVALID); alpar@100: } alpar@100: return me; alpar@100: } alpar@100: alpar@100: void refresh() { alpar@100: for(NodeIt n(_g);n!=INVALID;++n) { alpar@100: std::vector v; alpar@100: for(OutArcIt e(_g,n);e!=INVALID;++e) v.push_back(e); alpar@100: if(v.size()) { alpar@100: std::sort(v.begin(),v.end(),ArcLess(_g)); alpar@100: Arc head = refreshRec(v,0,v.size()-1); alpar@100: _head.set(n, head); alpar@100: _parent.set(head, INVALID); alpar@100: } alpar@100: else _head.set(n, INVALID); alpar@100: } alpar@100: } alpar@100: alpar@100: void zig(Arc v) { alpar@100: Arc w = _parent[v]; alpar@100: _parent.set(v, _parent[w]); alpar@100: _parent.set(w, v); alpar@100: _left.set(w, _right[v]); alpar@100: _right.set(v, w); alpar@100: if (_parent[v] != INVALID) { alpar@100: if (_right[_parent[v]] == w) { alpar@100: _right.set(_parent[v], v); alpar@100: } else { alpar@100: _left.set(_parent[v], v); alpar@100: } alpar@100: } alpar@100: if (_left[w] != INVALID){ alpar@100: _parent.set(_left[w], w); alpar@100: } alpar@100: } alpar@100: alpar@100: void zag(Arc v) { alpar@100: Arc w = _parent[v]; alpar@100: _parent.set(v, _parent[w]); alpar@100: _parent.set(w, v); alpar@100: _right.set(w, _left[v]); alpar@100: _left.set(v, w); alpar@100: if (_parent[v] != INVALID){ alpar@100: if (_left[_parent[v]] == w) { alpar@100: _left.set(_parent[v], v); alpar@100: } else { alpar@100: _right.set(_parent[v], v); alpar@100: } alpar@100: } alpar@100: if (_right[w] != INVALID){ alpar@100: _parent.set(_right[w], w); alpar@100: } alpar@100: } alpar@100: alpar@100: void splay(Arc v) { alpar@100: while (_parent[v] != INVALID) { alpar@100: if (v == _left[_parent[v]]) { alpar@100: if (_parent[_parent[v]] == INVALID) { alpar@100: zig(v); alpar@100: } else { alpar@100: if (_parent[v] == _left[_parent[_parent[v]]]) { alpar@100: zig(_parent[v]); alpar@100: zig(v); alpar@100: } else { alpar@100: zig(v); alpar@100: zag(v); alpar@100: } alpar@100: } alpar@100: } else { alpar@100: if (_parent[_parent[v]] == INVALID) { alpar@100: zag(v); alpar@100: } else { alpar@100: if (_parent[v] == _left[_parent[_parent[v]]]) { alpar@100: zag(v); alpar@100: zig(v); alpar@100: } else { alpar@100: zag(_parent[v]); alpar@100: zag(v); alpar@100: } alpar@100: } alpar@100: } alpar@100: } alpar@100: _head[_g.source(v)] = v; alpar@100: } alpar@100: alpar@100: alpar@100: public: alpar@100: alpar@100: ///Find an arc between two nodes. alpar@100: alpar@100: ///Find an arc between two nodes in time O(logd), where alpar@100: /// d is the number of outgoing arcs of \c s. alpar@100: ///\param s The source node alpar@100: ///\param t The target node alpar@100: ///\return An arc from \c s to \c t if there exists, alpar@100: ///\ref INVALID otherwise. alpar@100: Arc operator()(Node s, Node t) const alpar@100: { alpar@100: Arc e = _head[s]; alpar@100: while (true) { alpar@100: if (_g.target(e) == t) { alpar@100: const_cast(*this).splay(e); alpar@100: return e; alpar@100: } else if (t < _g.target(e)) { alpar@100: if (_left[e] == INVALID) { alpar@100: const_cast(*this).splay(e); alpar@100: return INVALID; alpar@100: } else { alpar@100: e = _left[e]; alpar@100: } alpar@100: } else { alpar@100: if (_right[e] == INVALID) { alpar@100: const_cast(*this).splay(e); alpar@100: return INVALID; alpar@100: } else { alpar@100: e = _right[e]; alpar@100: } alpar@100: } alpar@100: } alpar@100: } alpar@100: alpar@100: ///Find the first arc between two nodes. alpar@100: alpar@100: ///Find the first arc between two nodes in time alpar@100: /// O(logd), where d is the number of alpar@100: /// outgoing arcs of \c s. alpar@100: ///\param s The source node alpar@100: ///\param t The target node alpar@100: ///\return An arc from \c s to \c t if there exists, \ref INVALID alpar@100: /// otherwise. alpar@100: Arc findFirst(Node s, Node t) const alpar@100: { alpar@100: Arc e = _head[s]; alpar@100: Arc r = INVALID; alpar@100: while (true) { alpar@100: if (_g.target(e) < t) { alpar@100: if (_right[e] == INVALID) { alpar@100: const_cast(*this).splay(e); alpar@100: return r; alpar@100: } else { alpar@100: e = _right[e]; alpar@100: } alpar@100: } else { alpar@100: if (_g.target(e) == t) { alpar@100: r = e; alpar@100: } alpar@100: if (_left[e] == INVALID) { alpar@100: const_cast(*this).splay(e); alpar@100: return r; alpar@100: } else { alpar@100: e = _left[e]; alpar@100: } alpar@100: } alpar@100: } alpar@100: } alpar@100: alpar@100: ///Find the next arc between two nodes. alpar@100: alpar@100: ///Find the next arc between two nodes in time alpar@100: /// O(logd), where d is the number of alpar@100: /// outgoing arcs of \c s. alpar@100: ///\param s The source node alpar@100: ///\param t The target node alpar@100: ///\return An arc from \c s to \c t if there exists, \ref INVALID alpar@100: /// otherwise. alpar@100: alpar@100: ///\note If \c e is not the result of the previous \c findFirst() alpar@100: ///operation then the amorized time bound can not be guaranteed. alpar@100: #ifdef DOXYGEN alpar@100: Arc findNext(Node s, Node t, Arc e) const alpar@100: #else alpar@100: Arc findNext(Node, Node t, Arc e) const alpar@100: #endif alpar@100: { alpar@100: if (_right[e] != INVALID) { alpar@100: e = _right[e]; alpar@100: while (_left[e] != INVALID) { alpar@100: e = _left[e]; alpar@100: } alpar@100: const_cast(*this).splay(e); alpar@100: } else { alpar@100: while (_parent[e] != INVALID && _right[_parent[e]] == e) { alpar@100: e = _parent[e]; alpar@100: } alpar@100: if (_parent[e] == INVALID) { alpar@100: return INVALID; alpar@100: } else { alpar@100: e = _parent[e]; alpar@100: const_cast(*this).splay(e); alpar@100: } alpar@100: } alpar@100: if (_g.target(e) == t) return e; alpar@100: else return INVALID; alpar@100: } alpar@100: alpar@100: }; alpar@100: alpar@100: ///Fast arc look up between given endpoints. alpar@100: alpar@100: ///\ingroup gutils alpar@100: ///Using this class, you can find an arc in a digraph from a given alpar@100: ///source to a given target in time O(log d), alpar@100: ///where d is the out-degree of the source node. alpar@100: /// alpar@100: ///It is not possible to find \e all parallel arcs between two nodes. alpar@100: ///Use \ref AllArcLookUp for this purpose. alpar@100: /// alpar@100: ///\warning This class is static, so you should refresh() (or at least alpar@100: ///refresh(Node)) this data structure alpar@100: ///whenever the digraph changes. This is a time consuming (superlinearly alpar@100: ///proportional (O(mlogm)) to the number of arcs). alpar@100: /// alpar@100: ///\param G The type of the underlying digraph. alpar@100: /// alpar@100: ///\sa DynArcLookUp alpar@100: ///\sa AllArcLookUp alpar@100: template alpar@100: class ArcLookUp alpar@100: { alpar@100: public: alpar@100: GRAPH_TYPEDEFS(typename G); alpar@100: typedef G Digraph; alpar@100: alpar@100: protected: alpar@100: const Digraph &_g; alpar@100: typename Digraph::template NodeMap _head; alpar@100: typename Digraph::template ArcMap _left; alpar@100: typename Digraph::template ArcMap _right; alpar@100: alpar@100: class ArcLess { alpar@100: const Digraph &g; alpar@100: public: alpar@100: ArcLess(const Digraph &_g) : g(_g) {} alpar@100: bool operator()(Arc a,Arc b) const alpar@100: { alpar@100: return g.target(a) &v,int a,int b) alpar@100: { alpar@100: int m=(a+b)/2; alpar@100: Arc me=v[m]; alpar@100: _left[me] = aO(dlogd), where d is alpar@100: ///the number of the outgoing arcs of \c n. alpar@100: void refresh(Node n) alpar@100: { alpar@100: std::vector v; alpar@100: for(OutArcIt e(_g,n);e!=INVALID;++e) v.push_back(e); alpar@100: if(v.size()) { alpar@100: std::sort(v.begin(),v.end(),ArcLess(_g)); alpar@100: _head[n]=refreshRec(v,0,v.size()-1); alpar@100: } alpar@100: else _head[n]=INVALID; alpar@100: } alpar@100: ///Refresh the full data structure. alpar@100: alpar@100: ///Build up the full search database. In fact, it simply calls alpar@100: ///\ref refresh(Node) "refresh(n)" for each node \c n. alpar@100: /// alpar@100: ///It runs in time O(mlogD), where m is alpar@100: ///the number of the arcs of \c n and D is the maximum alpar@100: ///out-degree of the digraph. alpar@100: alpar@100: void refresh() alpar@100: { alpar@100: for(NodeIt n(_g);n!=INVALID;++n) refresh(n); alpar@100: } alpar@100: alpar@100: ///Find an arc between two nodes. alpar@100: alpar@100: ///Find an arc between two nodes in time O(logd), where alpar@100: /// d is the number of outgoing arcs of \c s. alpar@100: ///\param s The source node alpar@100: ///\param t The target node alpar@100: ///\return An arc from \c s to \c t if there exists, alpar@100: ///\ref INVALID otherwise. alpar@100: /// alpar@100: ///\warning If you change the digraph, refresh() must be called before using alpar@100: ///this operator. If you change the outgoing arcs of alpar@100: ///a single node \c n, then alpar@100: ///\ref refresh(Node) "refresh(n)" is enough. alpar@100: /// alpar@100: Arc operator()(Node s, Node t) const alpar@100: { alpar@100: Arc e; alpar@100: for(e=_head[s]; alpar@100: e!=INVALID&&_g.target(e)!=t; alpar@100: e = t < _g.target(e)?_left[e]:_right[e]) ; alpar@100: return e; alpar@100: } alpar@100: alpar@100: }; alpar@100: alpar@100: ///Fast look up of all arcs between given endpoints. alpar@100: alpar@100: ///\ingroup gutils alpar@100: ///This class is the same as \ref ArcLookUp, with the addition alpar@100: ///that it makes it possible to find all arcs between given endpoints. alpar@100: /// alpar@100: ///\warning This class is static, so you should refresh() (or at least alpar@100: ///refresh(Node)) this data structure alpar@100: ///whenever the digraph changes. This is a time consuming (superlinearly alpar@100: ///proportional (O(mlogm)) to the number of arcs). alpar@100: /// alpar@100: ///\param G The type of the underlying digraph. alpar@100: /// alpar@100: ///\sa DynArcLookUp alpar@100: ///\sa ArcLookUp alpar@100: template alpar@100: class AllArcLookUp : public ArcLookUp alpar@100: { alpar@100: using ArcLookUp::_g; alpar@100: using ArcLookUp::_right; alpar@100: using ArcLookUp::_left; alpar@100: using ArcLookUp::_head; alpar@100: alpar@100: GRAPH_TYPEDEFS(typename G); alpar@100: typedef G Digraph; alpar@100: alpar@100: typename Digraph::template ArcMap _next; alpar@100: alpar@100: Arc refreshNext(Arc head,Arc next=INVALID) alpar@100: { alpar@100: if(head==INVALID) return next; alpar@100: else { alpar@100: next=refreshNext(_right[head],next); alpar@100: // _next[head]=next; alpar@100: _next[head]=( next!=INVALID && _g.target(next)==_g.target(head)) alpar@100: ? next : INVALID; alpar@100: return refreshNext(_left[head],head); alpar@100: } alpar@100: } alpar@100: alpar@100: void refreshNext() alpar@100: { alpar@100: for(NodeIt n(_g);n!=INVALID;++n) refreshNext(_head[n]); alpar@100: } alpar@100: alpar@100: public: alpar@100: ///Constructor alpar@100: alpar@100: ///Constructor. alpar@100: /// alpar@100: ///It builds up the search database, which remains valid until the digraph alpar@100: ///changes. alpar@100: AllArcLookUp(const Digraph &g) : ArcLookUp(g), _next(g) {refreshNext();} alpar@100: alpar@100: ///Refresh the data structure at a node. alpar@100: alpar@100: ///Build up the search database of node \c n. alpar@100: /// alpar@100: ///It runs in time O(dlogd), where d is alpar@100: ///the number of the outgoing arcs of \c n. alpar@100: alpar@100: void refresh(Node n) alpar@100: { alpar@100: ArcLookUp::refresh(n); alpar@100: refreshNext(_head[n]); alpar@100: } alpar@100: alpar@100: ///Refresh the full data structure. alpar@100: alpar@100: ///Build up the full search database. In fact, it simply calls alpar@100: ///\ref refresh(Node) "refresh(n)" for each node \c n. alpar@100: /// alpar@100: ///It runs in time O(mlogD), where m is alpar@100: ///the number of the arcs of \c n and D is the maximum alpar@100: ///out-degree of the digraph. alpar@100: alpar@100: void refresh() alpar@100: { alpar@100: for(NodeIt n(_g);n!=INVALID;++n) refresh(_head[n]); alpar@100: } alpar@100: alpar@100: ///Find an arc between two nodes. alpar@100: alpar@100: ///Find an arc between two nodes. alpar@100: ///\param s The source node alpar@100: ///\param t The target node alpar@100: ///\param prev The previous arc between \c s and \c t. It it is INVALID or alpar@100: ///not given, the operator finds the first appropriate arc. alpar@100: ///\return An arc from \c s to \c t after \c prev or alpar@100: ///\ref INVALID if there is no more. alpar@100: /// alpar@100: ///For example, you can count the number of arcs from \c u to \c v in the alpar@100: ///following way. alpar@100: ///\code alpar@100: ///AllArcLookUp ae(g); alpar@100: ///... alpar@100: ///int n=0; alpar@100: ///for(Arc e=ae(u,v);e!=INVALID;e=ae(u,v,e)) n++; alpar@100: ///\endcode alpar@100: /// alpar@100: ///Finding the first arc take O(logd) time, where alpar@100: /// d is the number of outgoing arcs of \c s. Then, the alpar@100: ///consecutive arcs are found in constant time. alpar@100: /// alpar@100: ///\warning If you change the digraph, refresh() must be called before using alpar@100: ///this operator. If you change the outgoing arcs of alpar@100: ///a single node \c n, then alpar@100: ///\ref refresh(Node) "refresh(n)" is enough. alpar@100: /// alpar@100: #ifdef DOXYGEN alpar@100: Arc operator()(Node s, Node t, Arc prev=INVALID) const {} alpar@100: #else alpar@100: using ArcLookUp::operator() ; alpar@100: Arc operator()(Node s, Node t, Arc prev) const alpar@100: { alpar@100: return prev==INVALID?(*this)(s,t):_next[prev]; alpar@100: } alpar@100: #endif alpar@100: alpar@100: }; alpar@100: alpar@100: /// @} alpar@100: alpar@100: } //END OF NAMESPACE LEMON alpar@100: alpar@100: #endif