lemon/suurballe.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 863 a93f1a27d831
child 1074 97d978243703
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
alpar@440
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@345
     2
 *
alpar@440
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@345
     4
 *
alpar@877
     5
 * Copyright (C) 2003-2010
alpar@345
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@345
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@345
     8
 *
alpar@345
     9
 * Permission to use, modify and distribute this software is granted
alpar@345
    10
 * provided that this copyright notice appears in all copies. For
alpar@345
    11
 * precise terms see the accompanying LICENSE file.
alpar@345
    12
 *
alpar@345
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@345
    14
 * express or implied, and with no claim as to its suitability for any
alpar@345
    15
 * purpose.
alpar@345
    16
 *
alpar@345
    17
 */
alpar@345
    18
alpar@345
    19
#ifndef LEMON_SUURBALLE_H
alpar@345
    20
#define LEMON_SUURBALLE_H
alpar@345
    21
alpar@345
    22
///\ingroup shortest_path
alpar@345
    23
///\file
alpar@345
    24
///\brief An algorithm for finding arc-disjoint paths between two
alpar@345
    25
/// nodes having minimum total length.
alpar@345
    26
alpar@345
    27
#include <vector>
kpeter@623
    28
#include <limits>
alpar@345
    29
#include <lemon/bin_heap.h>
alpar@345
    30
#include <lemon/path.h>
deba@519
    31
#include <lemon/list_graph.h>
kpeter@854
    32
#include <lemon/dijkstra.h>
deba@519
    33
#include <lemon/maps.h>
alpar@345
    34
alpar@345
    35
