gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Rename euler() to eulerian() (#65)
0 1 0
default
1 file changed with 8 insertions and 8 deletions:
↑ Collapse diff ↑
Show white space 384 line context
... ...
@@ -39,229 +39,229 @@
39 39
  /// \ingroup graph_prop
40 40
  ///This iterator converts to the \c Arc type of the digraph and using
41 41
  ///operator ++, it provides an Euler tour of a \e directed
42 42
  ///graph (if there exists).
43 43
  ///
44 44
  ///For example
45 45
  ///if the given digraph is Euler (i.e it has only one nontrivial component
46 46
  ///and the in-degree is equal to the out-degree for all nodes),
47 47
  ///the following code will put the arcs of \c g
48 48
  ///to the vector \c et according to an
49 49
  ///Euler tour of \c g.
50 50
  ///\code
51 51
  ///  std::vector<ListDigraph::Arc> et;
52 52
  ///  for(DiEulerIt<ListDigraph> e(g),e!=INVALID;++e)
53 53
  ///    et.push_back(e);
54 54
  ///\endcode
55 55
  ///If \c g is not Euler then the resulted tour will not be full or closed.
56 56
  ///\sa EulerIt
57 57
  ///\todo Test required
58 58
  template<class Digraph>
59 59
  class DiEulerIt
60 60
  {
61 61
    typedef typename Digraph::Node Node;
62 62
    typedef typename Digraph::NodeIt NodeIt;
63 63
    typedef typename Digraph::Arc Arc;
64 64
    typedef typename Digraph::ArcIt ArcIt;
65 65
    typedef typename Digraph::OutArcIt OutArcIt;
66 66
    typedef typename Digraph::InArcIt InArcIt;
67 67

	
68 68
    const Digraph &g;
69 69
    typename Digraph::template NodeMap<OutArcIt> nedge;
70 70
    std::list<Arc> euler;
71 71

	
72 72
  public:
73 73

	
74 74
    ///Constructor
75 75

	
76 76
    ///\param _g A digraph.
77 77
    ///\param start The starting point of the tour. If it is not given
78 78
    ///       the tour will start from the first node.
79 79
    DiEulerIt(const Digraph &_g,typename Digraph::Node start=INVALID)
80 80
      : g(_g), nedge(g)
81 81
    {
82 82
      if(start==INVALID) start=NodeIt(g);
83 83
      for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
84 84
      while(nedge[start]!=INVALID) {
85 85
        euler.push_back(nedge[start]);
86 86
        Node next=g.target(nedge[start]);
87 87
        ++nedge[start];
88 88
        start=next;
89 89
      }
90 90
    }
91 91

	
92 92
    ///Arc Conversion
93 93
    operator Arc() { return euler.empty()?INVALID:euler.front(); }
94 94
    bool operator==(Invalid) { return euler.empty(); }
95 95
    bool operator!=(Invalid) { return !euler.empty(); }
96 96

	
97 97
    ///Next arc of the tour
98 98
    DiEulerIt &operator++() {
99 99
      Node s=g.target(euler.front());
100 100
      euler.pop_front();
101 101
      //This produces a warning.Strange.
102 102
      //std::list<Arc>::iterator next=euler.begin();
103 103
      typename std::list<Arc>::iterator next=euler.begin();
104 104
      while(nedge[s]!=INVALID) {
105 105
        euler.insert(next,nedge[s]);
106 106
        Node n=g.target(nedge[s]);
107 107
        ++nedge[s];
108 108
        s=n;
109 109
      }
110 110
      return *this;
111 111
    }
112 112
    ///Postfix incrementation
113 113

	
114 114
    ///\warning This incrementation
115 115
    ///returns an \c Arc, not an \ref DiEulerIt, as one may
116 116
    ///expect.
117 117
    Arc operator++(int)
118 118
    {
119 119
      Arc e=*this;
120 120
      ++(*this);
121 121
      return e;
122 122
    }
123 123
  };
124 124

	
125 125
  ///Euler iterator for graphs.
126 126

	
127 127
  /// \ingroup graph_prop
128 128
  ///This iterator converts to the \c Arc (or \c Edge)
129 129
  ///type of the digraph and using
130 130
  ///operator ++, it provides an Euler tour of an undirected
131 131
  ///digraph (if there exists).
132 132
  ///
133 133
  ///For example
134 134
  ///if the given digraph if Euler (i.e it has only one nontrivial component
135 135
  ///and the degree of each node is even),
136 136
  ///the following code will print the arc IDs according to an
137 137
  ///Euler tour of \c g.
138 138
  ///\code
139 139
  ///  for(EulerIt<ListGraph> e(g),e!=INVALID;++e) {
140 140
  ///    std::cout << g.id(Edge(e)) << std::eol;
141 141
  ///  }
142 142
  ///\endcode
143 143
  ///Although the iterator provides an Euler tour of an graph,
144 144
  ///it still returns Arcs in order to indicate the direction of the tour.
145 145
  ///(But Arc will convert to Edges, of course).
146 146
  ///
147 147
  ///If \c g is not Euler then the resulted tour will not be full or closed.
148 148
  ///\sa EulerIt
149 149
  ///\todo Test required
150 150
  template<class Digraph>
151 151
  class EulerIt
152 152
  {
153 153
    typedef typename Digraph::Node Node;
154 154
    typedef typename Digraph::NodeIt NodeIt;
155 155
    typedef typename Digraph::Arc Arc;
156 156
    typedef typename Digraph::Edge Edge;
157 157
    typedef typename Digraph::ArcIt ArcIt;
158 158
    typedef typename Digraph::OutArcIt OutArcIt;
159 159
    typedef typename Digraph::InArcIt InArcIt;
160 160

	
161 161
    const Digraph &g;
162 162
    typename Digraph::template NodeMap<OutArcIt> nedge;
163 163
    typename Digraph::template EdgeMap<bool> visited;
164 164
    std::list<Arc> euler;
165 165

	
166 166
  public:
167 167

	
168 168
    ///Constructor
169 169

	
170 170
    ///\param _g An graph.
171 171
    ///\param start The starting point of the tour. If it is not given
172 172
    ///       the tour will start from the first node.
173 173
    EulerIt(const Digraph &_g,typename Digraph::Node start=INVALID)
174 174
      : g(_g), nedge(g), visited(g,false)
175 175
    {
176 176
      if(start==INVALID) start=NodeIt(g);
177 177
      for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
178 178
      while(nedge[start]!=INVALID) {
179 179
        euler.push_back(nedge[start]);
180 180
        visited[nedge[start]]=true;
181 181
        Node next=g.target(nedge[start]);
182 182
        ++nedge[start];
183 183
        start=next;
184 184
        while(nedge[start]!=INVALID && visited[nedge[start]]) ++nedge[start];
185 185
      }
186 186
    }
187 187

	
188 188
    ///Arc Conversion
189 189
    operator Arc() const { return euler.empty()?INVALID:euler.front(); }
190 190
    ///Arc Conversion
191 191
    operator Edge() const { return euler.empty()?INVALID:euler.front(); }
192 192
    ///\e
193 193
    bool operator==(Invalid) const { return euler.empty(); }
194 194
    ///\e
195 195
    bool operator!=(Invalid) const { return !euler.empty(); }
196 196

	
197 197
    ///Next arc of the tour
198 198
    EulerIt &operator++() {
199 199
      Node s=g.target(euler.front());
200 200
      euler.pop_front();
201 201
      typename std::list<Arc>::iterator next=euler.begin();
202 202

	
203 203
      while(nedge[s]!=INVALID) {
204 204
        while(nedge[s]!=INVALID && visited[nedge[s]]) ++nedge[s];
205 205
        if(nedge[s]==INVALID) break;
206 206
        else {
207 207
          euler.insert(next,nedge[s]);
208 208
          visited[nedge[s]]=true;
209 209
          Node n=g.target(nedge[s]);
210 210
          ++nedge[s];
211 211
          s=n;
212 212
        }
213 213
      }
214 214
      return *this;
215 215
    }
216 216

	
217 217
    ///Postfix incrementation
218 218

	
219 219
    ///\warning This incrementation
220 220
    ///returns an \c Arc, not an \ref EulerIt, as one may
221 221
    ///expect.
222 222
    Arc operator++(int)
223 223
    {
224 224
      Arc e=*this;
225 225
      ++(*this);
226 226
      return e;
227 227
    }
228 228
  };
229 229

	
230 230

	
231
  ///Checks if the graph is Euler
231
  ///Checks if the graph is Eulerian
232 232

	
233 233
  /// \ingroup graph_prop
234
  ///Checks if the graph is Euler. It works for both directed and undirected
234
  ///Checks if the graph is Eulerian. It works for both directed and undirected
235 235
  ///graphs.
236
  ///\note By definition, a digraph is called \e Euler if
236
  ///\note By definition, a digraph is called \e Eulerian if
237 237
  ///and only if it is connected and the number of its incoming and outgoing
238 238
  ///arcs are the same for each node.
239
  ///Similarly, an undirected graph is called \e Euler if
239
  ///Similarly, an undirected graph is called \e Eulerian if
240 240
  ///and only if it is connected and the number of incident arcs is even
241
  ///for each node. <em>Therefore, there are digraphs which are not Euler, but
242
  ///still have an Euler tour</em>.
241
  ///for each node. <em>Therefore, there are digraphs which are not Eulerian,
242
  ///but still have an Euler tour</em>.
243 243
  ///\todo Test required
244 244
  template<class Digraph>
245 245
#ifdef DOXYGEN
246 246
  bool
247 247
#else
248 248
  typename enable_if<UndirectedTagIndicator<Digraph>,bool>::type
249
  euler(const Digraph &g)
249
  eulerian(const Digraph &g)
250 250
  {
251 251
    for(typename Digraph::NodeIt n(g);n!=INVALID;++n)
252 252
      if(countIncEdges(g,n)%2) return false;
253 253
    return connected(g);
254 254
  }
255 255
  template<class Digraph>
256 256
  typename disable_if<UndirectedTagIndicator<Digraph>,bool>::type
257 257
#endif
258
  euler(const Digraph &g)
258
  eulerian(const Digraph &g)
259 259
  {
260 260
    for(typename Digraph::NodeIt n(g);n!=INVALID;++n)
261 261
      if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
262 262
    return connected(Undirector<const Digraph>(g));
263 263
  }
264 264

	
265 265
}
266 266

	
267 267
#endif
0 comments (0 inline)