gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Fix typos (ticket #192)
0 3 0
default
3 files changed with 4 insertions and 4 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -106,385 +106,385 @@
106 106
  }
107 107

	
108 108
  /// \ingroup connectivity
109 109
  ///
110 110
  /// \brief Find the connected components of an undirected graph
111 111
  ///
112 112
  /// Find the connected components of an undirected graph.
113 113
  ///
114 114
  /// \param graph The graph. It must be undirected.
115 115
  /// \retval compMap A writable node map. The values will be set from 0 to
116 116
  /// the number of the connected components minus one. Each values of the map
117 117
  /// will be set exactly once, the values of a certain component will be
118 118
  /// set continuously.
119 119
  /// \return The number of components
120 120
  ///
121 121
  template <class Graph, class NodeMap>
122 122
  int connectedComponents(const Graph &graph, NodeMap &compMap) {
123 123
    checkConcept<concepts::Graph, Graph>();
124 124
    typedef typename Graph::Node Node;
125 125
    typedef typename Graph::Arc Arc;
126 126
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
127 127

	
128 128
    typedef NullMap<Node, Arc> PredMap;
129 129
    typedef NullMap<Node, int> DistMap;
130 130

	
131 131
    int compNum = 0;
132 132
    typename Bfs<Graph>::
133 133
      template SetPredMap<PredMap>::
134 134
      template SetDistMap<DistMap>::
135 135
      Create bfs(graph);
136 136

	
137 137
    PredMap predMap;
138 138
    bfs.predMap(predMap);
139 139

	
140 140
    DistMap distMap;
141 141
    bfs.distMap(distMap);
142 142

	
143 143
    bfs.init();
144 144
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
145 145
      if(!bfs.reached(n)) {
146 146
        bfs.addSource(n);
147 147
        while (!bfs.emptyQueue()) {
148 148
          compMap.set(bfs.nextNode(), compNum);
149 149
          bfs.processNextNode();
150 150
        }
151 151
        ++compNum;
152 152
      }
153 153
    }
154 154
    return compNum;
155 155
  }
156 156

	
157 157
  namespace _connectivity_bits {
158 158

	
159 159
    template <typename Digraph, typename Iterator >
160 160
    struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
161 161
    public:
162 162
      typedef typename Digraph::Node Node;
163 163
      LeaveOrderVisitor(Iterator it) : _it(it) {}
164 164

	
165 165
      void leave(const Node& node) {
166 166
        *(_it++) = node;
167 167
      }
168 168

	
169 169
    private:
170 170
      Iterator _it;
171 171
    };
172 172

	
173 173
    template <typename Digraph, typename Map>
174 174
    struct FillMapVisitor : public DfsVisitor<Digraph> {
175 175
    public:
176 176
      typedef typename Digraph::Node Node;
177 177
      typedef typename Map::Value Value;
178 178

	
179 179
      FillMapVisitor(Map& map, Value& value)
180 180
        : _map(map), _value(value) {}
181 181

	
182 182
      void reach(const Node& node) {
183 183
        _map.set(node, _value);
184 184
      }
185 185
    private:
186 186
      Map& _map;
187 187
      Value& _value;
188 188
    };
189 189

	
190 190
    template <typename Digraph, typename ArcMap>
191 191
    struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
192 192
    public:
193 193
      typedef typename Digraph::Node Node;
194 194
      typedef typename Digraph::Arc Arc;
195 195

	
196 196
      StronglyConnectedCutArcsVisitor(const Digraph& digraph,
197 197
                                      ArcMap& cutMap,
198 198
                                      int& cutNum)
199 199
        : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
200 200
          _compMap(digraph, -1), _num(-1) {
201 201
      }
202 202

	
203 203
      void start(const Node&) {
204 204
        ++_num;
205 205
      }
206 206

	
207 207
      void reach(const Node& node) {
208 208
        _compMap.set(node, _num);
209 209
      }
210 210

	
211 211
      void examine(const Arc& arc) {
212 212
         if (_compMap[_digraph.source(arc)] !=
213 213
             _compMap[_digraph.target(arc)]) {
214 214
           _cutMap.set(arc, true);
215 215
           ++_cutNum;
216 216
         }
217 217
      }
218 218
    private:
219 219
      const Digraph& _digraph;
220 220
      ArcMap& _cutMap;
221 221
      int& _cutNum;
222 222

	
223 223
      typename Digraph::template NodeMap<int> _compMap;
224 224
      int _num;
225 225
    };
226 226

	
227 227
  }
228 228

	
229 229

	
230 230
  /// \ingroup connectivity
231 231
  ///
232 232
  /// \brief Check whether the given directed graph is strongly connected.
233 233
  ///
234 234
  /// Check whether the given directed graph is strongly connected. The
235 235
  /// graph is strongly connected when any two nodes of the graph are
236 236
  /// connected with directed paths in both direction.
237 237
  /// \return %False when the graph is not strongly connected.
238 238
  /// \see connected
239 239
  ///
240 240
  /// \note By definition, the empty graph is strongly connected.
241 241
  template <typename Digraph>
242 242
  bool stronglyConnected(const Digraph& digraph) {
243 243
    checkConcept<concepts::Digraph, Digraph>();
244 244

	
245 245
    typedef typename Digraph::Node Node;
246 246
    typedef typename Digraph::NodeIt NodeIt;
247 247

	
248 248
    typename Digraph::Node source = NodeIt(digraph);
249 249
    if (source == INVALID) return true;
250 250

	
251 251
    using namespace _connectivity_bits;
252 252

	
253 253
    typedef DfsVisitor<Digraph> Visitor;
254 254
    Visitor visitor;
255 255

	
256 256
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
257 257
    dfs.init();
258 258
    dfs.addSource(source);
259 259
    dfs.start();
260 260

	
261 261
    for (NodeIt it(digraph); it != INVALID; ++it) {
262 262
      if (!dfs.reached(it)) {
263 263
        return false;
264 264
      }
265 265
    }
266 266

	
267 267
    typedef ReverseDigraph<const Digraph> RDigraph;
268 268
    typedef typename RDigraph::NodeIt RNodeIt;
269 269
    RDigraph rdigraph(digraph);
270 270

	
271 271
    typedef DfsVisitor<Digraph> RVisitor;
272 272
    RVisitor rvisitor;
273 273

	
274 274
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
275 275
    rdfs.init();
276 276
    rdfs.addSource(source);
277 277
    rdfs.start();
278 278

	
279 279
    for (RNodeIt it(rdigraph); it != INVALID; ++it) {
280 280
      if (!rdfs.reached(it)) {
281 281
        return false;
282 282
      }
283 283
    }
284 284

	
285 285
    return true;
286 286
  }
287 287

	
288 288
  /// \ingroup connectivity
289 289
  ///
290 290
  /// \brief Count the strongly connected components of a directed graph
291 291
  ///
292 292
  /// Count the strongly connected components of a directed graph.
