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 192 line context
... ...
@@ -202,193 +202,193 @@
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
    }
... ...
@@ -1132,193 +1132,193 @@
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.
Ignore white space 6 line context
... ...
@@ -323,193 +323,193 @@
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);
Ignore white space 6 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;
0 comments (0 inline)