lemon/bipartite_matching.h
author deba
Fri, 07 Apr 2006 09:51:23 +0000
changeset 2040 c7bd55c0d820
child 2051 08652c1763f6
permissions -rw-r--r--
Bipartite Graph Max Cardinality Matching (Hopcroft-Karp)
Test for it

Some BpUgraph improvments
deba@2040
     1
/* -*- C++ -*-
deba@2040
     2
 *
deba@2040
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2040
     4
 *
deba@2040
     5
 * Copyright (C) 2003-2006
deba@2040
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2040
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2040
     8
 *
deba@2040
     9
 * Permission to use, modify and distribute this software is granted
deba@2040
    10
 * provided that this copyright notice appears in all copies. For
deba@2040
    11
 * precise terms see the accompanying LICENSE file.
deba@2040
    12
 *
deba@2040
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2040
    14
 * express or implied, and with no claim as to its suitability for any
deba@2040
    15
 * purpose.
deba@2040
    16
 *
deba@2040
    17
 */
deba@2040
    18
deba@2040
    19
#ifndef LEMON_BIPARTITE_MATCHING
deba@2040
    20
#define LEMON_BIPARTITE_MATCHING
deba@2040
    21
deba@2040
    22
#include <lemon/bpugraph_adaptor.h>
deba@2040
    23
#include <lemon/bfs.h>
deba@2040
    24
deba@2040
    25
#include <iostream>
deba@2040
    26
deba@2040
    27
///\ingroup matching
deba@2040
    28
///\file
deba@2040
    29
///\brief Maximum matching algorithms in bipartite graphs.
deba@2040
    30
deba@2040
    31