293 293
  /// The strongly connected components are the classes of an
294 294
  /// equivalence relation on the nodes of the graph. Two nodes are in
295 295
  /// the same class if they are connected with directed paths in both
296 296
  /// direction.
297 297
  ///
298
  /// \param graph The graph.
298
  /// \param digraph The graph.
299 299
  /// \return The number of components
300 300
  /// \note By definition, the empty graph has zero
301 301
  /// strongly connected components.
302 302
  template <typename Digraph>
303 303
  int countStronglyConnectedComponents(const Digraph& digraph) {
304 304
    checkConcept<concepts::Digraph, Digraph>();
305 305

	
306 306
    using namespace _connectivity_bits;
307 307

	
308 308
    typedef typename Digraph::Node Node;
309 309
    typedef typename Digraph::Arc Arc;
310 310
    typedef typename Digraph::NodeIt NodeIt;
311 311
    typedef typename Digraph::ArcIt ArcIt;
312 312

	
313 313
    typedef std::vector<Node> Container;
314 314
    typedef typename Container::iterator Iterator;
315 315

	
316 316
    Container nodes(countNodes(digraph));
317 317
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
318 318
    Visitor visitor(nodes.begin());
319 319

	
320 320
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
321 321
    dfs.init();
322 322
    for (NodeIt it(digraph); it != INVALID; ++it) {
323 323
      if (!dfs.reached(it)) {
324 324
        dfs.addSource(it);
325 325
        dfs.start();
326 326
      }
327 327
    }
328 328

	
329 329
    typedef typename Container::reverse_iterator RIterator;
330 330
    typedef ReverseDigraph<const Digraph> RDigraph;
331 331

	
332 332
    RDigraph rdigraph(digraph);
333 333

	
334 334
    typedef DfsVisitor<Digraph> RVisitor;
335 335
    RVisitor rvisitor;
336 336

	
337 337
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
338 338

	
339 339
    int compNum = 0;
340 340

	
341 341
    rdfs.init();
342 342
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
343 343
      if (!rdfs.reached(*it)) {
344 344
        rdfs.addSource(*it);
345 345
        rdfs.start();
346 346
        ++compNum;
347 347
      }
348 348
    }
349 349
    return compNum;
350 350
  }
351 351

	
352 352
  /// \ingroup connectivity
353 353
  ///
354 354
  /// \brief Find the strongly connected components of a directed graph
355 355
  ///
356 356
  /// Find the strongly connected components of a directed graph.  The
357 357
  /// strongly connected components are the classes of an equivalence
358 358
  /// relation on the nodes of the graph. Two nodes are in
359 359
  /// relationship when there are directed paths between them in both
360 360
  /// direction. In addition, the numbering of components will satisfy
361 361
  /// that there is no arc going from a higher numbered component to
362 362
  /// a lower.
363 363
  ///
364 364
  /// \param digraph The digraph.
365 365
  /// \retval compMap A writable node map. The values will be set from 0 to
366 366
  /// the number of the strongly connected components minus one. Each value
367 367
  /// of the map will be set exactly once, the values of a certain component
368 368
  /// will be set continuously.
369 369
  /// \return The number of components
370 370
  ///
371 371
  template <typename Digraph, typename NodeMap>
372 372
  int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
373 373
    checkConcept<concepts::Digraph, Digraph>();
374 374
    typedef typename Digraph::Node Node;
375 375
    typedef typename Digraph::NodeIt NodeIt;
376 376
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
377 377

	
378 378
    using namespace _connectivity_bits;
379 379

	
380 380
    typedef std::vector<Node> Container;
381 381
    typedef typename Container::iterator Iterator;
382 382

	
383 383
    Container nodes(countNodes(digraph));
384 384
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
385 385
    Visitor visitor(nodes.begin());
386 386

	
387 387
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
388 388
    dfs.init();
389 389
    for (NodeIt it(digraph); it != INVALID; ++it) {
390 390
      if (!dfs.reached(it)) {
391 391
        dfs.addSource(it);
392 392
        dfs.start();
393 393
      }
394 394
    }
395 395

	
396 396
    typedef typename Container::reverse_iterator RIterator;
397 397
    typedef ReverseDigraph<const Digraph> RDigraph;
398 398

	
399 399
    RDigraph rdigraph(digraph);
400 400

	
401 401
    int compNum = 0;
402 402

	
403 403
    typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
404 404
    RVisitor rvisitor(compMap, compNum);
405 405

	
406 406
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
407 407

	
408 408
    rdfs.init();
409 409
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
410 410
      if (!rdfs.reached(*it)) {
411 411
        rdfs.addSource(*it);
412 412
        rdfs.start();
413 413
        ++compNum;
414 414
      }
415 415
    }
416 416
    return compNum;
417 417
  }
418 418

	
419 419
  /// \ingroup connectivity
420 420
  ///
421 421
  /// \brief Find the cut arcs of the strongly connected components.
422 422
  ///
423 423
  /// Find the cut arcs of the strongly connected components.
424 424
  /// The strongly connected components are the classes of an equivalence
425 425
  /// relation on the nodes of the graph. Two nodes are in relationship
426 426
  /// when there are directed paths between them in both direction.
427 427
  /// The strongly connected components are separated by the cut arcs.
428 428
  ///
429 429
  /// \param graph The graph.
430 430
  /// \retval cutMap A writable node map. The values will be set true when the
431 431
  /// arc is a cut arc.
432 432
  ///
433 433
  /// \return The number of cut arcs
434 434
  template <typename Digraph, typename ArcMap>
435 435
  int stronglyConnectedCutArcs(const Digraph& graph, ArcMap& cutMap) {
436 436
    checkConcept<concepts::Digraph, Digraph>();
437 437
    typedef typename Digraph::Node Node;
438 438
    typedef typename Digraph::Arc Arc;
439 439
    typedef typename Digraph::NodeIt NodeIt;
440 440
    checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
441 441

	
442 442
    using namespace _connectivity_bits;
443 443

	
444 444
    typedef std::vector<Node> Container;
445 445
    typedef typename Container::iterator Iterator;
446 446

	
447 447
    Container nodes(countNodes(graph));
448 448
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
449 449
    Visitor visitor(nodes.begin());
450 450

	
451 451
    DfsVisit<Digraph, Visitor> dfs(graph, visitor);
452 452
    dfs.init();
453 453
    for (NodeIt it(graph); it != INVALID; ++it) {
454 454
      if (!dfs.reached(it)) {
455 455
        dfs.addSource(it);
456 456
        dfs.start();
457 457
      }
458 458
    }
459 459

	
460 460
    typedef typename Container::reverse_iterator RIterator;
461 461
    typedef ReverseDigraph<const Digraph> RDigraph;
462 462

	
463 463
    RDigraph rgraph(graph);
464 464

	
465 465
    int cutNum = 0;
466 466

	
467 467
    typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
468 468
    RVisitor rvisitor(rgraph, cutMap, cutNum);
469 469

	
470 470
    DfsVisit<RDigraph, RVisitor> rdfs(rgraph, rvisitor);
471 471

	
472 472
    rdfs.init();
473 473
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
474 474
      if (!rdfs.reached(*it)) {
475 475
        rdfs.addSource(*it);
476 476
        rdfs.start();
477 477
      }
478 478
    }
