lemon/nagamochi_ibaraki.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
child 978 eb252f805431
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.
deba@913
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@913
     2
 *
deba@913
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@913
     4
 *
deba@913
     5
 * Copyright (C) 2003-2010
deba@913
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@913
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@913
     8
 *
deba@913
     9
 * Permission to use, modify and distribute this software is granted
deba@913
    10
 * provided that this copyright notice appears in all copies. For
deba@913
    11
 * precise terms see the accompanying LICENSE file.
deba@913
    12
 *
deba@913
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@913
    14
 * express or implied, and with no claim as to its suitability for any
deba@913
    15
 * purpose.
deba@913
    16
 *
deba@913
    17
 */
deba@913
    18
deba@913
    19
#ifndef LEMON_NAGAMOCHI_IBARAKI_H
deba@913
    20
#define LEMON_NAGAMOCHI_IBARAKI_H
deba@913
    21
deba@913
    22
deba@913
    23
/// \ingroup min_cut
deba@913
    24
/// \file
deba@913
    25
/// \brief Implementation of the Nagamochi-Ibaraki algorithm.
deba@913
    26
deba@913
    27
#include <lemon/core.h>
deba@913
    28
#include <lemon/bin_heap.h>
deba@913
    29
#include <lemon/bucket_heap.h>
deba@913
    30
#include <lemon/maps.h>
deba@913
    31
#include <lemon/radix_sort.h>
deba@913
    32
#include <lemon/unionfind.h>
deba@913
    33
deba@913
    34
#include <cassert>
deba@913
    35
deba@913
    36