namespace lemon {
alpar@345
    36
kpeter@857
    37
  /// \brief Default traits class of Suurballe algorithm.
kpeter@857
    38
  ///
kpeter@857
    39
  /// Default traits class of Suurballe algorithm.
kpeter@857
    40
  /// \tparam GR The digraph type the algorithm runs on.
kpeter@857
    41
  /// \tparam LEN The type of the length map.
kpeter@857
    42
  /// The default value is <tt>GR::ArcMap<int></tt>.
kpeter@857
    43
#ifdef DOXYGEN
kpeter@857
    44
  template <typename GR, typename LEN>
kpeter@857
    45
#else
kpeter@857
    46
  template < typename GR,
kpeter@857
    47
             typename LEN = typename GR::template ArcMap<int> >
kpeter@857
    48
#endif
kpeter@857
    49
  struct SuurballeDefaultTraits
kpeter@857
    50
  {
kpeter@857
    51
    /// The type of the digraph.
kpeter@857
    52
    typedef GR Digraph;
kpeter@857
    53
    /// The type of the length map.
kpeter@857
    54
    typedef LEN LengthMap;
kpeter@857
    55
    /// The type of the lengths.
kpeter@857
    56
    typedef typename LEN::Value Length;
kpeter@857
    57
    /// The type of the flow map.
kpeter@857
    58
    typedef typename GR::template ArcMap<int> FlowMap;
kpeter@857
    59
    /// The type of the potential map.
kpeter@857
    60
    typedef typename GR::template NodeMap<Length> PotentialMap;
kpeter@857
    61
kpeter@857
    62
    /// \brief The path type
kpeter@857
    63
    ///
kpeter@857
    64
    /// The type used for storing the found arc-disjoint paths.
kpeter@857
    65
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
kpeter@857
    66
    /// and it must have an \c addBack() function.
kpeter@857
    67
    typedef lemon::Path<Digraph> Path;
alpar@877
    68
kpeter@857
    69
    /// The cross reference type used for the heap.
kpeter@857
    70
    typedef typename GR::template NodeMap<int> HeapCrossRef;
kpeter@857
    71
kpeter@857
    72
    /// \brief The heap type used for internal Dijkstra computations.
kpeter@857
    73
    ///
kpeter@857
    74
    /// The type of the heap used for internal Dijkstra computations.
kpeter@857
    75
    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept
kpeter@857
    76
    /// and its priority type must be \c Length.
kpeter@857
    77
    typedef BinHeap<Length, HeapCrossRef> Heap;
kpeter@857
    78
  };
kpeter@857
    79
alpar@345
    80
  /// \addtogroup shortest_path
alpar@345
    81
  /// @{
alpar@345
    82
kpeter@346
    83
  /// \brief Algorithm for finding arc-disjoint paths between two nodes
kpeter@346
    84
  /// having minimum total length.
alpar@345
    85
  ///
alpar@345
    86
  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
alpar@345
    87
  /// finding arc-disjoint paths having minimum total length (cost)
kpeter@346
    88
  /// from a given source node to a given target node in a digraph.
alpar@345
    89
  ///
kpeter@623
    90
  /// Note that this problem is a special case of the \ref min_cost_flow
kpeter@623
    91
  /// "minimum cost flow problem". This implementation is actually an
kpeter@623
    92
  /// efficient specialized version of the \ref CapacityScaling
kpeter@853
    93
  /// "successive shortest path" algorithm directly for this problem.
kpeter@623
    94
  /// Therefore this class provides query functions for flow values and
kpeter@623
    95
  /// node potentials (the dual solution) just like the minimum cost flow
kpeter@623
    96
  /// algorithms.
alpar@345
    97
  ///
kpeter@559
    98
  /// \tparam GR The digraph type the algorithm runs on.
kpeter@623
    99
  /// \tparam LEN The type of the length map.
kpeter@623
   100
  /// The default value is <tt>GR::ArcMap<int></tt>.
alpar@345
   101
  ///
kpeter@852
   102
  /// \warning Length values should be \e non-negative.
alpar@345
   103
  ///
kpeter@853
   104
  /// \note For finding \e node-disjoint paths, this algorithm can be used
kpeter@623
   105
  /// along with the \ref SplitNodes adaptor.
kpeter@346
   106
#ifdef DOXYGEN
kpeter@857
   107
  template <typename GR, typename LEN, typename TR>
kpeter@346
   108
#else
kpeter@623
   109
  template < typename GR,
kpeter@857
   110
             typename LEN = typename GR::template ArcMap<int>,
kpeter@857
   111
             typename TR = SuurballeDefaultTraits<GR, LEN> >
kpeter@346
   112
#endif
alpar@345
   113
  class Suurballe
alpar@345
   114
  {
kpeter@559
   115
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
alpar@345
   116
alpar@345
   117
    typedef ConstMap<Arc, int> ConstArcMap;
kpeter@559
   118
    typedef typename GR::template NodeMap<Arc> PredMap;
alpar@345
   119
alpar@345
   120
  public:
alpar@345
   121
kpeter@857
   122
    /// The type of the digraph.
kpeter@857
   123
    typedef typename TR::Digraph Digraph;
kpeter@559
   124
    /// The type of the length map.
kpeter@857
   125
    typedef typename TR::LengthMap LengthMap;
kpeter@559
   126
    /// The type of the lengths.
kpeter@857
   127
    typedef typename TR::Length Length;
kpeter@857
   128
kpeter@623
   129
    /// The type of the flow map.
kpeter@857
   130
    typedef typename TR::FlowMap FlowMap;
kpeter@623
   131
    /// The type of the potential map.
kpeter@857
   132
    typedef typename TR::PotentialMap PotentialMap;
kpeter@857
   133
    /// The type of the path structures.
kpeter@857
   134
    typedef typename TR::Path Path;
kpeter@857
   135
    /// The cross reference type used for the heap.
kpeter@857
   136
    typedef typename TR::HeapCrossRef HeapCrossRef;
kpeter@857
   137
    /// The heap type used for internal Dijkstra computations.
kpeter@857
   138
    typedef typename TR::Heap Heap;
kpeter@623
   139
kpeter@857
   140
    /// The \ref SuurballeDefaultTraits "traits class" of the algorithm.
kpeter@857
   141
    typedef TR Traits;
alpar@345
   142
alpar@345
   143
  private:
alpar@440
   144
kpeter@623
   145
    // ResidualDijkstra is a special implementation of the
kpeter@623
   146
    // Dijkstra algorithm for finding shortest paths in the
kpeter@623
   147
    // residual network with respect to the reduced arc lengths
kpeter@623
   148
    // and modifying the node potentials according to the
kpeter@623
   149
    // distance of the nodes.
alpar@345
   150
    class ResidualDijkstra
alpar@345
   151
    {
alpar@345
   152
    private:
alpar@345
   153
alpar@345
   154
      const Digraph &_graph;
kpeter@853
   155
      const LengthMap &_length;
alpar@345
   156
      const FlowMap &_flow;
kpeter@853
   157
      PotentialMap &_pi;
alpar@345
   158
      PredMap &_pred;
alpar@345
   159
      Node _s;
alpar@345
   160
      Node _t;
alpar@877
   161
kpeter@853
   162
      PotentialMap _dist;
kpeter@853
   163
      std::vector<Node> _proc_nodes;
alpar@345
   164
alpar@345
   165
    public:
alpar@345
   166
kpeter@853
   167
      // Constructor
kpeter@853
   168
      ResidualDijkstra(Suurballe &srb) :
kpeter@853
   169
        _graph(srb._graph), _length(srb._length),
alpar@877
   170
        _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred),
kpeter@853
   171
        _s(srb._s), _t(srb._t), _dist(_graph) {}
alpar@877
   172
kpeter@853
   173
      // Run the algorithm and return true if a path is found
kpeter@853
   174
      // from the source node to the target node.
kpeter@853
   175
      bool run(int cnt) {
kpeter@853
   176
        return cnt == 0 ? startFirst() : start();
kpeter@853
   177
      }
alpar@345
   178
kpeter@853
   179
    private:
alpar@877
   180
kpeter@853
   181
      // Execute the algorithm for the first time (the flow and potential
kpeter@853
   182
      // functions have to be identically zero).
kpeter@853
   183
      bool startFirst() {
alpar@345
   184
        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
alpar@345
   185
        Heap heap(heap_cross_ref);
alpar@345
   186
        heap.push(_s, 0);
alpar@345
   187
        _pred[_s] = INVALID;
alpar@345
   188
        _proc_nodes.clear();
alpar@345
   189
kpeter@346
   190
        // Process nodes
alpar@345
   191
        while (!heap.empty() && heap.top() != _t) {
alpar@345
   192
          Node u = heap.top(), v;
kpeter@853
   193
          Length d = heap.prio(), dn;
alpar@345
   194
          _dist[u] = heap.prio();
kpeter@853
   195
          _proc_nodes.push_back(u);
alpar@345
   196
          heap.pop();
kpeter@853
   197
kpeter@853
   198
          // Traverse outgoing arcs
kpeter@853
   199
          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
kpeter@853
   200
            v = _graph.target(e);
kpeter@853
   201
            switch(heap.state(v)) {
kpeter@853
   202
              case Heap::PRE_HEAP:
kpeter@853
   203
                heap.push(v, d + _length[e]);
kpeter@853
   204
                _pred[v] = e;
kpeter@853
   205
                break;
kpeter@853
   206
              case Heap::IN_HEAP:
kpeter@853
   207
                dn = d + _length[e];
kpeter@853
   208
                if (dn < heap[v]) {
kpeter@853
   209
                  heap.decrease(v, dn);
kpeter@853
   210
                  _pred[v] = e;
kpeter@853
   211
                }
kpeter@853
   212
                break;
kpeter@853
   213
              case Heap::POST_HEAP:
kpeter@853
   214
                break;
kpeter@853
   215
            }
kpeter@853
   216
          }
kpeter@853
   217
        }
kpeter@853
   218
        if (heap.empty()) return false;
kpeter@853
   219
kpeter@853
   220
        // Update potentials of processed nodes
kpeter@853
   221
        Length t_dist = heap.prio();
kpeter@853
   222
        for (int i = 0; i < int(_proc_nodes.size()); ++i)
kpeter@853
   223
          _pi[_proc_nodes[i]] = _dist[_proc_nodes[i]] - t_dist;
kpeter@853
   224
        return true;
kpeter@853
   225
      }
kpeter@853
   226
kpeter@853
   227
      // Execute the algorithm.
kpeter@853
   228
      bool start() {
kpeter@853
   229
        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
kpeter@853
   230
        Heap heap(heap_cross_ref);
kpeter@853
   231
        heap.push(_s, 0);
kpeter@853
   232
        _pred[_s] = INVALID;
kpeter@853
   233
        _proc_nodes.clear();
kpeter@853
   234
kpeter@853
   235
        // Process nodes
kpeter@853
   236
        while (!heap.empty() && heap.top() != _t) {
kpeter@853
   237
          Node u = heap.top(), v;
kpeter@853
   238
          Length d = heap.prio() + _pi[u], dn;
kpeter@853
   239
          _dist[u] = heap.prio();
alpar@345
   240
          _proc_nodes.push_back(u);
kpeter@853
   241
          heap.pop();
alpar@345
   242
kpeter@346
   243
          // Traverse outgoing arcs
alpar@345
   244
          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
alpar@345
   245
            if (_flow[e] == 0) {
alpar@345
   246
              v = _graph.target(e);
alpar@345
   247
              switch(heap.state(v)) {
kpeter@853
   248
                case Heap::PRE_HEAP:
kpeter@853
   249
                  heap.push(v, d + _length[e] - _pi[v]);
alpar@345
   250
                  _pred[v] = e;
kpeter@853
   251
                  break;
kpeter@853
   252
                case Heap::IN_HEAP:
kpeter@853
   253
                  dn = d + _length[e] - _pi[v];
kpeter@853
   254
                  if (dn < heap[v]) {
kpeter@853
   255
                    heap.decrease(v, dn);
kpeter@853
   256
                    _pred[v] = e;
kpeter@853
   257
                  }
kpeter@853
   258
                  break;
kpeter@853
   259
                case Heap::POST_HEAP:
kpeter@853
   260
                  break;
alpar@345
   261
              }
alpar@345
   262
            }
alpar@345
   263
          }
alpar@345
   264
kpeter@346
   265
          // Traverse incoming arcs
alpar@345
   266
          for (InArcIt e(_graph, u); e != INVALID; ++e) {
alpar@345
   267
            if (_flow[e] == 1) {
alpar@345
   268
              v = _graph.source(e);
alpar@345
   269
              switch(heap.state(v)) {
kpeter@853
   270
                case Heap::PRE_HEAP:
kpeter@853
   271
                  heap.push(v, d - _length[e] - _pi[v]);
alpar@345
   272
                  _pred[v] = e;
kpeter@853
   273
                  break;
kpeter@853
   274
                case Heap::IN_HEAP:
kpeter@853
   275
                  dn = d - _length[e] - _pi[v];
kpeter@853
   276
                  if (dn < heap[v]) {
kpeter@853
   277
                    heap.decrease(v, dn);
kpeter@853
   278
                    _pred[v] = e;
kpeter@853
   279
                  }
kpeter@853
   280
                  break;
kpeter@853
   281
                case Heap::POST_HEAP:
kpeter@853
   282
                  break;
alpar@345
   283
              }
alpar@345
   284
            }
alpar@345
   285
          }
alpar@345
   286
        }
alpar@345
   287
        if (heap.empty()) return false;
alpar@345
   288
kpeter@346
   289
        // Update potentials of processed nodes
alpar@345
   290
        Length t_dist = heap.prio();
alpar@345
   291
        for (int i = 0; i < int(_proc_nodes.size()); ++i)
kpeter@853
   292
          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
alpar@345
   293
        return true;
alpar@345
   294
      }