479 479
    return cutNum;
480 480
  }
481 481

	
482 482
  namespace _connectivity_bits {
483 483

	
484 484
    template <typename Digraph>
485 485
    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
486 486
    public:
487 487
      typedef typename Digraph::Node Node;
488 488
      typedef typename Digraph::Arc Arc;
489 489
      typedef typename Digraph::Edge Edge;
490 490

	
... ...
@@ -1036,385 +1036,385 @@
1036 1036
  template <typename Graph>
1037 1037
  bool biEdgeConnected(const Graph& graph) {
1038 1038
    return countBiEdgeConnectedComponents(graph) <= 1;
1039 1039
  }
1040 1040

	
1041 1041
  /// \ingroup connectivity
1042 1042
  ///
1043 1043
  /// \brief Count the bi-edge-connected components.
1044 1044
  ///
1045 1045
  /// This function count the bi-edge-connected components in an undirected
1046 1046
  /// graph. The bi-edge-connected components are the classes of an equivalence
1047 1047
  /// relation on the nodes. Two nodes are in relationship when they are
1048 1048
  /// connected with at least two edge-disjoint paths.
1049 1049
  ///
1050 1050
  /// \param graph The undirected graph.
1051 1051
  /// \return The number of components.
1052 1052
  template <typename Graph>
1053 1053
  int countBiEdgeConnectedComponents(const Graph& graph) {
1054 1054
    checkConcept<concepts::Graph, Graph>();
1055 1055
    typedef typename Graph::NodeIt NodeIt;
1056 1056

	
1057 1057
    using namespace _connectivity_bits;
1058 1058

	
1059 1059
    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
1060 1060

	
1061 1061
    int compNum = 0;
1062 1062
    Visitor visitor(graph, compNum);
1063 1063

	
1064 1064
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1065 1065
    dfs.init();
1066 1066

	
1067 1067
    for (NodeIt it(graph); it != INVALID; ++it) {
1068 1068
      if (!dfs.reached(it)) {
1069 1069
        dfs.addSource(it);
1070 1070
        dfs.start();
1071 1071
      }
1072 1072
    }
1073 1073
    return compNum;
1074 1074
  }
1075 1075

	
1076 1076
  /// \ingroup connectivity
1077 1077
  ///
1078 1078
  /// \brief Find the bi-edge-connected components.
1079 1079
  ///
1080 1080
  /// This function finds the bi-edge-connected components in an undirected
1081 1081
  /// graph. The bi-edge-connected components are the classes of an equivalence
1082 1082
  /// relation on the nodes. Two nodes are in relationship when they are
1083 1083
  /// connected at least two edge-disjoint paths.
1084 1084
  ///
1085 1085
  /// \param graph The graph.
1086 1086
  /// \retval compMap A writable node map. The values will be set from 0 to
1087 1087
  /// the number of the biconnected components minus one. Each values
1088 1088
  /// of the map will be set exactly once, the values of a certain component
1089 1089
  /// will be set continuously.
1090 1090
  /// \return The number of components.
1091 1091
  ///
1092 1092
  template <typename Graph, typename NodeMap>
1093 1093
  int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
1094 1094
    checkConcept<concepts::Graph, Graph>();
1095 1095
    typedef typename Graph::NodeIt NodeIt;
1096 1096
    typedef typename Graph::Node Node;
1097 1097
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
1098 1098

	
1099 1099
    using namespace _connectivity_bits;
1100 1100

	
1101 1101
    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
1102 1102

	
1103 1103
    int compNum = 0;
1104 1104
    Visitor visitor(graph, compMap, compNum);
1105 1105

	
1106 1106
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1107 1107
    dfs.init();
1108 1108

	
1109 1109
    for (NodeIt it(graph); it != INVALID; ++it) {
1110 1110
      if (!dfs.reached(it)) {
1111 1111
        dfs.addSource(it);
1112 1112
        dfs.start();
1113 1113
      }
1114 1114
    }
1115 1115
    return compNum;
1116 1116
  }
1117 1117

	
1118 1118
  /// \ingroup connectivity
1119 1119
  ///
1120 1120
  /// \brief Find the bi-edge-connected cut edges.
1121 1121
  ///
1122 1122
  /// This function finds the bi-edge-connected components in an undirected
1123 1123
  /// graph. The bi-edge-connected components are the classes of an equivalence
1124 1124
  /// relation on the nodes. Two nodes are in relationship when they are
1125 1125
  /// connected with at least two edge-disjoint paths. The bi-edge-connected
1126 1126
  /// components are separted by edges which are the cut edges of the
1127 1127
  /// components.
1128 1128
  ///
1129 1129
  /// \param graph The graph.
1130 1130
  /// \retval cutMap A writable node map. The values will be set true when the
1131 1131
  /// edge is a cut edge.
1132 1132
  /// \return The number of cut edges.
1133 1133
  template <typename Graph, typename EdgeMap>
1134 1134
  int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
1135 1135
    checkConcept<concepts::Graph, Graph>();
1136 1136
    typedef typename Graph::NodeIt NodeIt;
1137 1137
    typedef typename Graph::Edge Edge;
1138 1138
    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
1139 1139

	
1140 1140
    using namespace _connectivity_bits;
1141 1141

	
1142 1142
    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
1143 1143

	
1144 1144
    int cutNum = 0;
1145 1145
    Visitor visitor(graph, cutMap, cutNum);
1146 1146

	
1147 1147
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1148 1148
    dfs.init();
1149 1149

	
1150 1150
    for (NodeIt it(graph); it != INVALID; ++it) {
1151 1151
      if (!dfs.reached(it)) {
1152 1152
        dfs.addSource(it);
1153 1153
        dfs.start();
1154 1154
      }
1155 1155
    }
1156 1156
    return cutNum;
1157 1157
  }
1158 1158

	
1159 1159

	
1160 1160
  namespace _connectivity_bits {
1161 1161

	
1162 1162
    template <typename Digraph, typename IntNodeMap>
1163 1163
    class TopologicalSortVisitor : public DfsVisitor<Digraph> {
1164 1164
    public:
1165 1165
      typedef typename Digraph::Node Node;
1166 1166
      typedef typename Digraph::Arc edge;
1167 1167

	
1168 1168
      TopologicalSortVisitor(IntNodeMap& order, int num)
1169 1169
        : _order(order), _num(num) {}
1170 1170

	
1171 1171
      void leave(const Node& node) {
1172 1172
        _order.set(node, --_num);
1173 1173
      }
1174 1174

	
1175 1175
    private:
1176 1176
      IntNodeMap& _order;
1177 1177
      int _num;
1178 1178
    };
1179 1179

	
1180 1180
  }
