graph.h

Go to the documentation of this file.
00001 // Copyright (C) 2006 Ivo Nowak and Stefan Vigerske
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Author: Stefan Vigerske
00006 
00007 #ifndef GRAPH_H
00008 #define GRAPH_H
00009 #include "standard.h"
00010 
00011 template <typename NodeDataType=int, typename EdgeDataType=int, bool multi_edges=false> class Edge;
00012 
00013 // -------------------------------- Node ------------------------------------
00014 
00015 template <typename NodeDataType=int, typename EdgeDataType=int, bool multi_edges=false> struct NodeAdj;
00016 template <typename NodeDataType, typename EdgeDataType> struct NodeAdj<NodeDataType,EdgeDataType,false> {
00017         typedef Edge<NodeDataType, EdgeDataType, false> EdgeType;
00018         typedef map<int, typename set<EdgeType>::iterator> adj_type;
00019 };
00020 template <typename NodeDataType, typename EdgeDataType> struct NodeAdj<NodeDataType,EdgeDataType,true> {
00021         typedef Edge<NodeDataType, EdgeDataType, true> EdgeType;
00022         typedef multimap<int, typename set<EdgeType>::iterator> adj_type;
00023 };
00024 
00025 template <typename NodeDataType=int, typename EdgeDataType=int, bool multi_edges=false> class Node {
00026                 friend ostream& operator<<(ostream& out, const Node<NodeDataType,EdgeDataType,multi_edges>& node) {
00027                         out << node.index << '(' << node.data << ')' << ':';
00028                         for (typename Node<NodeDataType,EdgeDataType,multi_edges>::adj_type::const_iterator it(node.adj.begin()); it!=node.adj.end(); ++it)
00029                                 out << ' ' << it->first << '(' << it->second->data << ')';
00030                         return out;
00031                 }
00032 
00033         public:
00034                 typedef typename NodeAdj<NodeDataType,EdgeDataType,multi_edges>::adj_type adj_type;
00035 
00036         private:
00037                 unsigned int index;
00038 
00039                 mutable adj_type adj;
00040 
00041                 typedef Node<NodeDataType, EdgeDataType, multi_edges> NodeType;
00042                 typedef Edge<NodeDataType, EdgeDataType, multi_edges> EdgeType;
00043 
00044         public:
00045                 mutable NodeDataType data;
00046 
00047                 Node(unsigned int index_, const NodeDataType& data_=NodeDataType())
00048                 : index(index_), data(data_)
00049                 { }
00050 
00051                 unsigned int idx() const { return index; }
00052 
00053                 bool operator<(const NodeType& node) const {
00054                         return index<node.index;
00055                 }
00056 
00057                 void add_data(const NodeDataType& data2) const { data+=data2; }
00058                 void add_neighbour(int neighbour_index, typename set<EdgeType>::iterator& edge) const {
00059                         adj.insert(typename adj_type::value_type(neighbour_index, edge));
00060                 }
00061 
00062                 const adj_type& get_adj() const { return adj; }
00063 };
00064 
00065 // -------------------------------- Edge ------------------------------------
00066 
00067 template <typename NodeDataType, typename EdgeDataType> class Edge<NodeDataType, EdgeDataType, false> {
00068         private:
00069                 typedef Node<NodeDataType, EdgeDataType, false> NodeType;
00070                 typedef Edge<NodeDataType, EdgeDataType, false> EdgeType;
00071 
00072                 typename set<NodeType>::iterator node1, node2;
00073 
00074         public:
00075                 mutable EdgeDataType data;
00076 
00077                 Edge(const typename set<NodeType>::iterator& node1_, const typename set<NodeType>::iterator& node2_, const EdgeDataType& data_=EdgeDataType())
00078                 : node1(node1_), node2(node2_), data(data_)
00079                 { }
00080 
00081                 void add_data(const EdgeDataType& data2) const { data+=data2; }
00082 
00083                 bool operator<(const EdgeType& e) const {
00084                         return pair<unsigned int,unsigned int>(node1->idx(), node2->idx())<pair<unsigned int, unsigned int>(e.node1->idx(), e.node2->idx());
00085                 }
00086 
00087                 const NodeType& get_node1() const { return *node1; }
00088                 const NodeType& get_node2() const { return *node2; }
00089 
00090 /*
00091                                 Node& neighbour(const Node& node) const {
00092                                         return (&node==&node1->second) ? node2->second : node1->second;
00093                                 }
00094 */
00095 
00096 };
00097 
00098 // -------------------------------- MultiEdge ------------------------------------
00099 
00100 template <typename NodeDataType, typename EdgeDataType> class Edge<NodeDataType, EdgeDataType, true> {
00101         private:
00102                 typedef Node<NodeDataType, EdgeDataType, true> NodeType;
00103                 typedef Edge<NodeDataType, EdgeDataType, true> EdgeType;
00104 
00105                 typename set<NodeType>::iterator node1, node2;
00106 
00107         public:
00108                 EdgeDataType data;
00109 
00110                 Edge(const typename set<NodeType>::iterator& node1_, const typename set<NodeType>::iterator& node2_, const EdgeDataType& data_=EdgeDataType())
00111                 : node1(node1_), node2(node2_), data(data_)
00112                 { }
00113 
00114                 void add_data(const EdgeDataType& data2) const { data+=data2; }
00115 
00116                 bool operator<(const EdgeType& e) const {
00117                         if (node1->idx()==e.node1->idx() && node2->idx()==e.node2->idx()) return data<e.data;
00118                         return pair<unsigned int,unsigned int>(node1->idx(), node2->idx())<pair<unsigned int, unsigned int>(e.node1->idx(), e.node2->idx());
00119                 }
00120 
00121                 const NodeType& get_node1() const { return *node1; }
00122                 const NodeType& get_node2() const { return *node2; }
00123 };
00124 
00125 // -------------------------------- Graph ---------------------------------------
00126 
00127 template <typename NodeDataType=int, typename EdgeDataType=int, bool directed=false, bool multi_edges=false> class Graph {
00128                 friend ostream& operator<<(ostream& out, const Graph<NodeDataType,EdgeDataType,directed,multi_edges>& g) {
00129                         out << g.n() << " nodes, " << g.m() << " edges:" << endl;
00130                         for (typename set<Node<NodeDataType, EdgeDataType, multi_edges> >::const_iterator it(g.nodes.begin()); it!=g.nodes.end(); ++it)
00131                                 out << *it << endl;
00132                         return out;
00133                 }
00134 
00135         public:
00136                 typedef Node<NodeDataType, EdgeDataType, multi_edges> NodeType;
00137                 typedef Edge<NodeDataType, EdgeDataType, multi_edges> EdgeType;
00138 
00139                 set<NodeType> nodes;
00140                 set<EdgeType> edges;
00141 
00142                 typename set<NodeType>::iterator add_node(unsigned int index, const NodeDataType& data=NodeDataType());
00143                 const NodeType& get_node(unsigned int index) const;
00144 
00145                 typename set<EdgeType>::iterator add_edge(typename set<NodeType>::iterator node1, typename set<NodeType>::iterator node2, const EdgeDataType& data=EdgeDataType());
00146                 typename set<EdgeType>::iterator add_edge(unsigned int index1, unsigned int index2, const EdgeDataType& data=EdgeDataType());
00147 
00151         int n() const { return nodes.size(); }
00152 
00156         int m() const { return edges.size(); }
00157 
00158                 void clear() { nodes.clear(); edges.clear(); }
00159 
00160 };
00161 
00162 template<typename NodeDataType, typename EdgeDataType, bool directed, bool multi_edges>
00163 typename set<Node<NodeDataType, EdgeDataType, multi_edges> >::iterator Graph<NodeDataType,EdgeDataType,directed,multi_edges>::add_node(unsigned int index, const NodeDataType& data) {
00164         pair<typename set<NodeType>::iterator, bool> ret(nodes.insert(NodeType(index, data)));
00165         if (!ret.second) ret.first->add_data(data);
00166         return ret.first;
00167 }
00168 
00169 template<typename NodeDataType, typename EdgeDataType, bool directed, bool multi_edges>
00170 const Node<NodeDataType,EdgeDataType,multi_edges>& Graph<NodeDataType,EdgeDataType,directed,multi_edges>::get_node(unsigned int index) const {
00171         typename set<NodeType>::const_iterator it(nodes.find(NodeType(index)));
00172         assert(it!=nodes.end());
00173         assert(index==it->idx());
00174         return *it;
00175 }
00176 
00177 template<typename NodeDataType, typename EdgeDataType, bool directed, bool multi_edges>
00178 typename set<Edge<NodeDataType, EdgeDataType, multi_edges> >::iterator Graph<NodeDataType,EdgeDataType,directed,multi_edges>::add_edge(typename set<NodeType>::iterator node1, typename set<NodeType>::iterator node2, const EdgeDataType& data) {
00179         assert(node1->idx()!=node2->idx()); // do not allow loops
00180         if ((!directed) && node1->idx()>node2->idx()) return add_edge(node2, node1, data);
00181 
00182         pair<typename set<EdgeType>::iterator, bool> ret(edges.insert(EdgeType(node1, node2, data)));
00183         if (!ret.second) { // edge already there
00184                 ret.first->add_data(data);
00185                 return ret.first;
00186         }
00187 
00188         node1->add_neighbour(node2->idx(), ret.first);
00189         if (!directed) node2->add_neighbour(node1->idx(), ret.first);
00190         return ret.first;
00191 }
00192 
00193 template<typename NodeDataType, typename EdgeDataType, bool directed, bool multi_edges>
00194 typename set<Edge<NodeDataType, EdgeDataType, multi_edges> >::iterator Graph<NodeDataType,EdgeDataType,directed,multi_edges>::add_edge(unsigned int index1, unsigned int index2, const EdgeDataType& data) {
00195         typename set<NodeType>::iterator node1(add_node(index1));
00196         typename set<NodeType>::iterator node2(add_node(index2));
00197         return add_edge(node1, node2, data);
00198 }
00199 
00200 #endif // GRAPH_H

Generated on Mon Oct 20 03:12:05 2008 for LaGO by  doxygen 1.4.7