alpar@345
   295
alpar@345
   296
    }; //class ResidualDijkstra
alpar@345
   297
kpeter@857
   298
  public:
kpeter@857
   299
kpeter@857
   300
    /// \name Named Template Parameters
kpeter@857
   301
    /// @{
kpeter@857
   302
kpeter@857
   303
    template <typename T>
kpeter@857
   304
    struct SetFlowMapTraits : public Traits {
kpeter@857
   305
      typedef T FlowMap;
kpeter@857
   306
    };
kpeter@857
   307
kpeter@857
   308
    /// \brief \ref named-templ-param "Named parameter" for setting
kpeter@857
   309
    /// \c FlowMap type.
kpeter@857
   310
    ///
kpeter@857
   311
    /// \ref named-templ-param "Named parameter" for setting
kpeter@857
   312
    /// \c FlowMap type.
kpeter@857
   313
    template <typename T>
kpeter@857
   314
    struct SetFlowMap
kpeter@857
   315
      : public Suurballe<GR, LEN, SetFlowMapTraits<T> > {
kpeter@857
   316
      typedef Suurballe<GR, LEN, SetFlowMapTraits<T> > Create;
kpeter@857
   317
    };
kpeter@857
   318
kpeter@857
   319
    template <typename T>
kpeter@857
   320
    struct SetPotentialMapTraits : public Traits {
kpeter@857
   321
      typedef T PotentialMap;
kpeter@857
   322
    };