1181 1181

	
1182 1182
  /// \ingroup connectivity
1183 1183
  ///
1184 1184
  /// \brief Sort the nodes of a DAG into topolgical order.
1185 1185
  ///
1186 1186
  /// Sort the nodes of a DAG into topolgical order.
1187 1187
  ///
1188 1188
  /// \param graph The graph. It must be directed and acyclic.
1189 1189
  /// \retval order A writable node map. The values will be set from 0 to
1190 1190
  /// the number of the nodes in the graph minus one. Each values of the map
1191 1191
  /// will be set exactly once, the values  will be set descending order.
1192 1192
  ///
1193 1193
  /// \see checkedTopologicalSort
1194 1194
  /// \see dag
1195 1195
  template <typename Digraph, typename NodeMap>
1196 1196
  void topologicalSort(const Digraph& graph, NodeMap& order) {
1197 1197
    using namespace _connectivity_bits;
1198 1198

	
1199 1199
    checkConcept<concepts::Digraph, Digraph>();
1200 1200
    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
1201 1201

	
1202 1202
    typedef typename Digraph::Node Node;
1203 1203
    typedef typename Digraph::NodeIt NodeIt;
1204 1204
    typedef typename Digraph::Arc Arc;
1205 1205

	
1206 1206
    TopologicalSortVisitor<Digraph, NodeMap>
1207 1207
      visitor(order, countNodes(graph));
1208 1208

	
1209 1209
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1210 1210
      dfs(graph, visitor);
1211 1211

	
1212 1212
    dfs.init();
1213 1213
    for (NodeIt it(graph); it != INVALID; ++it) {
1214 1214
      if (!dfs.reached(it)) {
1215 1215
        dfs.addSource(it);
1216 1216
        dfs.start();
1217 1217
      }
1218 1218
    }
1219 1219
  }
1220 1220

	
1221 1221
  /// \ingroup connectivity
1222 1222
  ///
1223 1223
  /// \brief Sort the nodes of a DAG into topolgical order.
1224 1224
  ///
1225 1225
  /// Sort the nodes of a DAG into topolgical order. It also checks
1226 1226
  /// that the given graph is DAG.
1227 1227
  ///
1228
  /// \param graph The graph. It must be directed and acyclic.
1228
  /// \param digraph The graph. It must be directed and acyclic.
1229 1229
  /// \retval order A readable - writable node map. The values will be set
1230 1230
  /// from 0 to the number of the nodes in the graph minus one. Each values
1231 1231
  /// of the map will be set exactly once, the values will be set descending
1232 1232
  /// order.
1233 1233
  /// \return %False when the graph is not DAG.
1234 1234
  ///
1235 1235
  /// \see topologicalSort
1236 1236
  /// \see dag
1237 1237
  template <typename Digraph, typename NodeMap>
1238 1238
  bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
1239 1239
    using namespace _connectivity_bits;
1240 1240

	
1241 1241
    checkConcept<concepts::Digraph, Digraph>();
1242 1242
    checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
1243 1243
      NodeMap>();
1244 1244

	
1245 1245
    typedef typename Digraph::Node Node;
1246 1246
    typedef typename Digraph::NodeIt NodeIt;
1247 1247
    typedef typename Digraph::Arc Arc;
1248 1248

	
1249 1249
    for (NodeIt it(digraph); it != INVALID; ++it) {
1250 1250
      order.set(it, -1);
1251 1251
    }
1252 1252

	
1253 1253
    TopologicalSortVisitor<Digraph, NodeMap>
1254 1254
      visitor(order, countNodes(digraph));
1255 1255

	
1256 1256
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1257 1257
      dfs(digraph, visitor);
1258 1258

	
1259 1259
    dfs.init();
1260 1260
    for (NodeIt it(digraph); it != INVALID; ++it) {
1261 1261
      if (!dfs.reached(it)) {
1262 1262
        dfs.addSource(it);
1263 1263
        while (!dfs.emptyQueue()) {
1264 1264
           Arc arc = dfs.nextArc();
1265 1265
           Node target = digraph.target(arc);
1266 1266
           if (dfs.reached(target) && order[target] == -1) {
1267 1267
             return false;
1268 1268
           }
1269 1269
           dfs.processNextArc();
1270 1270
         }
1271 1271
      }
1272 1272
    }
1273 1273
    return true;
1274 1274
  }
1275 1275

	
1276 1276
  /// \ingroup connectivity
1277 1277
  ///
1278 1278
  /// \brief Check that the given directed graph is a DAG.
1279 1279
  ///
1280 1280
  /// Check that the given directed graph is a DAG. The DAG is
1281 1281
  /// an Directed Acyclic Digraph.
1282 1282
  /// \return %False when the graph is not DAG.
1283 1283
  /// \see acyclic
1284 1284
  template <typename Digraph>
1285 1285
  bool dag(const Digraph& digraph) {
1286 1286

	
1287 1287
    checkConcept<concepts::Digraph, Digraph>();
1288 1288

	
1289 1289
    typedef typename Digraph::Node Node;
1290 1290
    typedef typename Digraph::NodeIt NodeIt;
1291 1291
    typedef typename Digraph::Arc Arc;
1292 1292

	
1293 1293
    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
1294 1294

	
1295 1295
    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
1296 1296
      Create dfs(digraph);
1297 1297

	
1298 1298
    ProcessedMap processed(digraph);
1299 1299
    dfs.processedMap(processed);
1300 1300

	
1301 1301
    dfs.init();
1302 1302
    for (NodeIt it(digraph); it != INVALID; ++it) {
1303 1303
      if (!dfs.reached(it)) {
1304 1304
        dfs.addSource(it);
1305 1305
        while (!dfs.emptyQueue()) {
1306 1306
          Arc edge = dfs.nextArc();
1307 1307
          Node target = digraph.target(edge);
1308 1308
          if (dfs.reached(target) && !processed[target]) {
1309 1309
            return false;
1310 1310
          }
1311 1311
          dfs.processNextArc();
1312 1312
        }
1313 1313
      }
1314 1314
    }
1315 1315
    return true;
1316 1316
  }
1317 1317

	
1318 1318
  /// \ingroup connectivity
1319 1319
  ///
1320 1320
  /// \brief Check that the given undirected graph is acyclic.
1321 1321
  ///
1322 1322
  /// Check that the given undirected graph acyclic.
1323 1323
  /// \param graph The undirected graph.
1324 1324
  /// \return %True when there is no circle in the graph.
1325 1325
  /// \see dag
1326 1326
  template <typename Graph>
