#line 1 "/user/cvsspst/ees1cg/RAVL/RAVL-0.7/Core/Container/Graph/Graph.hh" // This file is part of RAVL, Recognition And Vision Library // Copyright (C) 2001, University of Surrey // This code may be redistributed under the terms of the GNU Lesser // General Public License (LGPL). See the lgpl.licence file for details or // see http://www.gnu.org/copyleft/lesser.html // file-header-ends-here #ifndef RAVL_GRAPH_HEADER #define RAVL_GRAPH_HEADER 1 ////////////////////////////////////////////////////////////// //! file="Ravl/Core/Container/Graph/Graph.hh" //! lib=RavlCore //! author="Charles Galambos" //! date="10/12/1996" //! docentry="Ravl.Core.Graphs" //! rcsid="$Id: Graph.hh,v 1.4 2002/08/08 15:37:22 craftit Exp $" //! userlevel=Normal //! example=exGraph.cc #include "Ravl/GraphBase.hh" #include "Ravl/Hash.hh" namespace RavlN { template class GraphC; template class GraphNodeIterC; template class GraphNodeHC; template class GraphEdgeIterC; template class GraphLinearIterC; //! userlevel=Normal //: Templated graphs. template class GraphC : public GraphBaseC { public: GraphC(GraphTypeT type = GRAPH_DIRECTED) : GraphBaseC(type) {} //: Creates an empty graph, directed or undirected. GraphC(const GraphC & g) : GraphBaseC(g) {} //: Creates another access to the graph 'g'. // The constructor does not // change the content of the graph 'g', but its reference counting. // However, the content of the graph 'g' can be changed through // the this new access later. ~GraphC() {} //: Destructor. typedef GraphEdgeIterC EdgeIter; typedef GraphNodeIterC NodeIter; typedef GraphC Graph; inline GraphC Copy(); //: Make a copy of this graph. GraphC Copy(HashC & NodeMap); //: Make a copy of this graph. // The mapping between new and old nodes is in NodeMap. const GraphC & operator=(const GraphC & g) { GraphBaseC::operator=(g); return *this; } //: Creates another access to the graph 'g'. // The assigment does not // change the content of the graph 'g', but its reference counting. // However, the content of the graph 'g' can be changed through // the this new access later. //:------------------------------------------ //: Creation of graph structure. inline GraphNodeIterC InsNode(const NodeT &Dat); //: Inserts one node to the graph. // Returns the node iterator pointing to the new element. inline GraphEdgeIterC InsEdge(NodeIter &fromNode, NodeIter &toNode, const EdgeT &Dat ); //: Inserts one egde to the graph. // Returns an edge iterator pointing to the new element. inline GraphEdgeIterC InsEdge(const GraphNodeHC &fromNode, const GraphNodeHC &toNode, const EdgeT &Dat ); //: Inserts one egde to the graph. // Returns an edge iterator pointing to the new element. UIntT NoNodes() const { return Nodes().Size(); } //: Count the number of nodes in the graph. // This actuall iterates through the list and so is slow. UIntT NoEdges() const { return Edges().Size(); } //: Count the number of edges in the graph. // This actuall iterates through the list and so is slow. //:--------------------------------------- //: Tests on graph structure. bool IsCyclic() { return GraphBaseC::IsCyclic(); } //: Test if a directed graph contains cycles. protected: GraphBaseBodyC &Body() { return GraphBaseC::Body(); } //: Access body. const GraphBaseBodyC &Body() const { return GraphBaseC::Body(); } //: Access body. friend class GraphNodeIterC; friend class GraphEdgeIterC; friend class GraphLinearIterC; }; } #include "Ravl/GraphNode.hh" #include "Ravl/GraphEdge.hh" namespace RavlN { /////////////////////////////// // Make a copy of this graph. template inline GraphC GraphC::Copy() { HashC NodeMap; return Copy(NodeMap); } /////////////////////////////// // Make a copy of this graph, return Node-Map. template GraphC GraphC::Copy(HashC,GraphNodeIterC > &NodeMap) { GraphC Newun; for(GraphNodeIterC NIt(*this);NIt.IsElm();NIt.Next()) NodeMap[NIt] = Newun.InsNode(NIt.Data()); for(GraphEdgeIterC EIt(*this);EIt.IsElm();EIt.Next()) Newun.InsEdge(NodeMap[EIt.Source()],NodeMap[EIt.Target()],EIt.Data()); return Newun; } /////////////////////////////// // Inserts one node to the graph. Returns the node iterator. template inline GraphNodeIterC GraphC::InsNode(const NodeT &dat) { return GraphNodeIterC(GraphBaseC::InsNode(*new GraphNodeDatC(Body(), dat, AllocNodeID() ))); } ////////////////////////////////// // Inserts one egde to the graph. Returns the edge iterator. template inline GraphEdgeIterC GraphC::InsEdge(GraphNodeIterC &fromNode, GraphNodeIterC & toNode, const EdgeT &Dat) { return GraphEdgeIterC(GraphBaseC::InsEdge(*new GraphEdgeDatC(fromNode.NodeRep(), toNode.NodeRep(), Dat, AllocEdgeID()))); } template inline GraphEdgeIterC GraphC::InsEdge(const GraphNodeHC &fromNode, const GraphNodeHC &toNode, const EdgeT &Dat ) { return GraphEdgeIterC(GraphBaseC::InsEdge(*new GraphEdgeDatC(fromNode.NodeRep(), toNode.NodeRep(), Dat, AllocEdgeID()))); } //: Write graph out to a stream. template ostream &operator<<(ostream &out,const GraphC &g) { HashC,UIntT > nodeMap; // Output all the nodes and give them an id each. out << g.NoNodes() << "\n"; // Write the number of nodes. UIntT id = 1; for(GraphNodeIterC nIt(const_cast &>(g));nIt;nIt++) { nodeMap[GraphNodeHC(nIt)] = id++; out << nIt.Data() << "\n"; } for(GraphEdgeIterC nIt(const_cast &>(g));nIt;nIt++) { out << nodeMap[nIt.SourceH()] << " " << nodeMap[nIt.TargetH()] << "\n"; out << nIt.Data() << "\n"; } out << "0\n"; // Write end of edge marker. return out; } //: Read graph from a stream. template istream &operator>>(istream &in,GraphC &g) { HashC< UIntT,GraphNodeHC > nodeMap; // Output all the nodes and give them an id each. UIntT nodes; in >> nodes; UIntT id = 1; for(;id <= nodes;id++) { NodeT dat; in >> dat; nodeMap[id] = g.InsNode(dat); } UIntT n1,n2; while(1) { in >> n1; if(n1 == 0) // Got terminator ? break; in >> n2; EdgeT dat; in >> dat; g.InsEdge(nodeMap[n1],nodeMap[n2],dat); } return in; } } #endif