hegyi@677: // -*- c++ -*- hegyi@677: #ifndef HUGO_NET_GRAPH_H hegyi@677: #define HUGO_NET_GRAPH_H hegyi@677: hegyi@677: ///\file hegyi@677: ///\brief Declaration of HierarchyGraph. hegyi@677: hegyi@677: #include hegyi@677: #include hegyi@677: hegyi@677: /// The namespace of HugoLib hegyi@691: namespace hugo hegyi@691: { hegyi@677: hegyi@677: // @defgroup empty_graph The HierarchyGraph class hegyi@677: // @{ hegyi@677: hegyi@677: /// A graph class in that a simple edge can represent a path. hegyi@690: hegyi@677: /// This class provides common features of a graph structure hegyi@677: /// that represents a network. You can handle with it layers. This hegyi@677: /// means that a node in one layer can be a complete network in a nother hegyi@677: /// layer. hegyi@677: hegyi@691: template < class Gact, class Gsub > class HierarchyGraph hegyi@677: { hegyi@677: hegyi@677: public: hegyi@677: hegyi@677: /// The actual layer hegyi@677: Gact actuallayer; hegyi@677: hegyi@677: hegyi@690: /// Map of the subnetworks in the sublayer hegyi@690: /// The appropriate edge nodes are also stored here hegyi@677: hegyi@690: class SubNetwork hegyi@690: { hegyi@690: hegyi@690: struct actedgesubnodestruct hegyi@690: { hegyi@691: typename Gact::Edge actedge; hegyi@691: typename Gsub::Node subnode; hegyi@690: }; hegyi@690: hegyi@690: int edgenumber; hegyi@690: bool connectable; hegyi@691: Gact *actuallayer; hegyi@690: typename Gact::Node * actuallayernode; hegyi@691: Gsub *subnetwork; hegyi@691: actedgesubnodestruct *assignments; hegyi@690: hegyi@690: public: hegyi@690: hegyi@691: int addAssignment (typename Gact::Edge actedge, hegyi@691: typename Gsub::Node subnode) hegyi@690: { hegyi@691: if (!(actuallayer->valid (actedge))) hegyi@691: { hegyi@691: cerr << "The given edge is not in the given network!" << endl; hegyi@691: return -1; hegyi@691: } hegyi@691: else if ((actuallayer->id (actuallayer->tail (actedge)) != hegyi@691: actuallayer->id (*actuallayernode)) hegyi@691: && (actuallayer->id (actuallayer->head (actedge)) != hegyi@691: actuallayer->id (*actuallayernode))) hegyi@691: { hegyi@691: cerr << "The given edge does not connect to the given node!" << hegyi@691: endl; hegyi@691: return -1; hegyi@691: } hegyi@690: hegyi@691: if (!(subnetwork->valid (subnode))) hegyi@691: { hegyi@691: cerr << "The given node is not in the given network!" << endl; hegyi@691: return -1; hegyi@691: } hegyi@690: hegyi@691: int i = 0; hegyi@690: //while in the array there is valid note that is not equvivalent with the one that would be noted increase i hegyi@691: while ((i < edgenumber) hegyi@691: && (actuallayer->valid (assignments[i].actedge)) hegyi@691: && (assignments[i].actedge != actedge)) hegyi@691: i++; hegyi@691: if (assignments[i].actedge == actedge) hegyi@691: { hegyi@691: cout << "Warning: Redefinement of assigment!!!" << endl; hegyi@691: } hegyi@691: if (i == edgenumber) hegyi@691: { hegyi@691: cout << hegyi@691: "This case can't be!!! (because there should be the guven edge in the array already and the cycle had to stop)" hegyi@691: << endl; hegyi@691: } hegyi@690: //if(!(actuallayer->valid(assignments[i].actedge))) //this condition is necessary if we do not obey redefinition hegyi@690: { hegyi@691: assignments[i].actedge = actedge; hegyi@691: assignments[i].subnode = subnode; hegyi@690: } hegyi@690: hegyi@690: /// If to all of the edges a subnode is assigned then the subnetwork is connectable (attachable?) hegyi@690: /// We do not need to check for further attributes, because to notice an assignment we need hegyi@690: /// all of them to be correctly initialised before. hegyi@691: if (i == edgenumber - 1) hegyi@691: connectable = 1; hegyi@690: hegyi@690: return 0; hegyi@690: } hegyi@690: hegyi@691: int setSubNetwork (Gsub * sn) hegyi@690: { hegyi@691: subnetwork = sn; hegyi@690: return 0; hegyi@690: } hegyi@690: hegyi@691: int setActualLayer (Gact * al) hegyi@690: { hegyi@691: actuallayer = al; hegyi@690: return 0; hegyi@690: } hegyi@690: hegyi@691: int setActualLayerNode (typename Gact::Node * aln) hegyi@690: { hegyi@690: typename Gact::InEdgeIt iei; hegyi@690: typename Gact::OutEdgeIt oei; hegyi@690: hegyi@691: actuallayernode = aln; hegyi@690: hegyi@691: edgenumber = 0; hegyi@690: hegyi@691: if (actuallayer) hegyi@690: { hegyi@691: for (iei = actuallayer->first (iei, (*actuallayernode)); hegyi@691: ((actuallayer->valid (iei)) hegyi@691: && (actuallayer->head (iei) == (*actuallayernode))); hegyi@691: actuallayer->next (iei)) hegyi@691: { hegyi@691: cout << actuallayer->id (actuallayer-> hegyi@691: tail (iei)) << " " << actuallayer-> hegyi@691: id (actuallayer->head (iei)) << endl; hegyi@691: edgenumber++; hegyi@691: } hegyi@691: //cout << "Number of in-edges: " << edgenumber << endl; hegyi@691: for (oei = actuallayer->first (oei, (*actuallayernode)); hegyi@691: ((actuallayer->valid (oei)) hegyi@691: && (actuallayer->tail (oei) == (*actuallayernode))); hegyi@691: actuallayer->next (oei)) hegyi@691: { hegyi@691: cout << actuallayer->id (actuallayer-> hegyi@691: tail (oei)) << " " << actuallayer-> hegyi@691: id (actuallayer->head (oei)) << endl; hegyi@691: edgenumber++; hegyi@691: } hegyi@691: //cout << "Number of in+out-edges: " << edgenumber << endl; hegyi@691: assignments = new actedgesubnodestruct[edgenumber]; hegyi@691: for (int i = 0; i < edgenumber; i++) hegyi@691: { hegyi@691: assignments[i].actedge = INVALID; hegyi@691: assignments[i].subnode = INVALID; hegyi@691: } hegyi@690: } hegyi@691: else hegyi@690: { hegyi@691: cerr << "There is no actual layer defined yet!" << endl; hegyi@691: return -1; hegyi@690: } hegyi@690: hegyi@690: return 0; hegyi@690: } hegyi@690: hegyi@691: SubNetwork ():edgenumber (0), connectable (false), actuallayer (NULL), hegyi@691: actuallayernode (NULL), subnetwork (NULL), hegyi@691: assignments (NULL) hegyi@690: { hegyi@690: } hegyi@690: hegyi@690: }; hegyi@690: hegyi@691: typename Gact::template NodeMap < SubNetwork > subnetworks; hegyi@677: hegyi@677: hegyi@677: /// Defalult constructor. hegyi@677: /// We don't need any extra lines, because the actuallayer hegyi@677: /// variable has run its constructor, when we have created this class hegyi@677: /// So only the two maps has to be initialised here. hegyi@691: HierarchyGraph ():subnetworks (actuallayer) hegyi@677: { hegyi@677: } hegyi@677: hegyi@677: hegyi@677: ///Copy consructor. hegyi@691: HierarchyGraph (const HierarchyGraph < Gact, Gsub > &HG):actuallayer (HG.actuallayer), hegyi@691: subnetworks hegyi@691: (actuallayer) hegyi@677: { hegyi@677: } hegyi@677: hegyi@690: hegyi@677: /// The base type of the node iterators. hegyi@677: hegyi@677: /// This is the base type of each node iterators, hegyi@677: /// thus each kind of node iterator will convert to this. hegyi@677: /// The Node type of the HierarchyGraph is the Node type of the actual layer. hegyi@677: typedef typename Gact::Node Node; hegyi@677: hegyi@690: hegyi@677: /// This iterator goes through each node. hegyi@677: hegyi@677: /// Its usage is quite simple, for example you can count the number hegyi@677: /// of nodes in graph \c G of type \c Graph like this: hegyi@677: /// \code hegyi@677: ///int count=0; hegyi@677: ///for(Graph::NodeIt n(G);G.valid(n);G.next(n)) count++; hegyi@677: /// \endcode hegyi@677: /// The NodeIt type of the HierarchyGraph is the NodeIt type of the actual layer. hegyi@677: typedef typename Gact::NodeIt NodeIt; hegyi@690: hegyi@690: hegyi@677: /// The base type of the edge iterators. hegyi@677: /// The Edge type of the HierarchyGraph is the Edge type of the actual layer. hegyi@691: typedef typename Gact::Edge Edge; hegyi@677: hegyi@690: hegyi@677: /// This iterator goes trough the outgoing edges of a node. hegyi@677: hegyi@677: /// This iterator goes trough the \e outgoing edges of a certain node hegyi@677: /// of a graph. hegyi@677: /// Its usage is quite simple, for example you can count the number hegyi@677: /// of outgoing edges of a node \c n hegyi@677: /// in graph \c G of type \c Graph as follows. hegyi@677: /// \code hegyi@677: ///int count=0; hegyi@677: ///for(Graph::OutEdgeIt e(G,n);G.valid(e);G.next(e)) count++; hegyi@677: /// \endcode hegyi@677: /// The OutEdgeIt type of the HierarchyGraph is the OutEdgeIt type of the actual layer. hegyi@677: typedef typename Gact::OutEdgeIt OutEdgeIt; hegyi@677: hegyi@677: hegyi@677: /// This iterator goes trough the incoming edges of a node. hegyi@677: hegyi@677: /// This iterator goes trough the \e incoming edges of a certain node hegyi@677: /// of a graph. hegyi@677: /// Its usage is quite simple, for example you can count the number hegyi@677: /// of outgoing edges of a node \c n hegyi@677: /// in graph \c G of type \c Graph as follows. hegyi@677: /// \code hegyi@677: ///int count=0; hegyi@677: ///for(Graph::InEdgeIt e(G,n);G.valid(e);G.next(e)) count++; hegyi@677: /// \endcode hegyi@677: /// The InEdgeIt type of the HierarchyGraph is the InEdgeIt type of the actual layer. hegyi@677: typedef typename Gact::InEdgeIt InEdgeIt; hegyi@677: hegyi@677: hegyi@677: /// This iterator goes through each edge. hegyi@677: hegyi@677: /// This iterator goes through each edge of a graph. hegyi@677: /// Its usage is quite simple, for example you can count the number hegyi@677: /// of edges in a graph \c G of type \c Graph as follows: hegyi@677: /// \code hegyi@677: ///int count=0; hegyi@677: ///for(Graph::EdgeIt e(G);G.valid(e);G.next(e)) count++; hegyi@677: /// \endcode hegyi@677: /// The EdgeIt type of the HierarchyGraph is the EdgeIt type of the actual layer. hegyi@677: typedef typename Gact::EdgeIt EdgeIt; hegyi@677: hegyi@677: hegyi@677: /// First node of the graph. hegyi@677: hegyi@677: /// \retval i the first node. hegyi@677: /// \return the first node. hegyi@691: typename Gact::NodeIt & first (typename Gact::NodeIt & i) const hegyi@691: { hegyi@691: return actuallayer.first (i); hegyi@691: } hegyi@677: hegyi@677: hegyi@677: /// The first incoming edge. hegyi@691: typename Gact::InEdgeIt & first (typename Gact::InEdgeIt & i, hegyi@691: typename Gact::Node) const hegyi@691: { hegyi@691: return actuallayer.first (i); hegyi@691: } hegyi@677: hegyi@677: hegyi@677: /// The first outgoing edge. hegyi@691: typename Gact::OutEdgeIt & first (typename Gact::OutEdgeIt & i, hegyi@691: typename Gact::Node) const hegyi@691: { hegyi@691: return actuallayer.first (i); hegyi@691: } hegyi@677: hegyi@677: hegyi@677: // SymEdgeIt &first(SymEdgeIt &, Node) const { return i;} hegyi@677: /// The first edge of the Graph. hegyi@691: typename Gact::EdgeIt & first (typename Gact::EdgeIt & i) const hegyi@691: { hegyi@691: return actuallayer.first (i); hegyi@691: } hegyi@677: hegyi@677: hegyi@677: // Node getNext(Node) const {} hegyi@677: // InEdgeIt getNext(InEdgeIt) const {} hegyi@677: // OutEdgeIt getNext(OutEdgeIt) const {} hegyi@677: // //SymEdgeIt getNext(SymEdgeIt) const {} hegyi@677: // EdgeIt getNext(EdgeIt) const {} hegyi@677: hegyi@677: hegyi@677: /// Go to the next node. hegyi@691: typename Gact::NodeIt & next (typename Gact::NodeIt & i) const hegyi@691: { hegyi@691: return actuallayer.next (i); hegyi@691: } hegyi@677: /// Go to the next incoming edge. hegyi@691: typename Gact::InEdgeIt & next (typename Gact::InEdgeIt & i) const hegyi@691: { hegyi@691: return actuallayer.next (i); hegyi@691: } hegyi@677: /// Go to the next outgoing edge. hegyi@691: typename Gact::OutEdgeIt & next (typename Gact::OutEdgeIt & i) const hegyi@691: { hegyi@691: return actuallayer.next (i); hegyi@691: } hegyi@677: //SymEdgeIt &next(SymEdgeIt &) const {} hegyi@677: /// Go to the next edge. hegyi@691: typename Gact::EdgeIt & next (typename Gact::EdgeIt & i) const hegyi@691: { hegyi@691: return actuallayer.next (i); hegyi@691: } hegyi@677: hegyi@677: ///Gives back the head node of an edge. hegyi@691: typename Gact::Node head (typename Gact::Edge edge) const hegyi@691: { hegyi@691: return actuallayer.head (edge); hegyi@691: } hegyi@677: ///Gives back the tail node of an edge. hegyi@691: typename Gact::Node tail (typename Gact::Edge edge) const hegyi@691: { hegyi@691: return actuallayer.tail (edge); hegyi@691: } hegyi@690: hegyi@677: // Node aNode(InEdgeIt) const {} hegyi@677: // Node aNode(OutEdgeIt) const {} hegyi@677: // Node aNode(SymEdgeIt) const {} hegyi@677: hegyi@677: // Node bNode(InEdgeIt) const {} hegyi@677: // Node bNode(OutEdgeIt) const {} hegyi@677: // Node bNode(SymEdgeIt) const {} hegyi@677: hegyi@677: /// Checks if a node iterator is valid hegyi@677: hegyi@677: ///\todo Maybe, it would be better if iterator converted to hegyi@677: ///bool directly, as Jacint prefers. hegyi@691: bool valid (const typename Gact::Node & node) const hegyi@691: { hegyi@691: return actuallayer.valid (node); hegyi@691: } hegyi@677: /// Checks if an edge iterator is valid hegyi@677: hegyi@677: ///\todo Maybe, it would be better if iterator converted to hegyi@677: ///bool directly, as Jacint prefers. hegyi@691: bool valid (const typename Gact::Edge & edge) const hegyi@691: { hegyi@691: return actuallayer.valid (edge); hegyi@691: } hegyi@677: hegyi@677: ///Gives back the \e id of a node. hegyi@677: hegyi@677: ///\warning Not all graph structures provide this feature. hegyi@677: /// hegyi@691: int id (const typename Gact::Node & node) const hegyi@691: { hegyi@691: return actuallayer.id (node); hegyi@691: } hegyi@677: ///Gives back the \e id of an edge. hegyi@677: hegyi@677: ///\warning Not all graph structures provide this feature. hegyi@677: /// hegyi@691: int id (const typename Gact::Edge & edge) const hegyi@691: { hegyi@691: return actuallayer.id (edge); hegyi@691: } hegyi@677: hegyi@677: //void setInvalid(Node &) const {}; hegyi@677: //void setInvalid(Edge &) const {}; hegyi@690: hegyi@677: ///Add a new node to the graph. hegyi@677: hegyi@677: /// \return the new node. hegyi@677: /// hegyi@691: typename Gact::Node addNode () hegyi@691: { hegyi@691: return actuallayer.addNode (); hegyi@691: } hegyi@677: ///Add a new edge to the graph. hegyi@677: hegyi@677: ///Add a new edge to the graph with tail node \c tail hegyi@677: ///and head node \c head. hegyi@677: ///\return the new edge. hegyi@691: typename Gact::Edge addEdge (typename Gact::Node node1, hegyi@691: typename Gact::Node node2) hegyi@691: { hegyi@691: return actuallayer.addEdge (node1, node2); hegyi@691: } hegyi@690: hegyi@677: /// Resets the graph. hegyi@677: hegyi@677: /// This function deletes all edges and nodes of the graph. hegyi@677: /// It also frees the memory allocated to store them. hegyi@691: void clear () hegyi@691: { hegyi@691: actuallayer.clear (); hegyi@691: } hegyi@677: hegyi@691: int nodeNum () const hegyi@691: { hegyi@691: return actuallayer.nodeNum (); hegyi@691: } hegyi@691: int edgeNum () const hegyi@691: { hegyi@691: return actuallayer.edgeNum (); hegyi@691: } hegyi@677: hegyi@677: ///Read/write/reference map of the nodes to type \c T. hegyi@677: hegyi@677: ///Read/write/reference map of the nodes to type \c T. hegyi@677: /// \sa MemoryMapSkeleton hegyi@677: /// \todo We may need copy constructor hegyi@677: /// \todo We may need conversion from other nodetype hegyi@677: /// \todo We may need operator= hegyi@677: /// \warning Making maps that can handle bool type (NodeMap) hegyi@677: /// needs extra attention! hegyi@677: hegyi@691: template < class T > class NodeMap hegyi@677: { hegyi@677: public: hegyi@677: typedef T ValueType; hegyi@677: typedef Node KeyType; hegyi@677: hegyi@691: NodeMap (const HierarchyGraph &) hegyi@691: { hegyi@691: } hegyi@691: NodeMap (const HierarchyGraph &, T) hegyi@691: { hegyi@691: } hegyi@677: hegyi@691: template < typename TT > NodeMap (const NodeMap < TT > &) hegyi@691: { hegyi@691: } hegyi@677: hegyi@677: /// Sets the value of a node. hegyi@677: hegyi@677: /// Sets the value associated with node \c i to the value \c t. hegyi@677: /// hegyi@691: void set (Node, T) hegyi@691: { hegyi@691: } hegyi@677: // Gets the value of a node. hegyi@677: //T get(Node i) const {return *(T*)0;} //FIXME: Is it necessary? hegyi@691: T & operator[](Node) hegyi@691: { hegyi@691: return *(T *) 0; hegyi@691: } hegyi@691: const T & operator[] (Node) const hegyi@691: { hegyi@691: return *(T *) 0; hegyi@691: } hegyi@677: hegyi@677: /// Updates the map if the graph has been changed hegyi@677: hegyi@677: /// \todo Do we need this? hegyi@677: /// hegyi@691: void update () hegyi@691: { hegyi@691: } hegyi@691: void update (T a) hegyi@691: { hegyi@691: } //FIXME: Is it necessary hegyi@677: }; hegyi@677: hegyi@677: ///Read/write/reference map of the edges to type \c T. hegyi@677: hegyi@677: ///Read/write/reference map of the edges to type \c T. hegyi@677: ///It behaves exactly in the same way as \ref NodeMap. hegyi@677: /// \sa NodeMap hegyi@677: /// \sa MemoryMapSkeleton hegyi@677: /// \todo We may need copy constructor hegyi@677: /// \todo We may need conversion from other edgetype hegyi@677: /// \todo We may need operator= hegyi@691: template < class T > class EdgeMap hegyi@677: { hegyi@677: public: hegyi@677: typedef T ValueType; hegyi@677: typedef Edge KeyType; hegyi@677: hegyi@691: EdgeMap (const HierarchyGraph &) hegyi@691: { hegyi@691: } hegyi@691: EdgeMap (const HierarchyGraph &, T) hegyi@691: { hegyi@691: } hegyi@690: hegyi@677: ///\todo It can copy between different types. hegyi@677: /// hegyi@691: template < typename TT > EdgeMap (const EdgeMap < TT > &) hegyi@691: { hegyi@691: } hegyi@677: hegyi@691: void set (Edge, T) hegyi@691: { hegyi@691: } hegyi@677: //T get(Edge) const {return *(T*)0;} hegyi@691: T & operator[](Edge) hegyi@691: { hegyi@691: return *(T *) 0; hegyi@691: } hegyi@691: const T & operator[] (Edge) const hegyi@691: { hegyi@691: return *(T *) 0; hegyi@691: } hegyi@690: hegyi@691: void update () hegyi@691: { hegyi@691: } hegyi@691: void update (T a) hegyi@691: { hegyi@691: } //FIXME: Is it necessary hegyi@677: }; hegyi@677: }; hegyi@677: hegyi@677: /// An empty eraseable graph class. hegyi@690: hegyi@677: /// This class provides all the common features of an \e eraseable graph hegyi@677: /// structure, hegyi@677: /// however completely without implementations and real data structures hegyi@677: /// behind the interface. hegyi@677: /// All graph algorithms should compile with this class, but it will not hegyi@677: /// run properly, of course. hegyi@677: /// hegyi@677: /// \todo This blabla could be replaced by a sepatate description about hegyi@677: /// Skeletons. hegyi@677: /// hegyi@677: /// It can be used for checking the interface compatibility, hegyi@677: /// or it can serve as a skeleton of a new graph structure. hegyi@690: /// hegyi@677: /// Also, you will find here the full documentation of a certain graph hegyi@677: /// feature, the documentation of a real graph imlementation hegyi@677: /// like @ref ListGraph or hegyi@677: /// @ref SmartGraph will just refer to this structure. hegyi@691: template < typename Gact, typename Gsub > class EraseableHierarchyGraph:public HierarchyGraph < Gact, hegyi@691: Gsub hegyi@691: > hegyi@677: { hegyi@677: public: hegyi@677: /// Deletes a node. hegyi@691: void erase (typename Gact::Node n) hegyi@691: { hegyi@691: actuallayer.erase (n); hegyi@691: } hegyi@677: /// Deletes an edge. hegyi@691: void erase (typename Gact::Edge e) hegyi@691: { hegyi@691: actuallayer.erase (e); hegyi@691: } hegyi@677: hegyi@677: /// Defalult constructor. hegyi@691: EraseableHierarchyGraph () hegyi@691: { hegyi@691: } hegyi@677: ///Copy consructor. hegyi@691: EraseableHierarchyGraph (const HierarchyGraph < Gact, Gsub > &EPG) hegyi@691: { hegyi@691: } hegyi@677: }; hegyi@677: hegyi@690: hegyi@677: // @} hegyi@677: hegyi@691: } //namespace hugo hegyi@677: hegyi@677: hegyi@677: #endif // HUGO_SKELETON_GRAPH_H