namespace lemon {
deba@913
    37
deba@913
    38
  /// \brief Default traits class for NagamochiIbaraki class.
deba@913
    39
  ///
deba@913
    40
  /// Default traits class for NagamochiIbaraki class.
deba@913
    41
  /// \param GR The undirected graph type.
deba@913
    42
  /// \param CM Type of capacity map.
deba@913
    43
  template <typename GR, typename CM>
deba@913
    44
  struct NagamochiIbarakiDefaultTraits {
deba@913
    45
    /// The type of the capacity map.
deba@913
    46
    typedef typename CM::Value Value;
deba@913
    47
deba@913
    48
    /// The undirected graph type the algorithm runs on.
deba@913
    49
    typedef GR Graph;
deba@913
    50
deba@913
    51
    /// \brief The type of the map that stores the edge capacities.
deba@913
    52
    ///
deba@913
    53
    /// The type of the map that stores the edge capacities.
deba@913
    54
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
deba@913
    55
    typedef CM CapacityMap;
deba@913
    56
deba@913
    57
    /// \brief Instantiates a CapacityMap.
deba@913
    58
    ///
deba@913
    59
    /// This function instantiates a \ref CapacityMap.
deba@913
    60
#ifdef DOXYGEN
deba@913
    61
    static CapacityMap *createCapacityMap(const Graph& graph)
deba@913
    62
#else
deba@913
    63
    static CapacityMap *createCapacityMap(const Graph&)
deba@913
    64
#endif
deba@913
    65
    {
deba@913
    66
        LEMON_ASSERT(false, "CapacityMap is not initialized");
deba@913
    67
        return 0; // ignore warnings
deba@913
    68
    }
deba@913
    69
deba@913
    70
    /// \brief The cross reference type used by heap.
deba@913
    71
    ///
deba@913
    72
    /// The cross reference type used by heap.
deba@913
    73
    /// Usually \c Graph::NodeMap<int>.
deba@913
    74
    typedef typename Graph::template NodeMap<int> HeapCrossRef;
deba@913
    75
deba@913
    76
    /// \brief Instantiates a HeapCrossRef.
deba@913
    77
    ///
deba@913
    78
    /// This function instantiates a \ref HeapCrossRef.
deba@913
    79
    /// \param g is the graph, to which we would like to define the
deba@913
    80
    /// \ref HeapCrossRef.
deba@913
    81
    static HeapCrossRef *createHeapCrossRef(const Graph& g) {
deba@913
    82
      return new HeapCrossRef(g);
deba@913
    83
    }
deba@913
    84
deba@913
    85
    /// \brief The heap type used by NagamochiIbaraki algorithm.
deba@913
    86
    ///
deba@913
    87
    /// The heap type used by NagamochiIbaraki algorithm. It has to
deba@913
    88
    /// maximize the priorities.
deba@913
    89
    ///
deba@913
    90
    /// \sa BinHeap
deba@913
    91
    /// \sa NagamochiIbaraki
deba@913
    92
    typedef BinHeap<Value, HeapCrossRef, std::greater<Value> > Heap;
deba@913
    93
deba@913
    94
    /// \brief Instantiates a Heap.
deba@913
    95
    ///
deba@913
    96
    /// This function instantiates a \ref Heap.
deba@913
    97
    /// \param r is the cross reference of the heap.
deba@913
    98
    static Heap *createHeap(HeapCrossRef& r) {
deba@913
    99
      return new Heap(r);
deba@913
   100
    }
deba@913
   101
  };
deba@913
   102
deba@913
   103
  /// \ingroup min_cut
deba@913
   104
  ///
deba@913
   105
  /// \brief Calculates the minimum cut in an undirected graph.
deba@913
   106
  ///
deba@913
   107
  /// Calculates the minimum cut in an undirected graph with the
deba@913
   108
  /// Nagamochi-Ibaraki algorithm. The algorithm separates the graph's
deba@913
   109
  /// nodes into two partitions with the minimum sum of edge capacities
deba@913
   110
  /// between the two partitions. The algorithm can be used to test
deba@913
   111
  /// the network reliability, especially to test how many links have
deba@913
   112
  /// to be destroyed in the network to split it to at least two
deba@913
   113
  /// distinict subnetworks.
deba@913
   114
  ///
deba@913
   115
  /// The complexity of the algorithm is \f$ O(nm\log(n)) \f$ but with
deba@913
   116
  /// \ref FibHeap "Fibonacci heap" it can be decreased to
deba@913
   117
  /// \f$ O(nm+n^2\log(n)) \f$.  When the edges have unit capacities,
deba@913
   118
  /// \c BucketHeap can be used which yields \f$ O(nm) \f$ time
deba@913
   119
  /// complexity.
deba@913
   120
  ///
deba@913
   121
  /// \warning The value type of the capacity map should be able to
deba@913
   122
  /// hold any cut value of the graph, otherwise the result can
deba@913
   123
  /// overflow.
deba@913
   124
  /// \note This capacity is supposed to be integer type.
deba@913
   125
#ifdef DOXYGEN
deba@913
   126
  template <typename GR, typename CM, typename TR>
deba@913
   127
#else
deba@913
   128
  template <typename GR,
deba@913
   129
            typename CM = typename GR::template EdgeMap<int>,
deba@913
   130
            typename TR = NagamochiIbarakiDefaultTraits<GR, CM> >
deba@913
   131
#endif
deba@913
   132
  class NagamochiIbaraki {
deba@913
   133
  public:
deba@913
   134
deba@913
   135
    typedef TR Traits;
deba@913
   136
    /// The type of the underlying graph.
deba@913
   137
    typedef typename Traits::Graph Graph;
deba@913
   138
deba@913
   139
    /// The type of the capacity map.
deba@913
   140
    typedef typename Traits::CapacityMap CapacityMap;
deba@913
   141
    /// The value type of the capacity map.
deba@913
   142
    typedef typename Traits::CapacityMap::Value Value;
deba@913
   143
deba@913
   144
    /// The heap type used by the algorithm.
deba@913
   145
    typedef typename Traits::Heap Heap;
deba@913
   146
    /// The cross reference type used for the heap.
deba@913
   147
    typedef typename Traits::HeapCrossRef HeapCrossRef;
deba@913
   148
deba@913
   149
    ///\name Named template parameters
deba@913
   150
deba@913
   151
    ///@{
deba@913
   152
deba@913
   153
    struct SetUnitCapacityTraits : public Traits {
deba@913
   154
      typedef ConstMap<typename Graph::Edge, Const<int, 1> > CapacityMap;
deba@913
   155
      static CapacityMap *createCapacityMap(const Graph&) {
deba@913
   156
        return new CapacityMap();
deba@913
   157
      }
deba@913
   158
    };
deba@913
   159
deba@913
   160
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@913
   161
    /// the capacity map to a constMap<Edge, int, 1>() instance
deba@913
   162
    ///
deba@913
   163
    /// \ref named-templ-param "Named parameter" for setting
deba@913
   164
    /// the capacity map to a constMap<Edge, int, 1>() instance
deba@913
   165
    struct SetUnitCapacity
deba@913
   166
      : public NagamochiIbaraki<Graph, CapacityMap,
deba@913
   167
                                SetUnitCapacityTraits> {
deba@913
   168
      typedef NagamochiIbaraki<Graph, CapacityMap,
deba@913
   169
                               SetUnitCapacityTraits> Create;
deba@913
   170
    };
deba@913
   171
deba@913
   172
deba@913
   173
    template <class H, class CR>
deba@913
   174
    struct SetHeapTraits : public Traits {
deba@913
   175
      typedef CR HeapCrossRef;
deba@913
   176
      typedef H Heap;
deba@913
   177
      static HeapCrossRef *createHeapCrossRef(int num) {
deba@913
   178
        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
deba@913
   179
        return 0; // ignore warnings
deba@913
   180
      }
deba@913
   181
      static Heap *createHeap(HeapCrossRef &) {
deba@913
   182
        LEMON_ASSERT(false, "Heap is not initialized");
deba@913
   183
        return 0; // ignore warnings
deba@913
   184
      }
deba@913
   185
    };
deba@913
   186
deba@913
   187
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@913
   188
    /// heap and cross reference type
deba@913
   189
    ///
deba@913
   190
    /// \ref named-templ-param "Named parameter" for setting heap and
deba@913
   191
    /// cross reference type. The heap has to maximize the priorities.
deba@913
   192
    template <class H, class CR = RangeMap<int> >
deba@913
   193
    struct SetHeap
deba@913
   194
      : public NagamochiIbaraki<Graph, CapacityMap, SetHeapTraits<H, CR> > {
deba@913
   195
      typedef NagamochiIbaraki< Graph, CapacityMap, SetHeapTraits<H, CR> >
deba@913
   196
      Create;
deba@913
   197
    };
deba@913
   198
deba@913
   199
    template <class H, class CR>
deba@913
   200
    struct SetStandardHeapTraits : public Traits {
deba@913
   201
      typedef CR HeapCrossRef;
deba@913
   202
      typedef H Heap;
deba@913
   203
      static HeapCrossRef *createHeapCrossRef(int size) {
deba@913
   204
        return new HeapCrossRef(size);
deba@913
   205
      }
deba@913
   206
      static Heap *createHeap(HeapCrossRef &crossref) {
deba@913
   207
        return new Heap(crossref);
deba@913
   208
      }
deba@913
   209
    };
deba@913
   210
deba@913
   211
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@913
   212
    /// heap and cross reference type with automatic allocation
deba@913
   213
    ///
deba@913
   214
    /// \ref named-templ-param "Named parameter" for setting heap and
deba@913
   215
    /// cross reference type with automatic allocation. They should
deba@913
   216
    /// have standard constructor interfaces to be able to
deba@913
   217
    /// automatically created by the algorithm (i.e. the graph should
deba@913
   218
    /// be passed to the constructor of the cross reference and the
deba@913
   219
    /// cross reference should be passed to the constructor of the
deba@913
   220
    /// heap). However, external heap and cross reference objects
deba@913
   221
    /// could also be passed to the algorithm using the \ref heap()
deba@913
   222
    /// function before calling \ref run() or \ref init(). The heap
deba@913
   223
    /// has to maximize the priorities.
deba@913
   224
    /// \sa SetHeap
deba@913
   225
    template <class H, class CR = RangeMap<int> >
deba@913
   226
    struct SetStandardHeap
deba@913
   227
      : public NagamochiIbaraki<Graph, CapacityMap,
deba@913
   228
                                SetStandardHeapTraits<H, CR> > {
deba@913
   229
      typedef NagamochiIbaraki<Graph, CapacityMap,
deba@913
   230
                               SetStandardHeapTraits<H, CR> > Create;
deba@913
   231
    };
deba@913
   232
deba@913
   233
    ///@}
deba@913
   234
deba@913
   235
deba@913
   236
  private:
deba@913
   237
deba@913
   238
    const Graph &_graph;
deba@913
   239
    const CapacityMap *_capacity;
deba@913
   240
    bool _local_capacity; // unit capacity
deba@913
   241
deba@913
   242
    struct ArcData {
deba@913
   243
      typename Graph::Node target;
deba@913
   244
      int prev, next;
deba@913
   245
    };
deba@913
   246
    struct EdgeData {
deba@913
   247
      Value capacity;
deba@913
   248
      Value cut;
deba@913
   249
    };
deba@913
   250
deba@913
   251
    struct NodeData {
deba@913
   252
      int first_arc;
deba@913
   253
      typename Graph::Node prev, next;
deba@913
   254
      int curr_arc;
deba@913
   255
      typename Graph::Node last_rep;
deba@913
   256
      Value sum;
deba@913
   257
    };
deba@913
   258
deba@913
   259
    typename Graph::template NodeMap<NodeData> *_nodes;
deba@913
   260
    std::vector<ArcData> _arcs;
deba@913
   261
    std::vector<EdgeData> _edges;
deba@913
   262
deba@913
   263
    typename Graph::Node _first_node;
deba@913
   264
    int _node_num;
deba@913
   265
deba@913
   266
    Value _min_cut;
deba@913
   267
deba@913
   268
    HeapCrossRef *_heap_cross_ref;
deba@913
   269
    bool _local_heap_cross_ref;
deba@913
   270
    Heap *_heap;
deba@913
   271
    bool _local_heap;
deba@913
   272
deba@913
   273
    typedef typename Graph::template NodeMap<typename Graph::Node> NodeList;
deba@913
   274
    NodeList *_next_rep;
deba@913
   275
deba@913
   276
    typedef typename Graph::template NodeMap<bool> MinCutMap;
deba@913
   277
    MinCutMap *_cut_map;
deba@913
   278
deba@913
   279
    void createStructures() {
deba@913
   280
      if (!_nodes) {
deba@913
   281
        _nodes = new (typename Graph::template NodeMap<NodeData>)(_graph);
deba@913
   282
      }
deba@913
   283
      if (!_capacity) {
deba@913
   284
        _local_capacity = true;
deba@913
   285
        _capacity = Traits::createCapacityMap(_graph);
deba@913
   286
      }
deba@913
   287
      if (!_heap_cross_ref) {
deba@913
   288
        _local_heap_cross_ref = true;
deba@913
   289
        _heap_cross_ref = Traits::createHeapCrossRef(_graph);
deba@913
   290
      }
deba@913
   291
      if (!_heap) {
deba@913
   292
        _local_heap = true;
deba@913
   293
        _heap = Traits::createHeap(*_heap_cross_ref);
deba@913
   294
      }
deba@913
   295
      if (!_next_rep) {
deba@913
   296
        _next_rep = new NodeList(_graph);
deba@913
   297
      }
deba@913
   298
      if (!_cut_map) {
deba@913
   299
        _cut_map = new MinCutMap(_graph);
deba@913
   300
      }
deba@913
   301
    }
deba@913
   302
deba@913
   303
  public :
deba@913
   304
deba@913
   305
    typedef NagamochiIbaraki Create;
deba@913
   306
deba@913
   307
deba@913
   308
    /// \brief Constructor.
deba@913
   309
    ///
deba@913
   310
    /// \param graph The graph the algorithm runs on.
deba@913
   311
    /// \param capacity The capacity map used by the algorithm.
deba@913
   312
    NagamochiIbaraki(const Graph& graph, const CapacityMap& capacity)
deba@913
   313
      : _graph(graph), _capacity(&capacity), _local_capacity(false),
deba@913
   314
        _nodes(0), _arcs(), _edges(), _min_cut(),
deba@913
   315
        _heap_cross_ref(0), _local_heap_cross_ref(false),
deba@913
   316
        _heap(0), _local_heap(false),
deba@913
   317
        _next_rep(0), _cut_map(0) {}
deba@913
   318
deba@913
   319
    /// \brief Constructor.
deba@913
   320
    ///
deba@913
   321
    /// This constructor can be used only when the Traits class
deba@913
   322
    /// defines how can the local capacity map be instantiated.
deba@913
   323
    /// If the SetUnitCapacity used the algorithm automatically
deba@913
   324
    /// constructs the capacity map.
deba@913
   325
    ///
deba@913
   326
    ///\param graph The graph the algorithm runs on.
deba@913
   327
    NagamochiIbaraki(const Graph& graph)
deba@913
   328
      : _graph(graph), _capacity(0), _local_capacity(false),
deba@913
   329
        _nodes(0), _arcs(), _edges(), _min_cut(),
deba@913
   330
        _heap_cross_ref(0), _local_heap_cross_ref(false),
deba@913
   331
        _heap(0), _local_heap(false),
deba@913
   332
        _next_rep(0), _cut_map(0) {}
deba@913
   333
deba@913
   334
    /// \brief Destructor.
deba@913
   335
    ///
deba@913
   336
    /// Destructor.
deba@913
   337
    ~NagamochiIbaraki() {
deba@913
   338
      if (_local_capacity) delete _capacity;
deba@913
   339
      if (_nodes) delete _nodes;
deba@913
   340
      if (_local_heap) delete _heap;
deba@913
   341
      if (_local_heap_cross_ref) delete _heap_cross_ref;
deba@913
   342
      if (_next_rep) delete _next_rep;
deba@913
   343
      if (_cut_map) delete _cut_map;
deba@913
   344
    }
deba@913
   345
deba@913
   346
    /// \brief Sets the heap and the cross reference used by algorithm.
deba@913
   347
    ///
deba@913
   348
    /// Sets the heap and the cross reference used by algorithm.
deba@913
   349
    /// If you don't use this function before calling \ref run(),
deba@913
   350
    /// it will allocate one. The destuctor deallocates this
deba@913
   351
    /// automatically allocated heap and cross reference, of course.
deba@913
   352
    /// \return <tt> (*this) </tt>
deba@913
   353
    NagamochiIbaraki &heap(Heap& hp, HeapCrossRef &cr)
deba@913
   354
    {
deba@913
   355
      if (_local_heap_cross_ref) {
deba@913
   356
        delete _heap_cross_ref;
deba@913
   357
        _local_heap_cross_ref = false;
deba@913
   358
      }
deba@913
   359
      _heap_cross_ref = &cr;
deba@913
   360
      if (_local_heap) {
deba@913
   361
        delete _heap;
deba@913
   362
        _local_heap = false;
deba@913
   363
      }
deba@913
   364
      _heap = &hp;
deba@913
   365
      return *this;
deba@913
   366
    }
deba@913
   367
deba@913
   368
    /// \name Execution control
deba@913
   369
    /// The simplest way to execute the algorithm is to use
deba@913
   370
    /// one of the member functions called \c run().
deba@913
   371
    /// \n
deba@913
   372
    /// If you need more control on the execution,
deba@913
   373
    /// first you must call \ref init() and then call the start()
deba@913
   374
    /// or proper times the processNextPhase() member functions.
deba@913
   375
deba@913
   376
    ///@{
deba@913
   377
deba@913
   378
    /// \brief Initializes the internal data structures.
deba@913
   379
    ///
deba@913
   380
    /// Initializes the internal data structures.
deba@913
   381
    void init() {
deba@913
   382
      createStructures();
deba@913
   383
deba@913
   384
      int edge_num = countEdges(_graph);
deba@913
   385
      _edges.resize(edge_num);
deba@913
   386
      _arcs.resize(2 * edge_num);
deba@913
   387
deba@913
   388
      typename Graph::Node prev = INVALID;
deba@913
   389
      _node_num = 0;
deba@913
   390
      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
deba@913
   391
        (*_cut_map)[n] = false;
deba@913
   392
        (*_next_rep)[n] = INVALID;
deba@913
   393
        (*_nodes)[n].last_rep = n;
deba@913
   394
        (*_nodes)[n].first_arc = -1;
deba@913
   395
        (*_nodes)[n].curr_arc = -1;
deba@913
   396
        (*_nodes)[n].prev = prev;
deba@913
   397
        if (prev != INVALID) {
deba@913
   398
          (*_nodes)[prev].next = n;
deba@913
   399
        }
deba@913
   400
        (*_nodes)[n].next = INVALID;
deba@913
   401
        (*_nodes)[n].sum = 0;
deba@913
   402
        prev = n;
deba@913
   403
        ++_node_num;
deba@913
   404
      }
deba@913
   405
deba@913
   406
      _first_node = typename Graph::NodeIt(_graph);
deba@913
   407
deba@913
   408
      int index = 0;
deba@913
   409
      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
deba@913
   410
        for (typename Graph::OutArcIt a(_graph, n); a != INVALID; ++a) {
deba@913
   411
          typename Graph::Node m = _graph.target(a);
deba@913
   412
          
deba@913
   413
          if (!(n < m)) continue;
deba@913
   414
deba@913
   415
          (*_nodes)[n].sum += (*_capacity)[a];
deba@913
   416
          (*_nodes)[m].sum += (*_capacity)[a];
deba@913
   417
          
deba@913
   418
          int c = (*_nodes)[m].curr_arc;
deba@913
   419
          if (c != -1 && _arcs[c ^ 1].target == n) {
deba@913
   420
            _edges[c >> 1].capacity += (*_capacity)[a];
deba@913
   421
          } else {
deba@913
   422
            _edges[index].capacity = (*_capacity)[a];
deba@913
   423
            
deba@913
   424
            _arcs[index << 1].prev = -1;
deba@913
   425
            if ((*_nodes)[n].first_arc != -1) {
deba@913
   426
              _arcs[(*_nodes)[n].first_arc].prev = (index << 1);
deba@913
   427
            }
deba@913
   428
            _arcs[index << 1].next = (*_nodes)[n].first_arc;
deba@913
   429
            (*_nodes)[n].first_arc = (index << 1);
deba@913
   430
            _arcs[index << 1].target = m;
deba@913
   431
deba@913
   432
            (*_nodes)[m].curr_arc = (index << 1);
deba@913
   433
            
deba@913
   434
            _arcs[(index << 1) | 1].prev = -1;
deba@913
   435
            if ((*_nodes)[m].first_arc != -1) {
deba@913
   436
              _arcs[(*_nodes)[m].first_arc].prev = ((index << 1) | 1);
deba@913
   437
            }
deba@913
   438
            _arcs[(index << 1) | 1].next = (*_nodes)[m].first_arc;
deba@913
   439
            (*_nodes)[m].first_arc = ((index << 1) | 1);
deba@913
   440
            _arcs[(index << 1) | 1].target = n;
deba@913
   441
            
deba@913
   442
            ++index;
deba@913
   443
          }
deba@913
   444
        }
deba@913
   445
      }
deba@913
   446
deba@913
   447
      typename Graph::Node cut_node = INVALID;
deba@913
   448
      _min_cut = std::numeric_limits<Value>::max();
deba@913
   449
deba@913
   450
      for (typename Graph::Node n = _first_node; 
deba@913
   451
           n != INVALID; n = (*_nodes)[n].next) {
deba@913
   452
        if ((*_nodes)[n].sum < _min_cut) {
deba@913
   453
          cut_node = n;
deba@913
   454
          _min_cut = (*_nodes)[n].sum;
deba@913
   455
        }
deba@913
   456
      }
deba@913
   457
      (*_cut_map)[cut_node] = true;
deba@913
   458
      if (_min_cut == 0) {
deba@913
   459
        _first_node = INVALID;
deba@913
   460
      }
deba@913
   461
    }