kpeter@857
   323
kpeter@857
   324
    /// \brief \ref named-templ-param "Named parameter" for setting
kpeter@857
   325
    /// \c PotentialMap type.
kpeter@857
   326
    ///
kpeter@857
   327
    /// \ref named-templ-param "Named parameter" for setting
kpeter@857
   328
    /// \c PotentialMap type.
kpeter@857
   329
    template <typename T>
kpeter@857
   330
    struct SetPotentialMap
kpeter@857
   331
      : public Suurballe<GR, LEN, SetPotentialMapTraits<T> > {
kpeter@857
   332
      typedef Suurballe<GR, LEN, SetPotentialMapTraits<T> > Create;
kpeter@857
   333
    };
kpeter@857
   334
kpeter@857
   335
    template <typename T>
kpeter@857
   336
    struct SetPathTraits : public Traits {
kpeter@857
   337
      typedef T Path;
kpeter@857
   338
    };
kpeter@857
   339
kpeter@857
   340
    /// \brief \ref named-templ-param "Named parameter" for setting
kpeter@857
   341
    /// \c %Path type.
kpeter@857
   342
    ///
kpeter@857
   343
    /// \ref named-templ-param "Named parameter" for setting \c %Path type.
kpeter@857
   344
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
kpeter@857
   345
    /// and it must have an \c addBack() function.
kpeter@857
   346
    template <typename T>
kpeter@857
   347
    struct SetPath
kpeter@857
   348
      : public Suurballe<GR, LEN, SetPathTraits<T> > {
kpeter@857
   349
      typedef Suurballe<GR, LEN, SetPathTraits<T> > Create;
kpeter@857
   350
    };
alpar@877
   351
kpeter@857
   352
    template <typename H, typename CR>
kpeter@857
   353
    struct SetHeapTraits : public Traits {
kpeter@857
   354
      typedef H Heap;
kpeter@857
   355
      typedef CR HeapCrossRef;
kpeter@857
   356
    };
kpeter@857
   357
kpeter@857
   358
    /// \brief \ref named-templ-param "Named parameter" for setting
kpeter@857
   359
    /// \c Heap and \c HeapCrossRef types.
kpeter@857
   360
    ///
kpeter@857
   361
    /// \ref named-templ-param "Named parameter" for setting \c Heap
alpar@877
   362
    /// and \c HeapCrossRef types with automatic allocation.
kpeter@857
   363
    /// They will be used for internal Dijkstra computations.
kpeter@857
   364
    /// The heap type must conform to the \ref lemon::concepts::Heap "Heap"
kpeter@857
   365
    /// concept and its priority type must be \c Length.
kpeter@857
   366
    template <typename H,
kpeter@857
   367
              typename CR = typename Digraph::template NodeMap<int> >
kpeter@857
   368
    struct SetHeap
kpeter@857
   369
      : public Suurballe<GR, LEN, SetHeapTraits<H, CR> > {
kpeter@857
   370
      typedef Suurballe<GR, LEN, SetHeapTraits<H, CR> > Create;
kpeter@857
   371
    };
kpeter@857
   372
kpeter@857
   373
    /// @}
kpeter@857
   374
alpar@345
   375
  private:
alpar@345
   376
kpeter@346
   377
    // The digraph the algorithm runs on
alpar@345
   378
    const Digraph &_graph;
alpar@345
   379
    // The length map
