diff -r acd69f60b9c7 -r d8863141824d src/work/jacint/edmonds.h --- a/src/work/jacint/edmonds.h Wed May 05 17:51:56 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -// -*- C++ -*- -/* -Kell meg a dual oldal -esetleg az elejen moho matching kereses - - //baj van pos-sal: nem tudok vegigmaszni a halmazok elemein. De - //pos-ra nem lenne szukseg ha unionfindban lenne egy element ami - //true ha benne van false ha nincs - -MISI strukijahoz hasznalok: - -void addElement(b,a): b meg nem volt egy osztalyban sem, ezzel hozzaadjuk a osztalyahoz -void insert(a): a meg nem volt egy osztalyban sem, ezzel egy uj egyelemu osztalyt alkot -bool element(a): true ha benne van false ha nincs -void erase(a) - -ez a 4 a vegso szetrobbantashoz es egyideju elemfelsorolashoz kell, mas megoldas is jo ehelyett: - -bool empty(int i): ures-e az i nevu osztaly -int find(a) -void pop(int i): egy fix elso elemet kitorol az i osztalybol -T top(int i): visszad egy fix elso elemet - -unionfindba kene: -bool element(a): true ha benne van false ha nincs (vagy 'bool empty') -void split(a) (vagy clear) -T rep(a): visszaadja a halmazanak reprezentanselemet, lehet operator()-val is -void makeRep(a): a-t a sajat halmazanak reprezentansava teszi - -Szoljatok ha nem lehet valamelyiket hatekonyan -*/ - -#ifndef HUGO_EDMONDS_H -#define HUGO_EDMONDS_H - -#include - -#include -#include - -namespace hugo { - - template - class Edmonds { - - typedef typename Graph::Node Node; - typedef typename Graph::Edge Edge; - typedef typename Graph::EdgeIt EdgeIt; - typedef typename Graph::NodeIt NodeIt; - typedef typename Graph::OutEdgeIt OutEdgeIt; - - typedef UnionFindEnum ufe; - - const Graph& G; - - public: - Edmonds(Graph& _G) : G(_G) {} - - - int run(std::vector matching) { - - enum pos_enum{ - D=0, - A=1, - C=2 - }; - Graph::template NodeMap pos(G,C); - - int p=0; //needed for path - - typename Graph::NodeMap mate(G,INVALID); - for ( int i=0; i!=matching.size(); ++i ) { - Node u=G.aNode(matching[i]); - Node v=G.bNode(matching[i]); - mate.set(u,v); - mate.set(v,u); - } - matching.clear(); - - typename Graph::NodeMap ear(G,INVALID); - // a basepontok es a C-beliek earje szemet - - ufe::MapType blossom_base(G); - ufe blossom(blossom_base); - ufe::MapType tree_base(G); - ufe tree(tree_base); - - NodeIt v; - for(G.first(v); G.valid(v), G.next(v) ) { - - if ( pos[v]==C && mate[v]=INVALID ) { - - blossom.insert(v); - tree.insert(v); - pos.set(v,D); - - std::queue Q; //a vizsgalando csucsok sora - Q.push(v); - - while ( !Q.empty() ) { - Node x=Q.top(); - Q.pop(); - - OutEdgeIt e; - for( G.first(e); G.valid(e), G.next(e) ) { - Node y=G.bNode(e); - - if ( pos[y]==D ) { - - if ( tree.find(x) != tree.find(y) ) { //augment - augment(x, mate, ear, blossom, tree); - augment(y, mate, ear, blossom, tree); - mate.set(x)=y; - mate.set(y)=x; - goto increased; - } else - if ( blossom.find(x) != blossom.find(y) ) { - - typename Graph::NodeMap path(G,0); - - ++p; - Node b=blossom.find(x); - path.set(b,p); - while ( b!=INVALID ) { - b=blossom.find(ear[mate[b]]); - path.set(b,p); - } //going till the root - - Node w=y; - Node v=blossom.find(w); - while ( path[v]!=p ) { - Q.push(mate[v]); - w=shrink_step(w,v,mate,ear,tree,blossom); - v=blossom.find(w); - } - //now v is the base of the first common ancestor - - w=x; - Node z=blossom.find(w); - while ( z!=v ) { - Q.push(mate[z]); - w=shrink_step(w,z,mate,ear,tree,blossom); - z=blossom.find(w); - } - - ear.set(x,y); - ear.set(y,x); - - blossom.makeRep(v); - } - } else if ( pos[y] == C ) - - if ( mate[y]!=INVALID ) { //grow - ear.set(y,x); - Node w=mate(y); - blossom.insert(w); - tree.insert(w); - tree.join(y,x); - tree.join(w,x); - Q.push(w); - } else { - augment(x, mate, ear, blossom, tree); - mate.set(x)=y; - mate.set(y)=x; - goto increased; - } - } - } - increased: //Misi, warningol, hogy nincs utasitas! - } - } - - int s=0; - NodeIt v; - for(G.first(v); G.valid(v), G.next(v) ) - if ( mate[v]!=INVALID ) ++s; - - return (int)(s/2); - - //egyelore nem ad semmit vissza - - } - - - void augment(const Node x, typename Graph::NodeMap& mate, - typename Graph::NodeMap& ear, - ufe& blossom, ufe& tree) { - Node v=mate[x]; - while ( v!=INVALID ) { - Node u=ear[v]; - mate.set(v,u); - Node tmp=v; - v=mate[u]; - mate.set(u,tmp); - } - //FIXME, blossom szetszed - tree.eraseClass(x); - } - - - Node shrink_step(const Node z, const Node v, typename Graph::NodeMap& mate, - typename Graph::NodeMap& ear, - ufe& blossom, ufe& tree) { - if ( z!=v ) { - Node t=z; - Node u; - while ( t!=v ) { - u=mate[t]; - t=ear[u]; - } - ear.set(v,u); - } - - Node u=mate[v]; - Node w=ear[u]; - tree.erase(u); - tree.erase(v); - blossom.insert(u); - blossom.join(u,w); - blossom.join(v,w); - ear.set(w,u); - - return w; - } - - - }; - -} //namespace hugo - -#endif //EDMONDS_H - - - -