321 UFE& blossom, UFE& tree); |
327 UFE& blossom, UFE& tree); |
322 |
328 |
323 void normShrink(Node v, typename Graph::template NodeMap<Node>& ear, |
329 void normShrink(Node v, typename Graph::template NodeMap<Node>& ear, |
324 UFE& blossom, UFE& tree); |
330 UFE& blossom, UFE& tree); |
325 |
331 |
326 bool noShrinkStep(Node x, typename Graph::template NodeMap<Node>& ear, |
332 void shrink(Node x,Node y, typename Graph::template NodeMap<Node>& ear, |
327 UFE& blossom, UFE& tree, std::queue<Node>& Q); |
333 UFE& blossom, UFE& tree,std::queue<Node>& Q); |
328 |
334 |
329 void shrinkStep(Node& top, Node& middle, Node& bottom, |
335 void shrinkStep(Node& top, Node& middle, Node& bottom, |
330 typename Graph::template NodeMap<Node>& ear, |
336 typename Graph::template NodeMap<Node>& ear, |
331 UFE& blossom, UFE& tree, std::queue<Node>& Q); |
337 UFE& blossom, UFE& tree, std::queue<Node>& Q); |
332 |
338 |
|
339 bool growOrAugment(Node& y, Node& x, typename Graph::template |
|
340 NodeMap<Node>& ear, UFE& blossom, UFE& tree, |
|
341 std::queue<Node>& Q); |
|
342 |
333 void augment(Node x, typename Graph::template NodeMap<Node>& ear, |
343 void augment(Node x, typename Graph::template NodeMap<Node>& ear, |
334 UFE& blossom, UFE& tree); |
344 UFE& blossom, UFE& tree); |
335 |
345 |
336 }; |
346 }; |
337 |
347 |
340 // IMPLEMENTATIONS |
350 // IMPLEMENTATIONS |
341 // ********************************************************************** |
351 // ********************************************************************** |
342 |
352 |
343 |
353 |
344 template <typename Graph> |
354 template <typename Graph> |
345 void MaxMatching<Graph>::lateShrink(Node v, typename Graph::template NodeMap<Node>& ear, |
355 void MaxMatching<Graph>::lateShrink(Node v, typename Graph::template |
346 UFE& blossom, UFE& tree) { |
356 NodeMap<Node>& ear, UFE& blossom, UFE& tree) { |
|
357 //We have one tree which we grow, and also shrink but only if it cannot be |
|
358 //postponed. If we augment then we return to the "for" cycle of |
|
359 //runEdmonds(). |
347 |
360 |
348 std::queue<Node> Q; //queue of the totally unscanned nodes |
361 std::queue<Node> Q; //queue of the totally unscanned nodes |
349 Q.push(v); |
362 Q.push(v); |
350 std::queue<Node> R; |
363 std::queue<Node> R; |
351 //queue of the nodes which must be scanned for a possible shrink |
364 //queue of the nodes which must be scanned for a possible shrink |
352 |
365 |
353 while ( !Q.empty() ) { |
366 while ( !Q.empty() ) { |
354 Node x=Q.front(); |
367 Node x=Q.front(); |
355 Q.pop(); |
368 Q.pop(); |
356 if ( noShrinkStep( x, ear, blossom, tree, Q ) ) return; |
369 for( IncEdgeIt e(g,x); e!= INVALID; ++e ) { |
357 else R.push(x); |
370 Node y=g.runningNode(e); |
|
371 //growOrAugment grows if y is covered by the matching and |
|
372 //augments if not. In this latter case it returns 1. |
|
373 if ( position[y]==C && growOrAugment(y, x, ear, blossom, tree, Q) ) return; |
|
374 } |
|
375 R.push(x); |
358 } |
376 } |
359 |
377 |
360 while ( !R.empty() ) { |
378 while ( !R.empty() ) { |
361 Node x=R.front(); |
379 Node x=R.front(); |
362 R.pop(); |
380 R.pop(); |
363 |
381 |
364 for( IncEdgeIt e(g,x); e!=INVALID ; ++e ) { |
382 for( IncEdgeIt e(g,x); e!=INVALID ; ++e ) { |
365 Node y=g.runningNode(e); |
383 Node y=g.runningNode(e); |
366 |
384 |
367 if ( position[y] == D && blossom.find(x) != blossom.find(y) ) { |
385 if ( position[y] == D && blossom.find(x) != blossom.find(y) ) |
368 //x and y must be in the same tree |
386 //Recall that we have only one tree. |
|
387 shrink( x, y, ear, blossom, tree, Q); |
369 |
388 |
370 typename Graph::template NodeMap<bool> path(g,false); |
|
371 |
|
372 Node b=blossom.find(x); |
|
373 path.set(b,true); |
|
374 b=_mate[b]; |
|
375 while ( b!=INVALID ) { |
|
376 b=blossom.find(ear[b]); |
|
377 path.set(b,true); |
|
378 b=_mate[b]; |
|
379 } //going till the root |
|
380 |
|
381 Node top=y; |
|
382 Node middle=blossom.find(top); |
|
383 Node bottom=x; |
|
384 while ( !path[middle] ) |
|
385 shrinkStep(top, middle, bottom, ear, blossom, tree, Q); |
|
386 |
|
387 Node base=middle; |
|
388 top=x; |
|
389 middle=blossom.find(top); |
|
390 bottom=y; |
|
391 Node blossom_base=blossom.find(base); |
|
392 while ( middle!=blossom_base ) |
|
393 shrinkStep(top, middle, bottom, ear, blossom, tree, Q); |
|
394 |
|
395 blossom.makeRep(base); |
|
396 } // if shrink is needed |
|
397 |
|
398 while ( !Q.empty() ) { |
389 while ( !Q.empty() ) { |
399 Node x=Q.front(); |
390 Node x=Q.front(); |
400 Q.pop(); |
391 Q.pop(); |
401 if ( noShrinkStep(x, ear, blossom, tree, Q) ) return; |
392 for( IncEdgeIt e(g,x); e!= INVALID; ++e ) { |
402 else R.push(x); |
393 Node y=g.runningNode(e); |
|
394 //growOrAugment grows if y is covered by the matching and |
|
395 //augments if not. In this latter case it returns 1. |
|
396 if ( position[y]==C && growOrAugment(y, x, ear, blossom, tree, Q) ) return; |
|
397 } |
|
398 R.push(x); |
403 } |
399 } |
404 } //for e |
400 } //for e |
405 } // while ( !R.empty() ) |
401 } // while ( !R.empty() ) |
406 } |
402 } |
407 |
403 |
421 for( IncEdgeIt e(g,x); e!=INVALID; ++e ) { |
420 for( IncEdgeIt e(g,x); e!=INVALID; ++e ) { |
422 Node y=g.runningNode(e); |
421 Node y=g.runningNode(e); |
423 |
422 |
424 switch ( position[y] ) { |
423 switch ( position[y] ) { |
425 case D: //x and y must be in the same tree |
424 case D: //x and y must be in the same tree |
426 |
425 if ( blossom.find(x) != blossom.find(y) ) |
427 if ( blossom.find(x) != blossom.find(y) ) { //shrink |
426 //x and y are in the same tree |
428 typename Graph::template NodeMap<bool> path(g,false); |
427 shrink( x, y, ear, blossom, tree, Q); |
429 |
|
430 Node b=blossom.find(x); |
|
431 path.set(b,true); |
|
432 b=_mate[b]; |
|
433 while ( b!=INVALID ) { |
|
434 b=blossom.find(ear[b]); |
|
435 path.set(b,true); |
|
436 b=_mate[b]; |
|
437 } //going till the root |
|
438 |
|
439 Node top=y; |
|
440 Node middle=blossom.find(top); |
|
441 Node bottom=x; |
|
442 while ( !path[middle] ) |
|
443 shrinkStep(top, middle, bottom, ear, blossom, tree, Q); |
|
444 |
|
445 Node base=middle; |
|
446 top=x; |
|
447 middle=blossom.find(top); |
|
448 bottom=y; |
|
449 Node blossom_base=blossom.find(base); |
|
450 while ( middle!=blossom_base ) |
|
451 shrinkStep(top, middle, bottom, ear, blossom, tree, Q); |
|
452 |
|
453 blossom.makeRep(base); |
|
454 } |
|
455 break; |
428 break; |
456 case C: |
429 case C: |
457 if ( _mate[y]!=INVALID ) { //grow |
430 //growOrAugment grows if y is covered by the matching and |
458 |
431 //augments if not. In this latter case it returns 1. |
459 ear.set(y,x); |
432 if ( growOrAugment(y, x, ear, blossom, tree, Q) ) return; |
460 Node w=_mate[y]; |
|
461 blossom.insert(w); |
|
462 position.set(y,A); |
|
463 position.set(w,D); |
|
464 tree.insert(y); |
|
465 tree.insert(w); |
|
466 tree.join(y,blossom.find(x)); |
|
467 tree.join(w,y); |
|
468 Q.push(w); |
|
469 } else { //augment |
|
470 augment(x, ear, blossom, tree); |
|
471 _mate.set(x,y); |
|
472 _mate.set(y,x); |
|
473 return; |
|
474 } //if |
|
475 break; |
433 break; |
476 default: break; |
434 default: break; |
477 } |
435 } |
478 } |
436 } |
479 } |
437 } |
480 } |
438 } |
481 |
439 |
482 template <typename Graph> |
440 |
483 bool MaxMatching<Graph>::noShrinkStep(Node x, |
441 template <typename Graph> |
484 typename Graph::template |
442 void MaxMatching<Graph>::shrink(Node x,Node y, typename |
485 NodeMap<Node>& ear, |
443 Graph::template NodeMap<Node>& ear, |
486 UFE& blossom, UFE& tree, |
444 UFE& blossom, UFE& tree, std::queue<Node>& Q) { |
487 std::queue<Node>& Q) { |
445 //x and y are the two adjacent vertices in two blossoms. |
488 for( IncEdgeIt e(g,x); e!= INVALID; ++e ) { |
446 |
489 Node y=g.runningNode(e); |
447 typename Graph::template NodeMap<bool> path(g,false); |
490 |
448 |
491 if ( position[y]==C ) { |
449 Node b=blossom.find(x); |
492 if ( _mate[y]!=INVALID ) { //grow |
450 path.set(b,true); |
493 ear.set(y,x); |
451 b=_mate[b]; |
494 Node w=_mate[y]; |
452 while ( b!=INVALID ) { |
495 blossom.insert(w); |
453 b=blossom.find(ear[b]); |
496 position.set(y,A); |
454 path.set(b,true); |
497 position.set(w,D); |
455 b=_mate[b]; |
498 tree.insert(y); |
456 } //we go until the root through bases of blossoms and odd vertices |
499 tree.insert(w); |
457 |
500 tree.join(y,blossom.find(x)); |
458 Node top=y; |
501 tree.join(w,y); |
459 Node middle=blossom.find(top); |
502 Q.push(w); |
460 Node bottom=x; |
503 } else { //augment |
461 while ( !path[middle] ) |
504 augment(x, ear, blossom, tree); |
462 shrinkStep(top, middle, bottom, ear, blossom, tree, Q); |
505 _mate.set(x,y); |
463 //Until we arrive to a node on the path, we update blossom, tree |
506 _mate.set(y,x); |
464 //and the positions of the odd nodes. |
507 return true; |
465 |
508 } |
466 Node base=middle; |
509 } |
467 top=x; |
510 } |
468 middle=blossom.find(top); |
511 return false; |
469 bottom=y; |
|
470 Node blossom_base=blossom.find(base); |
|
471 while ( middle!=blossom_base ) |
|
472 shrinkStep(top, middle, bottom, ear, blossom, tree, Q); |
|
473 //Until we arrive to a node on the path, we update blossom, tree |
|
474 //and the positions of the odd nodes. |
|
475 |
|
476 blossom.makeRep(base); |
512 } |
477 } |
|
478 |
|
479 |
513 |
480 |
514 template <typename Graph> |
481 template <typename Graph> |
515 void MaxMatching<Graph>::shrinkStep(Node& top, Node& middle, Node& bottom, |
482 void MaxMatching<Graph>::shrinkStep(Node& top, Node& middle, Node& bottom, |
516 typename Graph::template |
483 typename Graph::template |
517 NodeMap<Node>& ear, |
484 NodeMap<Node>& ear, |
518 UFE& blossom, UFE& tree, |
485 UFE& blossom, UFE& tree, |
519 std::queue<Node>& Q) { |
486 std::queue<Node>& Q) { |
|
487 //We traverse a blossom and update everything. |
|
488 |
520 ear.set(top,bottom); |
489 ear.set(top,bottom); |
521 Node t=top; |
490 Node t=top; |
522 while ( t!=middle ) { |
491 while ( t!=middle ) { |
523 Node u=_mate[t]; |
492 Node u=_mate[t]; |
524 t=ear[u]; |
493 t=ear[u]; |
535 blossom.insert(bottom); |
504 blossom.insert(bottom); |
536 blossom.join(bottom, oldmiddle); |
505 blossom.join(bottom, oldmiddle); |
537 blossom.join(top, oldmiddle); |
506 blossom.join(top, oldmiddle); |
538 } |
507 } |
539 |
508 |
|
509 |
|
510 template <typename Graph> |
|
511 bool MaxMatching<Graph>::growOrAugment(Node& y, Node& x, typename Graph::template |
|
512 NodeMap<Node>& ear, UFE& blossom, UFE& tree, |
|
513 std::queue<Node>& Q) { |
|
514 //x is in a blossom in the tree, y is outside. If y is covered by |
|
515 //the matching we grow, otherwise we augment. In this case we |
|
516 //return 1. |
|
517 |
|
518 if ( _mate[y]!=INVALID ) { //grow |
|
519 ear.set(y,x); |
|
520 Node w=_mate[y]; |
|
521 blossom.insert(w); |
|
522 position.set(y,A); |
|
523 position.set(w,D); |
|
524 tree.insert(y); |
|
525 tree.insert(w); |
|
526 tree.join(y,blossom.find(x)); |
|
527 tree.join(w,y); |
|
528 Q.push(w); |
|
529 } else { //augment |
|
530 augment(x, ear, blossom, tree); |
|
531 _mate.set(x,y); |
|
532 _mate.set(y,x); |
|
533 return true; |
|
534 } |
|
535 return false; |
|
536 } |
|
537 |
|
538 |
540 template <typename Graph> |
539 template <typename Graph> |
541 void MaxMatching<Graph>::augment(Node x, |
540 void MaxMatching<Graph>::augment(Node x, |
542 typename Graph::template NodeMap<Node>& ear, |
541 typename Graph::template NodeMap<Node>& ear, |
543 UFE& blossom, UFE& tree) { |
542 UFE& blossom, UFE& tree) { |
544 Node v=_mate[x]; |
543 Node v=_mate[x]; |