deba@913
   462
deba@913
   463
  public:
deba@913
   464
deba@913
   465
    /// \brief Processes the next phase
deba@913
   466
    ///
deba@913
   467
    /// Processes the next phase in the algorithm. It must be called
deba@913
   468
    /// at most one less the number of the nodes in the graph.
deba@913
   469
    ///
deba@913
   470
    ///\return %True when the algorithm finished.
deba@913
   471
    bool processNextPhase() {
deba@913
   472
      if (_first_node == INVALID) return true;
deba@913
   473
deba@913
   474
      _heap->clear();
deba@913
   475
      for (typename Graph::Node n = _first_node; 
deba@913
   476
           n != INVALID; n = (*_nodes)[n].next) {
deba@913
   477
        (*_heap_cross_ref)[n] = Heap::PRE_HEAP;
deba@913
   478
      }
deba@913
   479
deba@913
   480
      std::vector<typename Graph::Node> order;
deba@913
   481
      order.reserve(_node_num);
deba@913
   482
      int sep = 0;
deba@913
   483
deba@913
   484
      Value alpha = 0;
deba@913
   485
      Value pmc = std::numeric_limits<Value>::max();
deba@913
   486
deba@913
   487
      _heap->push(_first_node, static_cast<Value>(0));
deba@913
   488
      while (!_heap->empty()) {
deba@913
   489
        typename Graph::Node n = _heap->top();
deba@913
   490
        Value v = _heap->prio();
deba@913
   491
deba@913
   492
        _heap->pop();
deba@913
   493
        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
deba@913
   494
          switch (_heap->state(_arcs[a].target)) {
deba@913
   495
          case Heap::PRE_HEAP: 
deba@913
   496
            {
deba@913
   497
              Value nv = _edges[a >> 1].capacity;
deba@913
   498
              _heap->push(_arcs[a].target, nv);
deba@913
   499
              _edges[a >> 1].cut = nv;
deba@913
   500
            } break;
deba@913
   501
          case Heap::IN_HEAP:
deba@913
   502
            {
deba@913
   503
              Value nv = _edges[a >> 1].capacity + (*_heap)[_arcs[a].target];
deba@913
   504
              _heap->decrease(_arcs[a].target, nv);
deba@913
   505
              _edges[a >> 1].cut = nv;
deba@913
   506
            } break;
deba@913
   507
          case Heap::POST_HEAP:
deba@913
   508
            break;
deba@913
   509
          }
deba@913
   510
        }
deba@913
   511
deba@913
   512
        alpha += (*_nodes)[n].sum;
deba@913
   513
        alpha -= 2 * v;
deba@913
   514
deba@913
   515
        order.push_back(n);
deba@913
   516
        if (!_heap->empty()) {
deba@913
   517
          if (alpha < pmc) {
deba@913
   518
            pmc = alpha;
deba@913
   519
            sep = order.size();
deba@913
   520
          }
deba@913
   521
        }
deba@913
   522
      }