1327 1327
  bool acyclic(const Graph& graph) {
1328 1328
    checkConcept<concepts::Graph, Graph>();
1329 1329
    typedef typename Graph::Node Node;
1330 1330
    typedef typename Graph::NodeIt NodeIt;
1331 1331
    typedef typename Graph::Arc Arc;
1332 1332
    Dfs<Graph> dfs(graph);
1333 1333
    dfs.init();
1334 1334
    for (NodeIt it(graph); it != INVALID; ++it) {
1335 1335
      if (!dfs.reached(it)) {
1336 1336
        dfs.addSource(it);
1337 1337
        while (!dfs.emptyQueue()) {
1338 1338
          Arc edge = dfs.nextArc();
1339 1339
          Node source = graph.source(edge);
1340 1340
          Node target = graph.target(edge);
1341 1341
          if (dfs.reached(target) &&
1342 1342
              dfs.predArc(source) != graph.oppositeArc(edge)) {
1343 1343
            return false;
1344 1344
          }
1345 1345
          dfs.processNextArc();
1346 1346
        }
1347 1347
      }
1348 1348
    }
1349 1349
    return true;
1350 1350
  }
1351 1351

	
1352 1352
  /// \ingroup connectivity
1353 1353
  ///
1354 1354
  /// \brief Check that the given undirected graph is tree.
1355 1355
  ///
1356 1356
  /// Check that the given undirected graph is tree.
1357 1357
  /// \param graph The undirected graph.
1358 1358
  /// \return %True when the graph is acyclic and connected.
1359 1359
  template <typename Graph>
1360 1360
  bool tree(const Graph& graph) {
1361 1361
    checkConcept<concepts::Graph, Graph>();
1362 1362
    typedef typename Graph::Node Node;
1363 1363
    typedef typename Graph::NodeIt NodeIt;
1364 1364
    typedef typename Graph::Arc Arc;
1365 1365
    Dfs<Graph> dfs(graph);
1366 1366
    dfs.init();
1367 1367
    dfs.addSource(NodeIt(graph));
1368 1368
    while (!dfs.emptyQueue()) {
1369 1369
      Arc edge = dfs.nextArc();
1370 1370
      Node source = graph.source(edge);
1371 1371
      Node target = graph.target(edge);
1372 1372
      if (dfs.reached(target) &&
1373 1373
          dfs.predArc(source) != graph.oppositeArc(edge)) {
1374 1374
        return false;
1375 1375
      }
1376 1376
      dfs.processNextArc();
1377 1377
    }
1378 1378
    for (NodeIt it(graph); it != INVALID; ++it) {
1379 1379
      if (!dfs.reached(it)) {
1380 1380
        return false;
1381 1381
      }
1382 1382
    }
1383 1383
    return true;
1384 1384
  }
1385 1385

	
1386 1386
  namespace _connectivity_bits {
1387 1387

	
1388 1388
    template <typename Digraph>
1389 1389
    class BipartiteVisitor : public BfsVisitor<Digraph> {
1390 1390
    public:
1391 1391
      typedef typename Digraph::Arc Arc;
1392 1392
      typedef typename Digraph::Node Node;
1393 1393

	
1394 1394
      BipartiteVisitor(const Digraph& graph, bool& bipartite)
1395 1395
        : _graph(graph), _part(graph), _bipartite(bipartite) {}
1396 1396

	
1397 1397
      void start(const Node& node) {
1398 1398
        _part[node] = true;
1399 1399
      }
1400 1400
      void discover(const Arc& edge) {
1401 1401
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1402 1402
      }
1403 1403
      void examine(const Arc& edge) {
1404 1404
        _bipartite = _bipartite &&
1405 1405
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
1406 1406
      }
1407 1407

	
1408 1408
    private:
1409 1409

	
1410 1410
      const Digraph& _graph;
1411 1411
      typename Digraph::template NodeMap<bool> _part;
1412 1412
      bool& _bipartite;
1413 1413
    };
1414 1414

	
1415 1415
    template <typename Digraph, typename PartMap>
1416 1416
    class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
1417 1417
    public:
1418 1418
      typedef typename Digraph::Arc Arc;
1419 1419
      typedef typename Digraph::Node Node;
1420 1420

	
Ignore white space 6 line context
... ...
@@ -227,385 +227,385 @@
227 227

	
228 228
      {
229 229
        std::set<Node> left_set, right_set;
230 230

	
231 231
        Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
232 232
        left_set.insert(left);
233 233

	
234 234
        Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
235 235
        right_set.insert(right);
236 236

	
237 237
        while (true) {
238 238
          if ((*_matching)[left] == INVALID) break;
239 239
          left = _graph.target((*_matching)[left]);
240 240
          left = (*_blossom_rep)[_blossom_set->
241 241
                                 find(_graph.target((*_ear)[left]))];
242 242
          if (right_set.find(left) != right_set.end()) {
243 243
            nca = left;
244 244
            break;
245 245
          }
246 246
          left_set.insert(left);
247 247

	
248 248
          if ((*_matching)[right] == INVALID) break;
249 249
          right = _graph.target((*_matching)[right]);
250 250
          right = (*_blossom_rep)[_blossom_set->
251 251
                                  find(_graph.target((*_ear)[right]))];
252 252
          if (left_set.find(right) != left_set.end()) {
253 253
            nca = right;
254 254
            break;
255 255
          }
256 256
          right_set.insert(right);
257 257
        }
258 258

	
259 259
        if (nca == INVALID) {
260 260
          if ((*_matching)[left] == INVALID) {
261 261
            nca = right;
262 262
            while (left_set.find(nca) == left_set.end()) {
263 263
              nca = _graph.target((*_matching)[nca]);
264 264
              nca =(*_blossom_rep)[_blossom_set->
265 265
                                   find(_graph.target((*_ear)[nca]))];
266 266
            }
267 267
          } else {
268 268
            nca = left;
269 269
            while (right_set.find(nca) == right_set.end()) {
270 270
              nca = _graph.target((*_matching)[nca]);
271 271
              nca = (*_blossom_rep)[_blossom_set->
272 272
                                   find(_graph.target((*_ear)[nca]))];
273 273
            }
274 274
          }
275 275
        }
276 276
      }
277 277

	
278 278
      {
279 279

	
280 280
        Node node = _graph.u(e);
281 281
        Arc arc = _graph.direct(e, true);
282 282
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
283 283

	
284 284
        while (base != nca) {
285 285
          _ear->set(node, arc);
286 286

	
287 287
          Node n = node;
288 288
          while (n != base) {
289 289
            n = _graph.target((*_matching)[n]);
290 290
            Arc a = (*_ear)[n];
291 291
            n = _graph.target(a);
292 292
            _ear->set(n, _graph.oppositeArc(a));
293 293
          }
294 294
          node = _graph.target((*_matching)[base]);
295 295
          _tree_set->erase(base);
296 296
          _tree_set->erase(node);
297 297
          _blossom_set->insert(node, _blossom_set->find(base));
298 298
          _status->set(node, EVEN);
299 299
          _node_queue[_last++] = node;
300 300
          arc = _graph.oppositeArc((*_ear)[node]);
301 301
          node = _graph.target((*_ear)[node]);
302 302
          base = (*_blossom_rep)[_blossom_set->find(node)];
303 303
          _blossom_set->join(_graph.target(arc), base);
304 304
        }
305 305
      }
306 306

	
307 307
      _blossom_rep->set(_blossom_set->find(nca), nca);
308 308

	
309 309
      {
310 310

	
311 311
        Node node = _graph.v(e);
312 312
        Arc arc = _graph.direct(e, false);
313 313
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
314 314

	
315 315
        while (base != nca) {
316 316
          _ear->set(node, arc);
317 317

	
318 318
          Node n = node;
319 319
          while (n != base) {
320 320
            n = _graph.target((*_matching)[n]);
321 321
            Arc a = (*_ear)[n];
322 322
            n = _graph.target(a);
323 323
            _ear->set(n, _graph.oppositeArc(a));
324 324
          }
325 325
          node = _graph.target((*_matching)[base]);
326 326
          _tree_set->erase(base);
327 327
          _tree_set->erase(node);
328 328
          _blossom_set->insert(node, _blossom_set->find(base));
329 329
          _status->set(node, EVEN);
330 330
          _node_queue[_last++] = node;
331 331
          arc = _graph.oppositeArc((*_ear)[node]);
332 332
          node = _graph.target((*_ear)[node]);
333 333
          base = (*_blossom_rep)[_blossom_set->find(node)];
334 334
          _blossom_set->join(_graph.target(arc), base);
335 335
        }
336 336
      }
337 337

	
338 338
      _blossom_rep->set(_blossom_set->find(nca), nca);
339 339
    }
