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@1448: #include klao@962: klao@962: namespace lemon { klao@962: namespace concept { klao@962: klao@1030: /// \addtogroup graph_concepts klao@1030: /// @{ klao@1030: klao@1030: 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>(); klao@1158: 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: 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: klao@1022: class UndirGraph { klao@1022: public: alpar@1448: ///\e alpar@1448: alpar@1448: ///\todo undocumented alpar@1448: /// alpar@1448: typedef True UndirTag; klao@1022: klao@1030: /// Type describing a node in the graph klao@1030: typedef GraphNode Node; klao@1030: klao@1030: /// Type describing an undirected edge klao@1030: typedef GraphItem<'u'> UndirEdge; klao@1030: klao@1030: /// Type describing an UndirEdge with direction klao@1030: #ifndef DOXYGEN klao@1158: typedef UndirGraphEdge Edge; klao@1030: #else klao@1030: typedef UndirGraphEdge Edge; klao@1030: #endif klao@1030: klao@1030: /// Iterator type which iterates over all nodes klao@1030: #ifndef DOXYGEN klao@1030: typedef GraphIterator NodeIt; klao@1030: #else klao@1030: typedef GraphIterator NodeIt; klao@1030: #endif klao@1030: klao@1030: /// Iterator type which iterates over all undirected edges klao@1030: #ifndef DOXYGEN klao@1030: typedef GraphIterator UndirEdgeIt; klao@1030: #else klao@1030: typedef GraphIterator UndirEdgeIt; klao@1030: #endif klao@1030: klao@1030: /// Iterator type which iterates over all directed edges. klao@1030: klao@1030: /// Iterator type which iterates over all edges (each undirected klao@1030: /// edge occurs twice with both directions. klao@1030: #ifndef DOXYGEN klao@1030: typedef GraphIterator EdgeIt; klao@1030: #else klao@1030: typedef GraphIterator EdgeIt; klao@1030: #endif klao@1030: klao@1030: klao@1030: /// Iterator of undirected edges incident to a node klao@1030: #ifndef DOXYGEN klao@1030: typedef GraphIncIterator IncEdgeIt; klao@1030: #else klao@1030: typedef GraphIncIterator IncEdgeIt; klao@1030: #endif klao@1030: klao@1030: /// Iterator of edges incoming to a node klao@1030: #ifndef DOXYGEN klao@1030: typedef GraphIncIterator InEdgeIt; klao@1030: #else klao@1030: typedef GraphIncIterator InEdgeIt; klao@1030: #endif klao@1030: klao@1030: /// Iterator of edges outgoing from a node klao@1030: #ifndef DOXYGEN klao@1030: typedef GraphIncIterator OutEdgeIt; klao@1030: #else klao@1030: typedef GraphIncIterator OutEdgeIt; klao@1030: #endif klao@1030: klao@1030: /// NodeMap template klao@1030: #ifdef DOXYGEN klao@1030: typedef GraphMap NodeMap; klao@1030: #endif klao@1030: klao@1030: /// UndirEdgeMap template klao@1030: #ifdef DOXYGEN klao@1030: typedef GraphMap UndirEdgeMap; klao@1030: #endif klao@1030: klao@1030: /// EdgeMap template klao@1030: #ifdef DOXYGEN klao@1030: typedef GraphMap EdgeMap; klao@1030: #endif klao@1030: klao@1030: template klao@1030: class NodeMap : public GraphMap { klao@1030: typedef GraphMap Parent; klao@1030: public: klao@1030: klao@1030: explicit NodeMap(const UndirGraph &g) : Parent(g) {} klao@1030: NodeMap(const UndirGraph &g, T t) : Parent(g, t) {} klao@1030: }; klao@1030: klao@1030: template klao@1030: class UndirEdgeMap : public GraphMap { klao@1030: typedef GraphMap Parent; klao@1030: public: klao@1030: klao@1030: explicit UndirEdgeMap(const UndirGraph &g) : Parent(g) {} klao@1030: UndirEdgeMap(const UndirGraph &g, T t) : Parent(g, t) {} klao@1030: }; klao@1030: klao@1030: template klao@1030: class EdgeMap : public GraphMap { klao@1030: typedef GraphMap Parent; klao@1030: public: klao@1030: klao@1030: explicit EdgeMap(const UndirGraph &g) : Parent(g) {} klao@1030: EdgeMap(const UndirGraph &g, T t) : Parent(g, t) {} 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