diff -r d8475431bbbb -r 8e85e6bbefdf lemon/graph_utils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/graph_utils.h Mon May 23 04:48:14 2005 +0000 @@ -0,0 +1,861 @@ +/* -*- C++ -*- + * lemon/graph_utils.h - Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_GRAPH_UTILS_H +#define LEMON_GRAPH_UTILS_H + +#include +#include +#include + +#include +#include +#include + +///\ingroup gutils +///\file +///\brief Graph utilities. +/// +///\todo Please +///revise the documentation. +/// + + +namespace lemon { + + /// \addtogroup gutils + /// @{ + + /// \brief Function to count the items in the graph. + /// + /// This function counts the items in the graph. + /// The complexity of the function is O(n) because + /// it iterates on all of the items. + + template + inline int countItems(const Graph& g) { + int num = 0; + for (ItemIt it(g); it != INVALID; ++it) { + ++num; + } + return num; + } + + // Node counting: + + template + inline + typename enable_if::type + _countNodes(const Graph &g) { + return g.nodeNum(); + } + + template + inline int _countNodes(Wrap w) { + return countItems(w.value); + } + + /// \brief Function to count the nodes in the graph. + /// + /// This function counts the nodes in the graph. + /// The complexity of the function is O(n) but for some + /// graph structure it is specialized to run in O(1). + /// + /// \todo refer how to specialize it + + template + inline int countNodes(const Graph& g) { + return _countNodes(g); + } + + // Edge counting: + + template + inline + typename enable_if::type + _countEdges(const Graph &g) { + return g.edgeNum(); + } + + template + inline int _countEdges(Wrap w) { + return countItems(w.value); + } + + /// \brief Function to count the edges in the graph. + /// + /// This function counts the edges in the graph. + /// The complexity of the function is O(e) but for some + /// graph structure it is specialized to run in O(1). + + template + inline int countEdges(const Graph& g) { + return _countEdges(g); + } + + // Undirected edge counting: + + template + inline + typename enable_if::type + _countUndirEdges(const Graph &g) { + return g.undirEdgeNum(); + } + + template + inline int _countUndirEdges(Wrap w) { + return countItems(w.value); + } + + /// \brief Function to count the edges in the graph. + /// + /// This function counts the edges in the graph. + /// The complexity of the function is O(e) but for some + /// graph structure it is specialized to run in O(1). + + template + inline int countUndirEdges(const Graph& g) { + return _countUndirEdges(g); + } + + + + template + inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) { + int num = 0; + for (DegIt it(_g, _n); it != INVALID; ++it) { + ++num; + } + return num; + } + + /// Finds an edge between two nodes of a graph. + + /// Finds an edge from node \c u to node \c v in graph \c g. + /// + /// If \c prev is \ref INVALID (this is the default value), then + /// it finds the first edge from \c u to \c v. Otherwise it looks for + /// the next edge from \c u to \c v after \c prev. + /// \return The found edge or \ref INVALID if there is no such an edge. + /// + /// Thus you can iterate through each edge from \c u to \c v as it follows. + /// \code + /// for(Edge e=findEdge(g,u,v);e!=INVALID;e=findEdge(g,u,v,e)) { + /// ... + /// } + /// \endcode + /// \todo We may want to use the \ref concept::GraphBase "GraphBase" + /// interface here... + /// \bug Untested ... + template + typename Graph::Edge findEdge(const Graph &g, + typename Graph::Node u, typename Graph::Node v, + typename Graph::Edge prev = INVALID) + { + typename Graph::OutEdgeIt e(g,prev); + // if(prev==INVALID) g.first(e,u); + if(prev==INVALID) e=typename Graph::OutEdgeIt(g,u); + else ++e; + while(e!=INVALID && g.target(e)!=v) ++e; + return e; + } + + ///\e + + ///\todo Please document. + /// + template + inline int countOutEdges(const Graph& _g, const typename Graph::Node& _n) { + return countNodeDegree(_g, _n); + } + + ///\e + + ///\todo Please document. + /// + template + inline int countInEdges(const Graph& _g, const typename Graph::Node& _n) { + return countNodeDegree(_g, _n); + } + + // graph copy + + template < + typename DestinationGraph, + typename SourceGraph, + typename NodeBijection> + void copyNodes(DestinationGraph& _d, const SourceGraph& _s, + NodeBijection& _nb) { + for (typename SourceGraph::NodeIt it(_s); it != INVALID; ++it) { + _nb[it] = _d.addNode(); + } + } + + template < + typename DestinationGraph, + typename SourceGraph, + typename NodeBijection, + typename EdgeBijection> + void copyEdges(DestinationGraph& _d, const SourceGraph& _s, + const NodeBijection& _nb, EdgeBijection& _eb) { + for (typename SourceGraph::EdgeIt it(_s); it != INVALID; ++it) { + _eb[it] = _d.addEdge(_nb[_s.source(it)], _nb[_s.target(it)]); + } + } + + template < + typename DestinationGraph, + typename SourceGraph, + typename NodeBijection, + typename EdgeBijection> + void copyGraph(DestinationGraph& _d, const SourceGraph& _s, + NodeBijection& _nb, EdgeBijection& _eb) { + nodeCopy(_d, _s, _nb); + edgeCopy(_d, _s, _nb, _eb); + } + + template < + typename _DestinationGraph, + typename _SourceGraph, + typename _NodeBijection + =typename _SourceGraph::template NodeMap, + typename _EdgeBijection + = typename _SourceGraph::template EdgeMap + > + class GraphCopy { + public: + + typedef _DestinationGraph DestinationGraph; + typedef _SourceGraph SourceGraph; + + typedef _NodeBijection NodeBijection; + typedef _EdgeBijection EdgeBijection; + + protected: + + NodeBijection node_bijection; + EdgeBijection edge_bijection; + + public: + + GraphCopy(DestinationGraph& _d, const SourceGraph& _s) { + copyGraph(_d, _s, node_bijection, edge_bijection); + } + + const NodeBijection& getNodeBijection() const { + return node_bijection; + } + + const EdgeBijection& getEdgeBijection() const { + return edge_bijection; + } + + }; + + + template + class ItemSetTraits {}; + + template + class ItemSetTraits<_Graph, typename _Graph::Node> { + public: + + typedef _Graph Graph; + + typedef typename Graph::Node Item; + typedef typename Graph::NodeIt ItemIt; + + template + class Map : public Graph::template NodeMap<_Value> { + public: + typedef typename Graph::template NodeMap<_Value> Parent; + typedef typename Parent::Value Value; + + Map(const Graph& _graph) : Parent(_graph) {} + Map(const Graph& _graph, const Value& _value) + : Parent(_graph, _value) {} + }; + + }; + + template + class ItemSetTraits<_Graph, typename _Graph::Edge> { + public: + + typedef _Graph Graph; + + typedef typename Graph::Edge Item; + typedef typename Graph::EdgeIt ItemIt; + + template + class Map : public Graph::template EdgeMap<_Value> { + public: + typedef typename Graph::template EdgeMap<_Value> Parent; + typedef typename Parent::Value Value; + + Map(const Graph& _graph) : Parent(_graph) {} + Map(const Graph& _graph, const Value& _value) + : Parent(_graph, _value) {} + }; + + }; + + template + class ItemSetTraits<_Graph, typename _Graph::UndirEdge> { + public: + + typedef _Graph Graph; + + typedef typename Graph::UndirEdge Item; + typedef typename Graph::UndirEdgeIt ItemIt; + + template + class Map : public Graph::template UndirEdgeMap<_Value> { + public: + typedef typename Graph::template UndirEdgeMap<_Value> Parent; + typedef typename Parent::Value Value; + + Map(const Graph& _graph) : Parent(_graph) {} + Map(const Graph& _graph, const Value& _value) + : Parent(_graph, _value) {} + }; + + }; + + /// @} + + /// \addtogroup graph_maps + /// @{ + + template + struct ReferenceMapTraits { + typedef typename Map::Value Value; + typedef typename Map::Value& Reference; + typedef const typename Map::Value& ConstReference; + typedef typename Map::Value* Pointer; + typedef const typename Map::Value* ConstPointer; + }; + + template + struct ReferenceMapTraits< + Map, + typename enable_if::type + > { + typedef typename Map::Value Value; + typedef typename Map::Reference Reference; + typedef typename Map::ConstReference ConstReference; + typedef typename Map::Pointer Pointer; + typedef typename Map::ConstPointer ConstPointer; + }; + + /// Provides an immutable and unique id for each item in the graph. + + /// The IdMap class provides an unique and immutable mapping for each item + /// in the graph. + /// + template + class IdMap { + public: + typedef _Graph Graph; + typedef int Value; + typedef _Item Item; + typedef _Item Key; + + typedef True NeedCopy; + + /// \brief Constructor. + /// + /// Constructor for creating id map. + IdMap(const Graph& _graph) : graph(&_graph) {} + + /// \brief Gives back the \e id of the item. + /// + /// Gives back the immutable and unique \e id of the map. + int operator[](const Item& item) const { return graph->id(item);} + + + private: + const Graph* graph; + + public: + + /// \brief The class represents the inverse of the map. + /// + /// The class represents the inverse of the map. + /// \see inverse() + class InverseMap { + public: + + typedef True NeedCopy; + + /// \brief Constructor. + /// + /// Constructor for creating an id-to-item map. + InverseMap(const Graph& _graph) : graph(&_graph) {} + + /// \brief Constructor. + /// + /// Constructor for creating an id-to-item map. + InverseMap(const IdMap& idMap) : graph(idMap.graph) {} + + /// \brief Gives back the given item from its id. + /// + /// Gives back the given item from its id. + /// + Item operator[](int id) const { return graph->fromId(id, Item());} + private: + const Graph* graph; + }; + + /// \brief Gives back the inverse of the map. + /// + /// Gives back the inverse of the map. + InverseMap inverse() const { return InverseMap(*graph);} + + }; + + + /// \brief General inversable graph-map type. + + /// This type provides simple inversable map functions. + /// The InversableMap wraps an arbitrary ReadWriteMap + /// and if a key is setted to a new value then store it + /// in the inverse map. + /// \param _Graph The graph type. + /// \param _Map The map to extend with inversable functionality. + template < + typename _Graph, + typename _Item, + typename _Value, + typename _Map + = typename ItemSetTraits<_Graph, _Item>::template Map<_Value>::Parent + > + class InvertableMap : protected _Map { + + public: + + typedef _Map Map; + typedef _Graph Graph; + + /// The key type of InvertableMap (Node, Edge, UndirEdge). + typedef typename _Map::Key Key; + /// The value type of the InvertableMap. + typedef typename _Map::Value Value; + + /// \brief Constructor. + /// + /// Construct a new InvertableMap for the graph. + /// + InvertableMap(const Graph& graph) : Map(graph) {} + + /// \brief The setter function of the map. + /// + /// Sets the mapped value. + void set(const Key& key, const Value& val) { + Value oldval = Map::operator[](key); + typename Container::iterator it = invMap.find(oldval); + if (it != invMap.end() && it->second == key) { + invMap.erase(it); + } + invMap.insert(make_pair(val, key)); + Map::set(key, val); + } + + /// \brief The getter function of the map. + /// + /// It gives back the value associated with the key. + const Value operator[](const Key& key) const { + return Map::operator[](key); + } + + /// \brief Add a new key to the map. + /// + /// Add a new key to the map. It is called by the + /// \c AlterationNotifier. + virtual void add(const Key& key) { + Map::add(key); + } + + /// \brief Erase the key from the map. + /// + /// Erase the key to the map. It is called by the + /// \c AlterationNotifier. + virtual void erase(const Key& key) { + Value val = Map::operator[](key); + typename Container::iterator it = invMap.find(val); + if (it != invMap.end() && it->second == key) { + invMap.erase(it); + } + Map::erase(key); + } + + /// \brief Clear the keys from the map and inverse map. + /// + /// Clear the keys from the map and inverse map. It is called by the + /// \c AlterationNotifier. + virtual void clear() { + invMap.clear(); + Map::clear(); + } + + private: + + typedef std::map Container; + Container invMap; + + public: + + /// \brief The inverse map type. + /// + /// The inverse of this map. The subscript operator of the map + /// gives back always the item what was last assigned to the value. + class InverseMap { + public: + /// \brief Constructor of the InverseMap. + /// + /// Constructor of the InverseMap. + InverseMap(const InvertableMap& _inverted) : inverted(_inverted) {} + + /// The value type of the InverseMap. + typedef typename InvertableMap::Key Value; + /// The key type of the InverseMap. + typedef typename InvertableMap::Value Key; + + /// \brief Subscript operator. + /// + /// Subscript operator. It gives back always the item + /// what was last assigned to the value. + Value operator[](const Key& key) const { + typename Container::const_iterator it = inverted.invMap.find(key); + return it->second; + } + + private: + const InvertableMap& inverted; + }; + + /// \brief It gives back the just readeable inverse map. + /// + /// It gives back the just readeable inverse map. + InverseMap inverse() const { + return InverseMap(*this); + } + + + + }; + + /// \brief Provides a mutable, continuous and unique descriptor for each + /// item in the graph. + /// + /// The DescriptorMap class provides a mutable, continuous and immutable + /// mapping for each item in the graph. The value for an item may mutated + /// on each operation when the an item erased or added to graph. + /// + /// \param _Graph The graph class the \c DescriptorMap belongs to. + /// \param _Item The Item is the Key of the Map. It may be Node, Edge or + /// UndirEdge. + /// \param _Map A ReadWriteMap mapping from the item type to integer. + template < + typename _Graph, + typename _Item, + typename _Map + = typename ItemSetTraits<_Graph, _Item>::template Map::Parent + > + class DescriptorMap : protected _Map { + + typedef _Item Item; + typedef _Map Map; + + public: + /// The graph class of DescriptorMap. + typedef _Graph Graph; + + /// The key type of DescriptorMap (Node, Edge, UndirEdge). + typedef typename _Map::Key Key; + /// The value type of DescriptorMap. + typedef typename _Map::Value Value; + + /// \brief Constructor. + /// + /// Constructor for descriptor map. + DescriptorMap(const Graph& _graph) : Map(_graph) { + build(); + } + + /// \brief Add a new key to the map. + /// + /// Add a new key to the map. It is called by the + /// \c AlterationNotifier. + virtual void add(const Item& item) { + Map::add(item); + Map::set(item, invMap.size()); + invMap.push_back(item); + } + + /// \brief Erase the key from the map. + /// + /// Erase the key to the map. It is called by the + /// \c AlterationNotifier. + virtual void erase(const Item& item) { + Map::set(invMap.back(), Map::operator[](item)); + invMap[Map::operator[](item)] = invMap.back(); + invMap.pop_back(); + Map::erase(item); + } + + /// \brief Build the unique map. + /// + /// Build the unique map. It is called by the + /// \c AlterationNotifier. + virtual void build() { + Map::build(); + Item it; + const typename Map::Graph* graph = Map::getGraph(); + for (graph->first(it); it != INVALID; graph->next(it)) { + Map::set(it, invMap.size()); + invMap.push_back(it); + } + } + + /// \brief Clear the keys from the map. + /// + /// Clear the keys from the map. It is called by the + /// \c AlterationNotifier. + virtual void clear() { + invMap.clear(); + Map::clear(); + } + + /// \brief Gives back the \e descriptor of the item. + /// + /// Gives back the mutable and unique \e descriptor of the map. + int operator[](const Item& item) const { + return Map::operator[](item); + } + + private: + + typedef std::vector Container; + Container invMap; + + public: + /// \brief The inverse map type. + /// + /// The inverse map type. + class InverseMap { + public: + /// \brief Constructor of the InverseMap. + /// + /// Constructor of the InverseMap. + InverseMap(const DescriptorMap& _inverted) + : inverted(_inverted) {} + + + /// The value type of the InverseMap. + typedef typename DescriptorMap::Key Value; + /// The key type of the InverseMap. + typedef typename DescriptorMap::Value Key; + + /// \brief Subscript operator. + /// + /// Subscript operator. It gives back the item + /// that the descriptor belongs to currently. + Value operator[](const Key& key) const { + return inverted.invMap[key]; + } + + private: + const DescriptorMap& inverted; + }; + + /// \brief Gives back the inverse of the map. + /// + /// Gives back the inverse of the map. + const InverseMap inverse() const { + return InverseMap(*this); + } + }; + + /// \brief Returns the source of the given edge. + /// + /// The SourceMap gives back the source Node of the given edge. + /// \author Balazs Dezso + template + class SourceMap { + public: + + typedef True NeedCopy; + + typedef typename Graph::Node Value; + typedef typename Graph::Edge Key; + + /// \brief Constructor + /// + /// Constructor + /// \param _graph The graph that the map belongs to. + SourceMap(const Graph& _graph) : graph(_graph) {} + + /// \brief The subscript operator. + /// + /// The subscript operator. + /// \param edge The edge + /// \return The source of the edge + Value operator[](const Key& edge) { + return graph.source(edge); + } + + private: + const Graph& graph; + }; + + /// \brief Returns a \ref SourceMap class + /// + /// This function just returns an \ref SourceMap class. + /// \relates SourceMap + template + inline SourceMap sourceMap(const Graph& graph) { + return SourceMap(graph); + } + + /// \brief Returns the target of the given edge. + /// + /// The TargetMap gives back the target Node of the given edge. + /// \author Balazs Dezso + template + class TargetMap { + public: + + typedef True NeedCopy; + + typedef typename Graph::Node Value; + typedef typename Graph::Edge Key; + + /// \brief Constructor + /// + /// Constructor + /// \param _graph The graph that the map belongs to. + TargetMap(const Graph& _graph) : graph(_graph) {} + + /// \brief The subscript operator. + /// + /// The subscript operator. + /// \param edge The edge + /// \return The target of the edge + Value operator[](const Key& key) { + return graph.target(key); + } + + private: + const Graph& graph; + }; + + /// \brief Returns a \ref TargetMap class + + /// This function just returns an \ref TargetMap class. + /// \relates TargetMap + template + inline TargetMap targetMap(const Graph& graph) { + return TargetMap(graph); + } + + /// \brief Returns the "forward" directed edge view of undirected edge. + /// + /// Returns the "forward" directed edge view of undirected edge. + /// \author Balazs Dezso + template + class ForwardMap { + public: + + typedef True NeedCopy; + + typedef typename Graph::Edge Value; + typedef typename Graph::UndirEdge Key; + + /// \brief Constructor + /// + /// Constructor + /// \param _graph The graph that the map belongs to. + ForwardMap(const Graph& _graph) : graph(_graph) {} + + /// \brief The subscript operator. + /// + /// The subscript operator. + /// \param key An undirected edge + /// \return The "forward" directed edge view of undirected edge + Value operator[](const Key& key) const { + return graph.edgeWithSource(key, graph.source(key)); + } + + private: + const Graph& graph; + }; + + /// \brief Returns a \ref ForwardMap class + + /// This function just returns an \ref ForwardMap class. + /// \relates ForwardMap + template + inline ForwardMap forwardMap(const Graph& graph) { + return ForwardMap(graph); + } + + /// \brief Returns the "backward" directed edge view of undirected edge. + /// + /// Returns the "backward" directed edge view of undirected edge. + /// \author Balazs Dezso + template + class BackwardMap { + public: + typedef True NeedCopy; + + typedef typename Graph::Edge Value; + typedef typename Graph::UndirEdge Key; + + /// \brief Constructor + /// + /// Constructor + /// \param _graph The graph that the map belongs to. + BackwardMap(const Graph& _graph) : graph(_graph) {} + + /// \brief The subscript operator. + /// + /// The subscript operator. + /// \param key An undirected edge + /// \return The "backward" directed edge view of undirected edge + Value operator[](const Key& key) const { + return graph.edgeWithSource(key, graph.target(key)); + } + + private: + const Graph& graph; + }; + + /// \brief Returns a \ref BackwardMap class + + /// This function just returns an \ref BackwardMap class. + /// \relates BackwardMap + template + inline BackwardMap backwardMap(const Graph& graph) { + return BackwardMap(graph); + } + + + /// @} + +} //END OF NAMESPACE LEMON + +#endif