deba@913
   523
deba@913
   524
      if (static_cast<int>(order.size()) < _node_num) {
deba@913
   525
        _first_node = INVALID;
deba@913
   526
        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
deba@913
   527
          (*_cut_map)[n] = false;
deba@913
   528
        }
deba@913
   529
        for (int i = 0; i < static_cast<int>(order.size()); ++i) {
deba@913
   530
          typename Graph::Node n = order[i];
deba@913
   531
          while (n != INVALID) {
deba@913
   532
            (*_cut_map)[n] = true;
deba@913
   533
            n = (*_next_rep)[n];
deba@913
   534
          }
deba@913
   535
        }
deba@913
   536
        _min_cut = 0;
deba@913
   537
        return true;
deba@913
   538
      }
deba@913
   539
deba@913
   540
      if (pmc < _min_cut) {
deba@913
   541
        for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
deba@913
   542
          (*_cut_map)[n] = false;
deba@913
   543
        }
deba@913
   544
        for (int i = 0; i < sep; ++i) {
deba@913
   545
          typename Graph::Node n = order[i];
deba@913
   546
          while (n != INVALID) {
deba@913
   547
            (*_cut_map)[n] = true;
deba@913
   548
            n = (*_next_rep)[n];
deba@913
   549
          }
deba@913
   550
        }