alpar@345
   380
    const LengthMap &_length;
alpar@440
   381
alpar@345
   382
    // Arc map of the current flow
alpar@345
   383
    FlowMap *_flow;
alpar@345
   384
    bool _local_flow;
alpar@345
   385
    // Node map of the current potentials
alpar@345
   386
    PotentialMap *_potential;
alpar@345
   387
    bool _local_potential;
alpar@345
   388
alpar@345
   389
    // The source node
kpeter@853
   390
    Node _s;
alpar@345
   391
    // The target node
kpeter@853
   392
    Node _t;
alpar@345
   393
alpar@345
   394
    // Container to store the found paths
kpeter@853
   395
    std::vector<Path> _paths;
alpar@345
   396
    int _path_num;
alpar@345
   397
alpar@345
   398
    // The pred arc map
alpar@345
   399
    PredMap _pred;
alpar@877
   400
kpeter@854
   401
    // Data for full init
kpeter@854
   402
    PotentialMap *_init_dist;
kpeter@854
   403
    PredMap *_init_pred;
kpeter@854
   404
    bool _full_init;
alpar@345
   405
kpeter@863
   406
  protected:
kpeter@863
   407
kpeter@863
   408
    Suurballe() {}
kpeter@863
   409
alpar@345
   410
  public:
alpar@345
   411
alpar@345
   412
    /// \brief Constructor.
alpar@345
   413
    ///
alpar@345
   414
    /// Constructor.
alpar@345
   415
    ///
kpeter@623
   416
    /// \param graph The digraph the algorithm runs on.
alpar@345
   417
    /// \param length The length (cost) values of the arcs.
kpeter@623
   418
    Suurballe( const Digraph &graph,
kpeter@623
   419
               const LengthMap &length ) :
kpeter@623
   420
      _graph(graph), _length(length), _flow(0), _local_flow(false),
kpeter@854
   421
      _potential(0), _local_potential(false), _pred(graph),
kpeter@854
   422
      _init_dist(0), _init_pred(0)
kpeter@852
   423
    {}
alpar@345
   424
alpar@345
   425
    /// Destructor.
alpar@345
   426
    ~Suurballe() {
alpar@345
   427
      if (_local_flow) delete _flow;
alpar@345
   428
      if (_local_potential) delete _potential;
kpeter@854
   429
      delete _init_dist;
kpeter@854
   430
      delete _init_pred;
alpar@345
   431
    }
alpar@345
   432
kpeter@346
   433
    /// \brief Set the flow map.
alpar@345
   434
    ///
kpeter@346
   435
    /// This function sets the flow map.
kpeter@623
   436
    /// If it is not used before calling \ref run() or \ref init(),
kpeter@623
   437
    /// an instance will be allocated automatically. The destructor
kpeter@623
   438
    /// deallocates this automatically allocated map, of course.
alpar@345
   439
    ///
kpeter@623
   440
    /// The found flow contains only 0 and 1 values, since it is the
kpeter@623
   441
    /// union of the found arc-disjoint paths.
alpar@345
   442
    ///
kpeter@559
   443
    /// \return <tt>(*this)</tt>
alpar@345
   444
    Suurballe& flowMap(FlowMap &map) {
alpar@345
   445
      if (_local_flow) {
alpar@345
   446
        delete _flow;
alpar@345
   447
        _local_flow = false;
alpar@345
   448
      }
alpar@345
   449
      _flow = &map;
alpar@345
   450
      return *this;
alpar@345
   451
    }
alpar@345
   452
kpeter@346
   453
    /// \brief Set the potential map.
alpar@345
   454
    ///
kpeter@346
   455
    /// This function sets the potential map.
kpeter@623
   456
    /// If it is not used before calling \ref run() or \ref init(),
kpeter@623
   457
    /// an instance will be allocated automatically. The destructor
kpeter@623
   458
    /// deallocates this automatically allocated map, of course.
alpar@345
   459
    ///
kpeter@623
   460
    /// The node potentials provide the dual solution of the underlying
kpeter@623
   461
    /// \ref min_cost_flow "minimum cost flow problem".
alpar@345
   462
    ///
kpeter@559
   463
    /// \return <tt>(*this)</tt>
alpar@345
   464
    Suurballe& potentialMap(PotentialMap &map) {
alpar@345
   465
      if (_local_potential) {
alpar@345
   466
        delete _potential;
alpar@345
   467
        _local_potential = false;
alpar@345
   468
      }
alpar@345
   469
      _potential = &map;
alpar@345
   470
      return *this;
alpar@345
   471
    }
alpar@345
   472
kpeter@584
   473
    /// \name Execution Control
alpar@345
   474
    /// The simplest way to execute the algorithm is to call the run()
kpeter@854
   475
    /// function.\n
kpeter@854
   476
    /// If you need to execute the algorithm many times using the same
kpeter@854
   477
    /// source node, then you may call fullInit() once and start()
kpeter@854
   478
    /// for each target node.\n
alpar@345
   479
    /// If you only need the flow that is the union of the found
kpeter@854
   480
    /// arc-disjoint paths, then you may call findFlow() instead of
