[Lemon-commits] [lemon_svn] alpar: r770 - hugo/trunk/src/work/alpar
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:41:24 CET 2006
Author: alpar
Date: Sun May 9 18:22:49 2004
New Revision: 770
Added:
hugo/trunk/src/work/alpar/fullgraph.h
- copied, changed from r766, /hugo/trunk/src/hugo/smart_graph.h
Log:
FullGraph class.
Copied: hugo/trunk/src/work/alpar/fullgraph.h (from r766, /hugo/trunk/src/hugo/smart_graph.h)
==============================================================================
--- /hugo/trunk/src/hugo/smart_graph.h (original)
+++ hugo/trunk/src/work/alpar/fullgraph.h Sun May 9 18:22:49 2004
@@ -1,11 +1,11 @@
// -*- mode:C++ -*-
-#ifndef HUGO_SMART_GRAPH_H
-#define HUGO_SMART_GRAPH_H
+#ifndef HUGO_FULL_GRAPH_H
+#define HUGO_FULL_GRAPH_H
///\ingroup graphs
///\file
-///\brief SmartGraph and SymSmartGraph classes.
+///\brief FullGraph and SymFullGraph classes.
#include <vector>
#include <limits.h>
@@ -16,71 +16,27 @@
/// \addtogroup graphs
/// @{
- class SymSmartGraph;
- ///A smart graph class.
+ ///A full graph class.
- ///This is a simple and fast graph implementation.
- ///It is also quite memory efficient, but at the price
- ///that <b> it does not support node and edge deletion</b>.
- ///It conforms to the graph interface documented under
+ ///This is a simple and fast directed full graph implementation.
+ ///It it completely static, so you can neither add nor delete either
+ ///edges or nodes.
+ ///Otherwise it conforms to the graph interface documented under
///the description of \ref GraphSkeleton.
///\sa \ref GraphSkeleton.
+ ///\todo Shouldn't we avoid loops?
///
- ///\todo Some member functions could be \c static.
///\author Alpar Juttner
- class SmartGraph {
-
- struct NodeT
- {
- int first_in,first_out;
- NodeT() : first_in(-1), first_out(-1) {}
- };
- struct EdgeT
- {
- int head, tail, next_in, next_out;
- //FIXME: is this necessary?
- EdgeT() : next_in(-1), next_out(-1) {}
- };
-
- std::vector<NodeT> nodes;
-
- std::vector<EdgeT> edges;
-
- protected:
-
- template <typename Key> class DynMapBase
- {
- protected:
- const SmartGraph* G;
- public:
- virtual void add(const Key k) = 0;
- virtual void erase(const Key k) = 0;
- DynMapBase(const SmartGraph &_G) : G(&_G) {}
- virtual ~DynMapBase() {}
- friend class SmartGraph;
- };
-
+ class FullGraph {
+ int NodeNum;
+ int EdgeNum;
public:
template <typename T> class EdgeMap;
- template <typename T> class EdgeMap;
+ template <typename T> class NodeMap;
class Node;
class Edge;
-
- // protected:
- // HELPME:
- protected:
- ///\bug It must be public because of SymEdgeMap.
- ///
- mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
- ///\bug It must be public because of SymEdgeMap.
- ///
- mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
-
- public:
-
-
class NodeIt;
class EdgeIt;
class OutEdgeIt;
@@ -91,37 +47,28 @@
public:
- SmartGraph() : nodes(), edges() { }
- SmartGraph(const SmartGraph &_g) : nodes(_g.nodes), edges(_g.edges) { }
+ ///Creates a full graph with \c n nodes.
+ FullGraph(int n) : NodeNum(n), EdgeNum(NodeNum*NodeNum) { }
+ ///
+ FullGraph(const FullGraph &_g)
+ : NodeNum(_g.nodeNum()), EdgeNum(NodeNum*NodeNum) { }
- ~SmartGraph()
- {
- for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
- i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
- for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
- i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
- }
+ int nodeNum() const { return NodeNum; } //FIXME: What is this?
+ int edgeNum() const { return EdgeNum; } //FIXME: What is this?
- int nodeNum() const { return nodes.size(); } //FIXME: What is this?
- int edgeNum() const { return edges.size(); } //FIXME: What is this?
+ int maxNodeId() const { return NodeNum; } //FIXME: What is this?
+ int maxEdgeId() const { return EdgeNum; } //FIXME: What is this?
- ///\bug This function does something different than
- ///its name would suggests...
- int maxNodeId() const { return nodes.size(); } //FIXME: What is this?
- ///\bug This function does something different than
- ///its name would suggests...
- int maxEdgeId() const { return edges.size(); } //FIXME: What is this?
-
- Node tail(Edge e) const { return edges[e.n].tail; }
- Node head(Edge e) const { return edges[e.n].head; }
+ Node tail(Edge e) const { return e.n%NodeNum; }
+ Node head(Edge e) const { return e.n/NodeNum; }
- Node aNode(OutEdgeIt e) const { return edges[e.n].tail; }
- Node aNode(InEdgeIt e) const { return edges[e.n].head; }
+ Node aNode(OutEdgeIt e) const { return tail(e); }
+ Node aNode(InEdgeIt e) const { return head(e); }
- Node bNode(OutEdgeIt e) const { return edges[e.n].head; }
- Node bNode(InEdgeIt e) const { return edges[e.n].tail; }
+ Node bNode(OutEdgeIt e) const { return head(e); }
+ Node bNode(InEdgeIt e) const { return tail(e); }
- NodeIt& first(NodeIt& v) const {
+ NodeIt& first(NodeIt& v) const {
v=NodeIt(*this); return v; }
EdgeIt& first(EdgeIt& e) const {
e=EdgeIt(*this); return e; }
@@ -130,73 +77,29 @@
InEdgeIt& first(InEdgeIt& e, const Node v) const {
e=InEdgeIt(*this,v); return e; }
-// template< typename It >
-// It first() const { It e; first(e); return e; }
-
-// template< typename It >
-// It first(Node v) const { It e; first(e,v); return e; }
-
bool valid(Edge e) const { return e.n!=-1; }
bool valid(Node n) const { return n.n!=-1; }
- ///\deprecated Use
- ///\code
- /// e=INVALID;
- ///\endcode
- ///instead.
- void setInvalid(Edge &e) { e.n=-1; }
- ///\deprecated Use
- ///\code
- /// e=INVALID;
- ///\endcode
- ///instead.
- void setInvalid(Node &n) { n.n=-1; }
-
template <typename It> It getNext(It it) const
{ It tmp(it); return next(tmp); }
NodeIt& next(NodeIt& it) const {
- it.n=(it.n+2)%(nodes.size()+1)-1;
+ it.n=(it.n+2)%(NodeNum+1)-1;
return it;
}
OutEdgeIt& next(OutEdgeIt& it) const
- { it.n=edges[it.n].next_out; return it; }
+ { it.n+=NodeNum; if(it.n>=EdgeNum) it.n=-1; return it; }
InEdgeIt& next(InEdgeIt& it) const
- { it.n=edges[it.n].next_in; return it; }
+ { if(!((++it.n)%NodeNum)) it.n=-1; return it; }
EdgeIt& next(EdgeIt& it) const { --it.n; return it; }
int id(Node v) const { return v.n; }
int id(Edge e) const { return e.n; }
- Node addNode() {
- Node n; n.n=nodes.size();
- nodes.push_back(NodeT()); //FIXME: Hmmm...
-
- for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
- i!=dyn_node_maps.end(); ++i) (**i).add(n);
-
- return n;
- }
-
- Edge addEdge(Node u, Node v) {
- Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm...
- edges[e.n].tail=u.n; edges[e.n].head=v.n;
- edges[e.n].next_out=nodes[u.n].first_out;
- edges[e.n].next_in=nodes[v.n].first_in;
- nodes[u.n].first_out=nodes[v.n].first_in=e.n;
-
- for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
- i!=dyn_edge_maps.end(); ++i) (**i).add(e);
-
- return e;
- }
-
- void clear() {nodes.clear();edges.clear();}
-
class Node {
- friend class SmartGraph;
+ friend class FullGraph;
template <typename T> friend class NodeMap;
-
+
friend class Edge;
friend class OutEdgeIt;
friend class InEdgeIt;
@@ -204,7 +107,7 @@
protected:
int n;
- friend int SmartGraph::id(Node v) const;
+ friend int FullGraph::id(Node v) const;
Node(int nn) {n=nn;}
public:
Node() {}
@@ -215,27 +118,24 @@
};
class NodeIt : public Node {
- friend class SmartGraph;
+ friend class FullGraph;
public:
NodeIt() : Node() { }
NodeIt(Invalid i) : Node(i) { }
- NodeIt(const SmartGraph& G) : Node(G.nodes.size()?0:-1) { }
+ NodeIt(const FullGraph& G) : Node(G.NodeNum?0:-1) { }
///\todo Undocumented conversion Node -\> NodeIt.
- NodeIt(const SmartGraph& G, const Node &n) : Node(n) { }
+ NodeIt(const FullGraph& G, const Node &n) : Node(n) { }
};
class Edge {
- friend class SmartGraph;
+ friend class FullGraph;
template <typename T> friend class EdgeMap;
-
- //template <typename T> friend class SymSmartGraph::SymEdgeMap;
- //friend Edge SymSmartGraph::opposite(Edge) const;
friend class Node;
friend class NodeIt;
protected:
- int n;
- friend int SmartGraph::id(Edge e) const;
+ int n; //NodeNum*head+tail;
+ friend int FullGraph::id(Edge e) const;
Edge(int nn) {n=nn;}
public:
@@ -245,41 +145,41 @@
bool operator!=(const Edge i) const {return n!=i.n;}
bool operator<(const Edge i) const {return n<i.n;}
///\bug This is a workaround until somebody tells me how to
- ///make class \c SymSmartGraph::SymEdgeMap friend of Edge
+ ///make class \c SymFullGraph::SymEdgeMap friend of Edge
int &idref() {return n;}
const int &idref() const {return n;}
};
class EdgeIt : public Edge {
- friend class SmartGraph;
+ friend class FullGraph;
public:
- EdgeIt(const SmartGraph& G) : Edge(G.edges.size()-1) { }
+ EdgeIt(const FullGraph& G) : Edge(G.EdgeNum-1) { }
EdgeIt (Invalid i) : Edge(i) { }
EdgeIt() : Edge() { }
///\bug This is a workaround until somebody tells me how to
- ///make class \c SymSmartGraph::SymEdgeMap friend of Edge
+ ///make class \c SymFullGraph::SymEdgeMap friend of Edge
int &idref() {return n;}
};
class OutEdgeIt : public Edge {
- friend class SmartGraph;
+ friend class FullGraph;
public:
OutEdgeIt() : Edge() { }
OutEdgeIt (Invalid i) : Edge(i) { }
- OutEdgeIt(const SmartGraph& G,const Node v)
- : Edge(G.nodes[v.n].first_out) {}
+ OutEdgeIt(const FullGraph& G,const Node v)
+ : Edge(v.n) {}
};
class InEdgeIt : public Edge {
- friend class SmartGraph;
+ friend class FullGraph;
public:
InEdgeIt() : Edge() { }
InEdgeIt (Invalid i) : Edge(i) { }
- InEdgeIt(const SmartGraph& G,Node v) :Edge(G.nodes[v.n].first_in){}
+ InEdgeIt(const FullGraph& G,Node v) :Edge(v.n*G.NodeNum){}
};
- template <typename T> class NodeMap : public DynMapBase<Node>
+ template <typename T> class NodeMap
{
std::vector<T> container;
@@ -287,59 +187,21 @@
typedef T ValueType;
typedef Node KeyType;
- NodeMap(const SmartGraph &_G) :
- DynMapBase<Node>(_G), container(_G.maxNodeId())
- {
- G->dyn_node_maps.push_back(this);
- }
- NodeMap(const SmartGraph &_G,const T &t) :
- DynMapBase<Node>(_G), container(_G.maxNodeId(),t)
- {
- G->dyn_node_maps.push_back(this);
- }
-
- NodeMap(const NodeMap<T> &m) :
- DynMapBase<Node>(*m.G), container(m.container)
- {
- G->dyn_node_maps.push_back(this);
- }
+ NodeMap(const FullGraph &_G) : container(_G.NodeNum) { }
+ NodeMap(const FullGraph &_G,const T &t) : container(_G.NodeNum,t) { }
+ NodeMap(const NodeMap<T> &m) : container(m.container) { }
template<typename TT> friend class NodeMap;
-
///\todo It can copy between different types.
- ///
- template<typename TT> NodeMap(const NodeMap<TT> &m) :
- DynMapBase<Node>(*m.G)
+ template<typename TT> NodeMap(const NodeMap<TT> &m)
+ : container(m.container.size())
{
- G->dyn_node_maps.push_back(this);
typename std::vector<TT>::const_iterator i;
for(typename std::vector<TT>::const_iterator i=m.container.begin();
i!=m.container.end();
i++)
container.push_back(*i);
}
- ~NodeMap()
- {
- if(G) {
- std::vector<DynMapBase<Node>* >::iterator i;
- for(i=G->dyn_node_maps.begin();
- i!=G->dyn_node_maps.end() && *i!=this; ++i) ;
- //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow...
- //A better way to do that: (Is this really important?)
- if(*i==this) {
- *i=G->dyn_node_maps.back();
- G->dyn_node_maps.pop_back();
- }
- }
- }
-
- void add(const Node k)
- {
- if(k.n>=int(container.size())) container.resize(k.n+1);
- }
-
- void erase(const Node) { }
-
void set(Node n, T a) { container[n.n]=a; }
//'T& operator[](Node n)' would be wrong here
typename std::vector<T>::reference
@@ -369,7 +231,7 @@
void update(T a) {} //Useless for Dynamic Maps
};
- template <typename T> class EdgeMap : public DynMapBase<Edge>
+ template <typename T> class EdgeMap
{
std::vector<T> container;
@@ -377,59 +239,22 @@
typedef T ValueType;
typedef Edge KeyType;
- EdgeMap(const SmartGraph &_G) :
- DynMapBase<Edge>(_G), container(_G.maxEdgeId())
- {
- //FIXME: What if there are empty Id's?
- //FIXME: Can I use 'this' in a constructor?
- G->dyn_edge_maps.push_back(this);
- }
- EdgeMap(const SmartGraph &_G,const T &t) :
- DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t)
- {
- G->dyn_edge_maps.push_back(this);
- }
- EdgeMap(const EdgeMap<T> &m) :
- DynMapBase<Edge>(*m.G), container(m.container)
- {
- G->dyn_edge_maps.push_back(this);
- }
+ EdgeMap(const FullGraph &_G) : container(_G.EdgeNum) { }
+ EdgeMap(const FullGraph &_G,const T &t) : container(_G.EdgeNum,t) { }
+ EdgeMap(const EdgeMap<T> &m) : container(m.container) { }
template<typename TT> friend class EdgeMap;
-
- ///\todo It can copy between different types.
- ///
+ ///\todo It can copy between different types.
+ ///\todo We could use 'copy'
template<typename TT> EdgeMap(const EdgeMap<TT> &m) :
- DynMapBase<Edge>(*m.G)
+ container(m.container.size())
{
- G->dyn_edge_maps.push_back(this);
typename std::vector<TT>::const_iterator i;
for(typename std::vector<TT>::const_iterator i=m.container.begin();
i!=m.container.end();
i++)
container.push_back(*i);
}
- ~EdgeMap()
- {
- if(G) {
- std::vector<DynMapBase<Edge>* >::iterator i;
- for(i=G->dyn_edge_maps.begin();
- i!=G->dyn_edge_maps.end() && *i!=this; ++i) ;
- //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
- //A better way to do that: (Is this really important?)
- if(*i==this) {
- *i=G->dyn_edge_maps.back();
- G->dyn_edge_maps.pop_back();
- }
- }
- }
-
- void add(const Edge k)
- {
- if(k.n>=int(container.size())) container.resize(k.n+1);
- }
- void erase(const Edge) { }
-
void set(Edge n, T a) { container[n.n]=a; }
//T get(Edge n) const { return container[n.n]; }
typename std::vector<T>::reference
@@ -454,158 +279,12 @@
return *this;
}
- void update() {} //Useless for DynMaps
- void update(T a) {} //Useless for DynMaps
+ void update() {}
+ void update(T a) {}
};
};
- ///Graph for bidirectional edges.
-
- ///The purpose of this graph structure is to handle graphs
- ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
- ///of oppositely directed edges.
- ///There is a new edge map type called
- ///\ref SymSmartGraph::SymEdgeMap "SymEdgeMap"
- ///that complements this
- ///feature by
- ///storing shared values for the edge pairs. The usual
- ///\ref GraphSkeleton::EdgeMap "EdgeMap"
- ///can be used
- ///as well.
- ///
- ///The oppositely directed edge can also be obtained easily
- ///using \ref opposite.
- ///\warning It shares the similarity with \ref SmartGraph that
- ///it is not possible to delete edges or nodes from the graph.
- //\sa \ref SmartGraph.
-
- class SymSmartGraph : public SmartGraph
- {
- public:
- template<typename T> class SymEdgeMap;
- template<typename T> friend class SymEdgeMap;
-
- SymSmartGraph() : SmartGraph() { }
- SymSmartGraph(const SmartGraph &_g) : SmartGraph(_g) { }
- ///Adds a pair of oppositely directed edges to the graph.
- Edge addEdge(Node u, Node v)
- {
- Edge e = SmartGraph::addEdge(u,v);
- SmartGraph::addEdge(v,u);
- return e;
- }
-
- ///The oppositely directed edge.
-
- ///Returns the oppositely directed
- ///pair of the edge \c e.
- Edge opposite(Edge e) const
- {
- Edge f;
- f.idref() = e.idref() - 2*(e.idref()%2) + 1;
- return f;
- }
-
- ///Common data storage for the edge pairs.
-
- ///This map makes it possible to store data shared by the oppositely
- ///directed pairs of edges.
- template <typename T> class SymEdgeMap : public DynMapBase<Edge>
- {
- std::vector<T> container;
-
- public:
- typedef T ValueType;
- typedef Edge KeyType;
-
- SymEdgeMap(const SymSmartGraph &_G) :
- DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2)
- {
- static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.push_back(this);
- }
- SymEdgeMap(const SymSmartGraph &_G,const T &t) :
- DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2,t)
- {
- G->dyn_edge_maps.push_back(this);
- }
-
- SymEdgeMap(const SymEdgeMap<T> &m) :
- DynMapBase<SymEdge>(*m.G), container(m.container)
- {
- G->dyn_node_maps.push_back(this);
- }
-
- // template<typename TT> friend class SymEdgeMap;
-
- ///\todo It can copy between different types.
- ///
-
- template<typename TT> SymEdgeMap(const SymEdgeMap<TT> &m) :
- DynMapBase<SymEdge>(*m.G)
- {
- G->dyn_node_maps.push_back(this);
- typename std::vector<TT>::const_iterator i;
- for(typename std::vector<TT>::const_iterator i=m.container.begin();
- i!=m.container.end();
- i++)
- container.push_back(*i);
- }
-
- ~SymEdgeMap()
- {
- if(G) {
- std::vector<DynMapBase<Edge>* >::iterator i;
- for(i=static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.begin();
- i!=static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.end()
- && *i!=this; ++i) ;
- //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
- //A better way to do that: (Is this really important?)
- if(*i==this) {
- *i=static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.back();
- static_cast<const SymSmartGraph*>(G)->dyn_edge_maps.pop_back();
- }
- }
- }
-
- void add(const Edge k)
- {
- if(!k.idref()%2&&k.idref()/2>=int(container.size()))
- container.resize(k.idref()/2+1);
- }
- void erase(const Edge k) { }
-
- void set(Edge n, T a) { container[n.idref()/2]=a; }
- //T get(Edge n) const { return container[n.idref()/2]; }
- typename std::vector<T>::reference
- operator[](Edge n) { return container[n.idref()/2]; }
- typename std::vector<T>::const_reference
- operator[](Edge n) const { return container[n.idref()/2]; }
-
- ///\warning There is no safety check at all!
- ///Using operator = between maps attached to different graph may
- ///cause serious problem.
- ///\todo Is this really so?
- ///\todo It can copy between different types.
- const SymEdgeMap<T>& operator=(const SymEdgeMap<T> &m)
- {
- container = m.container;
- return *this;
- }
- template<typename TT>
- const SymEdgeMap<T>& operator=(const SymEdgeMap<TT> &m)
- {
- std::copy(m.container.begin(), m.container.end(), container.begin());
- return *this;
- }
-
- void update() {} //Useless for DynMaps
- void update(T a) {} //Useless for DynMaps
-
- };
-
- };
-
/// @}
} //namespace hugo
@@ -613,4 +292,4 @@
-#endif //SMART_GRAPH_H
+#endif //HUGO_FULL_GRAPH_H
More information about the Lemon-commits
mailing list