deba@913
   551
        _min_cut = pmc;
deba@913
   552
      }
deba@913
   553
deba@913
   554
      for (typename Graph::Node n = _first_node;
deba@913
   555
           n != INVALID; n = (*_nodes)[n].next) {
deba@913
   556
        bool merged = false;
deba@913
   557
        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
deba@913
   558
          if (!(_edges[a >> 1].cut < pmc)) {
deba@913
   559
            if (!merged) {
deba@913
   560
              for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) {
deba@913
   561
                (*_nodes)[_arcs[b].target].curr_arc = b;          
deba@913
   562
              }
deba@913
   563
              merged = true;
deba@913
   564
            }
deba@913
   565
            typename Graph::Node m = _arcs[a].target;
deba@913
   566
            int nb = 0;
deba@913
   567
            for (int b = (*_nodes)[m].first_arc; b != -1; b = nb) {
deba@913
   568
              nb = _arcs[b].next;
deba@913
   569
              if ((b ^ a) == 1) continue;
deba@913
   570
              typename Graph::Node o = _arcs[b].target;
deba@913
   571
              int c = (*_nodes)[o].curr_arc; 
deba@913
   572
              if (c != -1 && _arcs[c ^ 1].target == n) {
deba@913
   573
                _edges[c >> 1].capacity += _edges[b >> 1].capacity;
deba@913
   574
                (*_nodes)[n].sum += _edges[b >> 1].capacity;
deba@913
   575
                if (_edges[b >> 1].cut < _edges[c >> 1].cut) {
deba@913
   576
                  _edges[b >> 1].cut = _edges[c >> 1].cut;
deba@913
   577
                }
deba@913
   578
                if (_arcs[b ^ 1].prev != -1) {
deba@913
   579
                  _arcs[_arcs[b ^ 1].prev].next = _arcs[b ^ 1].next;
deba@913
   580
                } else {
deba@913
   581
                  (*_nodes)[o].first_arc = _arcs[b ^ 1].next;
deba@913
   582
                }
deba@913
   583
                if (_arcs[b ^ 1].next != -1) {
deba@913
   584
                  _arcs[_arcs[b ^ 1].next].prev = _arcs[b ^ 1].prev;
deba@913
   585
                }
deba@913
   586
              } else {
deba@913
   587
                if (_arcs[a].next != -1) {
deba@913
   588
                  _arcs[_arcs[a].next].prev = b;
deba@913
   589
                }
deba@913
   590
                _arcs[b].next = _arcs[a].next;
deba@913
   591
                _arcs[b].prev = a;
deba@913
   592
                _arcs[a].next = b;
deba@913
   593
                _arcs[b ^ 1].target = n;
deba@913
   594
deba@913
   595
                (*_nodes)[n].sum += _edges[b >> 1].capacity;
deba@913
   596
                (*_nodes)[o].curr_arc = b;
deba@913
   597
              }
deba@913
   598
            }
deba@913
   599
deba@913
   600
            if (_arcs[a].prev != -1) {
deba@913
   601
              _arcs[_arcs[a].prev].next = _arcs[a].next;
deba@913
   602
            } else {
deba@913
   603
              (*_nodes)[n].first_arc = _arcs[a].next;
deba@913
   604
            }            
deba@913
   605
            if (_arcs[a].next != -1) {
deba@913
   606
              _arcs[_arcs[a].next].prev = _arcs[a].prev;
deba@913
   607
            }
deba@913
   608
deba@913
   609
            (*_nodes)[n].sum -= _edges[a >> 1].capacity;
deba@913
   610
            (*_next_rep)[(*_nodes)[n].last_rep] = m;
deba@913
   611
            (*_nodes)[n].last_rep = (*_nodes)[m].last_rep;
deba@913
   612
            
deba@913
   613
            if ((*_nodes)[m].prev != INVALID) {
deba@913
   614
              (*_nodes)[(*_nodes)[m].prev].next = (*_nodes)[m].next;
deba@913
   615
            } else{
deba@913
   616
              _first_node = (*_nodes)[m].next;
deba@913
   617
            }
deba@913
   618
            if ((*_nodes)[m].next != INVALID) {
deba@913
   619
              (*_nodes)[(*_nodes)[m].next].prev = (*_nodes)[m].prev;
deba@913
   620
            }
deba@913
   621
            --_node_num;
deba@913
   622
          }