340 340

	
341 341

	
342 342

	
343 343
    void extendOnArc(const Arc& a) {
344 344
      Node base = _graph.source(a);
345 345
      Node odd = _graph.target(a);
346 346

	
347 347
      _ear->set(odd, _graph.oppositeArc(a));
348 348
      Node even = _graph.target((*_matching)[odd]);
349 349
      _blossom_rep->set(_blossom_set->insert(even), even);
350 350
      _status->set(odd, ODD);
351 351
      _status->set(even, EVEN);
352 352
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
353 353
      _tree_set->insert(odd, tree);
354 354
      _tree_set->insert(even, tree);
355 355
      _node_queue[_last++] = even;
356 356

	
357 357
    }
358 358

	
359 359
    void augmentOnArc(const Arc& a) {
360 360
      Node even = _graph.source(a);
361 361
      Node odd = _graph.target(a);
362 362

	
363 363
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
364 364

	
365 365
      _matching->set(odd, _graph.oppositeArc(a));
366 366
      _status->set(odd, MATCHED);
367 367

	
368 368
      Arc arc = (*_matching)[even];
369 369
      _matching->set(even, a);
370 370

	
371 371
      while (arc != INVALID) {
372 372
        odd = _graph.target(arc);
373 373
        arc = (*_ear)[odd];
374 374
        even = _graph.target(arc);
375 375
        _matching->set(odd, arc);
376 376
        arc = (*_matching)[even];
377 377
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
378 378
      }
379 379

	
380 380
      for (typename TreeSet::ItemIt it(*_tree_set, tree);
381 381
           it != INVALID; ++it) {
382 382
        if ((*_status)[it] == ODD) {
383 383
          _status->set(it, MATCHED);
384 384
        } else {
385 385
          int blossom = _blossom_set->find(it);
386 386
          for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
387 387
               jt != INVALID; ++jt) {
388 388
            _status->set(jt, MATCHED);
389 389
          }
390 390
          _blossom_set->eraseClass(blossom);
391 391
        }
392 392
      }
393 393
      _tree_set->eraseClass(tree);
394 394

	
395 395
    }
396 396

	
397 397
  public:
398 398

	
399 399
    /// \brief Constructor
400 400
    ///
401 401
    /// Constructor.
402 402
    MaxMatching(const Graph& graph)
403 403
      : _graph(graph), _matching(0), _status(0), _ear(0),
404 404
        _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
405 405
        _tree_set_index(0), _tree_set(0) {}
406 406

	
407 407
    ~MaxMatching() {
408 408
      destroyStructures();
409 409
    }
410 410

	
411 411
    /// \name Execution control
412 412
    /// The simplest way to execute the algorithm is to use the
413 413
    /// \c run() member function.
414 414
    /// \n
415 415

	
416 416
    /// If you need better control on the execution, you must call
417 417
    /// \ref init(), \ref greedyInit() or \ref matchingInit()
418 418
    /// functions first, then you can start the algorithm with the \ref
419
    /// startParse() or startDense() functions.
419
    /// startSparse() or startDense() functions.
420 420

	
421 421
    ///@{
422 422

	
423 423
    /// \brief Sets the actual matching to the empty matching.
424 424
    ///
425 425
    /// Sets the actual matching to the empty matching.
426 426
    ///
427 427
    void init() {
428 428
      createStructures();
429 429
      for(NodeIt n(_graph); n != INVALID; ++n) {
430 430
        _matching->set(n, INVALID);
431 431
        _status->set(n, UNMATCHED);
432 432
      }
433 433
    }
434 434

	
435 435
    ///\brief Finds an initial matching in a greedy way
436 436
    ///
437 437
    ///It finds an initial matching in a greedy way.
438 438
    void greedyInit() {
439 439
      createStructures();
440 440
      for (NodeIt n(_graph); n != INVALID; ++n) {
441 441
        _matching->set(n, INVALID);
442 442
        _status->set(n, UNMATCHED);
443 443
      }
444 444
      for (NodeIt n(_graph); n != INVALID; ++n) {
445 445
        if ((*_matching)[n] == INVALID) {
446 446
          for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
447 447
            Node v = _graph.target(a);
448 448
            if ((*_matching)[v] == INVALID && v != n) {
449 449
              _matching->set(n, a);
450 450
              _status->set(n, MATCHED);
451 451
              _matching->set(v, _graph.oppositeArc(a));
452 452
              _status->set(v, MATCHED);
453 453
              break;
454 454
            }
455 455
          }
456 456
        }
457 457
      }
458 458
    }
459 459

	
460 460

	
461 461
    /// \brief Initialize the matching from a map containing.
462 462
    ///
463 463
    /// Initialize the matching from a \c bool valued \c Edge map. This
464 464
    /// map must have the property that there are no two incident edges
465 465
    /// with true value, ie. it contains a matching.
466 466
    /// \return %True if the map contains a matching.
467 467
    template <typename MatchingMap>
