diff -r 03e4d2128efe -r f30867b359a8 lemon/graph_utils.h --- a/lemon/graph_utils.h Fri Nov 03 14:14:05 2006 +0000 +++ b/lemon/graph_utils.h Fri Nov 03 14:20:24 2006 +0000 @@ -615,6 +615,21 @@ const SourceMap& _map; }; + template + class ItemCopy : public MapCopyBase { + public: + + ItemCopy(It& it, const Item& item) : _it(it), _item(item) {} + + virtual void copy(const Graph&, const RefMap& refMap) { + _it = refMap[_item]; + } + + private: + It& _it; + Item _item; + }; + template class RefCopy : public MapCopyBase { public: @@ -650,6 +665,95 @@ CrossRef& _cmap; }; + template + struct GraphCopySelector { + template + static void copy(Graph &target, const Source& source, + NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { + for (typename Source::NodeIt it(source); it != INVALID; ++it) { + nodeRefMap[it] = target.addNode(); + } + for (typename Source::EdgeIt it(source); it != INVALID; ++it) { + edgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], + nodeRefMap[source.target(it)]); + } + } + }; + + template + struct GraphCopySelector< + Graph, + typename enable_if::type> + { + template + static void copy(Graph &target, const Source& source, + NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { + target.clone(source, nodeRefMap, edgeRefMap); + } + }; + + template + struct UGraphCopySelector { + template + static void copy(UGraph &target, const Source& source, + NodeRefMap& nodeRefMap, UEdgeRefMap& uEdgeRefMap) { + for (typename Source::NodeIt it(source); it != INVALID; ++it) { + nodeRefMap[it] = target.addNode(); + } + for (typename Source::UEdgeIt it(source); it != INVALID; ++it) { + uEdgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], + nodeRefMap[source.target(it)]); + } + } + }; + + template + struct UGraphCopySelector< + UGraph, + typename enable_if::type> + { + template + static void copy(UGraph &target, const Source& source, + NodeRefMap& nodeRefMap, UEdgeRefMap& uEdgeRefMap) { + target.clone(source, nodeRefMap, uEdgeRefMap); + } + }; + + template + struct BpUGraphCopySelector { + template + static void copy(BpUGraph &target, const Source& source, + ANodeRefMap& aNodeRefMap, BNodeRefMap& bNodeRefMap, + UEdgeRefMap& uEdgeRefMap) { + for (typename Source::ANodeIt it(source); it != INVALID; ++it) { + aNodeRefMap[it] = target.addANode(); + } + for (typename Source::BNodeIt it(source); it != INVALID; ++it) { + bNodeRefMap[it] = target.addBNode(); + } + for (typename Source::UEdgeIt it(source); it != INVALID; ++it) { + uEdgeRefMap[it] = target.addEdge(aNodeRefMap[source.aNode(it)], + bNodeRefMap[source.bNode(it)]); + } + } + }; + + template + struct BpUGraphCopySelector< + BpUGraph, + typename enable_if::type> + { + template + static void copy(BpUGraph &target, const Source& source, + ANodeRefMap& aNodeRefMap, BNodeRefMap& bNodeRefMap, + UEdgeRefMap& uEdgeRefMap) { + target.clone(source, aNodeRefMap, bNodeRefMap, uEdgeRefMap); + } + }; + + } /// \brief Class to copy a graph. @@ -705,9 +809,10 @@ return *this; } - /// \brief Reverse and copies the node references into the given map. + /// \brief Copies the node cross references into the given map. /// - /// Reverse and copies the node references into the given map. + /// Copies the node cross references (reverse references) into + /// the given map. template GraphCopy& nodeCrossRef(NodeCrossRef& map) { nodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(tnode, node)); + return *this; + } + /// \brief Copies the edge references into the given map. /// /// Copies the edge references into the given map. @@ -738,9 +852,10 @@ return *this; } - /// \brief Reverse and copies the edge references into the given map. + /// \brief Copies the edge cross references into the given map. /// - /// Reverse and copies the edge references into the given map. + /// Copies the edge cross references (reverse references) into + /// the given map. template GraphCopy& edgeCrossRef(EdgeCrossRef& map) { edgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(tedge, edge)); + return *this; + } + /// \brief Executes the copies. /// /// Executes the copies. void run() { NodeRefMap nodeRefMap(source); - for (NodeIt it(source); it != INVALID; ++it) { - nodeRefMap[it] = target.addNode(); - } + EdgeRefMap edgeRefMap(source); + _graph_utils_bits::GraphCopySelector:: + copy(target, source, nodeRefMap, edgeRefMap); for (int i = 0; i < (int)nodeMapCopies.size(); ++i) { nodeMapCopies[i]->copy(source, nodeRefMap); } - EdgeRefMap edgeRefMap(source); - for (EdgeIt it(source); it != INVALID; ++it) { - edgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], - nodeRefMap[source.target(it)]); - } for (int i = 0; i < (int)edgeMapCopies.size(); ++i) { edgeMapCopies[i]->copy(source, edgeRefMap); - } + } } - private: - + protected: + + const Source& source; Target& target; @@ -808,6 +928,8 @@ /// source graph's nodes to the target graph's nodes and the \c ecr will /// contain the mapping from the target graph's edges to the source's /// edges. + /// + /// \see GraphCopy template GraphCopy copyGraph(Target& target, const Source& source) { return GraphCopy(target, source); @@ -894,9 +1016,10 @@ return *this; } - /// \brief Reverse and copies the node references into the given map. + /// \brief Copies the node cross references into the given map. /// - /// Reverse and copies the node references into the given map. + /// Copies the node cross references (reverse references) into + /// the given map. template UGraphCopy& nodeCrossRef(NodeCrossRef& map) { nodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(tnode, node)); + return *this; + } + /// \brief Copies the edge references into the given map. /// /// Copies the edge references into the given map. @@ -927,9 +1059,10 @@ return *this; } - /// \brief Reverse and copies the edge references into the given map. + /// \brief Copies the edge cross references into the given map. /// - /// Reverse and copies the edge references into the given map. + /// Copies the edge cross references (reverse references) into + /// the given map. template UGraphCopy& edgeCrossRef(EdgeCrossRef& map) { edgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(tedge, edge)); + return *this; + } + + /// \brief Copies the undirected edge references into the given map. + /// + /// Copies the undirected edge references into the given map. template UGraphCopy& uEdgeRef(UEdgeRef& map) { uEdgeMapCopies.push_back(new _graph_utils_bits::RefCopy UGraphCopy& uEdgeCrossRef(UEdgeCrossRef& map) { uEdgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy UGraphCopy& uEdgeMap(TargetMap& tmap, const SourceMap& map) { @@ -983,23 +1126,27 @@ return *this; } + /// \brief Make a copy of the given undirected edge. + /// + /// Make a copy of the given undirected edge. + UGraphCopy& uEdge(TUEdge& tuedge, const UEdge& uedge) { + uEdgeMapCopies.push_back(new _graph_utils_bits::ItemCopy(tuedge, uedge)); + return *this; + } + /// \brief Executes the copies. /// /// Executes the copies. void run() { NodeRefMap nodeRefMap(source); - for (NodeIt it(source); it != INVALID; ++it) { - nodeRefMap[it] = target.addNode(); - } + UEdgeRefMap uEdgeRefMap(source); + EdgeRefMap edgeRefMap(target, source, uEdgeRefMap, nodeRefMap); + _graph_utils_bits::UGraphCopySelector:: + copy(target, source, nodeRefMap, uEdgeRefMap); for (int i = 0; i < (int)nodeMapCopies.size(); ++i) { nodeMapCopies[i]->copy(source, nodeRefMap); } - UEdgeRefMap uEdgeRefMap(source); - EdgeRefMap edgeRefMap(target, source, uEdgeRefMap, nodeRefMap); - for (UEdgeIt it(source); it != INVALID; ++it) { - uEdgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], - nodeRefMap[source.target(it)]); - } for (int i = 0; i < (int)uEdgeMapCopies.size(); ++i) { uEdgeMapCopies[i]->copy(source, uEdgeRefMap); } @@ -1024,9 +1171,9 @@ }; - /// \brief Copy a graph to another graph. + /// \brief Copy an undirected graph to another graph. /// - /// Copy a graph to another graph. + /// Copy an undirected graph to another graph. /// The usage of the function: /// ///\code @@ -1037,12 +1184,378 @@ /// source graph's nodes to the target graph's nodes and the \c ecr will /// contain the mapping from the target graph's edges to the source's /// edges. + /// + /// \see UGraphCopy template UGraphCopy copyUGraph(Target& target, const Source& source) { return UGraphCopy(target, source); } + /// \brief Class to copy a bipartite undirected graph. + /// + /// Class to copy a bipartite undirected graph to another graph + /// (duplicate a graph). The simplest way of using it is through + /// the \c copyBpUGraph() function. + template + class BpUGraphCopy { + private: + + typedef typename Source::Node Node; + typedef typename Source::ANode ANode; + typedef typename Source::BNode BNode; + typedef typename Source::NodeIt NodeIt; + typedef typename Source::Edge Edge; + typedef typename Source::EdgeIt EdgeIt; + typedef typename Source::UEdge UEdge; + typedef typename Source::UEdgeIt UEdgeIt; + + typedef typename Target::Node TNode; + typedef typename Target::Edge TEdge; + typedef typename Target::UEdge TUEdge; + + typedef typename Source::template ANodeMap ANodeRefMap; + typedef typename Source::template BNodeMap BNodeRefMap; + typedef typename Source::template UEdgeMap UEdgeRefMap; + + struct NodeRefMap { + NodeRefMap(const Source& _source, const ANodeRefMap& _anode_ref, + const BNodeRefMap& _bnode_ref) + : source(_source), anode_ref(_anode_ref), bnode_ref(_bnode_ref) {} + + typedef typename Source::Node Key; + typedef typename Target::Node Value; + + Value operator[](const Key& key) const { + return source.aNode(key) ? anode_ref[key] : bnode_ref[key]; + } + + const Source& source; + const ANodeRefMap& anode_ref; + const BNodeRefMap& bnode_ref; + }; + + struct EdgeRefMap { + EdgeRefMap(const Target& _target, const Source& _source, + const UEdgeRefMap& _uedge_ref, const NodeRefMap& _node_ref) + : target(_target), source(_source), + uedge_ref(_uedge_ref), node_ref(_node_ref) {} + + typedef typename Source::Edge Key; + typedef typename Target::Edge Value; + + Value operator[](const Key& key) const { + bool forward = (source.direction(key) == + (node_ref[source.source((UEdge)key)] == + target.source(uedge_ref[(UEdge)key]))); + return target.direct(uedge_ref[key], forward); + } + + const Target& target; + const Source& source; + const UEdgeRefMap& uedge_ref; + const NodeRefMap& node_ref; + }; + + public: + + + /// \brief Constructor for the GraphCopy. + /// + /// It copies the content of the \c _source graph into the + /// \c _target graph. + BpUGraphCopy(Target& _target, const Source& _source) + : source(_source), target(_target) {} + + /// \brief Destructor of the GraphCopy + /// + /// Destructor of the GraphCopy + ~BpUGraphCopy() { + for (int i = 0; i < (int)aNodeMapCopies.size(); ++i) { + delete aNodeMapCopies[i]; + } + for (int i = 0; i < (int)bNodeMapCopies.size(); ++i) { + delete bNodeMapCopies[i]; + } + for (int i = 0; i < (int)nodeMapCopies.size(); ++i) { + delete nodeMapCopies[i]; + } + for (int i = 0; i < (int)edgeMapCopies.size(); ++i) { + delete edgeMapCopies[i]; + } + for (int i = 0; i < (int)uEdgeMapCopies.size(); ++i) { + delete uEdgeMapCopies[i]; + } + + } + + /// \brief Copies the A-node references into the given map. + /// + /// Copies the A-node references into the given map. + template + BpUGraphCopy& aNodeRef(ANodeRef& map) { + aNodeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); + return *this; + } + + /// \brief Copies the A-node cross references into the given map. + /// + /// Copies the A-node cross references (reverse references) into + /// the given map. + template + BpUGraphCopy& aNodeCrossRef(ANodeCrossRef& map) { + aNodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make copy of the given A-node map. + /// + /// Makes copy of the given map for the newly created graph. + /// The new map's key type is the target graph's node type, + /// and the copied map's key type is the source graph's node + /// type. + template + BpUGraphCopy& aNodeMap(TargetMap& tmap, const SourceMap& map) { + aNodeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); + return *this; + } + + /// \brief Copies the B-node references into the given map. + /// + /// Copies the B-node references into the given map. + template + BpUGraphCopy& bNodeRef(BNodeRef& map) { + bNodeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); + return *this; + } + + /// \brief Copies the B-node cross references into the given map. + /// + /// Copies the B-node cross references (reverse references) into + /// the given map. + template + BpUGraphCopy& bNodeCrossRef(BNodeCrossRef& map) { + bNodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make copy of the given B-node map. + /// + /// Makes copy of the given map for the newly created graph. + /// The new map's key type is the target graph's node type, + /// and the copied map's key type is the source graph's node + /// type. + template + BpUGraphCopy& bNodeMap(TargetMap& tmap, const SourceMap& map) { + bNodeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); + return *this; + } + /// \brief Copies the node references into the given map. + /// + /// Copies the node references into the given map. + template + BpUGraphCopy& nodeRef(NodeRef& map) { + nodeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); + return *this; + } + + /// \brief Copies the node cross references into the given map. + /// + /// Copies the node cross references (reverse references) into + /// the given map. + template + BpUGraphCopy& nodeCrossRef(NodeCrossRef& map) { + nodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make copy of the given map. + /// + /// Makes copy of the given map for the newly created graph. + /// The new map's key type is the target graph's node type, + /// and the copied map's key type is the source graph's node + /// type. + template + BpUGraphCopy& nodeMap(TargetMap& tmap, const SourceMap& map) { + nodeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); + return *this; + } + + /// \brief Make a copy of the given node. + /// + /// Make a copy of the given node. + BpUGraphCopy& node(TNode& tnode, const Node& node) { + nodeMapCopies.push_back(new _graph_utils_bits::ItemCopy(tnode, node)); + return *this; + } + + /// \brief Copies the edge references into the given map. + /// + /// Copies the edge references into the given map. + template + BpUGraphCopy& edgeRef(EdgeRef& map) { + edgeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); + return *this; + } + + /// \brief Copies the edge cross references into the given map. + /// + /// Copies the edge cross references (reverse references) into + /// the given map. + template + BpUGraphCopy& edgeCrossRef(EdgeCrossRef& map) { + edgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make copy of the given map. + /// + /// Makes copy of the given map for the newly created graph. + /// The new map's key type is the target graph's edge type, + /// and the copied map's key type is the source graph's edge + /// type. + template + BpUGraphCopy& edgeMap(TargetMap& tmap, const SourceMap& map) { + edgeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); + return *this; + } + + /// \brief Make a copy of the given edge. + /// + /// Make a copy of the given edge. + BpUGraphCopy& edge(TEdge& tedge, const Edge& edge) { + edgeMapCopies.push_back(new _graph_utils_bits::ItemCopy(tedge, edge)); + return *this; + } + + /// \brief Copies the undirected edge references into the given map. + /// + /// Copies the undirected edge references into the given map. + template + BpUGraphCopy& uEdgeRef(UEdgeRef& map) { + uEdgeMapCopies.push_back(new _graph_utils_bits::RefCopy(map)); + return *this; + } + + /// \brief Copies the undirected edge cross references into the given map. + /// + /// Copies the undirected edge cross references (reverse + /// references) into the given map. + template + BpUGraphCopy& uEdgeCrossRef(UEdgeCrossRef& map) { + uEdgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make copy of the given map. + /// + /// Makes copy of the given map for the newly created graph. + /// The new map's key type is the target graph's undirected edge type, + /// and the copied map's key type is the source graph's undirected edge + /// type. + template + BpUGraphCopy& uEdgeMap(TargetMap& tmap, const SourceMap& map) { + uEdgeMapCopies.push_back(new _graph_utils_bits::MapCopy(tmap, map)); + return *this; + } + + /// \brief Make a copy of the given undirected edge. + /// + /// Make a copy of the given undirected edge. + BpUGraphCopy& uEdge(TUEdge& tuedge, const UEdge& uedge) { + uEdgeMapCopies.push_back(new _graph_utils_bits::ItemCopy(tuedge, uedge)); + return *this; + } + + /// \brief Executes the copies. + /// + /// Executes the copies. + void run() { + ANodeRefMap aNodeRefMap(source); + BNodeRefMap bNodeRefMap(source); + NodeRefMap nodeRefMap(source, aNodeRefMap, bNodeRefMap); + UEdgeRefMap uEdgeRefMap(source); + EdgeRefMap edgeRefMap(target, source, uEdgeRefMap, nodeRefMap); + _graph_utils_bits::BpUGraphCopySelector:: + copy(target, source, aNodeRefMap, bNodeRefMap, uEdgeRefMap); + for (int i = 0; i < (int)aNodeMapCopies.size(); ++i) { + aNodeMapCopies[i]->copy(source, aNodeRefMap); + } + for (int i = 0; i < (int)bNodeMapCopies.size(); ++i) { + bNodeMapCopies[i]->copy(source, bNodeRefMap); + } + for (int i = 0; i < (int)nodeMapCopies.size(); ++i) { + nodeMapCopies[i]->copy(source, nodeRefMap); + } + for (int i = 0; i < (int)uEdgeMapCopies.size(); ++i) { + uEdgeMapCopies[i]->copy(source, uEdgeRefMap); + } + for (int i = 0; i < (int)edgeMapCopies.size(); ++i) { + edgeMapCopies[i]->copy(source, edgeRefMap); + } + } + + private: + + const Source& source; + Target& target; + + std::vector<_graph_utils_bits::MapCopyBase* > + aNodeMapCopies; + + std::vector<_graph_utils_bits::MapCopyBase* > + bNodeMapCopies; + + std::vector<_graph_utils_bits::MapCopyBase* > + nodeMapCopies; + + std::vector<_graph_utils_bits::MapCopyBase* > + edgeMapCopies; + + std::vector<_graph_utils_bits::MapCopyBase* > + uEdgeMapCopies; + + }; + + /// \brief Copy a bipartite undirected graph to another graph. + /// + /// Copy a bipartite undirected graph to another graph. + /// The usage of the function: + /// + ///\code + /// copyBpUGraph(trg, src).aNodeRef(anr).edgeCrossRef(ecr).run(); + ///\endcode + /// + /// After the copy the \c nr map will contain the mapping from the + /// source graph's nodes to the target graph's nodes and the \c ecr will + /// contain the mapping from the target graph's edges to the source's + /// edges. + /// + /// \see BpUGraphCopy + template + BpUGraphCopy + copyBpUGraph(Target& target, const Source& source) { + return BpUGraphCopy(target, source); + } + /// @}