kpeter@854
   481
    /// start().
alpar@345
   482
alpar@345
   483
    /// @{
alpar@345
   484
kpeter@346
   485
    /// \brief Run the algorithm.
alpar@345
   486
    ///
kpeter@346
   487
    /// This function runs the algorithm.
alpar@345
   488
    ///
kpeter@623
   489
    /// \param s The source node.
kpeter@623
   490
    /// \param t The target node.
alpar@345
   491
    /// \param k The number of paths to be found.
alpar@345
   492
    ///
kpeter@346
   493
    /// \return \c k if there are at least \c k arc-disjoint paths from
kpeter@346
   494
    /// \c s to \c t in the digraph. Otherwise it returns the number of
alpar@345
   495
    /// arc-disjoint paths found.
alpar@345
   496
    ///
kpeter@623
   497
    /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
kpeter@623
   498
    /// just a shortcut of the following code.
alpar@345
   499
    /// \code
kpeter@623
   500
    ///   s.init(s);
kpeter@854
   501
    ///   s.start(t, k);
alpar@345
   502
    /// \endcode
kpeter@623
   503
    int run(const Node& s, const Node& t, int k = 2) {
kpeter@623
   504
      init(s);
kpeter@854
   505
      start(t, k);
alpar@345
   506
      return _path_num;
alpar@345
   507
    }
alpar@345
   508
kpeter@346
   509
    /// \brief Initialize the algorithm.
alpar@345
   510
    ///
kpeter@854
   511
    /// This function initializes the algorithm with the given source node.
kpeter@623
   512
    ///
kpeter@623
   513
    /// \param s The source node.
kpeter@623
   514
    void init(const Node& s) {
kpeter@853
   515
      _s = s;
kpeter@623
   516
kpeter@346
   517
      // Initialize maps
alpar@345
   518
      if (!_flow) {
alpar@345
   519
        _flow = new FlowMap(_graph);
alpar@345
   520
        _local_flow = true;
alpar@345
   521
      }
alpar@345
   522
      if (!_potential) {
alpar@345
   523
        _potential = new PotentialMap(_graph);
alpar@345
   524
        _local_potential = true;
alpar@345
   525
      }
kpeter@854
   526
      _full_init = false;
kpeter@854
   527
    }
kpeter@854
   528
kpeter@854
   529
    /// \brief Initialize the algorithm and perform Dijkstra.
kpeter@854
   530
    ///
kpeter@854
   531
    /// This function initializes the algorithm and performs a full
kpeter@854
   532
    /// Dijkstra search from the given source node. It makes consecutive
kpeter@854
   533
    /// executions of \ref start() "start(t, k)" faster, since they
kpeter@854
   534
    /// have to perform %Dijkstra only k-1 times.
kpeter@854
   535
    ///
kpeter@854
   536
    /// This initialization is usually worth using instead of \ref init()
kpeter@854
   537
    /// if the algorithm is executed many times using the same source node.
kpeter@854
   538
    ///
kpeter@854
   539
    /// \param s The source node.
kpeter@854
   540
    void fullInit(const Node& s) {
kpeter@854
   541
      // Initialize maps
kpeter@854
   542
      init(s);
kpeter@854
   543
      if (!_init_dist) {
kpeter@854
   544
        _init_dist = new PotentialMap(_graph);
kpeter@854
   545
      }
kpeter@854
   546
      if (!_init_pred) {
kpeter@854
   547
        _init_pred = new PredMap(_graph);
kpeter@854
   548
      }
kpeter@854
   549
kpeter@854
   550
      // Run a full Dijkstra
kpeter@854
   551
      typename Dijkstra<Digraph, LengthMap>
kpeter@854
   552
        ::template SetStandardHeap<Heap>
kpeter@854
   553
        ::template SetDistMap<PotentialMap>
kpeter@854
   554
        ::template SetPredMap<PredMap>
kpeter@854
   555
        ::Create dijk(_graph, _length);
kpeter@854
   556
      dijk.distMap(*_init_dist).predMap(*_init_pred);
kpeter@854
   557
      dijk.run(s);
alpar@877
   558
kpeter@854
   559
      _full_init = true;
kpeter@854
   560
    }
kpeter@854
   561
kpeter@854
   562
    /// \brief Execute the algorithm.
kpeter@854
   563
    ///
kpeter@854
   564
    /// This function executes the algorithm.
kpeter@854
   565
    ///
kpeter@854
   566
    /// \param t The target node.
kpeter@854
   567
    /// \param k The number of paths to be found.
kpeter@854
   568
    ///
kpeter@854
   569
    /// \return \c k if there are at least \c k arc-disjoint paths from
kpeter@854
   570
    /// \c s to \c t in the digraph. Otherwise it returns the number of
kpeter@854
   571
    /// arc-disjoint paths found.
kpeter@854
   572
    ///
kpeter@854
   573
    /// \note Apart from the return value, <tt>s.start(t, k)</tt> is
kpeter@854
   574
    /// just a shortcut of the following code.
kpeter@854
   575
    /// \code
kpeter@854
   576
    ///   s.findFlow(t, k);