468 468
    bool matchingInit(const MatchingMap& matching) {
469 469
      createStructures();
470 470

	
471 471
      for (NodeIt n(_graph); n != INVALID; ++n) {
472 472
        _matching->set(n, INVALID);
473 473
        _status->set(n, UNMATCHED);
474 474
      }
475 475
      for(EdgeIt e(_graph); e!=INVALID; ++e) {
476 476
        if (matching[e]) {
477 477

	
478 478
          Node u = _graph.u(e);
479 479
          if ((*_matching)[u] != INVALID) return false;
480 480
          _matching->set(u, _graph.direct(e, true));
481 481
          _status->set(u, MATCHED);
482 482

	
483 483
          Node v = _graph.v(e);
484 484
          if ((*_matching)[v] != INVALID) return false;
485 485
          _matching->set(v, _graph.direct(e, false));
486 486
          _status->set(v, MATCHED);
487 487
        }
488 488
      }
489 489
      return true;
490 490
    }
491 491

	
492 492
    /// \brief Starts Edmonds' algorithm
493 493
    ///
494 494
    /// If runs the original Edmonds' algorithm.
495 495
    void startSparse() {
496 496
      for(NodeIt n(_graph); n != INVALID; ++n) {
497 497
        if ((*_status)[n] == UNMATCHED) {
498 498
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
499 499
          _tree_set->insert(n);
500 500
          _status->set(n, EVEN);
501 501
          processSparse(n);
502 502
        }
503 503
      }
504 504
    }
505 505

	
506 506
    /// \brief Starts Edmonds' algorithm.
507 507
    ///
508 508
    /// It runs Edmonds' algorithm with a heuristic of postponing
509 509
    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
510 510
    void startDense() {
511 511
      for(NodeIt n(_graph); n != INVALID; ++n) {
512 512
        if ((*_status)[n] == UNMATCHED) {
513 513
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
514 514
          _tree_set->insert(n);
515 515
          _status->set(n, EVEN);
516 516
          processDense(n);
517 517
        }
518 518
      }
519 519
    }
520 520

	
521 521

	
522 522
    /// \brief Runs Edmonds' algorithm
523 523
    ///
524 524
    /// Runs Edmonds' algorithm for sparse graphs (<tt>m<2*n</tt>)
525 525
    /// or Edmonds' algorithm with a heuristic of
526 526
    /// postponing shrinks for dense graphs.
527 527
    void run() {
528 528
      if (countEdges(_graph) < 2 * countNodes(_graph)) {
529 529
        greedyInit();
530 530
        startSparse();
531 531
      } else {
532 532
        init();
533 533
        startDense();
534 534
      }
535 535
    }
536 536

	
537 537
    /// @}
538 538

	
539 539
    /// \name Primal solution
540 540
    /// Functions to get the primal solution, ie. the matching.
541 541

	
542 542
    /// @{
543 543

	
544 544
    ///\brief Returns the size of the current matching.
545 545
    ///
546 546
    ///Returns the size of the current matching. After \ref
547 547
    ///run() it returns the size of the maximum matching in the graph.
548 548
    int matchingSize() const {
549 549
      int size = 0;
550 550
      for (NodeIt n(_graph); n != INVALID; ++n) {
551 551
        if ((*_matching)[n] != INVALID) {
552 552
          ++size;
553 553
        }
554 554
      }
555 555
      return size / 2;
556 556
    }
557 557

	
558 558
    /// \brief Returns true when the edge is in the matching.
559 559
    ///
560 560
    /// Returns true when the edge is in the matching.
561 561
    bool matching(const Edge& edge) const {
562 562
      return edge == (*_matching)[_graph.u(edge)];
563 563
    }
564 564

	
565 565
    /// \brief Returns the matching edge incident to the given node.
566 566
    ///
567 567
    /// Returns the matching edge of a \c node in the actual matching or
568 568
    /// INVALID if the \c node is not covered by the actual matching.
569 569
    Arc matching(const Node& n) const {
570 570
      return (*_matching)[n];
571 571
    }
572 572

	
573 573
    ///\brief Returns the mate of a node in the actual matching.
574 574
    ///
575 575
    ///Returns the mate of a \c node in the actual matching or
576 576
    ///INVALID if the \c node is not covered by the actual matching.
577 577
    Node mate(const Node& n) const {
578 578
      return (*_matching)[n] != INVALID ?
579 579
        _graph.target((*_matching)[n]) : INVALID;
580 580
    }
581 581

	
582 582
    /// @}
583 583

	
584 584
    /// \name Dual solution
585 585
    /// Functions to get the dual solution, ie. the decomposition.
586 586

	
587 587
    /// @{
588 588

	
589 589
    /// \brief Returns the class of the node in the Edmonds-Gallai
590 590
    /// decomposition.
591 591
    ///
592 592
    /// Returns the class of the node in the Edmonds-Gallai
593 593
    /// decomposition.
594 594
    Status decomposition(const Node& n) const {
595 595
      return (*_status)[n];
596 596
    }
597 597

	
598 598
    /// \brief Returns true when the node is in the barrier.
599 599
    ///
600 600
    /// Returns true when the node is in the barrier.
601 601
    bool barrier(const Node& n) const {
602 602
      return (*_status)[n] == ODD;
603 603
    }
604 604

	
605 605
    /// @}
606 606

	
607 607
  };
608 608

	
609 609
  /// \ingroup matching
610 610
  ///
611 611
  /// \brief Weighted matching in general graphs
Ignore white space 384 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_SUURBALLE_H
20 20
#define LEMON_SUURBALLE_H
21 21

	
22 22
///\ingroup shortest_path
23 23
///\file
24 24
///\brief An algorithm for finding arc-disjoint paths between two
25 25
/// nodes having minimum total length.
26 26

	
27 27
#include <vector>
28 28
#include <lemon/bin_heap.h>
29 29
#include <lemon/path.h>
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  /// \addtogroup shortest_path
34 34
  /// @{
35 35

	
36 36
  /// \brief Algorithm for finding arc-disjoint paths between two nodes
37 37
  /// having minimum total length.
38 38
  ///
39 39
  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
40 40
  /// finding arc-disjoint paths having minimum total length (cost)
41 41
  /// from a given source node to a given target node in a digraph.
42 42
  ///
43 43
  /// In fact, this implementation is the specialization of the
44 44
  /// \ref CapacityScaling "successive shortest path" algorithm.
45 45
  ///
46 46
  /// \tparam Digraph The digraph type the algorithm runs on.
47 47
  /// The default value is \c ListDigraph.
48 48
  /// \tparam LengthMap The type of the length (cost) map.
49 49
  /// The default value is <tt>Digraph::ArcMap<int></tt>.
50 50
  ///
51 51
  /// \warning Length values should be \e non-negative \e integers.
52 52
  ///
53 53
  /// \note For finding node-disjoint paths this algorithm can be used
54
  /// with \ref SplitDigraphAdaptor.
54
  /// with \ref SplitNodes.
55 55
#ifdef DOXYGEN
56 56
  template <typename Digraph, typename LengthMap>
57 57
#else
58 58
  template < typename Digraph = ListDigraph,
59 59
             typename LengthMap = typename Digraph::template ArcMap<int> >
60 60
#endif
61 61
  class Suurballe
