[Lemon-commits] [lemon_svn] deba: r2231 - in hugo/trunk/lemon: . bits
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:51:07 CET 2006
Author: deba
Date: Wed Oct 5 15:17:42 2005
New Revision: 2231
Modified:
hugo/trunk/lemon/bits/iterable_graph_extender.h
hugo/trunk/lemon/bits/undir_graph_extender.h
hugo/trunk/lemon/graph_utils.h
Log:
findUndirEdge, ConUndirEdgeIt
some modification in the undir graph extenders
Modified: hugo/trunk/lemon/bits/iterable_graph_extender.h
==============================================================================
--- hugo/trunk/lemon/bits/iterable_graph_extender.h (original)
+++ hugo/trunk/lemon/bits/iterable_graph_extender.h Wed Oct 5 15:17:42 2005
@@ -216,30 +216,25 @@
class IncEdgeIt : public Parent::UndirEdge {
const Graph* graph;
- bool forward;
+ bool direction;
friend class IterableUndirGraphExtender;
- template <typename G>
- friend class UndirGraphExtender;
public:
IncEdgeIt() { }
- IncEdgeIt(Invalid i) : UndirEdge(i), forward(false) { }
+ IncEdgeIt(Invalid i) : UndirEdge(i), direction(false) { }
- IncEdgeIt(const Graph& _graph, const Node &n)
- : graph(&_graph)
- {
- _graph._dirFirstOut(*this, n);
+ IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
+ _graph.firstInc(*this, direction, n);
}
IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
- : graph(&_graph), UndirEdge(ue)
- {
- forward = (_graph.source(ue) == n);
+ : graph(&_graph), UndirEdge(ue) {
+ direction = (_graph.source(ue) == n);
}
IncEdgeIt& operator++() {
- graph->_dirNextOut(*this);
+ graph->nextInc(*this, direction);
return *this;
}
};
@@ -251,13 +246,13 @@
///
/// Returns the base node of the iterator
Node baseNode(const IncEdgeIt &e) const {
- return _dirSource(e);
+ return e.direction ? source(e) : target(e);
}
/// Running node of the iterator
///
/// Returns the running node of the iterator
Node runningNode(const IncEdgeIt &e) const {
- return _dirTarget(e);
+ return e.direction ? target(e) : source(e);
}
/// \brief The opposite node on the given undirected edge.
Modified: hugo/trunk/lemon/bits/undir_graph_extender.h
==============================================================================
--- hugo/trunk/lemon/bits/undir_graph_extender.h (original)
+++ hugo/trunk/lemon/bits/undir_graph_extender.h Wed Oct 5 15:17:42 2005
@@ -71,18 +71,6 @@
return Edge(e,!e.forward);
}
- protected:
-
- template <typename E>
- Node _dirSource(const E &e) const {
- return e.forward ? Parent::source(e) : Parent::target(e);
- }
-
- template <typename E>
- Node _dirTarget(const E &e) const {
- return e.forward ? Parent::target(e) : Parent::source(e);
- }
-
public:
/// \todo Shouldn't the "source" of an undirected edge be called "aNode"
/// or something???
@@ -90,7 +78,7 @@
/// Source of the given Edge.
Node source(const Edge &e) const {
- return _dirSource(e);
+ return e.forward ? Parent::source(e) : Parent::target(e);
}
/// \todo Shouldn't the "target" of an undirected edge be called "bNode"
@@ -99,7 +87,7 @@
/// Target of the given Edge.
Node target(const Edge &e) const {
- return _dirTarget(e);
+ return e.forward ? Parent::target(e) : Parent::source(e);
}
Node oppositeNode(const Node &n, const UndirEdge &e) const {
@@ -154,11 +142,9 @@
}
}
-
- protected:
+ public:
- template <typename E>
- void _dirFirstOut(E &e, const Node &n) const {
+ void firstOut(Edge &e, const Node &n) const {
Parent::firstIn(e,n);
if( UndirEdge(e) != INVALID ) {
e.forward = false;
@@ -168,20 +154,7 @@
e.forward = true;
}
}
- template <typename E>
- void _dirFirstIn(E &e, const Node &n) const {
- Parent::firstOut(e,n);
- if( UndirEdge(e) != INVALID ) {
- e.forward = false;
- }
- else {
- Parent::firstIn(e,n);
- e.forward = true;
- }
- }
-
- template <typename E>
- void _dirNextOut(E &e) const {
+ void nextOut(Edge &e) const {
if( ! e.forward ) {
Node n = Parent::target(e);
Parent::nextIn(e);
@@ -194,8 +167,18 @@
Parent::nextOut(e);
}
}
- template <typename E>
- void _dirNextIn(E &e) const {
+
+ void firstIn(Edge &e, const Node &n) const {
+ Parent::firstOut(e,n);
+ if( UndirEdge(e) != INVALID ) {
+ e.forward = false;
+ }
+ else {
+ Parent::firstIn(e,n);
+ e.forward = true;
+ }
+ }
+ void nextIn(Edge &e) const {
if( ! e.forward ) {
Node n = Parent::source(e);
Parent::nextOut(e);
@@ -209,20 +192,38 @@
}
}
- public:
-
- void firstOut(Edge &e, const Node &n) const {
- _dirFirstOut(e, n);
+ void firstInc(UndirEdge &e, const Node &n) const {
+ Parent::firstOut(e, n);
+ if (e != INVALID) return;
+ Parent::firstIn(e, n);
}
- void firstIn(Edge &e, const Node &n) const {
- _dirFirstIn(e, n);
+ void nextInc(UndirEdge &e, const Node &n) const {
+ if (Parent::source(e) == n) {
+ Parent::nextOut(e);
+ if (e != INVALID) return;
+ Parent::firstIn(e, n);
+ } else {
+ Parent::nextIn(e);
+ }
}
- void nextOut(Edge &e) const {
- _dirNextOut(e);
- }
- void nextIn(Edge &e) const {
- _dirNextIn(e);
+ void firstInc(UndirEdge &e, bool &d, const Node &n) const {
+ d = true;
+ Parent::firstOut(e, n);
+ if (e != INVALID) return;
+ d = false;
+ Parent::firstIn(e, n);
+ }
+ void nextInc(UndirEdge &e, bool &d) const {
+ if (d) {
+ Node s = Parent::source(e);
+ Parent::nextOut(e);
+ if (e != INVALID) return;
+ d = false;
+ Parent::firstIn(e, s);
+ } else {
+ Parent::nextIn(e);
+ }
}
// Miscellaneous stuff:
@@ -262,10 +263,47 @@
int edgeNum() const {
return 2 * Parent::edgeNum();
}
+
int undirEdgeNum() const {
return Parent::edgeNum();
}
+ Edge findEdge(Node source, Node target, Edge prev) const {
+ if (prev == INVALID) {
+ UndirEdge edge = Parent::findEdge(source, target);
+ if (edge != INVALID) return direct(edge, true);
+ edge = Parent::findEdge(target, source);
+ if (edge != INVALID) return direct(edge, false);
+ } else if (direction(prev)) {
+ UndirEdge edge = Parent::findEdge(source, target, prev);
+ if (edge != INVALID) return direct(edge, true);
+ edge = Parent::findEdge(target, source);
+ if (edge != INVALID) return direct(edge, false);
+ } else {
+ UndirEdge edge = Parent::findEdge(target, source, prev);
+ if (edge != INVALID) return direct(edge, false);
+ }
+ return INVALID;
+ }
+
+ UndirEdge findUndirEdge(Node source, Node target, UndirEdge prev) const {
+ if (prev == INVALID) {
+ UndirEdge edge = Parent::findEdge(source, target);
+ if (edge != INVALID) return edge;
+ edge = Parent::findEdge(target, source);
+ if (edge != INVALID) return edge;
+ } else if (Parent::source(prev) == source) {
+ UndirEdge edge = Parent::findEdge(source, target, prev);
+ if (edge != INVALID) return edge;
+ edge = Parent::findEdge(target, source);
+ if (edge != INVALID) return edge;
+ } else {
+ UndirEdge edge = Parent::findEdge(target, source, prev);
+ if (edge != INVALID) return edge;
+ }
+ return INVALID;
+ }
+
};
}
Modified: hugo/trunk/lemon/graph_utils.h
==============================================================================
--- hugo/trunk/lemon/graph_utils.h (original)
+++ hugo/trunk/lemon/graph_utils.h Wed Oct 5 15:17:42 2005
@@ -160,9 +160,9 @@
return countNodeDegree<Graph, typename Graph::InEdgeIt>(_g, _n);
}
- /// \brief Function to count the number of the in-edges to node \c n.
+ /// \brief Function to count the number of the inc-edges to node \c n.
///
- /// This function counts the number of the in-edges to node \c n
+ /// This function counts the number of the inc-edges to node \c n
/// in the graph.
template <typename Graph>
inline int countIncEdges(const Graph& _g, const typename Graph::Node& _n) {
@@ -214,7 +214,6 @@
/// \endcode
// /// \todo We may want to use the "GraphBase"
// /// interface here...
- // /// It would not work with the undirected graphs.
template <typename Graph>
inline typename Graph::Edge findEdge(const Graph &g,
typename Graph::Node u,
@@ -271,6 +270,110 @@
const Graph& graph;
};
+ template <typename Graph>
+ inline
+ typename enable_if<
+ typename Graph::FindEdgeTag,
+ typename Graph::UndirEdge>::type
+ _findUndirEdge(const Graph &g,
+ typename Graph::Node u, typename Graph::Node v,
+ typename Graph::UndirEdge prev = INVALID) {
+ return g.findUndirEdge(u, v, prev);
+ }
+
+ template <typename Graph>
+ inline typename Graph::UndirEdge
+ _findUndirEdge(Wrap<Graph> w,
+ typename Graph::Node u,
+ typename Graph::Node v,
+ typename Graph::UndirEdge prev = INVALID) {
+ const Graph& g = w.value;
+ if (prev == INVALID) {
+ typename Graph::OutEdgeIt e(g, u);
+ while (e != INVALID && g.target(e) != v) ++e;
+ return e;
+ } else {
+ typename Graph::OutEdgeIt e(g, g.direct(prev, u)); ++e;
+ while (e != INVALID && g.target(e) != v) ++e;
+ return e;
+ }
+ }
+
+ /// \brief Finds an undir edge between two nodes of a graph.
+ ///
+ /// Finds an undir edge from node \c u to node \c v in graph \c g.
+ ///
+ /// 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 \ref INVALID if there is no such an edge.
+ ///
+ /// Thus you can iterate through each edge from \c u to \c v as it follows.
+ /// \code
+ /// for(UndirEdge e = findUndirEdge(g,u,v); e != INVALID;
+ /// e = findUndirEdge(g,u,v,e)) {
+ /// ...
+ /// }
+ /// \endcode
+ // /// \todo We may want to use the "GraphBase"
+ // /// interface here...
+ template <typename Graph>
+ inline typename Graph::UndirEdge
+ findUndirEdge(const Graph &g,
+ typename Graph::Node u,
+ typename Graph::Node v,
+ typename Graph::UndirEdge prev = INVALID) {
+ return _findUndirEdge<Graph>(g, u, v, prev);
+ }
+
+ /// \brief Iterator for iterating on undir edges connected the same nodes.
+ ///
+ /// Iterator for iterating on undir edges connected the same nodes. It is
+ /// higher level interface for the findUndirEdge() function. You can
+ /// use it the following way:
+ /// \code
+ /// for (ConUndirEdgeIt<Graph> it(g, src, trg); it != INVALID; ++it) {
+ /// ...
+ /// }
+ /// \endcode
+ ///
+ /// \author Balazs Dezso
+ template <typename _Graph>
+ class ConUndirEdgeIt : public _Graph::UndirEdge {
+ public:
+
+ typedef _Graph Graph;
+ typedef typename Graph::UndirEdge Parent;
+
+ typedef typename Graph::UndirEdge UndirEdge;
+ typedef typename Graph::Node Node;
+
+ /// \brief Constructor.
+ ///
+ /// Construct a new ConUndirEdgeIt iterating on the edges which
+ /// connects the \c u and \c v node.
+ ConUndirEdgeIt(const Graph& g, Node u, Node v) : graph(g) {
+ Parent::operator=(findUndirEdge(graph, u, v));
+ }
+
+ /// \brief Constructor.
+ ///
+ /// Construct a new ConUndirEdgeIt which continues the iterating from
+ /// the \c e edge.
+ ConUndirEdgeIt(const Graph& g, UndirEdge e) : Parent(e), graph(g) {}
+
+ /// \brief Increment operator.
+ ///
+ /// It increments the iterator and gives back the next edge.
+ ConUndirEdgeIt& operator++() {
+ Parent::operator=(findUndirEdge(graph, graph.source(*this),
+ graph.target(*this), *this));
+ return *this;
+ }
+ private:
+ const Graph& graph;
+ };
+
/// \brief Copy a map.
///
/// This function copies the \c source map to the \c target map. It uses the
@@ -552,8 +655,6 @@
typedef _Item Item;
typedef _Item Key;
- typedef True NeedCopy;
-
/// \brief Constructor.
///
/// Constructor for creating id map.
@@ -577,8 +678,6 @@
class InverseMap {
public:
- typedef True NeedCopy;
-
/// \brief Constructor.
///
/// Constructor for creating an id-to-item map.
@@ -906,8 +1005,6 @@
class SourceMap {
public:
- typedef True NeedCopy;
-
typedef typename Graph::Node Value;
typedef typename Graph::Edge Key;
@@ -947,8 +1044,6 @@
class TargetMap {
public:
- typedef True NeedCopy;
-
typedef typename Graph::Node Value;
typedef typename Graph::Edge Key;
@@ -988,8 +1083,6 @@
class ForwardMap {
public:
- typedef True NeedCopy;
-
typedef typename Graph::Edge Value;
typedef typename Graph::UndirEdge Key;
@@ -1028,7 +1121,6 @@
template <typename Graph>
class BackwardMap {
public:
- typedef True NeedCopy;
typedef typename Graph::Edge Value;
typedef typename Graph::UndirEdge Key;
@@ -1296,11 +1388,10 @@
protected:
static int index(int i, int j) {
- int m = i > j ? i : j;
if (i < j) {
- return m * m + i;
+ return j * j + i;
} else {
- return m * m + m + j;
+ return i * i + i + j;
}
}
More information about the Lemon-commits
mailing list