klao@962: /* -*- C++ -*- klao@962: * ladanyi@1435: * lemon/concept/undir_graph_component.h - Part of LEMON, a generic klao@962: * C++ optimization library klao@962: * alpar@1164: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi alpar@1359: * Kutatocsoport (Egervary Research Group on Combinatorial Optimization, klao@962: * EGRES). klao@962: * klao@962: * Permission to use, modify and distribute this software is granted klao@962: * provided that this copyright notice appears in all copies. For klao@962: * precise terms see the accompanying LICENSE file. klao@962: * klao@962: * This software is provided "AS IS" with no warranty of any kind, klao@962: * express or implied, and with no claim as to its suitability for any klao@962: * purpose. klao@962: * klao@962: */ klao@962: klao@1030: ///\ingroup graph_concepts klao@962: ///\file klao@962: ///\brief Undirected graphs and components of. klao@962: klao@962: klao@962: #ifndef LEMON_CONCEPT_UNDIR_GRAPH_H klao@962: #define LEMON_CONCEPT_UNDIR_GRAPH_H klao@962: klao@962: #include alpar@1620: #include alpar@1448: #include klao@962: klao@962: namespace lemon { klao@962: namespace concept { klao@962: klao@1030: /// Skeleton class which describes an edge with direction in \ref klao@1030: /// UndirGraph "undirected graph". klao@1158: template klao@1158: class UndirGraphEdge : public UndirGraph::UndirEdge { klao@1158: typedef typename UndirGraph::UndirEdge UndirEdge; klao@1158: typedef typename UndirGraph::Node Node; klao@1030: public: klao@1030: klao@1030: /// \e klao@1030: UndirGraphEdge() {} klao@1030: klao@1030: /// \e alpar@1367: UndirGraphEdge(const UndirGraphEdge& e) : UndirGraph::UndirEdge(e) {} klao@1030: klao@1030: /// \e klao@1030: UndirGraphEdge(Invalid) {} klao@1030: klao@1158: /// \brief Directed edge from undirected edge and a source node. klao@1030: /// klao@1158: /// Constructs a directed edge from undirected edge and a source node. klao@1158: /// klao@1158: /// \note You have to specify the graph for this constructor. klao@1158: UndirGraphEdge(const UndirGraph &g, klao@1158: UndirEdge undir_edge, Node n) { klao@1030: ignore_unused_variable_warning(undir_edge); klao@1158: ignore_unused_variable_warning(g); klao@1158: ignore_unused_variable_warning(n); klao@1030: } klao@1030: klao@1030: /// \e klao@1030: UndirGraphEdge& operator=(UndirGraphEdge) { return *this; } klao@1030: klao@1030: /// \e klao@1030: bool operator==(UndirGraphEdge) const { return true; } klao@1030: /// \e klao@1030: bool operator!=(UndirGraphEdge) const { return false; } klao@1030: klao@1030: /// \e klao@1030: bool operator<(UndirGraphEdge) const { return false; } klao@1030: klao@1030: template klao@1030: struct Constraints { klao@1030: void constraints() { klao@1158: const_constraints(); klao@1158: } klao@1158: void const_constraints() const { klao@1030: /// \bug This should be is_base_and_derived ... klao@1030: UndirEdge ue = e; klao@1030: ue = e; klao@1030: klao@1158: Edge e_with_source(graph,ue,n); klao@1158: ignore_unused_variable_warning(e_with_source); klao@1030: } klao@1030: Edge e; klao@1158: UndirEdge ue; klao@1158: UndirGraph graph; klao@1158: Node n; klao@1030: }; klao@1030: }; klao@1030: klao@962: klao@962: struct BaseIterableUndirGraphConcept { deba@989: klao@1022: template klao@1022: struct Constraints { klao@962: klao@1022: typedef typename Graph::UndirEdge UndirEdge; klao@1022: typedef typename Graph::Edge Edge; klao@1022: typedef typename Graph::Node Node; klao@962: klao@1022: void constraints() { klao@1022: checkConcept(); klao@1030: checkConcept, UndirEdge>(); alpar@1620: //checkConcept, Edge>(); klao@962: klao@1030: graph.first(ue); klao@1030: graph.next(ue); klao@1022: klao@1030: const_constraints(); klao@1030: } klao@1030: void const_constraints() { klao@1022: Node n; klao@1022: n = graph.target(ue); klao@1022: n = graph.source(ue); klao@1030: n = graph.oppositeNode(n0, ue); klao@1022: klao@1030: bool b; klao@1030: b = graph.forward(e); klao@1030: ignore_unused_variable_warning(b); klao@1022: } klao@1030: klao@1030: Graph graph; klao@1022: Edge e; klao@1030: Node n0; klao@1030: UndirEdge ue; klao@1022: }; klao@1022: klao@962: }; klao@962: klao@1022: klao@962: struct IterableUndirGraphConcept { klao@962: klao@1022: template klao@1022: struct Constraints { klao@1022: void constraints() { klao@1022: /// \todo we don't need the iterable component to be base iterable klao@1022: /// Don't we really??? klao@1022: //checkConcept< BaseIterableUndirGraphConcept, Graph > (); klao@962: klao@1022: checkConcept (); klao@1021: klao@1022: typedef typename Graph::UndirEdge UndirEdge; klao@1022: typedef typename Graph::UndirEdgeIt UndirEdgeIt; klao@1030: typedef typename Graph::IncEdgeIt IncEdgeIt; klao@1022: klao@1022: checkConcept, UndirEdgeIt>(); klao@1030: checkConcept, IncEdgeIt>(); klao@1022: } klao@1022: }; klao@1022: klao@1022: }; klao@1022: klao@1022: struct MappableUndirGraphConcept { klao@1022: klao@1022: template klao@1022: struct Constraints { klao@1022: klao@1022: struct Dummy { klao@1022: int value; klao@1022: Dummy() : value(0) {} klao@1022: Dummy(int _v) : value(_v) {} klao@1022: }; klao@1022: klao@1022: void constraints() { klao@1022: checkConcept(); klao@1022: klao@1022: typedef typename Graph::template UndirEdgeMap IntMap; klao@1022: checkConcept, klao@1022: IntMap >(); klao@1022: klao@1022: typedef typename Graph::template UndirEdgeMap BoolMap; klao@1022: checkConcept, klao@1022: BoolMap >(); klao@1022: klao@1022: typedef typename Graph::template UndirEdgeMap DummyMap; klao@1022: checkConcept, klao@1022: DummyMap >(); klao@1022: } klao@1022: }; klao@1022: klao@1022: }; klao@1022: klao@1022: struct ExtendableUndirGraphConcept { klao@1022: klao@1022: template klao@1022: struct Constraints { klao@1022: void constraints() { klao@1022: node_a = graph.addNode(); klao@1022: uedge = graph.addEdge(node_a, node_b); klao@1022: } klao@1022: typename Graph::Node node_a, node_b; klao@1022: typename Graph::UndirEdge uedge; klao@1022: Graph graph; klao@1022: }; klao@1022: klao@1022: }; klao@1022: klao@1022: struct ErasableUndirGraphConcept { klao@1022: klao@1022: template klao@1022: struct Constraints { klao@1022: void constraints() { klao@1022: graph.erase(n); klao@1022: graph.erase(e); klao@1022: } klao@1022: Graph graph; klao@1022: typename Graph::Node n; klao@1022: typename Graph::UndirEdge e; klao@1022: }; klao@1022: klao@1022: }; klao@1022: alpar@1620: /// \addtogroup graph_concepts alpar@1620: /// @{ alpar@1620: alpar@1620: klao@1030: /// Class describing the concept of Undirected Graphs. klao@1030: klao@1030: /// This class describes the common interface of all Undirected klao@1030: /// Graphs. klao@1030: /// klao@1030: /// As all concept describing classes it provides only interface klao@1030: /// without any sensible implementation. So any algorithm for klao@1030: /// undirected graph should compile with this class, but it will not klao@1030: /// run properly, of couse. klao@1030: /// klao@1030: /// In LEMON undirected graphs also fulfill the concept of directed klao@1030: /// graphs (\ref lemon::concept::Graph "Graph Concept"). For klao@1030: /// explanation of this and more see also the page \ref undir_graphs, klao@1030: /// a tutorial about undirected graphs. klao@1030: alpar@1620: class UndirGraph : public StaticGraph { klao@1022: public: alpar@1448: ///\e alpar@1448: alpar@1448: ///\todo undocumented alpar@1448: /// alpar@1448: typedef True UndirTag; klao@1022: alpar@1620: /// The base type of the undirected edge iterators. alpar@1620: alpar@1620: /// The base type of the undirected edge iterators. alpar@1620: /// alpar@1620: class UndirEdge { alpar@1620: public: alpar@1620: /// Default constructor klao@1030: alpar@1620: /// @warning The default constructor sets the iterator alpar@1620: /// to an undefined value. alpar@1620: UndirEdge() { } alpar@1620: /// Copy constructor. klao@1030: alpar@1620: /// Copy constructor. alpar@1620: /// alpar@1620: UndirEdge(const UndirEdge&) { } alpar@1620: /// Edge -> UndirEdge conversion klao@1030: alpar@1620: /// Edge -> UndirEdge conversion alpar@1620: /// alpar@1620: UndirEdge(const Edge&) { } alpar@1620: /// Initialize the iterator to be invalid. klao@1030: alpar@1620: /// Initialize the iterator to be invalid. alpar@1620: /// alpar@1620: UndirEdge(Invalid) { } alpar@1620: /// Equality operator klao@1030: alpar@1620: /// Two iterators are equal if and only if they point to the alpar@1620: /// same object or both are invalid. alpar@1620: bool operator==(UndirEdge) const { return true; } alpar@1620: /// Inequality operator klao@1030: alpar@1620: /// \sa operator==(UndirEdge n) alpar@1620: /// alpar@1620: bool operator!=(UndirEdge) const { return true; } klao@1030: alpar@1620: ///\e klao@1030: alpar@1620: ///\todo Do we need this? alpar@1620: /// alpar@1620: bool operator<(const UndirEdge &that) const { return true; } alpar@1620: }; alpar@1620: alpar@1620: /// This iterator goes through each undirected edge. klao@1030: alpar@1620: /// This iterator goes through each undirected edge of a graph. alpar@1620: /// Its usage is quite simple, for example you can count the number alpar@1620: /// of edges in a graph \c g of type \c Graph as follows: alpar@1620: /// \code alpar@1620: /// int count=0; alpar@1620: /// for(Graph::UndirEdgeIt e(g); e!=INVALID; ++e) ++count; alpar@1620: /// \endcode alpar@1620: class UndirEdgeIt : public UndirEdge { alpar@1620: public: alpar@1620: /// Default constructor alpar@1620: alpar@1620: /// @warning The default constructor sets the iterator alpar@1620: /// to an undefined value. alpar@1620: UndirEdgeIt() { } alpar@1620: /// Copy constructor. alpar@1620: alpar@1620: /// Copy constructor. alpar@1620: /// alpar@1620: UndirEdgeIt(const UndirEdgeIt& e) : UndirEdge(e) { } alpar@1620: /// Initialize the iterator to be invalid. klao@1030: alpar@1620: /// Initialize the iterator to be invalid. alpar@1620: /// alpar@1620: UndirEdgeIt(Invalid) { } alpar@1620: /// This constructor sets the iterator to the first edge. alpar@1620: alpar@1620: /// This constructor sets the iterator to the first edge of \c g. alpar@1620: UndirEdgeIt(const UndirGraph&) { } alpar@1620: /// UndirEdge -> UndirEdgeIt conversion klao@1030: alpar@1620: /// Sets the iterator to the value of the trivial iterator \c e. alpar@1620: /// This feature necessitates that each time we alpar@1620: /// iterate the edge-set, the iteration order is the same. alpar@1620: UndirEdgeIt(const UndirGraph&, const UndirEdge&) { } alpar@1620: ///Next edge alpar@1620: alpar@1620: /// Assign the iterator to the next edge. alpar@1620: UndirEdgeIt& operator++() { return *this; } alpar@1620: }; klao@1030: alpar@1620: /// This iterator goes trough the incident undirected edges of a node. klao@1030: alpar@1620: /// This iterator goes trough the incident undirected edges alpar@1620: /// of a certain node alpar@1620: /// of a graph. alpar@1620: /// Its usage is quite simple, for example you can compute the alpar@1620: /// degree (i.e. count the number alpar@1620: /// of incident edges of a node \c n alpar@1620: /// in graph \c g of type \c Graph as follows. alpar@1620: /// \code alpar@1620: /// int count=0; alpar@1620: /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count; alpar@1620: /// \endcode alpar@1620: class IncEdgeIt : public UndirEdge { alpar@1620: public: alpar@1620: /// Default constructor klao@1030: alpar@1620: /// @warning The default constructor sets the iterator alpar@1620: /// to an undefined value. alpar@1620: IncEdgeIt() { } alpar@1620: /// Copy constructor. alpar@1620: alpar@1620: /// Copy constructor. alpar@1620: /// alpar@1620: IncEdgeIt(const IncEdgeIt& e) : UndirEdge(e) { } alpar@1620: /// Initialize the iterator to be invalid. alpar@1620: alpar@1620: /// Initialize the iterator to be invalid. alpar@1620: /// alpar@1620: IncEdgeIt(Invalid) { } alpar@1620: /// This constructor sets the iterator to first incident edge. alpar@1620: alpar@1620: /// This constructor set the iterator to the first incident edge of alpar@1620: /// the node. alpar@1620: IncEdgeIt(const UndirGraph&, const Node&) { } alpar@1620: /// UndirEdge -> IncEdgeIt conversion alpar@1620: alpar@1620: /// Sets the iterator to the value of the trivial iterator \c e. alpar@1620: /// This feature necessitates that each time we alpar@1620: /// iterate the edge-set, the iteration order is the same. alpar@1620: IncEdgeIt(const UndirGraph&, const UndirEdge&) { } alpar@1620: /// Next incident edge alpar@1620: alpar@1620: /// Assign the iterator to the next incident edge alpar@1620: /// of the corresponding node. alpar@1620: IncEdgeIt& operator++() { return *this; } alpar@1620: }; alpar@1620: alpar@1620: /// Read write map of the undirected edges to type \c T. alpar@1620: alpar@1620: /// Reference map of the edges to type \c T. alpar@1620: /// \sa Reference alpar@1620: /// \warning Making maps that can handle bool type (UndirEdgeMap) alpar@1620: /// needs some extra attention! alpar@1620: template alpar@1620: class UndirEdgeMap : public ReadWriteMap alpar@1620: { klao@1030: public: klao@1030: alpar@1620: ///\e alpar@1620: UndirEdgeMap(const UndirGraph&) { } alpar@1620: ///\e alpar@1620: UndirEdgeMap(const UndirGraph&, T) { } alpar@1620: ///Copy constructor alpar@1620: UndirEdgeMap(const UndirEdgeMap& em) : ReadWriteMap(em) { } alpar@1620: ///Assignment operator alpar@1620: UndirEdgeMap &operator=(const UndirEdgeMap&) { return *this; } alpar@1620: // \todo fix this concept klao@1030: }; klao@1030: klao@1030: /// Is the Edge oriented "forward"? klao@1030: klao@1030: /// Returns whether the given directed edge is same orientation as klao@1030: /// the corresponding undirected edge. klao@1030: /// klao@1030: /// \todo "What does the direction of an undirected edge mean?" klao@1030: bool forward(Edge) const { return true; } klao@1030: klao@1030: /// Opposite node on an edge klao@1030: klao@1030: /// \return the opposite of the given Node on the given Edge klao@1030: /// klao@1030: /// \todo What should we do if given Node and Edge are not incident? klao@1030: Node oppositeNode(Node, UndirEdge) const { return INVALID; } klao@1030: klao@1030: /// First node of the undirected edge. klao@1030: klao@1030: /// \return the first node of the given UndirEdge. klao@1030: /// klao@1030: /// Naturally undirectected edges don't have direction and thus klao@1030: /// don't have source and target node. But we use these two methods klao@1030: /// to query the two endnodes of the edge. The direction of the edge klao@1030: /// which arises this way is called the inherent direction of the klao@1030: /// undirected edge, and is used to define the "forward" direction klao@1030: /// of the directed versions of the edges. klao@1030: /// \sa forward klao@1030: Node source(UndirEdge) const { return INVALID; } klao@1030: klao@1030: /// Second node of the undirected edge. klao@1030: Node target(UndirEdge) const { return INVALID; } klao@1030: klao@1030: /// Source node of the directed edge. klao@1030: Node source(Edge) const { return INVALID; } klao@1030: klao@1030: /// Target node of the directed edge. klao@1030: Node target(Edge) const { return INVALID; } klao@1030: klao@1030: /// First node of the graph klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void first(Node&) const {} klao@1030: /// Next node of the graph klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void next(Node&) const {} klao@1030: klao@1030: /// First undirected edge of the graph klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void first(UndirEdge&) const {} klao@1030: /// Next undirected edge of the graph klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void next(UndirEdge&) const {} klao@1030: klao@1030: /// First directed edge of the graph klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void first(Edge&) const {} klao@1030: /// Next directed edge of the graph klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void next(Edge&) const {} klao@1030: klao@1030: /// First outgoing edge from a given node klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void firstOut(Edge&, Node) const {} klao@1030: /// Next outgoing edge to a node klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void nextOut(Edge&) const {} klao@1030: klao@1030: /// First incoming edge to a given node klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void firstIn(Edge&, Node) const {} klao@1030: /// Next incoming edge to a node klao@1030: klao@1030: /// \note This method is part of so called \ref klao@1030: /// developpers_interface "Developpers' interface", so it shouldn't klao@1030: /// be used in an end-user program. klao@1030: void nextIn(Edge&) const {} klao@1030: klao@1030: klao@1158: /// Base node of the iterator klao@1158: /// klao@1158: /// Returns the base node (the source in this case) of the iterator klao@1158: Node baseNode(OutEdgeIt e) const { klao@1158: return source(e); klao@1158: } klao@1158: /// Running node of the iterator klao@1158: /// klao@1158: /// Returns the running node (the target in this case) of the klao@1158: /// iterator klao@1158: Node runningNode(OutEdgeIt e) const { klao@1158: return target(e); klao@1158: } klao@1158: klao@1158: /// Base node of the iterator klao@1158: /// klao@1158: /// Returns the base node (the target in this case) of the iterator klao@1158: Node baseNode(InEdgeIt e) const { klao@1158: return target(e); klao@1158: } klao@1158: /// Running node of the iterator klao@1158: /// klao@1158: /// Returns the running node (the source in this case) of the klao@1158: /// iterator klao@1158: Node runningNode(InEdgeIt e) const { klao@1158: return source(e); klao@1158: } klao@1158: klao@1158: /// Base node of the iterator klao@1158: /// klao@1158: /// Returns the base node of the iterator alpar@1367: Node baseNode(IncEdgeIt) const { klao@1158: return INVALID; klao@1158: } klao@1158: /// Running node of the iterator klao@1158: /// klao@1158: /// Returns the running node of the iterator alpar@1367: Node runningNode(IncEdgeIt) const { klao@1158: return INVALID; klao@1158: } klao@1158: klao@1158: klao@1022: template klao@1022: struct Constraints { klao@1022: void constraints() { klao@1022: checkConcept(); klao@1022: checkConcept(); klao@1022: checkConcept(); klao@1022: } klao@1022: }; klao@1022: klao@1022: }; klao@1022: klao@1022: class ExtendableUndirGraph : public UndirGraph { klao@1022: public: klao@1022: klao@1022: template klao@1022: struct Constraints { klao@1022: void constraints() { klao@1022: checkConcept(); klao@1022: checkConcept(); klao@1022: checkConcept(); klao@1022: klao@1022: checkConcept(); klao@1022: checkConcept(); klao@1022: checkConcept(); klao@1022: } klao@1022: }; klao@1022: klao@1022: }; klao@1022: klao@1022: class ErasableUndirGraph : public ExtendableUndirGraph { klao@1022: public: klao@1022: klao@1022: template klao@1022: struct Constraints { klao@1022: void constraints() { klao@1022: checkConcept(); klao@1022: checkConcept(); klao@1022: } klao@1022: }; klao@1022: klao@962: }; klao@962: klao@1030: /// @} klao@1030: klao@962: } klao@962: klao@962: } klao@962: klao@962: #endif