kpeter@854
   577
    ///   s.findPaths();
kpeter@854
   578
    /// \endcode
kpeter@854
   579
    int start(const Node& t, int k = 2) {
kpeter@854
   580
      findFlow(t, k);
kpeter@854
   581
      findPaths();
kpeter@854
   582
      return _path_num;
alpar@345
   583
    }
alpar@345
   584
kpeter@623
   585
    /// \brief Execute the algorithm to find an optimal flow.
alpar@345
   586
    ///
kpeter@346
   587
    /// This function executes the successive shortest path algorithm to
kpeter@623
   588
    /// find a minimum cost flow, which is the union of \c k (or less)
alpar@345
   589
    /// arc-disjoint paths.
alpar@345
   590
    ///
kpeter@623
   591
    /// \param t The target node.
kpeter@623
   592
    /// \param k The number of paths to be found.
kpeter@623
   593
    ///
kpeter@346
   594
    /// \return \c k if there are at least \c k arc-disjoint paths from
kpeter@623
   595
    /// the source node to the given node \c t in the digraph.
kpeter@623
   596
    /// Otherwise it returns the number of arc-disjoint paths found.
alpar@345
   597
    ///
alpar@345
   598
    /// \pre \ref init() must be called before using this function.
kpeter@623
   599
    int findFlow(const Node& t, int k = 2) {
kpeter@853
   600
      _t = t;
kpeter@853
   601
      ResidualDijkstra dijkstra(*this);
alpar@877
   602
kpeter@854
   603
      // Initialization
kpeter@854
   604
      for (ArcIt e(_graph); e != INVALID; ++e) {
kpeter@854
   605
        (*_flow)[e] = 0;
kpeter@854
   606
      }
kpeter@854
   607
      if (_full_init) {
kpeter@854
   608
        for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@854
   609
          (*_potential)[n] = (*_init_dist)[n];
kpeter@854
   610
        }
kpeter@854
   611
        Node u = _t;
kpeter@854
   612
        Arc e;
kpeter@854
   613
        while ((e = (*_init_pred)[u]) != INVALID) {
kpeter@854
   614
          (*_flow)[e] = 1;
kpeter@854
   615
          u = _graph.source(e);
alpar@877
   616
        }
kpeter@854
   617
        _path_num = 1;
kpeter@854
   618
      } else {
kpeter@854
   619
        for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@854
   620
          (*_potential)[n] = 0;
kpeter@854
   621
        }
kpeter@854
   622
        _path_num = 0;
kpeter@854
   623
      }
kpeter@623
   624
kpeter@346
   625
      // Find shortest paths
alpar@345
   626
      while (_path_num < k) {
kpeter@346
   627
        // Run Dijkstra
kpeter@853
   628
        if (!dijkstra.run(_path_num)) break;
alpar@345
   629
        ++_path_num;
alpar@345
   630
kpeter@346
   631
        // Set the flow along the found shortest path
kpeter@853
   632
        Node u = _t;
alpar@345
   633
        Arc e;
alpar@345
   634
        while ((e = _pred[u]) != INVALID) {
alpar@345
   635
          if (u == _graph.target(e)) {
alpar@345
   636
            (*_flow)[e] = 1;
alpar@345
   637
            u = _graph.source(e);
alpar@345
   638
          } else {
alpar@345
   639
            (*_flow)[e] = 0;
alpar@345
   640
            u = _graph.target(e);
alpar@345
   641
          }
alpar@345
   642
        }
alpar@345
   643
      }
alpar@345
   644
      return _path_num;
alpar@345
   645
    }
alpar@440
   646
kpeter@346
   647
    /// \brief Compute the paths from the flow.
alpar@345
   648
    ///
kpeter@853
   649
    /// This function computes arc-disjoint paths from the found minimum
kpeter@853
   650
    /// cost flow, which is the union of them.
alpar@345
   651
    ///
alpar@345
   652
    /// \pre \ref init() and \ref findFlow() must be called before using
alpar@345
   653
    /// this function.
alpar@345
   654
    void findPaths() {
alpar@345
   655
      FlowMap res_flow(_graph);
kpeter@346
   656
      for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
alpar@345
   657
kpeter@853
   658
      _paths.clear();
kpeter@853
   659
      _paths.resize(_path_num);
alpar@345
   660
      for (int i = 0; i < _path_num; ++i) {
kpeter@853
   661
        Node n = _s;
kpeter@853
   662
        while (n != _t) {
alpar@345
   663
          OutArcIt e(_graph, n);
alpar@345
   664
          for ( ; res_flow[e] == 0; ++e) ;
alpar@345
   665
          n = _graph.target(e);
kpeter@853
   666
          _paths[i].addBack(e);
alpar@345
   667
          res_flow[e] = 0;
alpar@345
   668
        }
alpar@345
   669
      }
alpar@345
   670
    }
alpar@345
   671
alpar@345
   672
    /// @}
alpar@345
   673
alpar@345
   674
    /// \name Query Functions
kpeter@346
   675
    /// The results of the algorithm can be obtained using these
alpar@345
   676
    /// functions.
alpar@345
   677
    /// \n The algorithm should be executed before using them.
