src/work/jacint/edmonds.h
changeset 534 22ce98f7d0f1
equal deleted inserted replaced
-1:000000000000 0:d2c3a328b9d8
       
     1 // -*- C++ -*-
       
     2 /*
       
     3 Kell meg a dual oldal
       
     4 esetleg az elejen moho matching kereses
       
     5 
       
     6   //baj van pos-sal: nem tudok vegigmaszni a halmazok elemein. De
       
     7   //pos-ra nem lenne szukseg ha unionfindban lenne egy element ami
       
     8   //true ha benne van false ha nincs
       
     9 
       
    10 MISI strukijahoz hasznalok:
       
    11 
       
    12 void addElement(b,a): b meg nem volt egy osztalyban sem, ezzel hozzaadjuk a osztalyahoz
       
    13 void insert(a): a meg nem volt egy osztalyban sem, ezzel egy uj egyelemu osztalyt alkot
       
    14 bool element(a): true ha benne van false ha nincs
       
    15 void erase(a)
       
    16 
       
    17 ez a 4 a vegso szetrobbantashoz es egyideju elemfelsorolashoz kell, mas megoldas is jo ehelyett:
       
    18 
       
    19 bool empty(int i): ures-e az i nevu osztaly
       
    20 int find(a)
       
    21 void pop(int i): egy fix elso elemet kitorol az i osztalybol
       
    22 T top(int i): visszad egy fix elso elemet 
       
    23 
       
    24 unionfindba kene:
       
    25 bool element(a): true ha benne van false ha nincs  (vagy 'bool empty')
       
    26 void split(a) (vagy clear)
       
    27 T rep(a): visszaadja a halmazanak reprezentanselemet, lehet operator()-val is
       
    28 void makeRep(a): a-t a sajat halmazanak reprezentansava teszi
       
    29 
       
    30 Szoljatok ha nem lehet valamelyiket hatekonyan
       
    31 */
       
    32 
       
    33 #ifndef HUGO_EDMONDS_H
       
    34 #define HUGO_EDMONDS_H
       
    35 
       
    36 #include <queue>
       
    37 
       
    38 #include <invalid.h>
       
    39 #include <unionfind.h>
       
    40 
       
    41 namespace hugo {
       
    42 
       
    43   template <typename Graph>
       
    44   class Edmonds {
       
    45     
       
    46     typedef typename Graph::Node Node;
       
    47     typedef typename Graph::Edge Edge;
       
    48     typedef typename Graph::EdgeIt EdgeIt;
       
    49     typedef typename Graph::NodeIt NodeIt;
       
    50     typedef typename Graph::OutEdgeIt OutEdgeIt;
       
    51 
       
    52     typedef UnionFindEnum<Node, Graph::NodeMap > ufe;
       
    53             
       
    54     const Graph& G;
       
    55 
       
    56   public:
       
    57     Edmonds(Graph& _G) : G(_G) {}
       
    58     
       
    59     
       
    60     int run(std::vector<Edge> matching) {
       
    61 
       
    62       enum pos_enum{
       
    63 	D=0,
       
    64 	A=1,
       
    65 	C=2
       
    66       };
       
    67       Graph::template NodeMap<pos_enum> pos(G,C);
       
    68 
       
    69       int p=0;   //needed for path
       
    70 
       
    71       typename Graph::NodeMap<Node> mate(G,INVALID);
       
    72       for ( int i=0; i!=matching.size(); ++i ) {
       
    73 	Node u=G.aNode(matching[i]);
       
    74 	Node v=G.bNode(matching[i]);
       
    75 	mate.set(u,v);
       
    76 	mate.set(v,u);
       
    77       }
       
    78       matching.clear();
       
    79 
       
    80       typename Graph::NodeMap<Node> ear(G,INVALID);   
       
    81       // a basepontok es a C-beliek earje szemet
       
    82 
       
    83       ufe::MapType blossom_base(G);
       
    84       ufe blossom(blossom_base);
       
    85       ufe::MapType tree_base(G);
       
    86       ufe tree(tree_base);
       
    87 
       
    88       NodeIt v;
       
    89       for(G.first(v); G.valid(v), G.next(v) ) {
       
    90 	
       
    91 	if ( pos[v]==C && mate[v]=INVALID ) {
       
    92 	  
       
    93 	  blossom.insert(v);
       
    94 	  tree.insert(v); 
       
    95 	  pos.set(v,D);
       
    96 
       
    97 	  std::queue<Node> Q;   //a vizsgalando csucsok sora
       
    98 	  Q.push(v);  
       
    99 
       
   100 	  while ( !Q.empty() ) {
       
   101 	    Node x=Q.top();
       
   102 	    Q.pop();
       
   103 	    
       
   104 	    OutEdgeIt e;
       
   105 	    for( G.first(e); G.valid(e), G.next(e) ) {
       
   106 	      Node y=G.bNode(e);
       
   107 
       
   108 	      if ( pos[y]==D ) { 
       
   109 
       
   110 		if ( tree.find(x) != tree.find(y) ) {  //augment 
       
   111 		  augment(x, mate, ear, blossom, tree); 
       
   112 		  augment(y, mate, ear, blossom, tree); 
       
   113 		  mate.set(x)=y;
       
   114 		  mate.set(y)=x;
       
   115 		  goto increased;
       
   116 		} else 
       
   117 		  if ( blossom.find(x) != blossom.find(y) ) {
       
   118 
       
   119 		    typename Graph::NodeMap<int> path(G,0);
       
   120 
       
   121 		    ++p;
       
   122 		    Node b=blossom.find(x);
       
   123 		    path.set(b,p);
       
   124 		    while ( b!=INVALID ) {
       
   125 		      b=blossom.find(ear[mate[b]]);
       
   126 		      path.set(b,p);
       
   127 		    }          //going till the root
       
   128 	
       
   129 		    Node w=y;
       
   130 		    Node v=blossom.find(w);
       
   131 		    while ( path[v]!=p ) {		      
       
   132 		      Q.push(mate[v]);
       
   133 		      w=shrink_step(w,v,mate,ear,tree,blossom);
       
   134 		      v=blossom.find(w);
       
   135 		    }
       
   136 		    //now v is the base of the first common ancestor
       
   137 
       
   138 		    w=x;
       
   139 		    Node z=blossom.find(w);
       
   140 		    while ( z!=v ) {
       
   141 		      Q.push(mate[z]);
       
   142 		      w=shrink_step(w,z,mate,ear,tree,blossom);
       
   143 		      z=blossom.find(w);
       
   144 		    }
       
   145 
       
   146 		    ear.set(x,y);
       
   147 		    ear.set(y,x);
       
   148 
       
   149 		    blossom.makeRep(v);
       
   150 		  }
       
   151 	      } else if ( pos[y] == C ) 
       
   152 		
       
   153 		if ( mate[y]!=INVALID ) {       //grow
       
   154 		  ear.set(y,x);
       
   155 		  Node w=mate(y);
       
   156 		  blossom.insert(w);
       
   157 		  tree.insert(w);
       
   158 		  tree.join(y,x);  
       
   159 		  tree.join(w,x);  
       
   160 		  Q.push(w);
       
   161 		} else {
       
   162 		  augment(x, mate, ear, blossom, tree); 
       
   163 		  mate.set(x)=y;
       
   164 		  mate.set(y)=x;
       
   165 		  goto increased;
       
   166 		}
       
   167 	    }
       
   168 	  }
       
   169 	increased:  //Misi, warningol, hogy nincs utasitas!
       
   170 	}
       
   171       }
       
   172 
       
   173       int s=0;
       
   174       NodeIt v;
       
   175       for(G.first(v); G.valid(v), G.next(v) ) 
       
   176 	if ( mate[v]!=INVALID ) ++s;
       
   177 	
       
   178       return (int)(s/2);
       
   179 
       
   180       //egyelore nem ad semmit vissza
       
   181       
       
   182     }
       
   183   
       
   184 
       
   185     void augment(const Node x, typename Graph::NodeMap<Node>& mate, 
       
   186 		 typename Graph::NodeMap<Node>& ear, 
       
   187 		 ufe& blossom, ufe& tree) { 
       
   188       Node v=mate[x];
       
   189       while ( v!=INVALID ) {
       
   190 	Node u=ear[v];
       
   191 	mate.set(v,u);
       
   192 	Node tmp=v;
       
   193 	v=mate[u];
       
   194 	mate.set(u,tmp);
       
   195       }
       
   196       //FIXME, blossom szetszed
       
   197       tree.eraseClass(x);
       
   198     }
       
   199 
       
   200 
       
   201     Node shrink_step(const Node z, const Node v, typename Graph::NodeMap<Node>& mate, 
       
   202 		     typename Graph::NodeMap<Node>& ear, 
       
   203 		     ufe& blossom, ufe& tree) {  
       
   204       if ( z!=v ) {
       
   205 	Node t=z;
       
   206 	Node u;
       
   207 	while ( t!=v ) {
       
   208 	  u=mate[t];
       
   209 	  t=ear[u];
       
   210 	}
       
   211 	ear.set(v,u);
       
   212       }
       
   213 
       
   214       Node u=mate[v];
       
   215       Node w=ear[u];
       
   216       tree.erase(u);
       
   217       tree.erase(v);
       
   218       blossom.insert(u);
       
   219       blossom.join(u,w);
       
   220       blossom.join(v,w);
       
   221       ear.set(w,u);      
       
   222 
       
   223       return w;
       
   224     }
       
   225 
       
   226 
       
   227   };
       
   228 
       
   229 } //namespace hugo
       
   230 
       
   231 #endif //EDMONDS_H
       
   232 
       
   233 
       
   234 
       
   235