1.1 --- a/src/work/alpar/fullgraph.h Sun May 09 16:22:49 2004 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,295 +0,0 @@
1.4 -// -*- mode:C++ -*-
1.5 -
1.6 -#ifndef HUGO_FULL_GRAPH_H
1.7 -#define HUGO_FULL_GRAPH_H
1.8 -
1.9 -///\ingroup graphs
1.10 -///\file
1.11 -///\brief FullGraph and SymFullGraph classes.
1.12 -
1.13 -#include <vector>
1.14 -#include <limits.h>
1.15 -
1.16 -#include <hugo/invalid.h>
1.17 -
1.18 -namespace hugo {
1.19 -
1.20 -/// \addtogroup graphs
1.21 -/// @{
1.22 -
1.23 - ///A full graph class.
1.24 -
1.25 - ///This is a simple and fast directed full graph implementation.
1.26 - ///It it completely static, so you can neither add nor delete either
1.27 - ///edges or nodes.
1.28 - ///Otherwise it conforms to the graph interface documented under
1.29 - ///the description of \ref GraphSkeleton.
1.30 - ///\sa \ref GraphSkeleton.
1.31 - ///\todo Shouldn't we avoid loops?
1.32 - ///
1.33 - ///\author Alpar Juttner
1.34 - class FullGraph {
1.35 - int NodeNum;
1.36 - int EdgeNum;
1.37 - public:
1.38 - template <typename T> class EdgeMap;
1.39 - template <typename T> class NodeMap;
1.40 -
1.41 - class Node;
1.42 - class Edge;
1.43 - class NodeIt;
1.44 - class EdgeIt;
1.45 - class OutEdgeIt;
1.46 - class InEdgeIt;
1.47 -
1.48 - template <typename T> class NodeMap;
1.49 - template <typename T> class EdgeMap;
1.50 -
1.51 - public:
1.52 -
1.53 - ///Creates a full graph with \c n nodes.
1.54 - FullGraph(int n) : NodeNum(n), EdgeNum(NodeNum*NodeNum) { }
1.55 - ///
1.56 - FullGraph(const FullGraph &_g)
1.57 - : NodeNum(_g.nodeNum()), EdgeNum(NodeNum*NodeNum) { }
1.58 -
1.59 - int nodeNum() const { return NodeNum; } //FIXME: What is this?
1.60 - int edgeNum() const { return EdgeNum; } //FIXME: What is this?
1.61 -
1.62 - int maxNodeId() const { return NodeNum; } //FIXME: What is this?
1.63 - int maxEdgeId() const { return EdgeNum; } //FIXME: What is this?
1.64 -
1.65 - Node tail(Edge e) const { return e.n%NodeNum; }
1.66 - Node head(Edge e) const { return e.n/NodeNum; }
1.67 -
1.68 - Node aNode(OutEdgeIt e) const { return tail(e); }
1.69 - Node aNode(InEdgeIt e) const { return head(e); }
1.70 -
1.71 - Node bNode(OutEdgeIt e) const { return head(e); }
1.72 - Node bNode(InEdgeIt e) const { return tail(e); }
1.73 -
1.74 - NodeIt& first(NodeIt& v) const {
1.75 - v=NodeIt(*this); return v; }
1.76 - EdgeIt& first(EdgeIt& e) const {
1.77 - e=EdgeIt(*this); return e; }
1.78 - OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
1.79 - e=OutEdgeIt(*this,v); return e; }
1.80 - InEdgeIt& first(InEdgeIt& e, const Node v) const {
1.81 - e=InEdgeIt(*this,v); return e; }
1.82 -
1.83 - bool valid(Edge e) const { return e.n!=-1; }
1.84 - bool valid(Node n) const { return n.n!=-1; }
1.85 -
1.86 - template <typename It> It getNext(It it) const
1.87 - { It tmp(it); return next(tmp); }
1.88 -
1.89 - NodeIt& next(NodeIt& it) const {
1.90 - it.n=(it.n+2)%(NodeNum+1)-1;
1.91 - return it;
1.92 - }
1.93 - OutEdgeIt& next(OutEdgeIt& it) const
1.94 - { it.n+=NodeNum; if(it.n>=EdgeNum) it.n=-1; return it; }
1.95 - InEdgeIt& next(InEdgeIt& it) const
1.96 - { if(!((++it.n)%NodeNum)) it.n=-1; return it; }
1.97 - EdgeIt& next(EdgeIt& it) const { --it.n; return it; }
1.98 -
1.99 - int id(Node v) const { return v.n; }
1.100 - int id(Edge e) const { return e.n; }
1.101 -
1.102 - class Node {
1.103 - friend class FullGraph;
1.104 - template <typename T> friend class NodeMap;
1.105 -
1.106 - friend class Edge;
1.107 - friend class OutEdgeIt;
1.108 - friend class InEdgeIt;
1.109 - friend class SymEdge;
1.110 -
1.111 - protected:
1.112 - int n;
1.113 - friend int FullGraph::id(Node v) const;
1.114 - Node(int nn) {n=nn;}
1.115 - public:
1.116 - Node() {}
1.117 - Node (Invalid) { n=-1; }
1.118 - bool operator==(const Node i) const {return n==i.n;}
1.119 - bool operator!=(const Node i) const {return n!=i.n;}
1.120 - bool operator<(const Node i) const {return n<i.n;}
1.121 - };
1.122 -
1.123 - class NodeIt : public Node {
1.124 - friend class FullGraph;
1.125 - public:
1.126 - NodeIt() : Node() { }
1.127 - NodeIt(Invalid i) : Node(i) { }
1.128 - NodeIt(const FullGraph& G) : Node(G.NodeNum?0:-1) { }
1.129 - ///\todo Undocumented conversion Node -\> NodeIt.
1.130 - NodeIt(const FullGraph& G, const Node &n) : Node(n) { }
1.131 - };
1.132 -
1.133 - class Edge {
1.134 - friend class FullGraph;
1.135 - template <typename T> friend class EdgeMap;
1.136 -
1.137 - friend class Node;
1.138 - friend class NodeIt;
1.139 - protected:
1.140 - int n; //NodeNum*head+tail;
1.141 - friend int FullGraph::id(Edge e) const;
1.142 -
1.143 - Edge(int nn) {n=nn;}
1.144 - public:
1.145 - Edge() { }
1.146 - Edge (Invalid) { n=-1; }
1.147 - bool operator==(const Edge i) const {return n==i.n;}
1.148 - bool operator!=(const Edge i) const {return n!=i.n;}
1.149 - bool operator<(const Edge i) const {return n<i.n;}
1.150 - ///\bug This is a workaround until somebody tells me how to
1.151 - ///make class \c SymFullGraph::SymEdgeMap friend of Edge
1.152 - int &idref() {return n;}
1.153 - const int &idref() const {return n;}
1.154 - };
1.155 -
1.156 - class EdgeIt : public Edge {
1.157 - friend class FullGraph;
1.158 - public:
1.159 - EdgeIt(const FullGraph& G) : Edge(G.EdgeNum-1) { }
1.160 - EdgeIt (Invalid i) : Edge(i) { }
1.161 - EdgeIt() : Edge() { }
1.162 - ///\bug This is a workaround until somebody tells me how to
1.163 - ///make class \c SymFullGraph::SymEdgeMap friend of Edge
1.164 - int &idref() {return n;}
1.165 - };
1.166 -
1.167 - class OutEdgeIt : public Edge {
1.168 - friend class FullGraph;
1.169 - public:
1.170 - OutEdgeIt() : Edge() { }
1.171 - OutEdgeIt (Invalid i) : Edge(i) { }
1.172 -
1.173 - OutEdgeIt(const FullGraph& G,const Node v)
1.174 - : Edge(v.n) {}
1.175 - };
1.176 -
1.177 - class InEdgeIt : public Edge {
1.178 - friend class FullGraph;
1.179 - public:
1.180 - InEdgeIt() : Edge() { }
1.181 - InEdgeIt (Invalid i) : Edge(i) { }
1.182 - InEdgeIt(const FullGraph& G,Node v) :Edge(v.n*G.NodeNum){}
1.183 - };
1.184 -
1.185 - template <typename T> class NodeMap
1.186 - {
1.187 - std::vector<T> container;
1.188 -
1.189 - public:
1.190 - typedef T ValueType;
1.191 - typedef Node KeyType;
1.192 -
1.193 - NodeMap(const FullGraph &_G) : container(_G.NodeNum) { }
1.194 - NodeMap(const FullGraph &_G,const T &t) : container(_G.NodeNum,t) { }
1.195 - NodeMap(const NodeMap<T> &m) : container(m.container) { }
1.196 -
1.197 - template<typename TT> friend class NodeMap;
1.198 - ///\todo It can copy between different types.
1.199 - template<typename TT> NodeMap(const NodeMap<TT> &m)
1.200 - : container(m.container.size())
1.201 - {
1.202 - typename std::vector<TT>::const_iterator i;
1.203 - for(typename std::vector<TT>::const_iterator i=m.container.begin();
1.204 - i!=m.container.end();
1.205 - i++)
1.206 - container.push_back(*i);
1.207 - }
1.208 - void set(Node n, T a) { container[n.n]=a; }
1.209 - //'T& operator[](Node n)' would be wrong here
1.210 - typename std::vector<T>::reference
1.211 - operator[](Node n) { return container[n.n]; }
1.212 - //'const T& operator[](Node n)' would be wrong here
1.213 - typename std::vector<T>::const_reference
1.214 - operator[](Node n) const { return container[n.n]; }
1.215 -
1.216 - ///\warning There is no safety check at all!
1.217 - ///Using operator = between maps attached to different graph may
1.218 - ///cause serious problem.
1.219 - ///\todo Is this really so?
1.220 - ///\todo It can copy between different types.
1.221 - const NodeMap<T>& operator=(const NodeMap<T> &m)
1.222 - {
1.223 - container = m.container;
1.224 - return *this;
1.225 - }
1.226 - template<typename TT>
1.227 - const NodeMap<T>& operator=(const NodeMap<TT> &m)
1.228 - {
1.229 - std::copy(m.container.begin(), m.container.end(), container.begin());
1.230 - return *this;
1.231 - }
1.232 -
1.233 - void update() {} //Useless for Dynamic Maps
1.234 - void update(T a) {} //Useless for Dynamic Maps
1.235 - };
1.236 -
1.237 - template <typename T> class EdgeMap
1.238 - {
1.239 - std::vector<T> container;
1.240 -
1.241 - public:
1.242 - typedef T ValueType;
1.243 - typedef Edge KeyType;
1.244 -
1.245 - EdgeMap(const FullGraph &_G) : container(_G.EdgeNum) { }
1.246 - EdgeMap(const FullGraph &_G,const T &t) : container(_G.EdgeNum,t) { }
1.247 - EdgeMap(const EdgeMap<T> &m) : container(m.container) { }
1.248 -
1.249 - template<typename TT> friend class EdgeMap;
1.250 - ///\todo It can copy between different types.
1.251 - ///\todo We could use 'copy'
1.252 - template<typename TT> EdgeMap(const EdgeMap<TT> &m) :
1.253 - container(m.container.size())
1.254 - {
1.255 - typename std::vector<TT>::const_iterator i;
1.256 - for(typename std::vector<TT>::const_iterator i=m.container.begin();
1.257 - i!=m.container.end();
1.258 - i++)
1.259 - container.push_back(*i);
1.260 - }
1.261 - void set(Edge n, T a) { container[n.n]=a; }
1.262 - //T get(Edge n) const { return container[n.n]; }
1.263 - typename std::vector<T>::reference
1.264 - operator[](Edge n) { return container[n.n]; }
1.265 - typename std::vector<T>::const_reference
1.266 - operator[](Edge n) const { return container[n.n]; }
1.267 -
1.268 - ///\warning There is no safety check at all!
1.269 - ///Using operator = between maps attached to different graph may
1.270 - ///cause serious problem.
1.271 - ///\todo Is this really so?
1.272 - ///\todo It can copy between different types.
1.273 - const EdgeMap<T>& operator=(const EdgeMap<T> &m)
1.274 - {
1.275 - container = m.container;
1.276 - return *this;
1.277 - }
1.278 - template<typename TT>
1.279 - const EdgeMap<T>& operator=(const EdgeMap<TT> &m)
1.280 - {
1.281 - std::copy(m.container.begin(), m.container.end(), container.begin());
1.282 - return *this;
1.283 - }
1.284 -
1.285 - void update() {}
1.286 - void update(T a) {}
1.287 - };
1.288 -
1.289 - };
1.290 -
1.291 - /// @}
1.292 -
1.293 -} //namespace hugo
1.294 -
1.295 -
1.296 -
1.297 -
1.298 -#endif //HUGO_FULL_GRAPH_H