[Lemon-commits] [lemon_svn] deba: r1220 - in hugo/trunk/src: hugo hugo/skeletons test
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:43:57 CET 2006
Author: deba
Date: Sun Sep 26 23:43:38 2004
New Revision: 1220
Added:
hugo/trunk/src/hugo/skeletons/sym_graph.h
hugo/trunk/src/test/sym_graph_test.cc
hugo/trunk/src/test/sym_graph_test.h
Removed:
hugo/trunk/src/hugo/sym_map.h
Modified:
hugo/trunk/src/hugo/Makefile.am
hugo/trunk/src/hugo/default_map.h
hugo/trunk/src/hugo/list_graph.h
hugo/trunk/src/hugo/map_bits.h
hugo/trunk/src/hugo/map_defines.h
hugo/trunk/src/hugo/map_registry.h
hugo/trunk/src/hugo/smart_graph.h
hugo/trunk/src/test/Makefile.am
hugo/trunk/src/test/graph_test.cc
hugo/trunk/src/test/test_tools.h
Log:
New symmetric Graph concept.
New symmetric list and smart graph.
Symmetric Graph tests based on the Graph Tests.
Modified: hugo/trunk/src/hugo/Makefile.am
==============================================================================
--- hugo/trunk/src/hugo/Makefile.am (original)
+++ hugo/trunk/src/hugo/Makefile.am Sun Sep 26 23:43:38 2004
@@ -18,12 +18,11 @@
map_registry.h \
map_bits.h \
maps.h \
- min_cost_flow.h \
+ min_cost_flow.h \
suurballe.h \
preflow.h \
path.h \
smart_graph.h \
- sym_map.h \
time_measure.h \
unionfind.h \
vector_map.h \
@@ -31,5 +30,6 @@
noinst_HEADERS = \
skeletons/graph.h \
+ skeletons/sym_graph.h \
skeletons/maps.h \
skeletons/path.h
Modified: hugo/trunk/src/hugo/default_map.h
==============================================================================
--- hugo/trunk/src/hugo/default_map.h (original)
+++ hugo/trunk/src/hugo/default_map.h Sun Sep 26 23:43:38 2004
@@ -59,12 +59,9 @@
: Parent(static_cast<const Parent&>(copy)) {} \
template <typename TT> \
DefaultMap(const DefaultMap<MapRegistry, TT>& copy) \
- : { \
- Parent::MapBase::operator= \
- (static_cast<const typename Parent::MapBase&>(copy)); \
+ : Parent(*copy.getGraph()) { \
if (Parent::getGraph()) { \
for (typename Parent::KeyIt it(*Parent::getGraph()); it!=INVALID; ++it) {\
- Parent::add(it); \
Parent::operator[](it) = copy[it]; \
} \
} \
Modified: hugo/trunk/src/hugo/list_graph.h
==============================================================================
--- hugo/trunk/src/hugo/list_graph.h (original)
+++ hugo/trunk/src/hugo/list_graph.h Sun Sep 26 23:43:38 2004
@@ -29,8 +29,6 @@
#include <hugo/map_registry.h>
#include <hugo/array_map.h>
-#include <hugo/sym_map.h>
-
#include <hugo/map_defines.h>
@@ -438,7 +436,7 @@
///
///\todo this date structure need some reconsiderations. Maybe it
///should be implemented independently from ListGraph.
-
+ /*
class SymListGraph : public ListGraph
{
public:
@@ -483,8 +481,402 @@
ListGraph::erase(f);
ListGraph::erase(e);
}
- };
+ };*/
+
+ class SymListGraph : public ListGraph {
+ typedef ListGraph Parent;
+ public:
+
+ typedef SymListGraph Graph;
+
+ typedef ListGraph::Node Node;
+ typedef ListGraph::NodeIt NodeIt;
+
+ class SymEdge;
+ class SymEdgeIt;
+
+ class Edge;
+ class EdgeIt;
+ class OutEdgeIt;
+ class InEdgeIt;
+
+ template <typename Value>
+ class NodeMap : public Parent::NodeMap<Value> {
+ public:
+ NodeMap(const SymListGraph& g)
+ : SymListGraph::Parent::NodeMap<Value>(g) {}
+ NodeMap(const SymListGraph& g, Value v)
+ : SymListGraph::Parent::NodeMap<Value>(g, v) {}
+ template<typename TT>
+ NodeMap(const NodeMap<TT>& copy)
+ : SymListGraph::Parent::NodeMap<Value>(copy) { }
+ };
+
+ template <typename Value>
+ class SymEdgeMap : public Parent::EdgeMap<Value> {
+ public:
+ typedef SymEdge KeyType;
+
+ SymEdgeMap(const SymListGraph& g)
+ : SymListGraph::Parent::EdgeMap<Value>(g) {}
+ SymEdgeMap(const SymListGraph& g, Value v)
+ : SymListGraph::Parent::EdgeMap<Value>(g, v) {}
+ template<typename TT>
+ SymEdgeMap(const SymEdgeMap<TT>& copy)
+ : SymListGraph::Parent::EdgeMap<Value>(copy) { }
+
+ };
+
+ // Create edge map registry.
+ CREATE_EDGE_MAP_REGISTRY;
+ // Create edge maps.
+ CREATE_EDGE_MAP(ArrayMap);
+
+ class Edge {
+ friend class SymListGraph;
+ friend class SymListGraph::EdgeIt;
+ friend class SymListGraph::OutEdgeIt;
+ friend class SymListGraph::InEdgeIt;
+
+ protected:
+ int id;
+
+ Edge(int pid) { id = pid; }
+
+ public:
+ /// An Edge with id \c n.
+
+ Edge() { }
+ Edge (Invalid) { id = -1; }
+
+ operator SymEdge(){ return SymEdge(id >> 1);}
+
+ bool operator==(const Edge i) const {return id == i.id;}
+ bool operator!=(const Edge i) const {return id != i.id;}
+ bool operator<(const Edge i) const {return id < i.id;}
+ // ///Validity check
+ // operator bool() { return n!=-1; }
+ };
+
+ class SymEdge : public ListGraph::Edge {
+ friend class SymListGraph;
+ friend class SymListGraph::Edge;
+ typedef ListGraph::Edge Parent;
+
+ protected:
+ SymEdge(int pid) : Parent(pid) {}
+ public:
+
+ SymEdge() { }
+ SymEdge(const ListGraph::Edge& i) : Parent(i) {}
+ SymEdge (Invalid) : Parent(INVALID) {}
+
+ };
+
+ class OutEdgeIt {
+ Parent::OutEdgeIt out;
+ Parent::InEdgeIt in;
+ public:
+ OutEdgeIt() {}
+ OutEdgeIt(const SymListGraph& g, Edge e) {
+ if (e.id & 1 == 0) {
+ out = Parent::OutEdgeIt(g, SymEdge(e));
+ in = Parent::InEdgeIt(g, g.tail(e));
+ } else {
+ out = Parent::OutEdgeIt(INVALID);
+ in = Parent::InEdgeIt(g, SymEdge(e));
+ }
+ }
+ OutEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
+
+ OutEdgeIt(const SymListGraph& g, const Node v)
+ : out(g, v), in(g, v) {}
+ OutEdgeIt &operator++() {
+ if (out != INVALID) {
+ ++out;
+ } else {
+ ++in;
+ }
+ return *this;
+ }
+
+ operator Edge() const {
+ if (out == INVALID && in == INVALID) return INVALID;
+ return out != INVALID ? forward(out) : backward(in);
+ }
+
+ bool operator==(const Edge i) const {return Edge(*this) == i;}
+ bool operator!=(const Edge i) const {return Edge(*this) != i;}
+ bool operator<(const Edge i) const {return Edge(*this) < i;}
+ };
+
+ class InEdgeIt {
+ Parent::OutEdgeIt out;
+ Parent::InEdgeIt in;
+ public:
+ InEdgeIt() {}
+ InEdgeIt(const SymListGraph& g, Edge e) {
+ if (e.id & 1 == 0) {
+ out = Parent::OutEdgeIt(g, SymEdge(e));
+ in = Parent::InEdgeIt(g, g.tail(e));
+ } else {
+ out = Parent::OutEdgeIt(INVALID);
+ in = Parent::InEdgeIt(g, SymEdge(e));
+ }
+ }
+ InEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
+
+ InEdgeIt(const SymListGraph& g, const Node v)
+ : out(g, v), in(g, v) {}
+
+ InEdgeIt &operator++() {
+ if (out != INVALID) {
+ ++out;
+ } else {
+ ++in;
+ }
+ return *this;
+ }
+
+ operator Edge() const {
+ if (out == INVALID && in == INVALID) return INVALID;
+ return out != INVALID ? backward(out) : forward(in);
+ }
+
+ bool operator==(const Edge i) const {return Edge(*this) == i;}
+ bool operator!=(const Edge i) const {return Edge(*this) != i;}
+ bool operator<(const Edge i) const {return Edge(*this) < i;}
+ };
+
+ class SymEdgeIt : public Parent::EdgeIt {
+
+ public:
+ SymEdgeIt() {}
+
+ SymEdgeIt(const SymListGraph& g)
+ : SymListGraph::Parent::EdgeIt(g) {}
+
+ SymEdgeIt(const SymListGraph& g, SymEdge e)
+ : SymListGraph::Parent::EdgeIt(g, e) {}
+
+ SymEdgeIt(Invalid i)
+ : SymListGraph::Parent::EdgeIt(INVALID) {}
+
+ SymEdgeIt& operator++() {
+ SymListGraph::Parent::EdgeIt::operator++();
+ return *this;
+ }
+
+ operator SymEdge() const {
+ return SymEdge
+ (static_cast<const SymListGraph::Parent::EdgeIt&>(*this));
+ }
+ bool operator==(const SymEdge i) const {return SymEdge(*this) == i;}
+ bool operator!=(const SymEdge i) const {return SymEdge(*this) != i;}
+ bool operator<(const SymEdge i) const {return SymEdge(*this) < i;}
+ };
+
+ class EdgeIt {
+ SymEdgeIt it;
+ bool fw;
+ public:
+ EdgeIt(const SymListGraph& g) : it(g), fw(true) {}
+ EdgeIt (Invalid i) : it(i) { }
+ EdgeIt(const SymListGraph& g, Edge e)
+ : it(g, SymEdge(e)), fw(id(e) & 1 == 0) { }
+ EdgeIt() { }
+ EdgeIt& operator++() {
+ fw = !fw;
+ if (fw) ++it;
+ return *this;
+ }
+ operator Edge() const {
+ if (it == INVALID) return INVALID;
+ return fw ? forward(it) : backward(it);
+ }
+ bool operator==(const Edge i) const {return Edge(*this) == i;}
+ bool operator!=(const Edge i) const {return Edge(*this) != i;}
+ bool operator<(const Edge i) const {return Edge(*this) < i;}
+
+ };
+
+ ///Number of nodes.
+ int nodeNum() const { return Parent::nodeNum(); }
+ ///Number of edges.
+ int edgeNum() const { return 2*Parent::edgeNum(); }
+ ///Number of symmetric edges.
+ int symEdgeNum() const { return Parent::edgeNum(); }
+ ///Set the expected maximum number of edges.
+
+ ///With this function, it is possible to set the expected number of edges.
+ ///The use of this fasten the building of the graph and makes
+ ///it possible to avoid the superfluous memory allocation.
+ void reserveSymEdge(int n) { Parent::reserveEdge(n); };
+
+ /// Maximum node ID.
+
+ /// Maximum node ID.
+ ///\sa id(Node)
+ int maxNodeId() const { return Parent::maxNodeId(); }
+ /// Maximum edge ID.
+
+ /// Maximum edge ID.
+ ///\sa id(Edge)
+ int maxEdgeId() const { return 2*Parent::maxEdgeId(); }
+ /// Maximum symmetric edge ID.
+
+ /// Maximum symmetric edge ID.
+ ///\sa id(SymEdge)
+ int maxSymEdgeId() const { return Parent::maxEdgeId(); }
+
+
+ Node tail(Edge e) const {
+ return e.id & 1 == 0 ?
+ Parent::tail(SymEdge(e)) : Parent::head(SymEdge(e));
+ }
+
+ Node head(Edge e) const {
+ return e.id & 1 == 0 ?
+ Parent::head(SymEdge(e)) : Parent::tail(SymEdge(e));
+ }
+
+ Node tail(SymEdge e) const {
+ return Parent::tail(e);
+ }
+
+ Node head(SymEdge e) const {
+ return Parent::head(e);
+ }
+
+ NodeIt& first(NodeIt& v) const {
+ v=NodeIt(*this); return v; }
+ EdgeIt& first(EdgeIt& e) const {
+ e=EdgeIt(*this); return e; }
+ SymEdgeIt& first(SymEdgeIt& e) const {
+ e=SymEdgeIt(*this); return e; }
+ OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
+ e=OutEdgeIt(*this,v); return e; }
+ InEdgeIt& first(InEdgeIt& e, const Node v) const {
+ e=InEdgeIt(*this,v); return e; }
+
+ /// Node ID.
+
+ /// The ID of a valid Node is a nonnegative integer not greater than
+ /// \ref maxNodeId(). The range of the ID's is not surely continuous
+ /// and the greatest node ID can be actually less then \ref maxNodeId().
+ ///
+ /// The ID of the \ref INVALID node is -1.
+ ///\return The ID of the node \c v.
+ static int id(Node v) { return Parent::id(v); }
+ /// Edge ID.
+
+ /// The ID of a valid Edge is a nonnegative integer not greater than
+ /// \ref maxEdgeId(). The range of the ID's is not surely continuous
+ /// and the greatest edge ID can be actually less then \ref maxEdgeId().
+ ///
+ /// The ID of the \ref INVALID edge is -1.
+ ///\return The ID of the edge \c e.
+ static int id(Edge e) { return e.id; }
+
+ /// The ID of a valid SymEdge is a nonnegative integer not greater than
+ /// \ref maxSymEdgeId(). The range of the ID's is not surely continuous
+ /// and the greatest edge ID can be actually less then \ref maxSymEdgeId().
+ ///
+ /// The ID of the \ref INVALID symmetric edge is -1.
+ ///\return The ID of the edge \c e.
+ static int id(SymEdge e) { return Parent::id(e); }
+
+ /// Adds a new node to the graph.
+
+ /// \warning It adds the new node to the front of the list.
+ /// (i.e. the lastly added node becomes the first.)
+ Node addNode() {
+ return Parent::addNode();
+ }
+
+ SymEdge addEdge(Node u, Node v) {
+ SymEdge se = Parent::addEdge(u, v);
+ edge_maps.add(forward(se));
+ edge_maps.add(backward(se));
+ return se;
+ }
+
+ /// Finds an edge between two nodes.
+
+ /// Finds an edge from node \c u to node \c v.
+ ///
+ /// If \c prev is \ref INVALID (this is the default value), then
+ /// It finds the first edge from \c u to \c v. Otherwise it looks for
+ /// the next edge from \c u to \c v after \c prev.
+ /// \return The found edge or INVALID if there is no such an edge.
+ Edge findEdge(Node u, Node v, Edge prev = INVALID)
+ {
+ if (prev == INVALID || id(prev) & 1 == 0) {
+ SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
+ if (se != INVALID) return forward(se);
+ } else {
+ SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
+ if (se != INVALID) return backward(se);
+ }
+ return INVALID;
+ }
+
+ /// Finds an symmetric edge between two nodes.
+
+ /// Finds an symmetric edge from node \c u to node \c v.
+ ///
+ /// If \c prev is \ref INVALID (this is the default value), then
+ /// It finds the first edge from \c u to \c v. Otherwise it looks for
+ /// the next edge from \c u to \c v after \c prev.
+ /// \return The found edge or INVALID if there is no such an edge.
+
+// SymEdge findEdge(Node u, Node v, SymEdge prev = INVALID)
+// {
+// if (prev == INVALID || id(prev) & 1 == 0) {
+// SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
+// if (se != INVALID) return se;
+// } else {
+// SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
+// if (se != INVALID) return se;
+// }
+// return INVALID;
+// }
+
+ public:
+
+ void erase(Node n) {
+ for (OutEdgeIt it(*this, n); it != INVALID; ++it) {
+ edge_maps.erase(it);
+ edge_maps.erase(opposite(it));
+ }
+ Parent::erase(n);
+ }
+
+ void erase(SymEdge e) {
+ edge_maps.erase(forward(e));
+ edge_maps.erase(backward(e));
+ Parent::erase(e);
+ };
+
+ void clear() {
+ edge_maps.clear();
+ Parent::clear();
+ }
+
+ static Edge opposite(Edge e) {
+ return Edge(id(e) ^ 1);
+ }
+
+ static Edge forward(SymEdge e) {
+ return Edge(id(e) << 1);
+ }
+
+ static Edge backward(SymEdge e) {
+ return Edge((id(e) << 1) & 1);
+ }
+
+ };
///A graph class containing only nodes.
Modified: hugo/trunk/src/hugo/map_bits.h
==============================================================================
--- hugo/trunk/src/hugo/map_bits.h (original)
+++ hugo/trunk/src/hugo/map_bits.h Sun Sep 26 23:43:38 2004
@@ -54,10 +54,10 @@
template <typename Graph>
struct KeyInfo<Graph, typename Graph::SymEdgeIt> {
static int maxId(const Graph& graph) {
- return graph.maxEdgeId() >> 1;
+ return graph.maxSymEdgeId();
}
- static int id(const Graph& graph, const typename Graph::Edge& edge) {
- return graph.id(edge) >> 1;
+ static int id(const Graph& graph, const typename Graph::SymEdge& edge) {
+ return graph.id(edge);
}
};
Modified: hugo/trunk/src/hugo/map_defines.h
==============================================================================
--- hugo/trunk/src/hugo/map_defines.h (original)
+++ hugo/trunk/src/hugo/map_defines.h Sun Sep 26 23:43:38 2004
@@ -114,8 +114,7 @@
/** This macro creates MapRegistry for Symmetric Edge Maps.
*/
#define CREATE_SYM_EDGE_MAP_REGISTRY \
-typedef SymEdgeIt<Graph, Edge, EdgeIt> SymEdgeIt; \
-typedef MapRegistry<Graph, Edge, SymEdgeIt> SymEdgeMapRegistry; \
+typedef MapRegistry<Graph, SymEdge, SymEdgeIt> SymEdgeMapRegistry; \
mutable SymEdgeMapRegistry sym_edge_maps;
@@ -127,9 +126,9 @@
*/
#define CREATE_SYM_EDGE_MAP(DynMap) \
template <typename Value> \
-class SymEdgeMap : public SymMap<DynMap, SymEdgeMapRegistry, Value> { \
+class SymEdgeMap : public DynMap<SymEdgeMapRegistry, Value> { \
public: \
-typedef SymMap<DynMap, SymEdgeMapRegistry, Value> Parent; \
+typedef DynMap<SymEdgeMapRegistry, Value> Parent; \
\
SymEdgeMap(const typename Parent::Graph& g) \
: Parent(g, g.sym_edge_maps) {} \
Modified: hugo/trunk/src/hugo/map_registry.h
==============================================================================
--- hugo/trunk/src/hugo/map_registry.h (original)
+++ hugo/trunk/src/hugo/map_registry.h Sun Sep 26 23:43:38 2004
@@ -252,7 +252,7 @@
/**
* Notify all the registered maps about a Key added.
*/
- void add(KeyType& key) {
+ void add(const KeyType& key) {
typename Container::iterator it;
for (it = container.begin(); it != container.end(); ++it) {
(*it)->add(key);
@@ -262,7 +262,7 @@
/**
* Notify all the registered maps about a Key erased.
*/
- void erase(KeyType& key) {
+ void erase(const KeyType& key) {
typename Container::iterator it;
for (it = container.begin(); it != container.end(); ++it) {
(*it)->erase(key);
Added: hugo/trunk/src/hugo/skeletons/sym_graph.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/hugo/skeletons/sym_graph.h Sun Sep 26 23:43:38 2004
@@ -0,0 +1,653 @@
+/* -*- C++ -*-
+ * src/hugo/skeletons/graph.h - Part of HUGOlib, a generic C++ optimization library
+ *
+ * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Combinatorial Optimization Research Group, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef HUGO_SKELETON_SYM_GRAPH_H
+#define HUGO_SKELETON_SYM_GRAPH_H
+
+///\ingroup skeletons
+///\file
+///\brief Declaration of SymGraph.
+
+#include <hugo/invalid.h>
+#include <hugo/skeletons/graph.h>
+#include <hugo/skeletons/maps.h>
+
+namespace hugo {
+ namespace skeleton {
+
+ /// \addtogroup skeletons
+ /// @{
+
+ /// An empty static graph class.
+
+ /// This class provides all the common features of a symmetric
+ /// graph structure, however completely without implementations and
+ /// real data structures behind the interface.
+ /// All graph algorithms should compile with this class, but it will not
+ /// run properly, of course.
+ ///
+ /// It can be used for checking the interface compatibility,
+ /// or it can serve as a skeleton of a new symmetric graph structure.
+ ///
+ /// Also, you will find here the full documentation of a certain graph
+ /// feature, the documentation of a real symmetric graph imlementation
+ /// like @ref SymListGraph or
+ /// @ref SymSmartGraph will just refer to this structure.
+ class StaticSymGraph
+ {
+ public:
+ /// Defalult constructor.
+
+ /// Defalult constructor.
+ ///
+ StaticSymGraph() { }
+ ///Copy consructor.
+
+// ///\todo It is not clear, what we expect from a copy constructor.
+// ///E.g. How to assign the nodes/edges to each other? What about maps?
+// StaticGraph(const StaticGraph& g) { }
+
+ /// The base type of node iterators,
+ /// or in other words, the trivial node iterator.
+
+ /// This is the base type of each node iterator,
+ /// thus each kind of node iterator converts to this.
+ /// More precisely each kind of node iterator should be inherited
+ /// from the trivial node iterator.
+ class Node {
+ public:
+ /// Default constructor
+
+ /// @warning The default constructor sets the iterator
+ /// to an undefined value.
+ Node() { }
+ /// Copy constructor.
+
+ /// Copy constructor.
+ ///
+ Node(const Node&) { }
+
+ /// Invalid constructor \& conversion.
+
+ /// This constructor initializes the iterator to be invalid.
+ /// \sa Invalid for more details.
+ Node(Invalid) { }
+ /// Equality operator
+
+ /// Two iterators are equal if and only if they point to the
+ /// same object or both are invalid.
+ bool operator==(Node) const { return true; }
+
+ /// Inequality operator
+
+ /// \sa \ref operator==(Node n)
+ ///
+ bool operator!=(Node) const { return true; }
+
+ ///Comparison operator.
+
+ ///This is a strict ordering between the nodes.
+ ///
+ ///This ordering can be different from the order in which NodeIt
+ ///goes through the nodes.
+ ///\todo Possibly we don't need it.
+ bool operator<(Node) const { return true; }
+ };
+
+ /// This iterator goes through each node.
+
+ /// This iterator goes through each node.
+ /// Its usage is quite simple, for example you can count the number
+ /// of nodes in graph \c g of type \c Graph like this:
+ /// \code
+ /// int count=0;
+ /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
+ /// \endcode
+ class NodeIt : public Node {
+ public:
+ /// Default constructor
+
+ /// @warning The default constructor sets the iterator
+ /// to an undefined value.
+ NodeIt() { }
+ /// Copy constructor.
+
+ /// Copy constructor.
+ ///
+ NodeIt(const NodeIt&) { }
+ /// Invalid constructor \& conversion.
+
+ /// Initialize the iterator to be invalid.
+ /// \sa Invalid for more details.
+ NodeIt(Invalid) { }
+ /// Sets the iterator to the first node.
+
+ /// Sets the iterator to the first node of \c g.
+ ///
+ NodeIt(const StaticSymGraph& g) { }
+ /// Node -> NodeIt conversion.
+
+ /// Sets the iterator to the node of \c g pointed by the trivial
+ /// iterator n.
+ /// This feature necessitates that each time we
+ /// iterate the edge-set, the iteration order is the same.
+ NodeIt(const StaticSymGraph& g, const Node& n) { }
+ /// Next node.
+
+ /// Assign the iterator to the next node.
+ ///
+ NodeIt& operator++() { return *this; }
+ };
+
+
+ /// The base type of the symmetric edge iterators.
+
+ /// The base type of the symmetric edge iterators.
+ ///
+ class SymEdge {
+ public:
+ /// Default constructor
+
+ /// @warning The default constructor sets the iterator
+ /// to an undefined value.
+ SymEdge() { }
+ /// Copy constructor.
+
+ /// Copy constructor.
+ ///
+ SymEdge(const SymEdge&) { }
+ /// Initialize the iterator to be invalid.
+
+ /// Initialize the iterator to be invalid.
+ ///
+ SymEdge(Invalid) { }
+ /// Equality operator
+
+ /// Two iterators are equal if and only if they point to the
+ /// same object or both are invalid.
+ bool operator==(SymEdge) const { return true; }
+ /// Inequality operator
+
+ /// \sa \ref operator==(Node n)
+ ///
+ bool operator!=(SymEdge) const { return true; }
+ ///Comparison operator.
+
+ ///This is a strict ordering between the nodes.
+ ///
+ ///This ordering can be different from the order in which NodeIt
+ ///goes through the nodes.
+ ///\todo Possibly we don't need it.
+ bool operator<(SymEdge) const { return true; }
+ };
+
+
+ /// The base type of the edge iterators.
+
+ /// The base type of the edge iterators.
+ ///
+ class Edge : public SymEdge {
+ public:
+ /// Default constructor
+
+ /// @warning The default constructor sets the iterator
+ /// to an undefined value.
+ Edge() { }
+ /// Copy constructor.
+
+ /// Copy constructor.
+ ///
+ Edge(const Edge&) { }
+ /// Initialize the iterator to be invalid.
+
+ /// Initialize the iterator to be invalid.
+ ///
+ Edge(Invalid) { }
+ /// Equality operator
+
+ /// Two iterators are equal if and only if they point to the
+ /// same object or both are invalid.
+ bool operator==(Edge) const { return true; }
+ /// Inequality operator
+
+ /// \sa \ref operator==(Node n)
+ ///
+ bool operator!=(Edge) const { return true; }
+ ///Comparison operator.
+
+ ///This is a strict ordering between the nodes.
+ ///
+ ///This ordering can be different from the order in which NodeIt
+ ///goes through the nodes.
+ ///\todo Possibly we don't need it.
+ bool operator<(Edge) const { return true; }
+ };
+
+ /// This iterator goes trough the outgoing edges of a node.
+
+ /// This iterator goes trough the \e outgoing edges of a certain node
+ /// of a graph.
+ /// Its usage is quite simple, for example you can count the number
+ /// of outgoing edges of a node \c n
+ /// in graph \c g of type \c Graph as follows.
+ /// \code
+ /// int count=0;
+ /// for (Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) ++count;
+ /// \endcode
+
+ class OutEdgeIt : public Edge {
+ public:
+ /// Default constructor
+
+ /// @warning The default constructor sets the iterator
+ /// to an undefined value.
+ OutEdgeIt() { }
+ /// Copy constructor.
+
+ /// Copy constructor.
+ ///
+ OutEdgeIt(const OutEdgeIt&) { }
+ /// Initialize the iterator to be invalid.
+
+ /// Initialize the iterator to be invalid.
+ ///
+ OutEdgeIt(Invalid) { }
+ /// This constructor sets the iterator to first outgoing edge.
+
+ /// This constructor set the iterator to the first outgoing edge of
+ /// node
+ ///@param n the node
+ ///@param g the graph
+ OutEdgeIt(const StaticSymGraph& g, const Node& n) { }
+ /// Edge -> OutEdgeIt conversion
+
+ /// Sets the iterator to the value of the trivial iterator \c e.
+ /// This feature necessitates that each time we
+ /// iterate the edge-set, the iteration order is the same.
+ OutEdgeIt(const StaticSymGraph& g, const Edge& e) { }
+ ///Next outgoing edge
+
+ /// Assign the iterator to the next
+ /// outgoing edge of the corresponding node.
+ OutEdgeIt& operator++() { return *this; }
+ };
+
+ /// This iterator goes trough the incoming edges of a node.
+
+ /// This iterator goes trough the \e incoming edges of a certain node
+ /// of a graph.
+ /// Its usage is quite simple, for example you can count the number
+ /// of outgoing edges of a node \c n
+ /// in graph \c g of type \c Graph as follows.
+ /// \code
+ /// int count=0;
+ /// for(Graph::InEdgeIt e(g, n); e!=INVALID; ++e) ++count;
+ /// \endcode
+
+ class InEdgeIt : public Edge {
+ public:
+ /// Default constructor
+
+ /// @warning The default constructor sets the iterator
+ /// to an undefined value.
+ InEdgeIt() { }
+ /// Copy constructor.
+
+ /// Copy constructor.
+ ///
+ InEdgeIt(const InEdgeIt&) { }
+ /// Initialize the iterator to be invalid.
+
+ /// Initialize the iterator to be invalid.
+ ///
+ InEdgeIt(Invalid) { }
+ /// This constructor sets the iterator to first incoming edge.
+
+ /// This constructor set the iterator to the first incoming edge of
+ /// node
+ ///@param n the node
+ ///@param g the graph
+ InEdgeIt(const StaticSymGraph& g, const Node& n) { }
+ /// Edge -> InEdgeIt conversion
+
+ /// Sets the iterator to the value of the trivial iterator \c e.
+ /// This feature necessitates that each time we
+ /// iterate the edge-set, the iteration order is the same.
+ InEdgeIt(const StaticSymGraph& g, const Edge& n) { }
+ /// Next incoming edge
+
+ /// Assign the iterator to the next inedge of the corresponding node.
+ ///
+ InEdgeIt& operator++() { return *this; }
+ };
+ /// This iterator goes through each symmetric edge.
+
+ /// This iterator goes through each symmetric edge of a graph.
+ /// Its usage is quite simple, for example you can count the number
+ /// of symmetric edges in a graph \c g of type \c Graph as follows:
+ /// \code
+ /// int count=0;
+ /// for(Graph::SymEdgeIt e(g); e!=INVALID; ++e) ++count;
+ /// \endcode
+ class SymEdgeIt : public SymEdge {
+ public:
+ /// Default constructor
+
+ /// @warning The default constructor sets the iterator
+ /// to an undefined value.
+ SymEdgeIt() { }
+ /// Copy constructor.
+
+ /// Copy constructor.
+ ///
+ SymEdgeIt(const SymEdgeIt&) { }
+ /// Initialize the iterator to be invalid.
+
+ /// Initialize the iterator to be invalid.
+ ///
+ SymEdgeIt(Invalid) { }
+ /// This constructor sets the iterator to first edge.
+
+ /// This constructor set the iterator to the first edge of
+ /// node
+ ///@param g the graph
+ SymEdgeIt(const StaticSymGraph& g) { }
+ /// Edge -> EdgeIt conversion
+
+ /// Sets the iterator to the value of the trivial iterator \c e.
+ /// This feature necessitates that each time we
+ /// iterate the edge-set, the iteration order is the same.
+ SymEdgeIt(const StaticSymGraph&, const SymEdge&) { }
+ ///Next edge
+
+ /// Assign the iterator to the next
+ /// edge of the corresponding node.
+ SymEdgeIt& operator++() { return *this; }
+ };
+ /// This iterator goes through each edge.
+
+ /// This iterator goes through each edge of a graph.
+ /// Its usage is quite simple, for example you can count the number
+ /// of edges in a graph \c g of type \c Graph as follows:
+ /// \code
+ /// int count=0;
+ /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
+ /// \endcode
+ class EdgeIt : public Edge {
+ public:
+ /// Default constructor
+
+ /// @warning The default constructor sets the iterator
+ /// to an undefined value.
+ EdgeIt() { }
+ /// Copy constructor.
+
+ /// Copy constructor.
+ ///
+ EdgeIt(const EdgeIt&) { }
+ /// Initialize the iterator to be invalid.
+
+ /// Initialize the iterator to be invalid.
+ ///
+ EdgeIt(Invalid) { }
+ /// This constructor sets the iterator to first edge.
+
+ /// This constructor set the iterator to the first edge of
+ /// node
+ ///@param g the graph
+ EdgeIt(const StaticSymGraph& g) { }
+ /// Edge -> EdgeIt conversion
+
+ /// Sets the iterator to the value of the trivial iterator \c e.
+ /// This feature necessitates that each time we
+ /// iterate the edge-set, the iteration order is the same.
+ EdgeIt(const StaticSymGraph&, const Edge&) { }
+ ///Next edge
+
+ /// Assign the iterator to the next
+ /// edge of the corresponding node.
+ EdgeIt& operator++() { return *this; }
+ };
+
+ /// First node of the graph.
+
+ /// \retval i the first node.
+ /// \return the first node.
+ ///
+ NodeIt& first(NodeIt& i) const { return i; }
+
+ /// The first incoming edge.
+
+ /// The first incoming edge.
+ ///
+ InEdgeIt& first(InEdgeIt &i, Node) const { return i; }
+ /// The first outgoing edge.
+
+ /// The first outgoing edge.
+ ///
+ OutEdgeIt& first(OutEdgeIt& i, Node) const { return i; }
+ /// The first edge of the Graph.
+
+ /// The first edge of the Graph.
+ ///
+ EdgeIt& first(EdgeIt& i) const { return i; }
+ /// The first symmetric edge of the Graph.
+
+ /// The first symmetric edge of the Graph.
+ ///
+ SymEdgeIt& first(SymEdgeIt& i) const { return i; }
+
+ ///Gives back the head node of an edge.
+
+ ///Gives back the head node of an edge.
+ ///
+ Node head(Edge) const { return INVALID; }
+ ///Gives back the tail node of an edge.
+
+ ///Gives back the tail node of an edge.
+ ///
+ Node tail(Edge) const { return INVALID; }
+
+ ///Gives back the first node of an symmetric edge.
+
+ ///Gives back the first node of an symmetric edge.
+ ///
+ Node head(SymEdge) const { return INVALID; }
+ ///Gives back the second node of an symmetric edge.
+
+ ///Gives back the second node of an symmetric edge.
+ ///
+ Node tail(SymEdge) const { return INVALID; }
+ ///Gives back the \e id of a node.
+
+ ///\warning Not all graph structures provide this feature.
+ ///
+ ///\todo Should each graph provide \c id?
+ int id(const Node&) const { return 0; }
+ ///Gives back the \e id of an edge.
+
+ ///\warning Not all graph structures provide this feature.
+ ///
+ ///\todo Should each graph provide \c id?
+ int id(const Edge&) const { return 0; }
+
+ ///\warning Not all graph structures provide this feature.
+ ///
+ ///\todo Should each graph provide \c id?
+ int id(const SymEdge&) const { return 0; }
+
+ /// .
+
+ ///\todo Should it be in the concept?
+ ///
+ int nodeNum() const { return 0; }
+ /// .
+
+ ///\todo Should it be in the concept?
+ ///
+ int edgeNum() const { return 0; }
+
+ ///\todo Should it be in the concept?
+ ///
+ int symEdgeNum() const { return 0; }
+
+
+ /// Gives back the forward directed edge of the symmetric edge.
+ Edge forward(SymEdge) const {return INVALID;}
+
+ /// Gives back the backward directed edge of the symmetric edge.
+ Edge backward(SymEdge) const {return INVALID;};
+
+ /// Gives back the opposite of the edge.
+ Edge opposite(Edge) const {return INVALID;}
+
+ ///Reference map of the nodes to type \c T.
+ /// \ingroup skeletons
+ ///Reference map of the nodes to type \c T.
+ /// \sa Reference
+ /// \warning Making maps that can handle bool type (NodeMap<bool>)
+ /// needs some extra attention!
+ template<class T> class NodeMap : public ReferenceMap< Node, T >
+ {
+ public:
+
+ /// .
+ NodeMap(const StaticSymGraph&) { }
+ /// .
+ NodeMap(const StaticSymGraph&, T) { }
+
+ ///Copy constructor
+ template<typename TT> NodeMap(const NodeMap<TT>&) { }
+ ///Assignment operator
+ template<typename TT> NodeMap& operator=(const NodeMap<TT>&)
+ { return *this; }
+ };
+
+ ///Reference map of the edges to type \c T.
+
+ /// \ingroup skeletons
+ ///Reference map of the edges to type \c T.
+ /// \sa Reference
+ /// \warning Making maps that can handle bool type (EdgeMap<bool>)
+ /// needs some extra attention!
+ template<class T> class EdgeMap
+ : public ReferenceMap<Edge,T>
+ {
+ public:
+
+ /// .
+ EdgeMap(const StaticSymGraph&) { }
+ /// .
+ EdgeMap(const StaticSymGraph&, T) { }
+
+ ///Copy constructor
+ template<typename TT> EdgeMap(const EdgeMap<TT>&) { }
+ ///Assignment operator
+ template<typename TT> EdgeMap &operator=(const EdgeMap<TT>&)
+ { return *this; }
+ };
+
+ ///Reference map of the edges to type \c T.
+
+ /// \ingroup skeletons
+ ///Reference map of the symmetric edges to type \c T.
+ /// \sa Reference
+ /// \warning Making maps that can handle bool type (EdgeMap<bool>)
+ /// needs some extra attention!
+ template<class T> class SymEdgeMap
+ : public ReferenceMap<SymEdge,T>
+ {
+ public:
+
+ /// .
+ SymEdgeMap(const StaticSymGraph&) { }
+ /// .
+ SymEdgeMap(const StaticSymGraph&, T) { }
+
+ ///Copy constructor
+ template<typename TT> SymEdgeMap(const SymEdgeMap<TT>&) { }
+ ///Assignment operator
+ template<typename TT> SymEdgeMap &operator=(const SymEdgeMap<TT>&)
+ { return *this; }
+ };
+ };
+
+
+
+ /// An empty non-static graph class.
+
+ /// This class provides everything that \ref StaticGraph
+ /// with additional functionality which enables to build a
+ /// graph from scratch.
+ class ExtendableSymGraph : public StaticSymGraph
+ {
+ public:
+ /// Defalult constructor.
+
+ /// Defalult constructor.
+ ///
+ ExtendableSymGraph() { }
+ ///Add a new node to the graph.
+
+ /// \return the new node.
+ ///
+ Node addNode() { return INVALID; }
+ ///Add a new edge to the graph.
+
+ ///Add a new symmetric edge to the graph with tail node \c t
+ ///and head node \c h.
+ ///\return the new edge.
+ SymEdge addEdge(Node h, Node t) { return INVALID; }
+
+ /// Resets the graph.
+
+ /// This function deletes all edges and nodes of the graph.
+ /// It also frees the memory allocated to store them.
+ /// \todo It might belong to \ref ErasableGraph.
+ void clear() { }
+ };
+
+ /// An empty erasable graph class.
+
+ /// This class is an extension of \ref ExtendableGraph. It also makes it
+ /// possible to erase edges or nodes.
+ class ErasableSymGraph : public ExtendableSymGraph
+ {
+ public:
+ /// Defalult constructor.
+
+ /// Defalult constructor.
+ ///
+ ErasableSymGraph() { }
+ /// Deletes a node.
+
+ /// Deletes node \c n node.
+ ///
+ void erase(Node n) { }
+ /// Deletes an edge.
+
+ /// Deletes edge \c e edge.
+ ///
+ void erase(SymEdge e) { }
+ };
+
+ // @}
+ } //namespace skeleton
+} //namespace hugo
+
+
+
+#endif // HUGO_SKELETON_GRAPH_H
Modified: hugo/trunk/src/hugo/smart_graph.h
==============================================================================
--- hugo/trunk/src/hugo/smart_graph.h (original)
+++ hugo/trunk/src/hugo/smart_graph.h Sun Sep 26 23:43:38 2004
@@ -27,8 +27,6 @@
#include <hugo/invalid.h>
#include <hugo/array_map.h>
-#include <hugo/sym_map.h>
-
#include <hugo/map_registry.h>
#include <hugo/map_defines.h>
@@ -298,6 +296,381 @@
};
+
+
+ class SymSmartGraph : public SmartGraph {
+ typedef SmartGraph Parent;
+ public:
+
+ typedef SymSmartGraph Graph;
+
+ typedef SmartGraph::Node Node;
+ typedef SmartGraph::NodeIt NodeIt;
+
+ class SymEdge;
+ class SymEdgeIt;
+
+ class Edge;
+ class EdgeIt;
+ class OutEdgeIt;
+ class InEdgeIt;
+
+ template <typename Value>
+ class NodeMap : public Parent::NodeMap<Value> {
+ public:
+ NodeMap(const SymSmartGraph& g)
+ : SymSmartGraph::Parent::NodeMap<Value>(g) {}
+ NodeMap(const SymSmartGraph& g, Value v)
+ : SymSmartGraph::Parent::NodeMap<Value>(g, v) {}
+ template<typename TT>
+ NodeMap(const NodeMap<TT>& copy)
+ : SymSmartGraph::Parent::NodeMap<Value>(copy) { }
+ };
+
+ template <typename Value>
+ class SymEdgeMap : public Parent::EdgeMap<Value> {
+ public:
+ typedef SymEdge KeyType;
+
+ SymEdgeMap(const SymSmartGraph& g)
+ : SymSmartGraph::Parent::EdgeMap<Value>(g) {}
+ SymEdgeMap(const SymSmartGraph& g, Value v)
+ : SymSmartGraph::Parent::EdgeMap<Value>(g, v) {}
+ template<typename TT>
+ SymEdgeMap(const SymEdgeMap<TT>& copy)
+ : SymSmartGraph::Parent::EdgeMap<Value>(copy) { }
+
+ };
+
+ // Create edge map registry.
+ CREATE_EDGE_MAP_REGISTRY;
+ // Create edge maps.
+ CREATE_EDGE_MAP(ArrayMap);
+
+ class Edge {
+ friend class SymSmartGraph;
+ friend class SymSmartGraph::EdgeIt;
+ friend class SymSmartGraph::OutEdgeIt;
+ friend class SymSmartGraph::InEdgeIt;
+
+ protected:
+ int id;
+
+ Edge(int pid) { id = pid; }
+
+ public:
+ /// An Edge with id \c n.
+
+ Edge() { }
+ Edge (Invalid) { id = -1; }
+
+ operator SymEdge(){ return SymEdge(id >> 1);}
+
+ bool operator==(const Edge i) const {return id == i.id;}
+ bool operator!=(const Edge i) const {return id != i.id;}
+ bool operator<(const Edge i) const {return id < i.id;}
+ // ///Validity check
+ // operator bool() { return n!=-1; }
+ };
+
+ class SymEdge : public SmartGraph::Edge {
+ friend class SymSmartGraph;
+ friend class SymSmartGraph::Edge;
+ typedef SmartGraph::Edge Parent;
+
+ protected:
+ SymEdge(int pid) : Parent(pid) {}
+ public:
+
+ SymEdge() { }
+ SymEdge(const SmartGraph::Edge& i) : Parent(i) {}
+ SymEdge (Invalid) : Parent(INVALID) {}
+
+ };
+
+ class OutEdgeIt {
+ Parent::OutEdgeIt out;
+ Parent::InEdgeIt in;
+ public:
+ OutEdgeIt() {}
+ OutEdgeIt(const SymSmartGraph& g, Edge e) {
+ if (e.id & 1 == 0) {
+ out = Parent::OutEdgeIt(g, SymEdge(e));
+ in = Parent::InEdgeIt(g, g.tail(e));
+ } else {
+ out = Parent::OutEdgeIt(INVALID);
+ in = Parent::InEdgeIt(g, SymEdge(e));
+ }
+ }
+ OutEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
+
+ OutEdgeIt(const SymSmartGraph& g, const Node v)
+ : out(g, v), in(g, v) {}
+ OutEdgeIt &operator++() {
+ if (out != INVALID) {
+ ++out;
+ } else {
+ ++in;
+ }
+ return *this;
+ }
+
+ operator Edge() const {
+ if (out == INVALID && in == INVALID) return INVALID;
+ return out != INVALID ? forward(out) : backward(in);
+ }
+
+ bool operator==(const Edge i) const {return Edge(*this) == i;}
+ bool operator!=(const Edge i) const {return Edge(*this) != i;}
+ bool operator<(const Edge i) const {return Edge(*this) < i;}
+ };
+
+ class InEdgeIt {
+ Parent::OutEdgeIt out;
+ Parent::InEdgeIt in;
+ public:
+ InEdgeIt() {}
+ InEdgeIt(const SymSmartGraph& g, Edge e) {
+ if (e.id & 1 == 0) {
+ out = Parent::OutEdgeIt(g, SymEdge(e));
+ in = Parent::InEdgeIt(g, g.tail(e));
+ } else {
+ out = Parent::OutEdgeIt(INVALID);
+ in = Parent::InEdgeIt(g, SymEdge(e));
+ }
+ }
+ InEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
+
+ InEdgeIt(const SymSmartGraph& g, const Node v)
+ : out(g, v), in(g, v) {}
+
+ InEdgeIt &operator++() {
+ if (out != INVALID) {
+ ++out;
+ } else {
+ ++in;
+ }
+ return *this;
+ }
+
+ operator Edge() const {
+ if (out == INVALID && in == INVALID) return INVALID;
+ return out != INVALID ? backward(out) : forward(in);
+ }
+
+ bool operator==(const Edge i) const {return Edge(*this) == i;}
+ bool operator!=(const Edge i) const {return Edge(*this) != i;}
+ bool operator<(const Edge i) const {return Edge(*this) < i;}
+ };
+
+ class SymEdgeIt : public Parent::EdgeIt {
+
+ public:
+ SymEdgeIt() {}
+
+ SymEdgeIt(const SymSmartGraph& g)
+ : SymSmartGraph::Parent::EdgeIt(g) {}
+
+ SymEdgeIt(const SymSmartGraph& g, SymEdge e)
+ : SymSmartGraph::Parent::EdgeIt(g, e) {}
+
+ SymEdgeIt(Invalid i)
+ : SymSmartGraph::Parent::EdgeIt(INVALID) {}
+
+ SymEdgeIt& operator++() {
+ SymSmartGraph::Parent::EdgeIt::operator++();
+ return *this;
+ }
+
+ operator SymEdge() const {
+ return SymEdge
+ (static_cast<const SymSmartGraph::Parent::EdgeIt&>(*this));
+ }
+ bool operator==(const SymEdge i) const {return SymEdge(*this) == i;}
+ bool operator!=(const SymEdge i) const {return SymEdge(*this) != i;}
+ bool operator<(const SymEdge i) const {return SymEdge(*this) < i;}
+ };
+
+ class EdgeIt {
+ SymEdgeIt it;
+ bool fw;
+ public:
+ EdgeIt(const SymSmartGraph& g) : it(g), fw(true) {}
+ EdgeIt (Invalid i) : it(i) { }
+ EdgeIt(const SymSmartGraph& g, Edge e)
+ : it(g, SymEdge(e)), fw(id(e) & 1 == 0) { }
+ EdgeIt() { }
+ EdgeIt& operator++() {
+ fw = !fw;
+ if (fw) ++it;
+ return *this;
+ }
+ operator Edge() const {
+ if (it == INVALID) return INVALID;
+ return fw ? forward(it) : backward(it);
+ }
+ bool operator==(const Edge i) const {return Edge(*this) == i;}
+ bool operator!=(const Edge i) const {return Edge(*this) != i;}
+ bool operator<(const Edge i) const {return Edge(*this) < i;}
+
+ };
+
+ ///Number of nodes.
+ int nodeNum() const { return Parent::nodeNum(); }
+ ///Number of edges.
+ int edgeNum() const { return 2*Parent::edgeNum(); }
+ ///Number of symmetric edges.
+ int symEdgeNum() const { return Parent::edgeNum(); }
+
+ /// Maximum node ID.
+
+ /// Maximum node ID.
+ ///\sa id(Node)
+ int maxNodeId() const { return Parent::maxNodeId(); }
+ /// Maximum edge ID.
+
+ /// Maximum edge ID.
+ ///\sa id(Edge)
+ int maxEdgeId() const { return 2*Parent::maxEdgeId(); }
+ /// Maximum symmetric edge ID.
+
+ /// Maximum symmetric edge ID.
+ ///\sa id(SymEdge)
+ int maxSymEdgeId() const { return Parent::maxEdgeId(); }
+
+
+ Node tail(Edge e) const {
+ return e.id & 1 == 0 ?
+ Parent::tail(SymEdge(e)) : Parent::head(SymEdge(e));
+ }
+
+ Node head(Edge e) const {
+ return e.id & 1 == 0 ?
+ Parent::head(SymEdge(e)) : Parent::tail(SymEdge(e));
+ }
+
+ Node tail(SymEdge e) const {
+ return Parent::tail(e);
+ }
+
+ Node head(SymEdge e) const {
+ return Parent::head(e);
+ }
+
+ NodeIt& first(NodeIt& v) const {
+ v=NodeIt(*this); return v; }
+ EdgeIt& first(EdgeIt& e) const {
+ e=EdgeIt(*this); return e; }
+ SymEdgeIt& first(SymEdgeIt& e) const {
+ e=SymEdgeIt(*this); return e; }
+ OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
+ e=OutEdgeIt(*this,v); return e; }
+ InEdgeIt& first(InEdgeIt& e, const Node v) const {
+ e=InEdgeIt(*this,v); return e; }
+
+ /// Node ID.
+
+ /// The ID of a valid Node is a nonnegative integer not greater than
+ /// \ref maxNodeId(). The range of the ID's is not surely continuous
+ /// and the greatest node ID can be actually less then \ref maxNodeId().
+ ///
+ /// The ID of the \ref INVALID node is -1.
+ ///\return The ID of the node \c v.
+ static int id(Node v) { return Parent::id(v); }
+ /// Edge ID.
+
+ /// The ID of a valid Edge is a nonnegative integer not greater than
+ /// \ref maxEdgeId(). The range of the ID's is not surely continuous
+ /// and the greatest edge ID can be actually less then \ref maxEdgeId().
+ ///
+ /// The ID of the \ref INVALID edge is -1.
+ ///\return The ID of the edge \c e.
+ static int id(Edge e) { return e.id; }
+
+ /// The ID of a valid SymEdge is a nonnegative integer not greater than
+ /// \ref maxSymEdgeId(). The range of the ID's is not surely continuous
+ /// and the greatest edge ID can be actually less then \ref maxSymEdgeId().
+ ///
+ /// The ID of the \ref INVALID symmetric edge is -1.
+ ///\return The ID of the edge \c e.
+ static int id(SymEdge e) { return Parent::id(e); }
+
+ /// Adds a new node to the graph.
+
+ /// \warning It adds the new node to the front of the list.
+ /// (i.e. the lastly added node becomes the first.)
+ Node addNode() {
+ return Parent::addNode();
+ }
+
+ SymEdge addEdge(Node u, Node v) {
+ SymEdge se = Parent::addEdge(u, v);
+ edge_maps.add(forward(se));
+ edge_maps.add(backward(se));
+ return se;
+ }
+
+ /// Finds an edge between two nodes.
+
+ /// Finds an edge from node \c u to node \c v.
+ ///
+ /// If \c prev is \ref INVALID (this is the default value), then
+ /// It finds the first edge from \c u to \c v. Otherwise it looks for
+ /// the next edge from \c u to \c v after \c prev.
+ /// \return The found edge or INVALID if there is no such an edge.
+ Edge findEdge(Node u, Node v, Edge prev = INVALID)
+ {
+ if (prev == INVALID || id(prev) & 1 == 0) {
+ SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
+ if (se != INVALID) return forward(se);
+ } else {
+ SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
+ if (se != INVALID) return backward(se);
+ }
+ return INVALID;
+ }
+
+ /// Finds an symmetric edge between two nodes.
+
+ /// Finds an symmetric edge from node \c u to node \c v.
+ ///
+ /// If \c prev is \ref INVALID (this is the default value), then
+ /// It finds the first edge from \c u to \c v. Otherwise it looks for
+ /// the next edge from \c u to \c v after \c prev.
+ /// \return The found edge or INVALID if there is no such an edge.
+
+// SymEdge findEdge(Node u, Node v, SymEdge prev = INVALID)
+// {
+// if (prev == INVALID || id(prev) & 1 == 0) {
+// SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
+// if (se != INVALID) return se;
+// } else {
+// SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
+// if (se != INVALID) return se;
+// }
+// return INVALID;
+// }
+
+ public:
+
+ void clear() {
+ edge_maps.clear();
+ Parent::clear();
+ }
+
+ static Edge opposite(Edge e) {
+ return Edge(id(e) ^ 1);
+ }
+
+ static Edge forward(SymEdge e) {
+ return Edge(id(e) << 1);
+ }
+
+ static Edge backward(SymEdge e) {
+ return Edge((id(e) << 1) & 1);
+ }
+
+ };
///Graph for bidirectional edges.
///The purpose of this graph structure is to handle graphs
@@ -318,7 +691,7 @@
///it is not possible to delete edges or nodes from the graph.
//\sa SmartGraph.
- class SymSmartGraph : public SmartGraph
+ /* class SymSmartGraph : public SmartGraph
{
public:
typedef SymSmartGraph Graph;
@@ -353,7 +726,7 @@
}
- };
+ };*/
/// @}
} //namespace hugo
Modified: hugo/trunk/src/test/Makefile.am
==============================================================================
--- hugo/trunk/src/test/Makefile.am (original)
+++ hugo/trunk/src/test/Makefile.am Sun Sep 26 23:43:38 2004
@@ -9,6 +9,7 @@
dfs_test \
dijkstra_test \
graph_test \
+ sym_graph_test \
graph_wrapper_test \
kruskal_test \
min_cost_flow_test \
@@ -28,6 +29,7 @@
dfs_test_SOURCES = dfs_test.cc
dijkstra_test_SOURCES = dijkstra_test.cc
graph_test_SOURCES = graph_test.cc
+sym_graph_test_SOURCES = sym_graph_test.cc
graph_wrapper_test_SOURCES = graph_wrapper_test.cc
kruskal_test_SOURCES = kruskal_test.cc
min_cost_flow_test_SOURCES = min_cost_flow_test.cc
Modified: hugo/trunk/src/test/graph_test.cc
==============================================================================
--- hugo/trunk/src/test/graph_test.cc (original)
+++ hugo/trunk/src/test/graph_test.cc Sun Sep 26 23:43:38 2004
@@ -63,7 +63,6 @@
for(NodeIt n(G);n!=INVALID;++n) {
checkGraphInEdgeList(G,n,3);
checkGraphOutEdgeList(G,n,3);
- ++n;
}
}
@@ -82,8 +81,8 @@
template void hugo::checkCompileGraphFindEdge<SmartGraph>(SmartGraph &);
//Compile SymSmartGraph
-template void hugo::checkCompileGraph<SymSmartGraph>(SymSmartGraph &);
-template void hugo::checkCompileGraphFindEdge<SymSmartGraph>(SymSmartGraph &);
+//template void hugo::checkCompileGraph<SymSmartGraph>(SymSmartGraph &);
+//template void hugo::checkCompileGraphFindEdge<SymSmartGraph>(SymSmartGraph &);
//Compile ListGraph
template void hugo::checkCompileGraph<ListGraph>(ListGraph &);
@@ -92,9 +91,9 @@
//Compile SymListGraph
-template void hugo::checkCompileGraph<SymListGraph>(SymListGraph &);
-template void hugo::checkCompileErasableGraph<SymListGraph>(SymListGraph &);
-template void hugo::checkCompileGraphFindEdge<SymListGraph>(SymListGraph &);
+//template void hugo::checkCompileGraph<SymListGraph>(SymListGraph &);
+//template void hugo::checkCompileErasableGraph<SymListGraph>(SymListGraph &);
+//template void hugo::checkCompileGraphFindEdge<SymListGraph>(SymListGraph &);
//Compile FullGraph
template void hugo::checkCompileStaticGraph<FullGraph>(FullGraph &);
@@ -131,14 +130,14 @@
checkPetersen(G);
}
{
- SymSmartGraph G;
- addPetersen(G);
- checkPetersen(G);
+ // SymSmartGraph G;
+ // addPetersen(G);
+ // checkPetersen(G);
}
{
- SymListGraph G;
- addPetersen(G);
- checkPetersen(G);
+ // SymListGraph G;
+ // addPetersen(G);
+ // checkPetersen(G);
}
///\file
Added: hugo/trunk/src/test/sym_graph_test.cc
==============================================================================
--- (empty file)
+++ hugo/trunk/src/test/sym_graph_test.cc Sun Sep 26 23:43:38 2004
@@ -0,0 +1,96 @@
+/* -*- C++ -*-
+ * src/test/sym_graph_test.cc - Part of HUGOlib, a generic C++ optimization library
+ *
+ * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Combinatorial Optimization Research Group, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include<iostream>
+
+#include<hugo/skeletons/sym_graph.h>
+
+#include<hugo/list_graph.h>
+#include<hugo/smart_graph.h>
+#include<hugo/full_graph.h>
+
+#include"test_tools.h"
+#include"graph_test.h"
+#include"sym_graph_test.h"
+
+/**
+\file
+This test makes consistency checks of list graph structures.
+
+G.addNode(), G.addEdge(), G.tail(), G.head()
+
+\todo Checks for empty graphs and isolated points.
+conversion.
+*/
+
+using namespace hugo;
+
+template<class Graph> void checkPetersen(Graph &G)
+{
+ typedef typename Graph::NodeIt NodeIt;
+
+
+ checkGraphNodeList(G,10);
+ checkGraphEdgeList(G,30);
+ checkGraphSymEdgeList(G,15);
+
+ for(NodeIt n(G);n!=INVALID;++n) {
+ checkGraphInEdgeList(G,n,3);
+ checkGraphOutEdgeList(G,n,3);
+ }
+}
+
+//Compile Graph
+template void hugo::checkCompileStaticSymGraph<skeleton::StaticSymGraph>
+(skeleton::StaticSymGraph &);
+
+template void hugo::checkCompileSymGraph<skeleton::ExtendableSymGraph>
+(skeleton::ExtendableSymGraph &);
+
+template void hugo::checkCompileErasableSymGraph<skeleton::ErasableSymGraph>
+(skeleton::ErasableSymGraph &);
+
+
+//Compile SymSmartGraph
+template void hugo::checkCompileSymGraph<SymSmartGraph>(SymSmartGraph &);
+template void hugo::checkCompileGraphFindEdge<SymSmartGraph>(SymSmartGraph &);
+
+//Compile SymListGraph
+template void hugo::checkCompileSymGraph<SymListGraph>(SymListGraph &);
+template void hugo::checkCompileErasableSymGraph<SymListGraph>(SymListGraph &);
+template void hugo::checkCompileGraphFindEdge<SymListGraph>(SymListGraph &);
+
+int main()
+{
+ {
+ SymSmartGraph G;
+ addSymPetersen(G);
+ checkPetersen(G);
+ }
+ {
+ SymListGraph G;
+ addSymPetersen(G);
+ checkPetersen(G);
+ }
+
+ ///\file
+ ///\todo map tests.
+ ///\todo copy constr tests.
+
+ std::cout << __FILE__ ": All tests passed.\n";
+
+ return 0;
+}
Added: hugo/trunk/src/test/sym_graph_test.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/test/sym_graph_test.h Sun Sep 26 23:43:38 2004
@@ -0,0 +1,179 @@
+/* -*- C++ -*-
+ * src/test/sym_graph_test.h - Part of HUGOlib, a generic C++ optimization library
+ *
+ * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Combinatorial Optimization Research Group, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+#ifndef HUGO_TEST_SYM_GRAPH_TEST_H
+#define HUGO_TEST_SYM_GRAPH_TEST_H
+
+
+#include "graph_test.h"
+#include "test_tools.h"
+
+//! \ingroup misc
+//! \file
+//! \brief Some utility to test symmetric graph classes.
+namespace hugo {
+
+ template<class Graph> void checkCompileStaticSymGraph(Graph &G)
+ {
+ typedef typename Graph::Node Node;
+ typedef typename Graph::NodeIt NodeIt;
+ typedef typename Graph::SymEdge SymEdge;
+ typedef typename Graph::SymEdgeIt SymEdgeIt;
+ typedef typename Graph::Edge Edge;
+ typedef typename Graph::EdgeIt EdgeIt;
+ typedef typename Graph::InEdgeIt InEdgeIt;
+ typedef typename Graph::OutEdgeIt OutEdgeIt;
+
+ checkCompileStaticGraph(G);
+
+ {
+ SymEdge i; SymEdge j(i); SymEdge k(INVALID);
+ i=j;
+ bool b; b=true;
+ b=(i==INVALID); b=(i!=INVALID);
+ b=(i==j); b=(i!=j); b=(i<j);
+ Edge e;
+ e = G.forward(i);
+ e = G.backward(i);
+ }
+ {
+ SymEdgeIt i; SymEdgeIt j(i); SymEdgeIt k(INVALID); SymEdgeIt l(G);
+ i=j;
+ j=G.first(i);
+ j=++i;
+ bool b; b=true;
+ b=(i==INVALID); b=(i!=INVALID);
+ SymEdge n(i);
+ n=i;
+ b=(i==j); b=(i!=j); b=(i<j);
+ //SymEdge ->SymEdgeIt conversion
+ SymEdgeIt ni(G,n);
+ }
+ {
+ Edge i, j;
+ j = G.opposite(i);
+ }
+ {
+ Node n;
+ SymEdge se;
+ se=INVALID;
+ n=G.tail(se);
+ n=G.head(se);
+ }
+ // id tests
+ { SymEdge n; int i=G.id(n); i=i; }
+ //SymEdgeMap tests
+ {
+ SymEdge k;
+ typename Graph::template SymEdgeMap<int> m(G);
+ typename Graph::template SymEdgeMap<int> const &cm = m; //Const map
+ //Inicialize with default value
+ typename Graph::template SymEdgeMap<int> mdef(G,12);
+ typename Graph::template SymEdgeMap<int> mm(cm); //Copy
+ typename Graph::template SymEdgeMap<double> dm(cm); //Copy from another type
+ int v;
+ v=m[k]; m[k]=v; m.set(k,v);
+ v=cm[k];
+
+ m=cm;
+ dm=cm; //Copy from another type
+ {
+ //Check the typedef's
+ typename Graph::template SymEdgeMap<int>::ValueType val;
+ val = 1;
+ typename Graph::template SymEdgeMap<int>::KeyType key;
+ key = typename Graph::SymEdgeIt(G);
+ }
+ }
+ { //bool SymEdgeMap
+ SymEdge k;
+ typename Graph::template SymEdgeMap<bool> m(G);
+ typename Graph::template SymEdgeMap<bool> const &cm = m; //Const map
+ //Inicialize with default value
+ typename Graph::template SymEdgeMap<bool> mdef(G,12);
+ typename Graph::template SymEdgeMap<bool> mm(cm); //Copy
+ typename Graph::template SymEdgeMap<int> dm(cm); //Copy from another type
+ bool v;
+ v=m[k]; m[k]=v; m.set(k,v);
+ v=cm[k];
+
+ m=cm;
+ dm=cm; //Copy from another type
+ m=dm; //Copy to another type
+ {
+ //Check the typedef's
+ typename Graph::template SymEdgeMap<bool>::ValueType val;
+ val=true;
+ typename Graph::template SymEdgeMap<bool>::KeyType key;
+ key= typename Graph::SymEdgeIt(G);
+ }
+ }
+ }
+
+ template<class Graph> void checkCompileSymGraph(Graph &G)
+ {
+ checkCompileStaticSymGraph(G);
+
+ typedef typename Graph::Node Node;
+ typedef typename Graph::NodeIt NodeIt;
+ typedef typename Graph::SymEdge SymEdge;
+ typedef typename Graph::SymEdgeIt SymEdgeIt;
+ typedef typename Graph::Edge Edge;
+ typedef typename Graph::EdgeIt EdgeIt;
+ typedef typename Graph::InEdgeIt InEdgeIt;
+ typedef typename Graph::OutEdgeIt OutEdgeIt;
+
+ Node n,m;
+ n=G.addNode();
+ m=G.addNode();
+ SymEdge e;
+ e = G.addEdge(n,m);
+
+ // G.clear();
+ }
+
+ template<class Graph> void checkCompileSymGraphEraseSymEdge(Graph &G)
+ {
+ typename Graph::SymEdge n;
+ G.erase(n);
+ }
+
+ template<class Graph> void checkCompileErasableSymGraph(Graph &G)
+ {
+ checkCompileSymGraph(G);
+ checkCompileGraphEraseNode(G);
+ checkCompileSymGraphEraseSymEdge(G);
+ }
+
+ template<class Graph> void checkGraphSymEdgeList(Graph &G, int nn)
+ {
+ typedef typename Graph::SymEdgeIt SymEdgeIt;
+
+ SymEdgeIt e(G);
+ for(int i=0;i<nn;i++) {
+ check(e!=INVALID,"Wrong SymEdge list linking.");
+ ++e;
+ }
+ check(e==INVALID,"Wrong SymEdge list linking.");
+ }
+
+ ///\file
+ ///\todo Check head(), tail() as well;
+
+
+} //namespace hugo
+
+
+#endif
Modified: hugo/trunk/src/test/test_tools.h
==============================================================================
--- hugo/trunk/src/test/test_tools.h (original)
+++ hugo/trunk/src/test/test_tools.h Sun Sep 26 23:43:38 2004
@@ -67,7 +67,7 @@
///Adds a Petersen graph to \c G.
///Adds a Petersen graph to \c G.
-///\return The nodes end edges og the generated graph.
+///\return The nodes and edges of the generated graph.
template<typename Graph>
PetStruct<Graph> addPetersen(Graph &G,int num=5)
@@ -87,6 +87,45 @@
return n;
}
+///Structure returned by \ref addSymPetersen().
+///Structure returned by \ref addSymPetersen().
+///
+template<class Graph> struct SymPetStruct
+{
+ ///Vector containing the outer nodes.
+ std::vector<typename Graph::Node> outer;
+ ///Vector containing the inner nodes.
+ std::vector<typename Graph::Node> inner;
+ ///Vector containing the edges of the inner circle.
+ std::vector<typename Graph::SymEdge> incir;
+ ///Vector containing the edges of the outer circle.
+ std::vector<typename Graph::SymEdge> outcir;
+ ///Vector containing the chord edges.
+ std::vector<typename Graph::SymEdge> chords;
+};
+
+///Adds a Petersen graph to the symmetric \c G.
+
+///Adds a Petersen graph to the symmetric \c G.
+///\return The nodes and edges of the generated graph.
+
+template<typename Graph>
+SymPetStruct<Graph> addSymPetersen(Graph &G,int num=5)
+{
+ SymPetStruct<Graph> n;
+
+ for(int i=0;i<num;i++) {
+ n.outer.push_back(G.addNode());
+ n.inner.push_back(G.addNode());
+ }
+
+ for(int i=0;i<num;i++) {
+ n.chords.push_back(G.addEdge(n.outer[i],n.inner[i]));
+ n.outcir.push_back(G.addEdge(n.outer[i],n.outer[(i+1)%5]));
+ n.incir.push_back(G.addEdge(n.inner[i],n.inner[(i+2)%5]));
+ }
+ return n;
+}
#endif
More information about the Lemon-commits
mailing list