62 62
  {
63 63
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
64 64

	
65 65
    typedef typename LengthMap::Value Length;
66 66
    typedef ConstMap<Arc, int> ConstArcMap;
67 67
    typedef typename Digraph::template NodeMap<Arc> PredMap;
68 68

	
69 69
  public:
70 70

	
71 71
    /// The type of the flow map.
72 72
    typedef typename Digraph::template ArcMap<int> FlowMap;
73 73
    /// The type of the potential map.
74 74
    typedef typename Digraph::template NodeMap<Length> PotentialMap;
75 75
    /// The type of the path structures.
76 76
    typedef SimplePath<Digraph> Path;
77 77

	
78 78
  private:
79 79
  
80 80
    /// \brief Special implementation of the Dijkstra algorithm
81 81
    /// for finding shortest paths in the residual network.
82 82
    ///
83 83
    /// \ref ResidualDijkstra is a special implementation of the
84 84
    /// \ref Dijkstra algorithm for finding shortest paths in the
85 85
    /// residual network of the digraph with respect to the reduced arc
86 86
    /// lengths and modifying the node potentials according to the
87 87
    /// distance of the nodes.
88 88
    class ResidualDijkstra
89 89
    {
90 90
      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
91 91
      typedef BinHeap<Length, HeapCrossRef> Heap;
92 92

	
93 93
    private:
94 94

	
95 95
      // The digraph the algorithm runs on
96 96
      const Digraph &_graph;
97 97

	
98 98
      // The main maps
99 99
      const FlowMap &_flow;
100 100
      const LengthMap &_length;
101 101
      PotentialMap &_potential;
102 102

	
103 103
      // The distance map
104 104
      PotentialMap _dist;
105 105
      // The pred arc map
106 106
      PredMap &_pred;
107 107
      // The processed (i.e. permanently labeled) nodes
108 108
      std::vector<Node> _proc_nodes;
109 109
      
110 110
      Node _s;
111 111
      Node _t;
112 112

	
113 113
    public:
114 114

	
115 115
      /// Constructor.
116 116
      ResidualDijkstra( const Digraph &digraph,
117 117
                        const FlowMap &flow,
118 118
                        const LengthMap &length,
119 119
                        PotentialMap &potential,
120 120
                        PredMap &pred,
121 121
                        Node s, Node t ) :
122 122
        _graph(digraph), _flow(flow), _length(length), _potential(potential),
123 123
        _dist(digraph), _pred(pred), _s(s), _t(t) {}
124 124

	
125 125
      /// \brief Run the algorithm. It returns \c true if a path is found
126 126
      /// from the source node to the target node.
127 127
      bool run() {
128 128
        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
129 129
        Heap heap(heap_cross_ref);
130 130
        heap.push(_s, 0);
131 131
        _pred[_s] = INVALID;
132 132
        _proc_nodes.clear();
133 133

	
134 134
        // Process nodes
135 135
        while (!heap.empty() && heap.top() != _t) {
136 136
          Node u = heap.top(), v;
137 137
          Length d = heap.prio() + _potential[u], nd;
138 138
          _dist[u] = heap.prio();
139 139
          heap.pop();
140 140
          _proc_nodes.push_back(u);
141 141

	
142 142
          // Traverse outgoing arcs
143 143
          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
144 144
            if (_flow[e] == 0) {
145 145
              v = _graph.target(e);
146 146
              switch(heap.state(v)) {
147 147
              case Heap::PRE_HEAP:
148 148
                heap.push(v, d + _length[e] - _potential[v]);
149 149
                _pred[v] = e;
150 150
                break;
151 151
              case Heap::IN_HEAP:
152 152
                nd = d + _length[e] - _potential[v];
153 153
                if (nd < heap[v]) {
154 154
                  heap.decrease(v, nd);
155 155
                  _pred[v] = e;
156 156
                }
157 157
                break;
158 158
              case Heap::POST_HEAP:
159 159
                break;
160 160
              }
161 161
            }
162 162
          }
163 163

	
164 164
          // Traverse incoming arcs
165 165
          for (InArcIt e(_graph, u); e != INVALID; ++e) {
166 166
            if (_flow[e] == 1) {
167 167
              v = _graph.source(e);
168 168
              switch(heap.state(v)) {
169 169
              case Heap::PRE_HEAP:
170 170
                heap.push(v, d - _length[e] - _potential[v]);
171 171
                _pred[v] = e;
172 172
                break;
173 173
              case Heap::IN_HEAP:
174 174
                nd = d - _length[e] - _potential[v];
175 175
                if (nd < heap[v]) {
176 176
                  heap.decrease(v, nd);
177 177
                  _pred[v] = e;
178 178
                }
179 179
                break;
180 180
              case Heap::POST_HEAP:
181 181
                break;
182 182
              }
183 183
            }
184 184
          }
185 185
        }
186 186
        if (heap.empty()) return false;
187 187

	
188 188
        // Update potentials of processed nodes
189 189
        Length t_dist = heap.prio();
190 190
        for (int i = 0; i < int(_proc_nodes.size()); ++i)
191 191
          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
192 192
        return true;
193 193
      }
194 194

	
195 195
    }; //class ResidualDijkstra
196 196

	
197 197
  private:
198 198

	
199 199
    // The digraph the algorithm runs on
200 200
    const Digraph &_graph;
201 201
    // The length map
202 202
    const LengthMap &_length;
203 203
    
204 204
    // Arc map of the current flow
205 205
    FlowMap *_flow;
206 206
    bool _local_flow;
207 207
    // Node map of the current potentials
208 208
    PotentialMap *_potential;
209 209
    bool _local_potential;
210 210

	
211 211
    // The source node
212 212
    Node _source;
213 213
    // The target node
214 214
    Node _target;
215 215

	
216 216
    // Container to store the found paths
217 217
    std::vector< SimplePath<Digraph> > paths;
218 218
    int _path_num;
219 219

	
220 220
    // The pred arc map
221 221
    PredMap _pred;
222 222
    // Implementation of the Dijkstra algorithm for finding augmenting
223 223
    // shortest paths in the residual network
224 224
    ResidualDijkstra *_dijkstra;
225 225

	
226 226
  public:
227 227

	
228 228
    /// \brief Constructor.
229 229
    ///
230 230
    /// Constructor.
231 231
    ///
232 232
    /// \param digraph The digraph the algorithm runs on.
233 233
    /// \param length The length (cost) values of the arcs.
234 234
    /// \param s The source node.
235 235
    /// \param t The target node.
236 236
    Suurballe( const Digraph &digraph,
237 237
               const LengthMap &length,
238 238
               Node s, Node t ) :
239 239
      _graph(digraph), _length(length), _flow(0), _local_flow(false),
240 240
      _potential(0), _local_potential(false), _source(s), _target(t),
241 241
      _pred(digraph) {}
242 242

	
243 243
    /// Destructor.
244 244
    ~Suurballe() {
245 245
      if (_local_flow) delete _flow;
246 246
      if (_local_potential) delete _potential;
0 comments (0 inline)