diff -r cd72eae05bdf -r 3c00344f49c9 lemon/core.h --- a/lemon/core.h Mon Jul 16 16:21:40 2018 +0200 +++ b/lemon/core.h Wed Oct 17 19:14:07 2018 +0200 @@ -2,7 +2,7 @@ * * This file is a part of LEMON, a generic C++ optimization library. * - * Copyright (C) 2003-2010 + * Copyright (C) 2003-2013 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Research Group on Combinatorial Optimization, EGRES). * @@ -19,6 +19,29 @@ #ifndef LEMON_CORE_H #define LEMON_CORE_H +///\file +///\brief LEMON core utilities. +/// +///This header file contains core utilities for LEMON. +///It is automatically included by all graph types, therefore it usually +///do not have to be included directly. + +// Disable the following warnings when compiling with MSVC: +// C4250: 'class1' : inherits 'class2::member' via dominance +// C4267: conversion from 'size_t' to 'type', possible loss of data +// C4355: 'this' : used in base member initializer list +// C4503: 'function' : decorated name length exceeded, name was truncated +// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning) +// C4996: 'function': was declared deprecated +#ifdef _MSC_VER +#pragma warning( disable : 4250 4267 4355 4503 4800 4996 ) +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) +// Needed by the [DI]GRAPH_TYPEDEFS marcos for gcc 4.8 +#pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#endif + #include #include @@ -27,22 +50,7 @@ #include #include -// Disable the following warnings when compiling with MSVC: -// C4250: 'class1' : inherits 'class2::member' via dominance -// C4355: 'this' : used in base member initializer list -// C4503: 'function' : decorated name length exceeded, name was truncated -// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning) -// C4996: 'function': was declared deprecated -#ifdef _MSC_VER -#pragma warning( disable : 4250 4355 4503 4800 4996 ) -#endif -///\file -///\brief LEMON core utilities. -/// -///This header file contains core utilities for LEMON. -///It is automatically included by all graph types, therefore it usually -///do not have to be included directly. namespace lemon { @@ -148,6 +156,49 @@ typedef typename Graph::template EdgeMap IntEdgeMap; \ typedef typename Graph::template EdgeMap DoubleEdgeMap + ///Create convenience typedefs for the bipartite graph types and iterators + + ///This \c \#define creates the same convenient type definitions as + ///defined by \ref GRAPH_TYPEDEFS(BpGraph) and ten more, namely it + ///creates \c RedNode, \c RedNodeIt, \c BoolRedNodeMap, + ///\c IntRedNodeMap, \c DoubleRedNodeMap, \c BlueNode, \c BlueNodeIt, + ///\c BoolBlueNodeMap, \c IntBlueNodeMap, \c DoubleBlueNodeMap. + /// + ///\note If the graph type is a dependent type, ie. the graph type depend + ///on a template parameter, then use \c TEMPLATE_BPGRAPH_TYPEDEFS() + ///macro. +#define BPGRAPH_TYPEDEFS(BpGraph) \ + GRAPH_TYPEDEFS(BpGraph); \ + typedef BpGraph::RedNode RedNode; \ + typedef BpGraph::RedNodeIt RedNodeIt; \ + typedef BpGraph::RedNodeMap BoolRedNodeMap; \ + typedef BpGraph::RedNodeMap IntRedNodeMap; \ + typedef BpGraph::RedNodeMap DoubleRedNodeMap; \ + typedef BpGraph::BlueNode BlueNode; \ + typedef BpGraph::BlueNodeIt BlueNodeIt; \ + typedef BpGraph::BlueNodeMap BoolBlueNodeMap; \ + typedef BpGraph::BlueNodeMap IntBlueNodeMap; \ + typedef BpGraph::BlueNodeMap DoubleBlueNodeMap + + ///Create convenience typedefs for the bipartite graph types and iterators + + ///\see BPGRAPH_TYPEDEFS + /// + ///\note Use this macro, if the graph type is a dependent type, + ///ie. the graph type depend on a template parameter. +#define TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph) \ + TEMPLATE_GRAPH_TYPEDEFS(BpGraph); \ + typedef typename BpGraph::RedNode RedNode; \ + typedef typename BpGraph::RedNodeIt RedNodeIt; \ + typedef typename BpGraph::template RedNodeMap BoolRedNodeMap; \ + typedef typename BpGraph::template RedNodeMap IntRedNodeMap; \ + typedef typename BpGraph::template RedNodeMap DoubleRedNodeMap; \ + typedef typename BpGraph::BlueNode BlueNode; \ + typedef typename BpGraph::BlueNodeIt BlueNodeIt; \ + typedef typename BpGraph::template BlueNodeMap BoolBlueNodeMap; \ + typedef typename BpGraph::template BlueNodeMap IntBlueNodeMap; \ + typedef typename BpGraph::template BlueNodeMap DoubleBlueNodeMap + /// \brief Function to count the items in a graph. /// /// This function counts the items (nodes, arcs etc.) in a graph. @@ -199,6 +250,74 @@ return _core_bits::CountNodesSelector::count(g); } + namespace _graph_utils_bits { + + template + struct CountRedNodesSelector { + static int count(const Graph &g) { + return countItems(g); + } + }; + + template + struct CountRedNodesSelector< + Graph, typename + enable_if::type> + { + static int count(const Graph &g) { + return g.redNum(); + } + }; + } + + /// \brief Function to count the red nodes in the graph. + /// + /// This function counts the red nodes in the graph. + /// The complexity of the function is O(n) but for some + /// graph structures it is specialized to run in O(1). + /// + /// If the graph contains a \e redNum() member function and a + /// \e NodeNumTag tag then this function calls directly the member + /// function to query the cardinality of the node set. + template + inline int countRedNodes(const Graph& g) { + return _graph_utils_bits::CountRedNodesSelector::count(g); + } + + namespace _graph_utils_bits { + + template + struct CountBlueNodesSelector { + static int count(const Graph &g) { + return countItems(g); + } + }; + + template + struct CountBlueNodesSelector< + Graph, typename + enable_if::type> + { + static int count(const Graph &g) { + return g.blueNum(); + } + }; + } + + /// \brief Function to count the blue nodes in the graph. + /// + /// This function counts the blue nodes in the graph. + /// The complexity of the function is O(n) but for some + /// graph structures it is specialized to run in O(1). + /// + /// If the graph contains a \e blueNum() member function and a + /// \e NodeNumTag tag then this function calls directly the member + /// function to query the cardinality of the node set. + template + inline int countBlueNodes(const Graph& g) { + return _graph_utils_bits::CountBlueNodesSelector::count(g); + } + // Arc counting: namespace _core_bits { @@ -440,13 +559,70 @@ { template static void copy(const From& from, Graph &to, - NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) { + NodeRefMap& nodeRefMap, + EdgeRefMap& edgeRefMap) { to.build(from, nodeRefMap, edgeRefMap); } }; + template + struct BpGraphCopySelector { + template + static void copy(const From& from, BpGraph &to, + RedNodeRefMap& redNodeRefMap, + BlueNodeRefMap& blueNodeRefMap, + EdgeRefMap& edgeRefMap) { + to.clear(); + for (typename From::RedNodeIt it(from); it != INVALID; ++it) { + redNodeRefMap[it] = to.addRedNode(); + } + for (typename From::BlueNodeIt it(from); it != INVALID; ++it) { + blueNodeRefMap[it] = to.addBlueNode(); + } + for (typename From::EdgeIt it(from); it != INVALID; ++it) { + edgeRefMap[it] = to.addEdge(redNodeRefMap[from.redNode(it)], + blueNodeRefMap[from.blueNode(it)]); + } + } + }; + + template + struct BpGraphCopySelector< + BpGraph, + typename enable_if::type> + { + template + static void copy(const From& from, BpGraph &to, + RedNodeRefMap& redNodeRefMap, + BlueNodeRefMap& blueNodeRefMap, + EdgeRefMap& edgeRefMap) { + to.build(from, redNodeRefMap, blueNodeRefMap, edgeRefMap); + } + }; + } + /// \brief Check whether a graph is undirected. + /// + /// This function returns \c true if the given graph is undirected. +#ifdef DOXYGEN + template + bool undirected(const GR& g) { return false; } +#else + template + typename enable_if, bool>::type + undirected(const GR&) { + return true; + } + template + typename disable_if, bool>::type + undirected(const GR&) { + return false; + } +#endif + /// \brief Class to copy a digraph. /// /// Class to copy a digraph to another digraph (duplicate a digraph). The @@ -972,6 +1148,454 @@ return GraphCopy(from, to); } + /// \brief Class to copy a bipartite graph. + /// + /// Class to copy a bipartite graph to another graph (duplicate a + /// graph). The simplest way of using it is through the + /// \c bpGraphCopy() function. + /// + /// This class not only make a copy of a bipartite graph, but it can + /// create references and cross references between the nodes, edges + /// and arcs of the two graphs, and it can copy maps for using with + /// the newly created graph. + /// + /// To make a copy from a graph, first an instance of BpGraphCopy + /// should be created, then the data belongs to the graph should + /// assigned to copy. In the end, the \c run() member should be + /// called. + /// + /// The next code copies a graph with several data: + ///\code + /// BpGraphCopy cg(orig_graph, new_graph); + /// // Create references for the nodes + /// OrigBpGraph::NodeMap nr(orig_graph); + /// cg.nodeRef(nr); + /// // Create cross references (inverse) for the edges + /// NewBpGraph::EdgeMap ecr(new_graph); + /// cg.edgeCrossRef(ecr); + /// // Copy a red node map + /// OrigBpGraph::RedNodeMap ormap(orig_graph); + /// NewBpGraph::RedNodeMap nrmap(new_graph); + /// cg.redNodeMap(ormap, nrmap); + /// // Copy a node + /// OrigBpGraph::Node on; + /// NewBpGraph::Node nn; + /// cg.node(on, nn); + /// // Execute copying + /// cg.run(); + ///\endcode + template + class BpGraphCopy { + private: + + typedef typename From::Node Node; + typedef typename From::RedNode RedNode; + typedef typename From::BlueNode BlueNode; + typedef typename From::NodeIt NodeIt; + typedef typename From::Arc Arc; + typedef typename From::ArcIt ArcIt; + typedef typename From::Edge Edge; + typedef typename From::EdgeIt EdgeIt; + + typedef typename To::Node TNode; + typedef typename To::RedNode TRedNode; + typedef typename To::BlueNode TBlueNode; + typedef typename To::Arc TArc; + typedef typename To::Edge TEdge; + + typedef typename From::template RedNodeMap RedNodeRefMap; + typedef typename From::template BlueNodeMap BlueNodeRefMap; + typedef typename From::template EdgeMap EdgeRefMap; + + struct NodeRefMap { + NodeRefMap(const From& from, const RedNodeRefMap& red_node_ref, + const BlueNodeRefMap& blue_node_ref) + : _from(from), _red_node_ref(red_node_ref), + _blue_node_ref(blue_node_ref) {} + + typedef typename From::Node Key; + typedef typename To::Node Value; + + Value operator[](const Key& key) const { + if (_from.red(key)) { + return _red_node_ref[_from.asRedNodeUnsafe(key)]; + } else { + return _blue_node_ref[_from.asBlueNodeUnsafe(key)]; + } + } + + const From& _from; + const RedNodeRefMap& _red_node_ref; + const BlueNodeRefMap& _blue_node_ref; + }; + + struct ArcRefMap { + ArcRefMap(const From& from, const To& to, const EdgeRefMap& edge_ref) + : _from(from), _to(to), _edge_ref(edge_ref) {} + + typedef typename From::Arc Key; + typedef typename To::Arc Value; + + Value operator[](const Key& key) const { + return _to.direct(_edge_ref[key], _from.direction(key)); + } + + const From& _from; + const To& _to; + const EdgeRefMap& _edge_ref; + }; + + public: + + /// \brief Constructor of BpGraphCopy. + /// + /// Constructor of BpGraphCopy for copying the content of the + /// \c from graph into the \c to graph. + BpGraphCopy(const From& from, To& to) + : _from(from), _to(to) {} + + /// \brief Destructor of BpGraphCopy + /// + /// Destructor of BpGraphCopy. + ~BpGraphCopy() { + for (int i = 0; i < int(_node_maps.size()); ++i) { + delete _node_maps[i]; + } + for (int i = 0; i < int(_red_maps.size()); ++i) { + delete _red_maps[i]; + } + for (int i = 0; i < int(_blue_maps.size()); ++i) { + delete _blue_maps[i]; + } + for (int i = 0; i < int(_arc_maps.size()); ++i) { + delete _arc_maps[i]; + } + for (int i = 0; i < int(_edge_maps.size()); ++i) { + delete _edge_maps[i]; + } + } + + /// \brief Copy the node references into the given map. + /// + /// This function copies the node references into the given map. + /// The parameter should be a map, whose key type is the Node type of + /// the source graph, while the value type is the Node type of the + /// destination graph. + template + BpGraphCopy& nodeRef(NodeRef& map) { + _node_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the node cross references into the given map. + /// + /// This function copies the node cross references (reverse references) + /// into the given map. The parameter should be a map, whose key type + /// is the Node type of the destination graph, while the value type is + /// the Node type of the source graph. + template + BpGraphCopy& nodeCrossRef(NodeCrossRef& map) { + _node_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given node map. + /// + /// This function makes a copy of the given node map for the newly + /// created graph. + /// The key type of the new map \c tmap should be the Node type of the + /// destination graph, and the key type of the original map \c map + /// should be the Node type of the source graph. + template + BpGraphCopy& nodeMap(const FromMap& map, ToMap& tmap) { + _node_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given node. + /// + /// This function makes a copy of the given node. + BpGraphCopy& node(const Node& node, TNode& tnode) { + _node_maps.push_back(new _core_bits::ItemCopy(node, tnode)); + return *this; + } + + /// \brief Copy the red node references into the given map. + /// + /// This function copies the red node references into the given + /// map. The parameter should be a map, whose key type is the + /// Node type of the source graph with the red item set, while the + /// value type is the Node type of the destination graph. + template + BpGraphCopy& redRef(RedRef& map) { + _red_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the red node cross references into the given map. + /// + /// This function copies the red node cross references (reverse + /// references) into the given map. The parameter should be a map, + /// whose key type is the Node type of the destination graph with + /// the red item set, while the value type is the Node type of the + /// source graph. + template + BpGraphCopy& redCrossRef(RedCrossRef& map) { + _red_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given red node map. + /// + /// This function makes a copy of the given red node map for the newly + /// created graph. + /// The key type of the new map \c tmap should be the Node type of + /// the destination graph with the red items, and the key type of + /// the original map \c map should be the Node type of the source + /// graph. + template + BpGraphCopy& redNodeMap(const FromMap& map, ToMap& tmap) { + _red_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given red node. + /// + /// This function makes a copy of the given red node. + BpGraphCopy& redNode(const RedNode& node, TRedNode& tnode) { + _red_maps.push_back(new _core_bits::ItemCopy(node, tnode)); + return *this; + } + + /// \brief Copy the blue node references into the given map. + /// + /// This function copies the blue node references into the given + /// map. The parameter should be a map, whose key type is the + /// Node type of the source graph with the blue item set, while the + /// value type is the Node type of the destination graph. + template + BpGraphCopy& blueRef(BlueRef& map) { + _blue_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the blue node cross references into the given map. + /// + /// This function copies the blue node cross references (reverse + /// references) into the given map. The parameter should be a map, + /// whose key type is the Node type of the destination graph with + /// the blue item set, while the value type is the Node type of the + /// source graph. + template + BpGraphCopy& blueCrossRef(BlueCrossRef& map) { + _blue_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given blue node map. + /// + /// This function makes a copy of the given blue node map for the newly + /// created graph. + /// The key type of the new map \c tmap should be the Node type of + /// the destination graph with the blue items, and the key type of + /// the original map \c map should be the Node type of the source + /// graph. + template + BpGraphCopy& blueNodeMap(const FromMap& map, ToMap& tmap) { + _blue_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given blue node. + /// + /// This function makes a copy of the given blue node. + BpGraphCopy& blueNode(const BlueNode& node, TBlueNode& tnode) { + _blue_maps.push_back(new _core_bits::ItemCopy(node, tnode)); + return *this; + } + + /// \brief Copy the arc references into the given map. + /// + /// This function copies the arc references into the given map. + /// The parameter should be a map, whose key type is the Arc type of + /// the source graph, while the value type is the Arc type of the + /// destination graph. + template + BpGraphCopy& arcRef(ArcRef& map) { + _arc_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the arc cross references into the given map. + /// + /// This function copies the arc cross references (reverse references) + /// into the given map. The parameter should be a map, whose key type + /// is the Arc type of the destination graph, while the value type is + /// the Arc type of the source graph. + template + BpGraphCopy& arcCrossRef(ArcCrossRef& map) { + _arc_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given arc map. + /// + /// This function makes a copy of the given arc map for the newly + /// created graph. + /// The key type of the new map \c tmap should be the Arc type of the + /// destination graph, and the key type of the original map \c map + /// should be the Arc type of the source graph. + template + BpGraphCopy& arcMap(const FromMap& map, ToMap& tmap) { + _arc_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given arc. + /// + /// This function makes a copy of the given arc. + BpGraphCopy& arc(const Arc& arc, TArc& tarc) { + _arc_maps.push_back(new _core_bits::ItemCopy(arc, tarc)); + return *this; + } + + /// \brief Copy the edge references into the given map. + /// + /// This function copies the edge references into the given map. + /// The parameter should be a map, whose key type is the Edge type of + /// the source graph, while the value type is the Edge type of the + /// destination graph. + template + BpGraphCopy& edgeRef(EdgeRef& map) { + _edge_maps.push_back(new _core_bits::RefCopy(map)); + return *this; + } + + /// \brief Copy the edge cross references into the given map. + /// + /// This function copies the edge cross references (reverse references) + /// into the given map. The parameter should be a map, whose key type + /// is the Edge type of the destination graph, while the value type is + /// the Edge type of the source graph. + template + BpGraphCopy& edgeCrossRef(EdgeCrossRef& map) { + _edge_maps.push_back(new _core_bits::CrossRefCopy(map)); + return *this; + } + + /// \brief Make a copy of the given edge map. + /// + /// This function makes a copy of the given edge map for the newly + /// created graph. + /// The key type of the new map \c tmap should be the Edge type of the + /// destination graph, and the key type of the original map \c map + /// should be the Edge type of the source graph. + template + BpGraphCopy& edgeMap(const FromMap& map, ToMap& tmap) { + _edge_maps.push_back(new _core_bits::MapCopy(map, tmap)); + return *this; + } + + /// \brief Make a copy of the given edge. + /// + /// This function makes a copy of the given edge. + BpGraphCopy& edge(const Edge& edge, TEdge& tedge) { + _edge_maps.push_back(new _core_bits::ItemCopy(edge, tedge)); + return *this; + } + + /// \brief Execute copying. + /// + /// This function executes the copying of the graph along with the + /// copying of the assigned data. + void run() { + RedNodeRefMap redNodeRefMap(_from); + BlueNodeRefMap blueNodeRefMap(_from); + NodeRefMap nodeRefMap(_from, redNodeRefMap, blueNodeRefMap); + EdgeRefMap edgeRefMap(_from); + ArcRefMap arcRefMap(_from, _to, edgeRefMap); + _core_bits::BpGraphCopySelector:: + copy(_from, _to, redNodeRefMap, blueNodeRefMap, edgeRefMap); + for (int i = 0; i < int(_node_maps.size()); ++i) { + _node_maps[i]->copy(_from, nodeRefMap); + } + for (int i = 0; i < int(_red_maps.size()); ++i) { + _red_maps[i]->copy(_from, redNodeRefMap); + } + for (int i = 0; i < int(_blue_maps.size()); ++i) { + _blue_maps[i]->copy(_from, blueNodeRefMap); + } + for (int i = 0; i < int(_edge_maps.size()); ++i) { + _edge_maps[i]->copy(_from, edgeRefMap); + } + for (int i = 0; i < int(_arc_maps.size()); ++i) { + _arc_maps[i]->copy(_from, arcRefMap); + } + } + + private: + + const From& _from; + To& _to; + + std::vector<_core_bits::MapCopyBase* > + _node_maps; + + std::vector<_core_bits::MapCopyBase* > + _red_maps; + + std::vector<_core_bits::MapCopyBase* > + _blue_maps; + + std::vector<_core_bits::MapCopyBase* > + _arc_maps; + + std::vector<_core_bits::MapCopyBase* > + _edge_maps; + + }; + + /// \brief Copy a graph to another graph. + /// + /// This function copies a graph to another graph. + /// The complete usage of it is detailed in the BpGraphCopy class, + /// but a short example shows a basic work: + ///\code + /// graphCopy(src, trg).nodeRef(nr).edgeCrossRef(ecr).run(); + ///\endcode + /// + /// After the copy the \c nr map will contain the mapping from the + /// nodes of the \c from graph to the nodes of the \c to graph and + /// \c ecr will contain the mapping from the edges of the \c to graph + /// to the edges of the \c from graph. + /// + /// \see BpGraphCopy + template + BpGraphCopy + bpGraphCopy(const From& from, To& to) { + return BpGraphCopy(from, to); + } + namespace _core_bits { template