Location: LEMON/LEMON-official/lemon/euler.h - annotation
Load file history
Merge
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r568:3af83b6be1df r567:42d4b889903a r567:42d4b889903a r568:3af83b6be1df r567:42d4b889903a r568:3af83b6be1df r567:42d4b889903a r567:42d4b889903a r568:3af83b6be1df r567:42d4b889903a r568:3af83b6be1df r568:3af83b6be1df r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r568:3af83b6be1df r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r568:3af83b6be1df r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a r567:42d4b889903a | /* -*- mode: C++; indent-tabs-mode: nil; -*-
*
* This file is a part of LEMON, a generic C++ optimization library.
*
* Copyright (C) 2003-2009
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
* (Egervary Research Group on Combinatorial Optimization, 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 LEMON_EULER_H
#define LEMON_EULER_H
#include<lemon/core.h>
#include<lemon/adaptors.h>
#include<lemon/connectivity.h>
#include <list>
/// \ingroup graph_prop
/// \file
/// \brief Euler tour
///
///This file provides an Euler tour iterator and ways to check
///if a digraph is euler.
namespace lemon {
///Euler iterator for digraphs.
/// \ingroup graph_prop
///This iterator converts to the \c Arc type of the digraph and using
///operator ++, it provides an Euler tour of a \e directed
///graph (if there exists).
///
///For example
///if the given digraph is Euler (i.e it has only one nontrivial component
///and the in-degree is equal to the out-degree for all nodes),
///the following code will put the arcs of \c g
///to the vector \c et according to an
///Euler tour of \c g.
///\code
/// std::vector<ListDigraph::Arc> et;
/// for(DiEulerIt<ListDigraph> e(g),e!=INVALID;++e)
/// et.push_back(e);
///\endcode
///If \c g is not Euler then the resulted tour will not be full or closed.
///\sa EulerIt
template<class Digraph>
class DiEulerIt
{
typedef typename Digraph::Node Node;
typedef typename Digraph::NodeIt NodeIt;
typedef typename Digraph::Arc Arc;
typedef typename Digraph::ArcIt ArcIt;
typedef typename Digraph::OutArcIt OutArcIt;
typedef typename Digraph::InArcIt InArcIt;
const Digraph &g;
typename Digraph::template NodeMap<OutArcIt> nedge;
std::list<Arc> euler;
public:
///Constructor
///\param _g A digraph.
///\param start The starting point of the tour. If it is not given
/// the tour will start from the first node.
DiEulerIt(const Digraph &_g,typename Digraph::Node start=INVALID)
: g(_g), nedge(g)
{
if(start==INVALID) start=NodeIt(g);
for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
while(nedge[start]!=INVALID) {
euler.push_back(nedge[start]);
Node next=g.target(nedge[start]);
++nedge[start];
start=next;
}
}
///Arc Conversion
operator Arc() { return euler.empty()?INVALID:euler.front(); }
bool operator==(Invalid) { return euler.empty(); }
bool operator!=(Invalid) { return !euler.empty(); }
///Next arc of the tour
DiEulerIt &operator++() {
Node s=g.target(euler.front());
euler.pop_front();
//This produces a warning.Strange.
//std::list<Arc>::iterator next=euler.begin();
typename std::list<Arc>::iterator next=euler.begin();
while(nedge[s]!=INVALID) {
euler.insert(next,nedge[s]);
Node n=g.target(nedge[s]);
++nedge[s];
s=n;
}
return *this;
}
///Postfix incrementation
///\warning This incrementation
///returns an \c Arc, not an \ref DiEulerIt, as one may
///expect.
Arc operator++(int)
{
Arc e=*this;
++(*this);
return e;
}
};
///Euler iterator for graphs.
/// \ingroup graph_prop
///This iterator converts to the \c Arc (or \c Edge)
///type of the digraph and using
///operator ++, it provides an Euler tour of an undirected
///digraph (if there exists).
///
///For example
///if the given digraph if Euler (i.e it has only one nontrivial component
///and the degree of each node is even),
///the following code will print the arc IDs according to an
///Euler tour of \c g.
///\code
/// for(EulerIt<ListGraph> e(g),e!=INVALID;++e) {
/// std::cout << g.id(Edge(e)) << std::eol;
/// }
///\endcode
///Although the iterator provides an Euler tour of an graph,
///it still returns Arcs in order to indicate the direction of the tour.
///(But Arc will convert to Edges, of course).
///
///If \c g is not Euler then the resulted tour will not be full or closed.
///\sa EulerIt
template<class Digraph>
class EulerIt
{
typedef typename Digraph::Node Node;
typedef typename Digraph::NodeIt NodeIt;
typedef typename Digraph::Arc Arc;
typedef typename Digraph::Edge Edge;
typedef typename Digraph::ArcIt ArcIt;
typedef typename Digraph::OutArcIt OutArcIt;
typedef typename Digraph::InArcIt InArcIt;
const Digraph &g;
typename Digraph::template NodeMap<OutArcIt> nedge;
typename Digraph::template EdgeMap<bool> visited;
std::list<Arc> euler;
public:
///Constructor
///\param _g An graph.
///\param start The starting point of the tour. If it is not given
/// the tour will start from the first node.
EulerIt(const Digraph &_g,typename Digraph::Node start=INVALID)
: g(_g), nedge(g), visited(g,false)
{
if(start==INVALID) start=NodeIt(g);
for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
while(nedge[start]!=INVALID) {
euler.push_back(nedge[start]);
visited[nedge[start]]=true;
Node next=g.target(nedge[start]);
++nedge[start];
start=next;
while(nedge[start]!=INVALID && visited[nedge[start]]) ++nedge[start];
}
}
///Arc Conversion
operator Arc() const { return euler.empty()?INVALID:euler.front(); }
///Arc Conversion
operator Edge() const { return euler.empty()?INVALID:euler.front(); }
///\e
bool operator==(Invalid) const { return euler.empty(); }
///\e
bool operator!=(Invalid) const { return !euler.empty(); }
///Next arc of the tour
EulerIt &operator++() {
Node s=g.target(euler.front());
euler.pop_front();
typename std::list<Arc>::iterator next=euler.begin();
while(nedge[s]!=INVALID) {
while(nedge[s]!=INVALID && visited[nedge[s]]) ++nedge[s];
if(nedge[s]==INVALID) break;
else {
euler.insert(next,nedge[s]);
visited[nedge[s]]=true;
Node n=g.target(nedge[s]);
++nedge[s];
s=n;
}
}
return *this;
}
///Postfix incrementation
///\warning This incrementation
///returns an \c Arc, not an \ref EulerIt, as one may
///expect.
Arc operator++(int)
{
Arc e=*this;
++(*this);
return e;
}
};
///Checks if the graph is Eulerian
/// \ingroup graph_prop
///Checks if the graph is Eulerian. It works for both directed and undirected
///graphs.
///\note By definition, a digraph is called \e Eulerian if
///and only if it is connected and the number of its incoming and outgoing
///arcs are the same for each node.
///Similarly, an undirected graph is called \e Eulerian if
///and only if it is connected and the number of incident arcs is even
///for each node. <em>Therefore, there are digraphs which are not Eulerian,
///but still have an Euler tour</em>.
template<class Digraph>
#ifdef DOXYGEN
bool
#else
typename enable_if<UndirectedTagIndicator<Digraph>,bool>::type
eulerian(const Digraph &g)
{
for(typename Digraph::NodeIt n(g);n!=INVALID;++n)
if(countIncEdges(g,n)%2) return false;
return connected(g);
}
template<class Digraph>
typename disable_if<UndirectedTagIndicator<Digraph>,bool>::type
#endif
eulerian(const Digraph &g)
{
for(typename Digraph::NodeIt n(g);n!=INVALID;++n)
if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
return connected(Undirector<const Digraph>(g));
}
}
#endif
|