deba@913
   623
        }
deba@913
   624
      }
deba@913
   625
deba@913
   626
      if (_node_num == 1) {
deba@913
   627
        _first_node = INVALID;
deba@913
   628
        return true;
deba@913
   629
      }
deba@913
   630
deba@913
   631
      return false;
deba@913
   632
    }
deba@913
   633
deba@913
   634
    /// \brief Executes the algorithm.
deba@913
   635
    ///
deba@913
   636
    /// Executes the algorithm.
deba@913
   637
    ///
deba@913
   638
    /// \pre init() must be called
deba@913
   639
    void start() {
deba@913
   640
      while (!processNextPhase()) {}
deba@913
   641
    }
deba@913
   642
deba@913
   643
deba@913
   644
    /// \brief Runs %NagamochiIbaraki algorithm.
deba@913
   645
    ///
deba@913
   646
    /// This method runs the %Min cut algorithm
deba@913
   647
    ///
deba@913
   648
    /// \note mc.run(s) is just a shortcut of the following code.
deba@913
   649
    ///\code
deba@913
   650
    ///  mc.init();
deba@913
   651
    ///  mc.start();
deba@913
   652
    ///\endcode
deba@913
   653
    void run() {
deba@913
   654
      init();
deba@913
   655
      start();
deba@913
   656
    }
