| [1057] | 1 | // -*- C++ -*- | 
|---|
 | 2 | #ifndef LEMON_MAX_MATCHING_H | 
|---|
 | 3 | #define LEMON_MAX_MATCHING_H | 
|---|
 | 4 |  | 
|---|
 | 5 | ///\ingroup galgs | 
|---|
 | 6 | ///\file | 
|---|
 | 7 | ///\brief Maximum matching algorithm. | 
|---|
 | 8 |  | 
|---|
 | 9 | #include <queue> | 
|---|
 | 10 |  | 
|---|
 | 11 |  | 
|---|
 | 12 | #include <iostream> | 
|---|
 | 13 |  | 
|---|
 | 14 |  | 
|---|
 | 15 |  | 
|---|
 | 16 | #include <invalid.h> | 
|---|
 | 17 | #include <unionfind.h> | 
|---|
 | 18 | #include <lemon/graph_utils.h> | 
|---|
 | 19 |  | 
|---|
 | 20 | namespace lemon { | 
|---|
 | 21 |  | 
|---|
 | 22 |   /// \addtogroup galgs | 
|---|
 | 23 |   /// @{ | 
|---|
 | 24 |  | 
|---|
 | 25 |   ///Maximum matching algorithms class. | 
|---|
 | 26 |  | 
|---|
 | 27 |   ///This class provides Edmonds' alternating forest matching | 
|---|
 | 28 |   ///algorithm. The starting matching (if any) can be passed to the | 
|---|
 | 29 |   ///algorithm using read-in functions \ref readNMapNode, \ref | 
|---|
 | 30 |   ///readNMapEdge or \ref readEMapBool depending on the container. The | 
|---|
 | 31 |   ///resulting maximum matching can be attained by write-out functions | 
|---|
 | 32 |   ///\ref writeNMapNode, \ref writeNMapEdge or \ref writeEMapBool | 
|---|
 | 33 |   ///depending on the preferred container.  | 
|---|
 | 34 |   /// | 
|---|
 | 35 |   ///The dual side of a mathcing is a map of the nodes to | 
|---|
 | 36 |   ///MaxMatching::pos_enum, having values D, A and C showing the | 
|---|
 | 37 |   ///Gallai-Edmonds decomposition of the graph. The nodes in D induce | 
|---|
 | 38 |   ///a graph with factor-critical components, the nodes in A form the | 
|---|
 | 39 |   ///barrier, and the nodes in C induce a graph having a perfect | 
|---|
 | 40 |   ///matching. This decomposition can be attained by calling \ref | 
|---|
 | 41 |   ///writePos after running the algorithm. Before subsequent runs, | 
|---|
 | 42 |   ///the function \ref resetPos() must be called. | 
|---|
 | 43 |   /// | 
|---|
 | 44 |   ///\param Graph The undirected graph type the algorithm runs on. | 
|---|
 | 45 |   /// | 
|---|
 | 46 |   ///\author Jacint Szabo   | 
|---|
 | 47 |   template <typename Graph> | 
|---|
 | 48 |   class MaxMatching { | 
|---|
 | 49 |     typedef typename Graph::Node Node; | 
|---|
 | 50 |     typedef typename Graph::Edge Edge; | 
|---|
 | 51 |     typedef typename Graph::UndirEdgeIt UndirEdgeIt; | 
|---|
 | 52 |     typedef typename Graph::NodeIt NodeIt; | 
|---|
 | 53 |     typedef typename Graph::IncEdgeIt IncEdgeIt; | 
|---|
 | 54 |  | 
|---|
 | 55 |     typedef UnionFindEnum<Node, Graph::template NodeMap> UFE; | 
|---|
 | 56 |  | 
|---|
 | 57 |   public: | 
|---|
 | 58 |      | 
|---|
 | 59 |     ///Indicates the Gallai-Edmonds decomposition of the graph. | 
|---|
 | 60 |  | 
|---|
 | 61 |     ///Indicates the Gallai-Edmonds decomposition of the graph, which | 
|---|
 | 62 |     ///shows an upper bound on the size of a maximum matching. The | 
|---|
 | 63 |     ///nodes with pos_enum \c D induce a graph with factor-critical | 
|---|
 | 64 |     ///components, the nodes in \c A form the canonical barrier, and the | 
|---|
 | 65 |     ///nodes in \c C induce a graph having a perfect matching.  | 
|---|
 | 66 |     enum pos_enum { | 
|---|
 | 67 |       D=0, | 
|---|
 | 68 |       A=1, | 
|---|
 | 69 |       C=2 | 
|---|
 | 70 |     };  | 
|---|
 | 71 |  | 
|---|
 | 72 |   private: | 
|---|
 | 73 |  | 
|---|
 | 74 |     static const int HEUR_density=2; | 
|---|
 | 75 |     const Graph& g; | 
|---|
 | 76 |     typename Graph::template NodeMap<Node> mate; | 
|---|
 | 77 |     typename Graph::template NodeMap<pos_enum> position; | 
|---|
 | 78 |       | 
|---|
 | 79 |   public: | 
|---|
 | 80 |      | 
|---|
 | 81 |     MaxMatching(const Graph& _g) : g(_g), mate(_g,INVALID), position(_g,C) {} | 
|---|
 | 82 |  | 
|---|
 | 83 |     ///Runs Edmonds' algorithm. | 
|---|
 | 84 |  | 
|---|
 | 85 |     ///Runs Edmonds' algorithm for sparse graphs (countEdges <= | 
|---|
 | 86 |     ///2*countNodes), and a heuristical Edmonds' algorithm with a | 
|---|
 | 87 |     ///heuristic of postponing shrinks for dense graphs. \pre Before | 
|---|
 | 88 |     ///the subsequent calls \ref resetPos must be called. | 
|---|
 | 89 |     inline void run(); | 
|---|
 | 90 |  | 
|---|
 | 91 |     ///Runs Edmonds' algorithm. | 
|---|
 | 92 |      | 
|---|
 | 93 |     ///If heur=0 it runs Edmonds' algorithm. If heur=1 it runs | 
|---|
 | 94 |     ///Edmonds' algorithm with a heuristic of postponing shrinks, | 
|---|
 | 95 |     ///giving a faster algorithm for dense graphs.  \pre Before the | 
|---|
 | 96 |     ///subsequent calls \ref resetPos must be called. | 
|---|
 | 97 |     void runEdmonds( int heur ); | 
|---|
 | 98 |  | 
|---|
 | 99 |     ///Finds a greedy matching starting from the actual matching. | 
|---|
 | 100 |      | 
|---|
 | 101 |     ///Starting form the actual matching stored, it finds a maximal | 
|---|
 | 102 |     ///greedy matching. | 
|---|
 | 103 |     void greedyMatching(); | 
|---|
 | 104 |  | 
|---|
 | 105 |     ///Returns the size of the actual matching stored. | 
|---|
 | 106 |  | 
|---|
 | 107 |     ///Returns the size of the actual matching stored. After \ref | 
|---|
 | 108 |     ///run() it returns the size of a maximum matching in the graph. | 
|---|
 | 109 |     int size () const; | 
|---|
 | 110 |  | 
|---|
 | 111 |     ///Resets the map storing the Gallai-Edmonds decomposition. | 
|---|
 | 112 |      | 
|---|
 | 113 |     ///Resets the map storing the Gallai-Edmonds decomposition of the | 
|---|
 | 114 |     ///graph, making it possible to run the algorithm. Must be called | 
|---|
 | 115 |     ///before all runs of the Edmonds algorithm, except for the first | 
|---|
 | 116 |     ///run. | 
|---|
 | 117 |     void resetPos(); | 
|---|
 | 118 |  | 
|---|
 | 119 |     ///Resets the actual matching to the empty matching. | 
|---|
 | 120 |  | 
|---|
 | 121 |     ///Resets the actual matching to the empty matching.   | 
|---|
 | 122 |     /// | 
|---|
 | 123 |     void resetMatching(); | 
|---|
 | 124 |  | 
|---|
 | 125 |     ///Reads a matching from a \c Node map of \c Nodes. | 
|---|
 | 126 |  | 
|---|
 | 127 |     ///Reads a matching from a \c Node map of \c Nodes. This map must be \e | 
|---|
 | 128 |     ///symmetric, i.e. if \c map[u]=v then \c map[v]=u must hold, and | 
|---|
 | 129 |     ///\c uv will be an edge of the matching. | 
|---|
 | 130 |     template<typename NMapN> | 
|---|
 | 131 |     void readNMapNode(NMapN& map) { | 
|---|
 | 132 |       for(NodeIt v(g); v!=INVALID; ++v) { | 
|---|
 | 133 |         mate.set(v,map[v]);    | 
|---|
 | 134 |       }  | 
|---|
 | 135 |     }  | 
|---|
 | 136 |      | 
|---|
 | 137 |     ///Writes the stored matching to a \c Node map of \c Nodes. | 
|---|
 | 138 |  | 
|---|
 | 139 |     ///Writes the stored matching to a \c Node map of \c Nodes. The | 
|---|
 | 140 |     ///resulting map will be \e symmetric, i.e. if \c map[u]=v then \c | 
|---|
 | 141 |     ///map[v]=u will hold, and now \c uv is an edge of the matching. | 
|---|
 | 142 |     template<typename NMapN> | 
|---|
 | 143 |     void writeNMapNode (NMapN& map) const { | 
|---|
 | 144 |       for(NodeIt v(g); v!=INVALID; ++v) { | 
|---|
 | 145 |         map.set(v,mate[v]);    | 
|---|
 | 146 |       }  | 
|---|
 | 147 |     }  | 
|---|
 | 148 |  | 
|---|
 | 149 |     ///Reads a matching from a \c Node map of \c Edges. | 
|---|
 | 150 |  | 
|---|
 | 151 |     ///Reads a matching from a \c Node map of incident \c Edges. This | 
|---|
 | 152 |     ///map must have the property that if \c G.target(map[u])=v then \c | 
|---|
 | 153 |     ///G.target(map[v])=u must hold, and now this edge is an edge of | 
|---|
 | 154 |     ///the matching. | 
|---|
 | 155 |     template<typename NMapE> | 
|---|
 | 156 |     void readNMapEdge(NMapE& map) { | 
|---|
 | 157 |      for(NodeIt v(g); v!=INVALID; ++v) { | 
|---|
 | 158 |         Edge e=map[v]; | 
|---|
 | 159 |         if ( g.valid(e) ) | 
|---|
 | 160 |           g.source(e) == v ? mate.set(v,g.target(e)) : mate.set(v,g.source(e));  | 
|---|
 | 161 |       }  | 
|---|
 | 162 |     }  | 
|---|
 | 163 |      | 
|---|
 | 164 |     ///Writes the matching stored to a \c Node map of \c Edges. | 
|---|
 | 165 |  | 
|---|
 | 166 |     ///Writes the stored matching to a \c Node map of incident \c | 
|---|
 | 167 |     ///Edges. This map will have the property that if \c | 
|---|
 | 168 |     ///g.target(map[u])=v then \c g.target(map[v])=u holds, and now this | 
|---|
 | 169 |     ///edge is an edge of the matching. | 
|---|
 | 170 |     template<typename NMapE> | 
|---|
 | 171 |     void writeNMapEdge (NMapE& map)  const { | 
|---|
 | 172 |       typename Graph::template NodeMap<bool> todo(g,true);  | 
|---|
 | 173 |       for(NodeIt v(g); v!=INVALID; ++v) { | 
|---|
 | 174 |         if ( todo[v] && mate[v]!=INVALID ) { | 
|---|
 | 175 |           Node u=mate[v]; | 
|---|
 | 176 |           for(IncEdgeIt e(g,v); e!=INVALID; ++e) { | 
|---|
 | 177 |             if ( g.target(e) == u ) { | 
|---|
 | 178 |               map.set(u,e); | 
|---|
 | 179 |               map.set(v,e); | 
|---|
 | 180 |               todo.set(u,false); | 
|---|
 | 181 |               todo.set(v,false); | 
|---|
 | 182 |               break; | 
|---|
 | 183 |             } | 
|---|
 | 184 |           } | 
|---|
 | 185 |         } | 
|---|
 | 186 |       }  | 
|---|
 | 187 |     } | 
|---|
 | 188 |  | 
|---|
 | 189 |  | 
|---|
 | 190 |     ///Reads a matching from an \c Edge map of \c bools. | 
|---|
 | 191 |      | 
|---|
 | 192 |     ///Reads a matching from an \c Edge map of \c bools. This map must | 
|---|
 | 193 |     ///have the property that there are no two adjacent edges \c e, \c | 
|---|
 | 194 |     ///f with \c map[e]=map[f]=true. The edges \c e with \c | 
|---|
 | 195 |     ///map[e]=true form the matching. | 
|---|
 | 196 |     template<typename EMapB> | 
|---|
 | 197 |     void readEMapBool(EMapB& map) { | 
|---|
 | 198 |       for(UndirEdgeIt e(g); e!=INVALID; ++e) { | 
|---|
 | 199 |         if ( map[e] ) { | 
|---|
 | 200 |           Node u=g.source(e);      | 
|---|
 | 201 |           Node v=g.target(e); | 
|---|
 | 202 |           mate.set(u,v); | 
|---|
 | 203 |           mate.set(v,u); | 
|---|
 | 204 |         }  | 
|---|
 | 205 |       }  | 
|---|
 | 206 |     } | 
|---|
 | 207 |     //iterable boolmap? | 
|---|
 | 208 |  | 
|---|
 | 209 |  | 
|---|
 | 210 |     ///Writes the matching stored to an \c Edge map of \c bools. | 
|---|
 | 211 |  | 
|---|
 | 212 |     ///Writes the matching stored to an \c Edge map of \c bools. This | 
|---|
 | 213 |     ///map will have the property that there are no two adjacent edges | 
|---|
 | 214 |     ///\c e, \c f with \c map[e]=map[f]=true. The edges \c e with \c | 
|---|
 | 215 |     ///map[e]=true form the matching. | 
|---|
 | 216 |     template<typename EMapB> | 
|---|
 | 217 |     void writeEMapBool (EMapB& map) const { | 
|---|
 | 218 |       for(UndirEdgeIt e(g); e!=INVALID; ++e) map.set(e,false); | 
|---|
 | 219 |  | 
|---|
 | 220 |       typename Graph::template NodeMap<bool> todo(g,true);  | 
|---|
 | 221 |       for(NodeIt v(g); v!=INVALID; ++v) { | 
|---|
 | 222 |         if ( todo[v] && mate[v]!=INVALID ) { | 
|---|
 | 223 |           Node u=mate[v]; | 
|---|
 | 224 |           for(IncEdgeIt e(g,v); e!=INVALID; ++e) { | 
|---|
 | 225 |             if ( g.target(e) == u ) { | 
|---|
 | 226 |               map.set(e,true); | 
|---|
 | 227 |               todo.set(u,false); | 
|---|
 | 228 |               todo.set(v,false); | 
|---|
 | 229 |               break; | 
|---|
 | 230 |             } | 
|---|
 | 231 |           } | 
|---|
 | 232 |         } | 
|---|
 | 233 |       }  | 
|---|
 | 234 |     } | 
|---|
 | 235 |  | 
|---|
 | 236 |  | 
|---|
 | 237 |     ///Writes the canonical decomposition of the graph after running | 
|---|
 | 238 |     ///the algorithm. | 
|---|
 | 239 |  | 
|---|
 | 240 |     ///After calling any run methods of the class, and before calling | 
|---|
 | 241 |     ///\ref resetPos(), it writes the Gallai-Edmonds canonical | 
|---|
 | 242 |     ///decomposition of the graph. \c map must be a node map | 
|---|
 | 243 |     ///of \ref pos_enum 's. | 
|---|
 | 244 |     template<typename NMapEnum> | 
|---|
 | 245 |     void writePos (NMapEnum& map) const { | 
|---|
 | 246 |       for(NodeIt v(g); v!=INVALID; ++v)  map.set(v,position[v]); | 
|---|
 | 247 |     } | 
|---|
 | 248 |  | 
|---|
 | 249 |   private:  | 
|---|
 | 250 |  | 
|---|
 | 251 |     void lateShrink(Node v, typename Graph::template NodeMap<Node>& ear,   | 
|---|
 | 252 |                     UFE& blossom, UFE& tree); | 
|---|
 | 253 |  | 
|---|
 | 254 |     void normShrink(Node v, typename Graph::NodeMap<Node>& ear,   | 
|---|
 | 255 |                     UFE& blossom, UFE& tree); | 
|---|
 | 256 |  | 
|---|
 | 257 |     bool noShrinkStep(Node x, typename Graph::NodeMap<Node>& ear,   | 
|---|
 | 258 |                       UFE& blossom, UFE& tree, std::queue<Node>& Q); | 
|---|
 | 259 |  | 
|---|
 | 260 |     void shrinkStep(Node& top, Node& middle, Node& bottom, typename Graph::NodeMap<Node>& ear,   | 
|---|
 | 261 |                     UFE& blossom, UFE& tree, std::queue<Node>& Q); | 
|---|
 | 262 |  | 
|---|
 | 263 |     void augment(Node x, typename Graph::NodeMap<Node>& ear,   | 
|---|
 | 264 |                  UFE& blossom, UFE& tree); | 
|---|
 | 265 |   }; | 
|---|
 | 266 |  | 
|---|
 | 267 |  | 
|---|
 | 268 |   // ********************************************************************** | 
|---|
 | 269 |   //  IMPLEMENTATIONS | 
|---|
 | 270 |   // ********************************************************************** | 
|---|
 | 271 |  | 
|---|
 | 272 |  | 
|---|
 | 273 |   template <typename Graph> | 
|---|
 | 274 |   void MaxMatching<Graph>::run() { | 
|---|
 | 275 |     if ( countUndirEdges(g) < HEUR_density*countNodes(g) ) { | 
|---|
 | 276 |       greedyMatching(); | 
|---|
 | 277 |       runEdmonds(1); | 
|---|
 | 278 |     } else runEdmonds(0); | 
|---|
 | 279 |   } | 
|---|
 | 280 |  | 
|---|
 | 281 |  | 
|---|
 | 282 |   template <typename Graph> | 
|---|
 | 283 |   void MaxMatching<Graph>::runEdmonds( int heur=1 ) { | 
|---|
 | 284 |        | 
|---|
 | 285 |     std::cout<<"Entering runEdmonds"<<std::endl; | 
|---|
 | 286 |  | 
|---|
 | 287 |     typename Graph::template NodeMap<Node> ear(g,INVALID);  | 
|---|
 | 288 |     //undefined for the base nodes of the blossoms (i.e. for the | 
|---|
 | 289 |     //representative elements of UFE blossom) and for the nodes in C | 
|---|
 | 290 |   | 
|---|
 | 291 |     typename UFE::MapType blossom_base(g); | 
|---|
 | 292 |     UFE blossom(blossom_base); | 
|---|
 | 293 |     typename UFE::MapType tree_base(g); | 
|---|
 | 294 |     UFE tree(tree_base); | 
|---|
 | 295 |  | 
|---|
 | 296 |     for(NodeIt v(g); v!=INVALID; ++v) { | 
|---|
 | 297 |       if ( position[v]==C && mate[v]==INVALID ) { | 
|---|
 | 298 |         blossom.insert(v); | 
|---|
 | 299 |         tree.insert(v);  | 
|---|
 | 300 |         position.set(v,D); | 
|---|
 | 301 |         if ( heur == 1 ) lateShrink( v, ear, blossom, tree ); | 
|---|
 | 302 |         else normShrink( v, ear, blossom, tree ); | 
|---|
 | 303 |       } | 
|---|
 | 304 |     } | 
|---|
 | 305 |  | 
|---|
 | 306 |  | 
|---|
 | 307 |     std::cout<<" runEdmonds end"<<std::endl; | 
|---|
 | 308 |  | 
|---|
 | 309 |  | 
|---|
 | 310 |   } | 
|---|
 | 311 |      | 
|---|
 | 312 |   template <typename Graph> | 
|---|
 | 313 |   void MaxMatching<Graph>::lateShrink(Node v, typename Graph::template NodeMap<Node>& ear,   | 
|---|
 | 314 |                                       UFE& blossom, UFE& tree) { | 
|---|
 | 315 |       | 
|---|
 | 316 |  | 
|---|
 | 317 |     std::cout<<"Entering lateShrink"<<std::endl; | 
|---|
 | 318 |  | 
|---|
 | 319 |  | 
|---|
 | 320 |     std::queue<Node> Q;   //queue of the totally unscanned nodes | 
|---|
 | 321 |     Q.push(v);   | 
|---|
 | 322 |     std::queue<Node> R;    | 
|---|
 | 323 |     //queue of the nodes which must be scanned for a possible shrink | 
|---|
 | 324 |        | 
|---|
 | 325 |     while ( !Q.empty() ) { | 
|---|
 | 326 |       Node x=Q.front(); | 
|---|
 | 327 |       Q.pop(); | 
|---|
 | 328 |       if ( noShrinkStep( x, ear, blossom, tree, Q ) ) return; | 
|---|
 | 329 |       else R.push(x); | 
|---|
 | 330 |     } | 
|---|
 | 331 |        | 
|---|
 | 332 |     while ( !R.empty() ) { | 
|---|
 | 333 |       Node x=R.front(); | 
|---|
 | 334 |       R.pop(); | 
|---|
 | 335 |          | 
|---|
 | 336 |       for( IncEdgeIt e(g,x); e!=INVALID ; ++e ) { | 
|---|
 | 337 |         Node y=g.target(e); | 
|---|
 | 338 |  | 
|---|
 | 339 |         if ( position[y] == D && blossom.find(x) != blossom.find(y) ) {  | 
|---|
 | 340 |           //x and y must be in the same tree//biztos? az oddbol d-belive lettek is? | 
|---|
 | 341 |          | 
|---|
 | 342 |           typename Graph::template NodeMap<bool> path(g,false); | 
|---|
 | 343 |  | 
|---|
 | 344 |           Node b=blossom.find(x); | 
|---|
 | 345 |           path.set(b,true); | 
|---|
 | 346 |           b=mate[b]; | 
|---|
 | 347 |           while ( b!=INVALID ) {  | 
|---|
 | 348 |             b=blossom.find(ear[b]); | 
|---|
 | 349 |             path.set(b,true); | 
|---|
 | 350 |             b=mate[b]; | 
|---|
 | 351 |           } //going till the root | 
|---|
 | 352 |          | 
|---|
 | 353 |           Node top=y; | 
|---|
 | 354 |           Node middle=blossom.find(top); | 
|---|
 | 355 |           Node bottom=x; | 
|---|
 | 356 |           while ( !path[middle] ) | 
|---|
 | 357 |             shrinkStep(top, middle, bottom, ear, blossom, tree, Q); | 
|---|
 | 358 |                    | 
|---|
 | 359 |           Node base=middle; | 
|---|
 | 360 |           top=x; | 
|---|
 | 361 |           middle=blossom.find(top); | 
|---|
 | 362 |           bottom=y; | 
|---|
 | 363 |           Node blossom_base=blossom.find(base); | 
|---|
 | 364 |           while ( middle!=blossom_base ) | 
|---|
 | 365 |             shrinkStep(top, middle, bottom, ear, blossom, tree, Q); | 
|---|
 | 366 |                    | 
|---|
 | 367 |           blossom.makeRep(base); | 
|---|
 | 368 |         } // if shrink is needed | 
|---|
 | 369 |  | 
|---|
 | 370 |         //most nehany odd node is d-beli lett, es rajuk az is megnezendo hogy mely d-beliekkel szonszedosak mas faban | 
|---|
 | 371 |  | 
|---|
 | 372 |         while ( !Q.empty() ) { | 
|---|
 | 373 |           Node x=Q.front(); | 
|---|
 | 374 |           Q.pop(); | 
|---|
 | 375 |           if ( noShrinkStep(x, ear, blossom, tree, Q) ) return; | 
|---|
 | 376 |           else R.push(x); | 
|---|
 | 377 |         } | 
|---|
 | 378 |       } //for e | 
|---|
 | 379 |     } // while ( !R.empty() ) | 
|---|
 | 380 |   } | 
|---|
 | 381 |  | 
|---|
 | 382 |  | 
|---|
 | 383 |   template <typename Graph> | 
|---|
 | 384 |   void MaxMatching<Graph>::normShrink(Node v, typename Graph::NodeMap<Node>& ear,   | 
|---|
 | 385 |                                       UFE& blossom, UFE& tree) { | 
|---|
 | 386 |  | 
|---|
 | 387 |  | 
|---|
 | 388 |     std::cout<<"Entering normShrink with node "<<g.id(v)<<std::endl; | 
|---|
 | 389 |  | 
|---|
 | 390 |  | 
|---|
 | 391 |     std::queue<Node> Q;   //queue of the unscanned nodes | 
|---|
 | 392 |     Q.push(v);   | 
|---|
 | 393 |     while ( !Q.empty() ) { | 
|---|
 | 394 |  | 
|---|
 | 395 |       std::cout<<"beginning of norm while"<<std::endl; | 
|---|
 | 396 |  | 
|---|
 | 397 |       Node x=Q.front(); | 
|---|
 | 398 |       Q.pop(); | 
|---|
 | 399 |          | 
|---|
 | 400 |       for( IncEdgeIt e(g,x); e!=INVALID; ++e ) { | 
|---|
 | 401 |  | 
|---|
 | 402 |  | 
|---|
 | 403 |         for( IncEdgeIt f(g,x); f!=INVALID; ++f ) { | 
|---|
 | 404 |           std::cout<<"Starting for." <<std::endl; | 
|---|
 | 405 |           std::cout<<"edges " << g.id(f)<< " : " << g.id(g.target(f))<<std::endl; | 
|---|
 | 406 |           std::cout<<"Ending for." <<std::endl; | 
|---|
 | 407 |         } | 
|---|
 | 408 |  | 
|---|
 | 409 |         std::cout<<"Ending the whole for." <<std::endl; | 
|---|
 | 410 |         std::cout<<"for (In normShrink) with edge " << g.id(e)<< " : " << g.id(x); | 
|---|
 | 411 |  | 
|---|
 | 412 |         Node y=g.target(e); | 
|---|
 | 413 |          | 
|---|
 | 414 |         std::cout<<" "<<g.id(y)<<std::endl; | 
|---|
 | 415 |                | 
|---|
 | 416 |         switch ( position[y] ) { | 
|---|
 | 417 |         case D:          //x and y must be in the same tree //asszem nem!!! | 
|---|
 | 418 |  | 
|---|
 | 419 |           std::cout<<" pos[y] " << position[y]<<std::endl; | 
|---|
 | 420 |           std::cout<<" blossom.find(x) ="<< g.id(blossom.find(x))<<std::endl; | 
|---|
 | 421 |           std::cout<<" blossom.find(y) ="<< g.id(blossom.find(y))<<std::endl; | 
|---|
 | 422 |  | 
|---|
 | 423 |  | 
|---|
 | 424 |           if ( blossom.find(x) != blossom.find(y) ) { //shrink | 
|---|
 | 425 |             typename Graph::template NodeMap<bool> path(g,false); | 
|---|
 | 426 |                | 
|---|
 | 427 |             Node b=blossom.find(x); | 
|---|
 | 428 |             path.set(b,true); | 
|---|
 | 429 |             b=mate[b]; | 
|---|
 | 430 |             while ( b!=INVALID ) {  | 
|---|
 | 431 |               b=blossom.find(ear[b]); | 
|---|
 | 432 |               path.set(b,true); | 
|---|
 | 433 |               b=mate[b]; | 
|---|
 | 434 |             } //going till the root | 
|---|
 | 435 |          | 
|---|
 | 436 |             Node top=y; | 
|---|
 | 437 |             Node middle=blossom.find(top); | 
|---|
 | 438 |             Node bottom=x; | 
|---|
 | 439 |             while ( !path[middle] ) | 
|---|
 | 440 |               shrinkStep(top, middle, bottom, ear, blossom, tree, Q); | 
|---|
 | 441 |                  | 
|---|
 | 442 |             Node base=middle; | 
|---|
 | 443 |             top=x; | 
|---|
 | 444 |             middle=blossom.find(top); | 
|---|
 | 445 |             bottom=y; | 
|---|
 | 446 |             Node blossom_base=blossom.find(base); | 
|---|
 | 447 |             while ( middle!=blossom_base ) | 
|---|
 | 448 |               shrinkStep(top, middle, bottom, ear, blossom, tree, Q); | 
|---|
 | 449 |                  | 
|---|
 | 450 |             blossom.makeRep(base); | 
|---|
 | 451 |           } | 
|---|
 | 452 |           break; | 
|---|
 | 453 |         case C: | 
|---|
 | 454 |           if ( mate[y]!=INVALID ) {   //grow | 
|---|
 | 455 |              | 
|---|
 | 456 |             std::cout<<"grow"<<std::endl; | 
|---|
 | 457 |  | 
|---|
 | 458 |             ear.set(y,x); | 
|---|
 | 459 |             Node w=mate[y]; | 
|---|
 | 460 |             blossom.insert(w); | 
|---|
 | 461 |             position.set(y,A);  | 
|---|
 | 462 |             position.set(w,D);  | 
|---|
 | 463 |             tree.insert(y); | 
|---|
 | 464 |             tree.insert(w); | 
|---|
 | 465 |             tree.join(y,blossom.find(x));   | 
|---|
 | 466 |             tree.join(w,y);   | 
|---|
 | 467 |             Q.push(w); | 
|---|
 | 468 |  | 
|---|
 | 469 |           } else {                 //augment   | 
|---|
 | 470 |  | 
|---|
 | 471 |             std::cout<<"augment"<<std::endl; | 
|---|
 | 472 |  | 
|---|
 | 473 |             augment(x, ear, blossom, tree); | 
|---|
 | 474 |             mate.set(x,y); | 
|---|
 | 475 |             mate.set(y,x); | 
|---|
 | 476 |             return; | 
|---|
 | 477 |           } //if  | 
|---|
 | 478 |  | 
|---|
 | 479 |           std::cout<<"end c eset"<<std::endl; | 
|---|
 | 480 |           break; | 
|---|
 | 481 |         default: break; | 
|---|
 | 482 |         } | 
|---|
 | 483 |         std::cout<<"end switch"<<std::endl; | 
|---|
 | 484 |       } | 
|---|
 | 485 |     } | 
|---|
 | 486 |   } | 
|---|
 | 487 |  | 
|---|
 | 488 |   template <typename Graph> | 
|---|
 | 489 |   void MaxMatching<Graph>::greedyMatching() { | 
|---|
 | 490 |     for(NodeIt v(g); v!=INVALID; ++v) | 
|---|
 | 491 |       if ( mate[v]==INVALID ) { | 
|---|
 | 492 |         for( IncEdgeIt e(g,v); e!=INVALID ; ++e ) { | 
|---|
 | 493 |           Node y=g.target(e); | 
|---|
 | 494 |           if ( mate[y]==INVALID && y!=v ) { | 
|---|
 | 495 |             mate.set(v,y); | 
|---|
 | 496 |             mate.set(y,v); | 
|---|
 | 497 |             break; | 
|---|
 | 498 |           } | 
|---|
 | 499 |         } | 
|---|
 | 500 |       }  | 
|---|
 | 501 |   } | 
|---|
 | 502 |     | 
|---|
 | 503 |   template <typename Graph> | 
|---|
 | 504 |   int MaxMatching<Graph>::size() const { | 
|---|
 | 505 |     int s=0; | 
|---|
 | 506 |     for(NodeIt v(g); v!=INVALID; ++v) { | 
|---|
 | 507 |       if ( mate[v]!=INVALID ) { | 
|---|
 | 508 |         ++s; | 
|---|
 | 509 |       } | 
|---|
 | 510 |     } | 
|---|
 | 511 |     return (int)s/2; | 
|---|
 | 512 |   } | 
|---|
 | 513 |  | 
|---|
 | 514 |   template <typename Graph> | 
|---|
 | 515 |   void MaxMatching<Graph>::resetPos() { | 
|---|
 | 516 |     for(NodeIt v(g); v!=INVALID; ++v) | 
|---|
 | 517 |       position.set(v,C);       | 
|---|
 | 518 |   } | 
|---|
 | 519 |  | 
|---|
 | 520 |   template <typename Graph> | 
|---|
 | 521 |   void MaxMatching<Graph>::resetMatching() { | 
|---|
 | 522 |     for(NodeIt v(g); v!=INVALID; ++v) | 
|---|
 | 523 |       mate.set(v,INVALID);       | 
|---|
 | 524 |   } | 
|---|
 | 525 |  | 
|---|
 | 526 |   template <typename Graph> | 
|---|
 | 527 |   bool MaxMatching<Graph>::noShrinkStep(Node x, typename Graph::NodeMap<Node>& ear,   | 
|---|
 | 528 |                                         UFE& blossom, UFE& tree, std::queue<Node>& Q) { | 
|---|
 | 529 |     for( IncEdgeIt e(g,x); e!= INVALID; ++e ) { | 
|---|
 | 530 |       Node y=g.target(e); | 
|---|
 | 531 |          | 
|---|
 | 532 |       if ( position[y]==C ) { | 
|---|
 | 533 |         if ( mate[y]!=INVALID ) {       //grow | 
|---|
 | 534 |           ear.set(y,x); | 
|---|
 | 535 |           Node w=mate[y]; | 
|---|
 | 536 |           blossom.insert(w); | 
|---|
 | 537 |           position.set(y,A); | 
|---|
 | 538 |           position.set(w,D); | 
|---|
 | 539 |           tree.insert(y); | 
|---|
 | 540 |           tree.insert(w); | 
|---|
 | 541 |           tree.join(y,blossom.find(x));   | 
|---|
 | 542 |           tree.join(w,y);   | 
|---|
 | 543 |           Q.push(w); | 
|---|
 | 544 |         } else {                      //augment  | 
|---|
 | 545 |           augment(x, ear, blossom, tree); | 
|---|
 | 546 |           mate.set(x,y); | 
|---|
 | 547 |           mate.set(y,x); | 
|---|
 | 548 |           return true; | 
|---|
 | 549 |         } | 
|---|
 | 550 |       } | 
|---|
 | 551 |     } | 
|---|
 | 552 |     return false; | 
|---|
 | 553 |   } | 
|---|
 | 554 |  | 
|---|
 | 555 |   template <typename Graph> | 
|---|
 | 556 |   void MaxMatching<Graph>::shrinkStep(Node& top, Node& middle, Node& bottom, typename Graph::NodeMap<Node>& ear,   | 
|---|
 | 557 |                                       UFE& blossom, UFE& tree, std::queue<Node>& Q) { | 
|---|
 | 558 |     ear.set(top,bottom); | 
|---|
 | 559 |     Node t=top; | 
|---|
 | 560 |     while ( t!=middle ) { | 
|---|
 | 561 |       Node u=mate[t]; | 
|---|
 | 562 |       t=ear[u]; | 
|---|
 | 563 |       ear.set(t,u); | 
|---|
 | 564 |     }  | 
|---|
 | 565 |     bottom=mate[middle]; | 
|---|
 | 566 |     position.set(bottom,D); | 
|---|
 | 567 |     Q.push(bottom); | 
|---|
 | 568 |     top=ear[bottom];             | 
|---|
 | 569 |     Node oldmiddle=middle; | 
|---|
 | 570 |     middle=blossom.find(top); | 
|---|
 | 571 |     tree.erase(bottom); | 
|---|
 | 572 |     tree.erase(oldmiddle); | 
|---|
 | 573 |     blossom.insert(bottom); | 
|---|
 | 574 |     blossom.join(bottom, oldmiddle); | 
|---|
 | 575 |     blossom.join(top, oldmiddle); | 
|---|
 | 576 |   } | 
|---|
 | 577 |  | 
|---|
 | 578 |   template <typename Graph> | 
|---|
 | 579 |   void MaxMatching<Graph>::augment(Node x, typename Graph::NodeMap<Node>& ear,   | 
|---|
 | 580 |                                    UFE& blossom, UFE& tree) {  | 
|---|
 | 581 |     Node v=mate[x]; | 
|---|
 | 582 |     while ( v!=INVALID ) { | 
|---|
 | 583 |          | 
|---|
 | 584 |       Node u=ear[v]; | 
|---|
 | 585 |       mate.set(v,u); | 
|---|
 | 586 |       Node tmp=v; | 
|---|
 | 587 |       v=mate[u]; | 
|---|
 | 588 |       mate.set(u,tmp); | 
|---|
 | 589 |     } | 
|---|
 | 590 |     typename UFE::ItemIt it; | 
|---|
 | 591 |     for (tree.first(it,blossom.find(x)); tree.valid(it); tree.next(it)) {    | 
|---|
 | 592 |       if ( position[it] == D ) { | 
|---|
 | 593 |         typename UFE::ItemIt b_it; | 
|---|
 | 594 |         for (blossom.first(b_it,it); blossom.valid(b_it); blossom.next(b_it)) {   | 
|---|
 | 595 |           position.set( b_it ,C); | 
|---|
 | 596 |         } | 
|---|
 | 597 |         blossom.eraseClass(it); | 
|---|
 | 598 |       } else position.set( it ,C); | 
|---|
 | 599 |     } | 
|---|
 | 600 |     tree.eraseClass(x); | 
|---|
 | 601 |  | 
|---|
 | 602 |   } | 
|---|
 | 603 |  | 
|---|
 | 604 |   /// @} | 
|---|
 | 605 |    | 
|---|
 | 606 | } //END OF NAMESPACE LEMON | 
|---|
 | 607 |  | 
|---|
 | 608 | #endif //EDMONDS_H | 
|---|