alpar@345
   678
alpar@345
   679
    /// @{
alpar@345
   680
kpeter@623
   681
    /// \brief Return the total length of the found paths.
kpeter@623
   682
    ///
kpeter@623
   683
    /// This function returns the total length of the found paths, i.e.
kpeter@623
   684
    /// the total cost of the found flow.
kpeter@623
   685
    /// The complexity of the function is O(e).
kpeter@623
   686
    ///
kpeter@623
   687
    /// \pre \ref run() or \ref findFlow() must be called before using
kpeter@623
   688
    /// this function.
kpeter@623
   689
    Length totalLength() const {
kpeter@623
   690
      Length c = 0;
kpeter@623
   691
      for (ArcIt e(_graph); e != INVALID; ++e)
kpeter@623
   692
        c += (*_flow)[e] * _length[e];
kpeter@623
   693
      return c;
kpeter@623
   694
    }
kpeter@623
   695
kpeter@623
   696
    /// \brief Return the flow value on the given arc.
kpeter@623
   697
    ///
kpeter@623
   698
    /// This function returns the flow value on the given arc.
kpeter@623
   699
    /// It is \c 1 if the arc is involved in one of the found arc-disjoint
kpeter@623
   700
    /// paths, otherwise it is \c 0.
kpeter@623
   701
    ///
kpeter@623
   702
    /// \pre \ref run() or \ref findFlow() must be called before using
kpeter@623
   703
    /// this function.
kpeter@623
   704
    int flow(const Arc& arc) const {
kpeter@623
   705
      return (*_flow)[arc];
kpeter@623
   706
    }
kpeter@623
   707
kpeter@623
   708
    /// \brief Return a const reference to an arc map storing the
alpar@345
   709
    /// found flow.
alpar@345
   710
    ///
kpeter@623
   711
    /// This function returns a const reference to an arc map storing
kpeter@346
   712
    /// the flow that is the union of the found arc-disjoint paths.
alpar@345
   713
    ///
kpeter@346
   714
    /// \pre \ref run() or \ref findFlow() must be called before using
kpeter@346
   715
    /// this function.
alpar@345
   716
    const FlowMap& flowMap() const {
alpar@345
   717
      return *_flow;
alpar@345
   718
    }
alpar@345
   719
kpeter@346
   720
    /// \brief Return the potential of the given node.
alpar@345
   721
    ///
kpeter@346
   722
    /// This function returns the potential of the given node.
kpeter@623
   723
    /// The node potentials provide the dual solution of the
kpeter@623
   724
    /// underlying \ref min_cost_flow "minimum cost flow problem".
alpar@345
   725
    ///
kpeter@346
   726
    /// \pre \ref run() or \ref findFlow() must be called before using
kpeter@346
   727
    /// this function.
alpar@345
   728
    Length potential(const Node& node) const {
alpar@345
   729
      return (*_potential)[node];
alpar@345
   730
    }
alpar@345
   731
kpeter@623
   732
    /// \brief Return a const reference to a node map storing the
kpeter@623
   733
    /// found potentials (the dual solution).
alpar@345
   734
    ///
kpeter@623
   735
    /// This function returns a const reference to a node map storing
kpeter@623
   736
    /// the found potentials that provide the dual solution of the
kpeter@623
   737
    /// underlying \ref min_cost_flow "minimum cost flow problem".
alpar@345
   738
    ///
kpeter@346
   739
    /// \pre \ref run() or \ref findFlow() must be called before using
kpeter@346
   740
    /// this function.
kpeter@623
   741
    const PotentialMap& potentialMap() const {
kpeter@623
   742
      return *_potential;
alpar@345
   743
    }
alpar@345
   744
kpeter@346
   745
    /// \brief Return the number of the found paths.
alpar@345
   746
    ///
kpeter@346
   747
    /// This function returns the number of the found paths.
alpar@345
   748
    ///
kpeter@346
   749
    /// \pre \ref run() or \ref findFlow() must be called before using
kpeter@346
   750
    /// this function.
alpar@345
   751
    int pathNum() const {
alpar@345
   752
      return _path_num;
alpar@345
   753
    }
alpar@345
   754
kpeter@346
   755
    /// \brief Return a const reference to the specified path.
alpar@345
   756
    ///
kpeter@346
   757
    /// This function returns a const reference to the specified path.
alpar@345
   758
    ///
kpeter@623
   759
    /// \param i The function returns the <tt>i</tt>-th path.
alpar@345
   760
    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
alpar@345
   761
    ///
kpeter@346
   762
    /// \pre \ref run() or \ref findPaths() must be called before using
kpeter@346
   763
    /// this function.
kpeter@851
   764
    const Path& path(int i) const {
kpeter@853
   765
      return _paths[i];
alpar@345
   766
    }
alpar@345
   767
alpar@345
   768
    /// @}
alpar@345
   769
alpar@345
   770
  }; //class Suurballe
alpar@345
   771
alpar@345
   772
  ///@}
alpar@345
   773
alpar@345
   774
} //namespace lemon
alpar@345
   775
alpar@345
   776
#endif //LEMON_SUURBALLE_H