namespace lemon {
deba@2040
    32
deba@2040
    33
  /// \ingroup matching
deba@2040
    34
  ///
deba@2040
    35
  /// \brief Bipartite Max Cardinality Matching algorithm
deba@2040
    36
  ///
deba@2040
    37
  /// Bipartite Max Cardinality Matching algorithm. This class implements
deba@2040
    38
  /// the Hopcroft-Karp algorithm wich has \f$ O(e\sqrt{n}) \f$ time
deba@2040
    39
  /// complexity.
deba@2040
    40
  template <typename BpUGraph>
deba@2040
    41
  class MaxBipartiteMatching {
deba@2040
    42
  protected:
deba@2040
    43
deba@2040
    44
    typedef BpUGraph Graph;
deba@2040
    45
deba@2040
    46
    typedef typename Graph::Node Node;
deba@2040
    47
    typedef typename Graph::ANodeIt ANodeIt;
deba@2040
    48
    typedef typename Graph::BNodeIt BNodeIt;
deba@2040
    49
    typedef typename Graph::UEdge UEdge;
deba@2040
    50
    typedef typename Graph::UEdgeIt UEdgeIt;
deba@2040
    51
    typedef typename Graph::IncEdgeIt IncEdgeIt;
deba@2040
    52
deba@2040
    53
    typedef typename BpUGraph::template ANodeMap<UEdge> ANodeMatchingMap;
deba@2040
    54
    typedef typename BpUGraph::template BNodeMap<UEdge> BNodeMatchingMap;
deba@2040
    55
deba@2040
    56
deba@2040
    57
  public:
deba@2040
    58
deba@2040
    59
    /// \brief Constructor.
deba@2040
    60
    ///
deba@2040
    61
    /// Constructor of the algorithm. 
deba@2040
    62
    MaxBipartiteMatching(const BpUGraph& _graph) 
deba@2040
    63
      : anode_matching(_graph), bnode_matching(_graph), graph(&_graph) {}
deba@2040
    64
deba@2040
    65
    /// \name Execution control
deba@2040
    66
    /// The simplest way to execute the algorithm is to use
deba@2040
    67
    /// one of the member functions called \c run().
deba@2040
    68
    /// \n
deba@2040
    69
    /// If you need more control on the execution,
deba@2040
    70
    /// first you must call \ref init() or one alternative for it.
deba@2040
    71
    /// Finally \ref start() will perform the matching computation or
deba@2040
    72
    /// with step-by-step execution you can augment the solution.
deba@2040
    73
deba@2040
    74
    /// @{
deba@2040
    75
deba@2040
    76
    /// \brief Initalize the data structures.
deba@2040
    77
    ///
deba@2040
    78
    /// It initalizes the data structures and creates an empty matching.
deba@2040
    79
    void init() {
deba@2040
    80
      for (ANodeIt it(*graph); it != INVALID; ++it) {
deba@2040
    81
        anode_matching[it] = INVALID;
deba@2040
    82
      }
deba@2040
    83
      for (BNodeIt it(*graph); it != INVALID; ++it) {
deba@2040
    84
        bnode_matching[it] = INVALID;
deba@2040
    85
      }
deba@2040
    86
      matching_value = 0;
deba@2040
    87
    }
deba@2040
    88
deba@2040
    89
    /// \brief Initalize the data structures.
deba@2040
    90
    ///
deba@2040
    91
    /// It initalizes the data structures and creates a greedy
deba@2040
    92
    /// matching.  From this matching sometimes it is faster to get
deba@2040
    93
    /// the matching than from the initial empty matching.
deba@2040
    94
    void greedyInit() {
deba@2040
    95
      matching_value = 0;
deba@2040
    96
      for (BNodeIt it(*graph); it != INVALID; ++it) {
deba@2040
    97
        bnode_matching[it] = INVALID;
deba@2040
    98
      }
deba@2040
    99
      for (ANodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   100
        anode_matching[it] = INVALID;
deba@2040
   101
        for (IncEdgeIt jt(*graph, it); jt != INVALID; ++jt) {
deba@2040
   102
          if (bnode_matching[graph->bNode(jt)] == INVALID) {
deba@2040
   103
            anode_matching[it] = jt;
deba@2040
   104
            bnode_matching[graph->bNode(jt)] = jt;
deba@2040
   105
            ++matching_value;
deba@2040
   106
            break;
deba@2040
   107
          }
deba@2040
   108
        }
deba@2040
   109
      }
deba@2040
   110
    }
deba@2040
   111
deba@2040
   112
    /// \brief Initalize the data structures with an initial matching.
deba@2040
   113
    ///
deba@2040
   114
    /// It initalizes the data structures with an initial matching.
deba@2040
   115
    template <typename MatchingMap>
deba@2040
   116
    void matchingInit(const MatchingMap& matching) {
deba@2040
   117
      for (ANodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   118
        anode_matching[it] = INVALID;
deba@2040
   119
      }
deba@2040
   120
      for (BNodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   121
        bnode_matching[it] = INVALID;
deba@2040
   122
      }
deba@2040
   123
      matching_value = 0;
deba@2040
   124
      for (UEdgeIt it(*graph); it != INVALID; ++it) {
deba@2040
   125
        if (matching[it]) {
deba@2040
   126
          ++matching_value;
deba@2040
   127
          anode_matching[graph->aNode(it)] = it;
deba@2040
   128
          bnode_matching[graph->bNode(it)] = it;
deba@2040
   129
        }
deba@2040
   130
      }
deba@2040
   131
    }
deba@2040
   132
deba@2040
   133
    /// \brief Initalize the data structures with an initial matching.
deba@2040
   134
    ///
deba@2040
   135
    /// It initalizes the data structures with an initial matching.
deba@2040
   136
    /// \return %True when the given map contains really a matching.
deba@2040
   137
    template <typename MatchingMap>
deba@2040
   138
    void checkedMatchingInit(const MatchingMap& matching) {
deba@2040
   139
      for (ANodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   140
        anode_matching[it] = INVALID;
deba@2040
   141
      }
deba@2040
   142
      for (BNodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   143
        bnode_matching[it] = INVALID;
deba@2040
   144
      }
deba@2040
   145
      matching_value = 0;
deba@2040
   146
      for (UEdgeIt it(*graph); it != INVALID; ++it) {
deba@2040
   147
        if (matching[it]) {
deba@2040
   148
          ++matching_value;
deba@2040
   149
          if (anode_matching[graph->aNode(it)] != INVALID) {
deba@2040
   150
            return false;
deba@2040
   151
          }
deba@2040
   152
          anode_matching[graph->aNode(it)] = it;
deba@2040
   153
          if (bnode_matching[graph->aNode(it)] != INVALID) {
deba@2040
   154
            return false;
deba@2040
   155
          }
deba@2040
   156
          bnode_matching[graph->bNode(it)] = it;
deba@2040
   157
        }
deba@2040
   158
      }
deba@2040
   159
      return false;
deba@2040
   160
    }
deba@2040
   161
deba@2040
   162
    /// \brief An augmenting phase of the Hopcroft-Karp algorithm
deba@2040
   163
    ///
deba@2040
   164
    /// It runs an augmenting phase of the Hopcroft-Karp
deba@2040
   165
    /// algorithm. The phase finds maximum count of edge disjoint
deba@2040
   166
    /// augmenting paths and augments on these paths. The algorithm
deba@2040
   167
    /// consists at most of \f$ O(\sqrt{n}) \f$ phase and one phase is
deba@2040
   168
    /// \f$ O(e) \f$ long.
deba@2040
   169
    bool augment() {
deba@2040
   170
deba@2040
   171
      typename Graph::template ANodeMap<bool> areached(*graph, false);
deba@2040
   172
      typename Graph::template BNodeMap<bool> breached(*graph, false);
deba@2040
   173
deba@2040
   174
      typename Graph::template BNodeMap<UEdge> bpred(*graph, INVALID);
deba@2040
   175
deba@2040
   176
      std::vector<Node> queue, bqueue;
deba@2040
   177
      for (ANodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   178
        if (anode_matching[it] == INVALID) {
deba@2040
   179
          queue.push_back(it);
deba@2040
   180
          areached[it] = true;
deba@2040
   181
        }
deba@2040
   182
      }
deba@2040
   183
deba@2040
   184
      bool success = false;
deba@2040
   185
deba@2040
   186
      while (!success && !queue.empty()) {
deba@2040
   187
        std::vector<Node> newqueue;
deba@2040
   188
        for (int i = 0; i < (int)queue.size(); ++i) {
deba@2040
   189
          Node anode = queue[i];
deba@2040
   190
          for (IncEdgeIt jt(*graph, anode); jt != INVALID; ++jt) {
deba@2040
   191
            Node bnode = graph->bNode(jt);
deba@2040
   192
            if (breached[bnode]) continue;
deba@2040
   193
            breached[bnode] = true;
deba@2040
   194
            bpred[bnode] = jt;
deba@2040
   195
            if (bnode_matching[bnode] == INVALID) {
deba@2040
   196
              bqueue.push_back(bnode);
deba@2040
   197
              success = true;
deba@2040
   198
            } else {           
deba@2040
   199
              Node newanode = graph->aNode(bnode_matching[bnode]);
deba@2040
   200
              if (!areached[newanode]) {
deba@2040
   201
                areached[newanode] = true;
deba@2040
   202
                newqueue.push_back(newanode);
deba@2040
   203
              }
deba@2040
   204
            }
deba@2040
   205
          }
deba@2040
   206
        }
deba@2040
   207
        queue.swap(newqueue);
deba@2040
   208
      }
deba@2040
   209
deba@2040
   210
      if (success) {
deba@2040
   211
deba@2040
   212
        typename Graph::template ANodeMap<bool> aused(*graph, false);
deba@2040
   213
        
deba@2040
   214
        for (int i = 0; i < (int)bqueue.size(); ++i) {
deba@2040
   215
          Node bnode = bqueue[i];
deba@2040
   216
deba@2040
   217
          bool used = false;
deba@2040
   218
deba@2040
   219
          while (bnode != INVALID) {
deba@2040
   220
            UEdge uedge = bpred[bnode];
deba@2040
   221
            Node anode = graph->aNode(uedge);
deba@2040
   222
            
deba@2040
   223
            if (aused[anode]) {
deba@2040
   224
              used = true;
deba@2040
   225
              break;
deba@2040
   226
            }
deba@2040
   227
            
deba@2040
   228
            bnode = anode_matching[anode] != INVALID ? 
deba@2040
   229
              graph->bNode(anode_matching[anode]) : INVALID;
deba@2040
   230
            
deba@2040
   231
          }
deba@2040
   232
          
deba@2040
   233
          if (used) continue;
deba@2040
   234
deba@2040
   235
          bnode = bqueue[i];
deba@2040
   236
          while (bnode != INVALID) {
deba@2040
   237
            UEdge uedge = bpred[bnode];
deba@2040
   238
            Node anode = graph->aNode(uedge);
deba@2040
   239
            
deba@2040
   240
            bnode_matching[bnode] = uedge;
deba@2040
   241
deba@2040
   242
            bnode = anode_matching[anode] != INVALID ? 
deba@2040
   243
              graph->bNode(anode_matching[anode]) : INVALID;
deba@2040
   244
            
deba@2040
   245
            anode_matching[anode] = uedge;
deba@2040
   246
deba@2040
   247
            aused[anode] = true;
deba@2040
   248
          }
deba@2040
   249
          ++matching_value;
deba@2040
   250
deba@2040
   251
        }
deba@2040
   252
      }
deba@2040
   253
      return success;
deba@2040
   254
    }
deba@2040
   255
deba@2040
   256
    /// \brief An augmenting phase of the Ford-Fulkerson algorithm
deba@2040
   257
    ///
deba@2040
   258
    /// It runs an augmenting phase of the Ford-Fulkerson
deba@2040
   259
    /// algorithm. The phase finds only one augmenting path and 
deba@2040
   260
    /// augments only on this paths. The algorithm consists at most 
deba@2040
   261
    /// of \f$ O(n) \f$ simple phase and one phase is at most 
deba@2040
   262
    /// \f$ O(e) \f$ long.
deba@2040
   263
    bool simpleAugment() {
deba@2040
   264
deba@2040
   265
      typename Graph::template ANodeMap<bool> areached(*graph, false);
deba@2040
   266
      typename Graph::template BNodeMap<bool> breached(*graph, false);
deba@2040
   267
deba@2040
   268
      typename Graph::template BNodeMap<UEdge> bpred(*graph, INVALID);
deba@2040
   269
deba@2040
   270
      std::vector<Node> queue;
deba@2040
   271
      for (ANodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   272
        if (anode_matching[it] == INVALID) {
deba@2040
   273
          queue.push_back(it);
deba@2040
   274
          areached[it] = true;
deba@2040
   275
        }
deba@2040
   276
      }
deba@2040
   277
deba@2040
   278
      while (!queue.empty()) {
deba@2040
   279
        std::vector<Node> newqueue;
deba@2040
   280
        for (int i = 0; i < (int)queue.size(); ++i) {
deba@2040
   281
          Node anode = queue[i];
deba@2040
   282
          for (IncEdgeIt jt(*graph, anode); jt != INVALID; ++jt) {
deba@2040
   283
            Node bnode = graph->bNode(jt);
deba@2040
   284
            if (breached[bnode]) continue;
deba@2040
   285
            breached[bnode] = true;
deba@2040
   286
            bpred[bnode] = jt;
deba@2040
   287
            if (bnode_matching[bnode] == INVALID) {
deba@2040
   288
              while (bnode != INVALID) {
deba@2040
   289
                UEdge uedge = bpred[bnode];
deba@2040
   290
                anode = graph->aNode(uedge);
deba@2040
   291
                
deba@2040
   292
                bnode_matching[bnode] = uedge;
deba@2040
   293
                
deba@2040
   294
                bnode = anode_matching[anode] != INVALID ? 
deba@2040
   295
                  graph->bNode(anode_matching[anode]) : INVALID;
deba@2040
   296
                
deba@2040
   297
                anode_matching[anode] = uedge;
deba@2040
   298
                
deba@2040
   299
              }
deba@2040
   300
              ++matching_value;
deba@2040
   301
              return true;
deba@2040
   302
            } else {           
deba@2040
   303
              Node newanode = graph->aNode(bnode_matching[bnode]);
deba@2040
   304
              if (!areached[newanode]) {
deba@2040
   305
                areached[newanode] = true;
deba@2040
   306
                newqueue.push_back(newanode);
deba@2040
   307
              }
deba@2040
   308
            }
deba@2040
   309
          }
deba@2040
   310
        }
deba@2040
   311
        queue.swap(newqueue);
deba@2040
   312
      }
deba@2040
   313
      
deba@2040
   314
      return false;
deba@2040
   315
    }
deba@2040
   316
deba@2040
   317
    /// \brief Starts the algorithm.
deba@2040
   318
    ///
deba@2040
   319
    /// Starts the algorithm. It runs augmenting phases until the optimal
deba@2040
   320
    /// solution reached.
deba@2040
   321
    void start() {
deba@2040
   322
      while (augment()) {}
deba@2040
   323
    }
deba@2040
   324
deba@2040
   325
    /// \brief Runs the algorithm.
deba@2040
   326
    ///
deba@2040
   327
    /// It just initalize the algorithm and then start it.
deba@2040
   328
    void run() {
deba@2040
   329
      init();
deba@2040
   330
      start();
deba@2040
   331
    }
deba@2040
   332
deba@2040
   333
    /// @}
deba@2040
   334
deba@2040
   335
    /// \name Query Functions
deba@2040
   336
    /// The result of the %Matching algorithm can be obtained using these
deba@2040
   337
    /// functions.\n
deba@2040
   338
    /// Before the use of these functions,
deba@2040
   339
    /// either run() or start() must be called.
deba@2040
   340
    
deba@2040
   341
    ///@{
deba@2040
   342
deba@2040
   343
    /// \brief Returns an minimum covering of the nodes.
deba@2040
   344
    ///
deba@2040
   345
    /// The minimum covering set problem is the dual solution of the
deba@2040
   346
    /// maximum bipartite matching. It provides an solution for this
deba@2040
   347
    /// problem what is proof of the optimality of the matching.
deba@2040
   348
    /// \return The size of the cover set.
deba@2040
   349
    template <typename CoverMap>
deba@2040
   350
    int coverSet(CoverMap& covering) {
deba@2040
   351
deba@2040
   352
      typename Graph::template ANodeMap<bool> areached(*graph, false);
deba@2040
   353
      typename Graph::template BNodeMap<bool> breached(*graph, false);
deba@2040
   354
      
deba@2040
   355
      std::vector<Node> queue;
deba@2040
   356
      for (ANodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   357
        if (anode_matching[it] == INVALID) {
deba@2040
   358
          queue.push_back(it);
deba@2040
   359
        }
deba@2040
   360
      }
deba@2040
   361
deba@2040
   362
      while (!queue.empty()) {
deba@2040
   363
        std::vector<Node> newqueue;
deba@2040
   364
        for (int i = 0; i < (int)queue.size(); ++i) {
deba@2040
   365
          Node anode = queue[i];
deba@2040
   366
          for (IncEdgeIt jt(*graph, anode); jt != INVALID; ++jt) {
deba@2040
   367
            Node bnode = graph->bNode(jt);
deba@2040
   368
            if (breached[bnode]) continue;
deba@2040
   369
            breached[bnode] = true;
deba@2040
   370
            if (bnode_matching[bnode] != INVALID) {
deba@2040
   371
              Node newanode = graph->aNode(bnode_matching[bnode]);
deba@2040
   372
              if (!areached[newanode]) {
deba@2040
   373
                areached[newanode] = true;
deba@2040
   374
                newqueue.push_back(newanode);
deba@2040
   375
              }
deba@2040
   376
            }
deba@2040
   377
          }
deba@2040
   378
        }
deba@2040
   379
        queue.swap(newqueue);
deba@2040
   380
      }
deba@2040
   381
deba@2040
   382
      int size = 0;
deba@2040
   383
      for (ANodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   384
        covering[it] = !areached[it] && anode_matching[it] != INVALID;
deba@2040
   385
        if (!areached[it] && anode_matching[it] != INVALID) {
deba@2040
   386
          ++size;
deba@2040
   387
        }
deba@2040
   388
      }
deba@2040
   389
      for (BNodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   390
        covering[it] = breached[it];
deba@2040
   391
        if (breached[it]) {
deba@2040
   392
          ++size;
deba@2040
   393
        }
deba@2040
   394
      }
deba@2040
   395
      return size;
deba@2040
   396
    }
deba@2040
   397
deba@2040
   398
    /// \brief Set true all matching uedge in the map.
deba@2040
   399
    /// 
deba@2040
   400
    /// Set true all matching uedge in the map. It does not change the
deba@2040
   401
    /// value mapped to the other uedges.
deba@2040
   402
    /// \return The number of the matching edges.
deba@2040
   403
    template <typename MatchingMap>
deba@2040
   404
    int quickMatching(MatchingMap& matching) {
deba@2040
   405
      for (ANodeIt it(*graph); it != INVALID; ++it) {
deba@2040
   406
        if (anode_matching[it] != INVALID) {
deba@2040
   407
          matching[anode_matching[it]] = true;
deba@2040
   408
        }
deba@2040
   409
      }
deba@2040
   410
      return matching_value;
deba@2040
   411
    }
deba@2040
   412
deba@2040
   413
    /// \brief Set true all matching uedge in the map and the others to false.
deba@2040
   414
    /// 
deba@2040
   415
    /// Set true all matching uedge in the map and the others to false.
deba@2040
   416
    /// \return The number of the matching edges.
deba@2040
   417
    template <typename MatchingMap>
deba@2040
   418
    int matching(MatchingMap& matching) {
deba@2040
   419
      for (UEdgeIt it(*graph); it != INVALID; ++it) {
deba@2040
   420
        matching[it] = it == anode_matching[graph->aNode(it)];
deba@2040
   421
      }
deba@2040
   422
      return matching_value;
deba@2040
   423
    }
deba@2040
   424
deba@2040
   425
deba@2040
   426
    /// \brief Return true if the given uedge is in the matching.
deba@2040
   427
    /// 
deba@2040
   428
    /// It returns true if the given uedge is in the matching.
deba@2040
   429
    bool matchingEdge(const UEdge& edge) {
deba@2040
   430
      return anode_matching[graph->aNode(edge)] == edge;
deba@2040
   431
    }
deba@2040
   432
deba@2040
   433
    /// \brief Returns the matching edge from the node.
deba@2040
   434
    /// 
deba@2040
   435
    /// Returns the matching edge from the node. If there is not such
deba@2040
   436
    /// edge it gives back \c INVALID.
deba@2040
   437
    UEdge matchingEdge(const Node& node) {
deba@2040
   438
      if (graph->aNode(node)) {
deba@2040
   439
        return anode_matching[node];
deba@2040
   440
      } else {
deba@2040
   441
        return bnode_matching[node];
deba@2040
   442
      }
deba@2040
   443
    }
deba@2040
   444
deba@2040
   445
    /// \brief Gives back the number of the matching edges.
deba@2040
   446
    ///
deba@2040
   447
    /// Gives back the number of the matching edges.
deba@2040
   448
    int matchingValue() const {
deba@2040
   449
      return matching_value;
deba@2040
   450
    }
deba@2040
   451
deba@2040
   452
    /// @}
deba@2040
   453
deba@2040
   454
  private:
deba@2040
   455
deba@2040
   456
    ANodeMatchingMap anode_matching;
deba@2040
   457
    BNodeMatchingMap bnode_matching;
deba@2040
   458
    const Graph *graph;
deba@2040
   459
deba@2040
   460
    int matching_value;
deba@2040
   461
  
deba@2040
   462
  };
deba@2040
   463
deba@2040
   464
}
deba@2040
   465
deba@2040
   466
#endif