deba@913
   657
deba@913
   658
    ///@}
deba@913
   659
deba@913
   660
    /// \name Query Functions
deba@913
   661
    ///
deba@913
   662
    /// The result of the %NagamochiIbaraki
deba@913
   663
    /// algorithm can be obtained using these functions.\n
deba@913
   664
    /// Before the use of these functions, either run() or start()
deba@913
   665
    /// must be called.
deba@913
   666
deba@913
   667
    ///@{
deba@913
   668
deba@913
   669
    /// \brief Returns the min cut value.
deba@913
   670
    ///
deba@913
   671
    /// Returns the min cut value if the algorithm finished.
deba@913
   672
    /// After the first processNextPhase() it is a value of a
deba@913
   673
    /// valid cut in the graph.
deba@913
   674
    Value minCutValue() const {
deba@913
   675
      return _min_cut;
deba@913
   676
    }
deba@913
   677
deba@913
   678
    /// \brief Returns a min cut in a NodeMap.
deba@913
   679
    ///
deba@913
   680
    /// It sets the nodes of one of the two partitions to true and
deba@913
   681
    /// the other partition to false.
deba@913
   682
    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
deba@913
   683
    /// \c bool (or convertible) value type.
deba@913
   684
    template <typename CutMap>
deba@913
   685
    Value minCutMap(CutMap& cutMap) const {
deba@913
   686
      for (typename Graph::NodeIt n(_graph); n != INVALID; ++n) {
deba@913
   687
        cutMap.set(n, (*_cut_map)[n]);
deba@913
   688
      }
deba@913
   689
      return minCutValue();
deba@913
   690
    }
deba@913
   691
deba@913
   692
    ///@}
deba@913
   693
deba@913
   694
  };
deba@913
   695
}
deba@913
   696
deba@913
   697
#endif