Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/graphAlgorithms/match/altPath.cpp
00001 #include "altPath.h"
00002 
00003 using namespace grafalgo;
00004 
00005 // Find a maximum size matching in the bipartite graph graf and
00006 // return it as a list of edges. Return the number of edges
00007 // in the matching in size.
00008 altPath::altPath(Graph& graf1, Dlist& match1, int& size)
00009                  : graf(&graf1), match(&match1) {
00010         pEdge = new edge[graf->n()+1];
00011         
00012         edge e;
00013         size = 0;
00014         while((e = findPath()) != 0) { augment(e); size++; }
00015 
00016         delete [] pEdge;
00017 }
00018 
00019 // Modify the matching by augmenting along the path defined by
00020 // the edge e and the pEdge pointers.
00021 void altPath::augment(edge e) {
00022         vertex u; edge ee;
00023 
00024         u = graf->left(e);
00025         while (pEdge[u] != 0) {
00026                 ee = pEdge[u]; match->remove(ee);  u = graf->mate(u,ee); 
00027                 ee = pEdge[u]; match->addLast(ee); u = graf->mate(u,ee); 
00028         }
00029         u = graf->right(e);
00030         while (pEdge[u] != 0) {
00031                 ee = pEdge[u]; match->remove(ee);  u = graf->mate(u,ee); 
00032                 ee = pEdge[u]; match->addLast(ee); u = graf->mate(u,ee); 
00033         }
00034         match->addLast(e);
00035 }
00036 
00037 // Search for an augmenting path in the bipartite graph graf.
00038 // Return the edge that joins two separate trees in the forest
00039 // defined by pEdge. This edge, together with the paths
00040 // to the tree roots is an augmenting path.
00041 //
00042 edge altPath::findPath() {
00043         vertex u,v,w,x,y; edge e, f;
00044         enum stype { unreached, odd, even };
00045         stype state[graf->n()+1];
00046         edge mEdge[graf->n()+1];  // mEdge[u] = matching edge incident to u
00047 
00048         for (u = 1; u <= graf->n(); u++) {
00049                 state[u] = even; mEdge[u] = pEdge[u] = 0;
00050         }
00051 
00052         for (e = match->first(); e != 0; e = match->next(e)) {
00053                 u = graf->left(e); v = graf->right(e);
00054                 state[u] = state[v] = unreached;
00055                 mEdge[u] = mEdge[v] = e;
00056         }
00057         List q(graf->m());
00058         for (e = graf->first(); e != 0; e = graf->next(e)) {
00059                 if (state[graf->left(e)] == even ||
00060                     state[graf->right(e)] == even)
00061                         q.addLast(e);
00062         }
00063 
00064         while (!q.empty()) {
00065                 e = q.first(); q.removeFirst();
00066                 v = (state[graf->left(e)] == even ?
00067                         graf->left(e) : graf->right(e));
00068                 w = graf->mate(v,e);
00069                 if (state[w] == unreached && mEdge[w] != 0) {
00070                         x = graf->mate(w,mEdge[w]);
00071                         state[w] = odd; pEdge[w] = e;
00072                         state[x] = even; pEdge[x] = mEdge[x];
00073                         for (f = graf->firstAt(x); f != 0;
00074                              f = graf->nextAt(x,f)) {
00075                                 if ((f != mEdge[x]) && !q.member(f))
00076                                         q.addLast(f);
00077                         }
00078                 } else if (state[w] == even) {
00079                         for (x = w; pEdge[x] != 0; x = graf->mate(x,pEdge[x])){}
00080                         for (y = v; pEdge[y] != 0; y = graf->mate(y,pEdge[y])){}
00081                         if (x == y) Util::fatal("findpath: graph not bipartite");
00082                         return e;
00083                 }
00084         }
00085         return 0;
00086 }
 All Classes Files Functions Variables Typedefs Friends