# HG changeset patch # User jacint # Date 1083835583 0 # Node ID d8863141824dfd3634fd217a4338e623050102cf # Parent acd69f60b9c7f7b1f7261a8dff7d61628e7aa2ab diff -r acd69f60b9c7 -r d8863141824d src/work/jacint/edmonds.cc --- a/src/work/jacint/edmonds.cc Wed May 05 17:51:56 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -#include -#include -#include - -#include -#include - -using namespace hugo; - -int main (int, char*[]) -{ - typedef ListGraph::NodeIt NodeIt; - typedef ListGraph::EdgeIt EdgeIt; - typedef ListGraph::Node Node; - typedef ListGraph::Edge Edge; - typedef ListGraph::OutEdgeIt OutEdgeIt; - typedef ListGraph::InEdgeIt InEdgeIt; - - ListGraph flow_test; - - /* //Ahuja könyv példája, maxflowvalue=13*/ - Node s=flow_test.addNode(); - Node v1=flow_test.addNode(); - Node v2=flow_test.addNode(); - Node v3=flow_test.addNode(); - Node v4=flow_test.addNode(); - Node v5=flow_test.addNode(); - Node t=flow_test.addNode(); - - ListGraph::NodeMap Node_name(flow_test); - Node_name.set(s, "s"); - Node_name.set(v1, "v1"); - Node_name.set(v2, "v2"); - Node_name.set(v3, "v3"); - Node_name.set(v4, "v4"); - Node_name.set(v5, "v5"); - Node_name.set(t, "t"); - - Edge s_v1=flow_test.addEdge(s, v1); - Edge s_v2=flow_test.addEdge(s, v2); - Edge s_v3=flow_test.addEdge(s, v3); - Edge v2_v4=flow_test.addEdge(v2, v4); - Edge v2_v5=flow_test.addEdge(v2, v5); - Edge v3_v5=flow_test.addEdge(v3, v5); - Edge v4_t=flow_test.addEdge(v4, t); - Edge v5_t=flow_test.addEdge(v5, t); - Edge v2_s=flow_test.addEdge(v2, s); - - ListGraph::EdgeMap cap(flow_test); - cap.set(s_v1, 0); - cap.set(s_v2, 10); - cap.set(s_v3, 10); - cap.set(v2_v4, 5); - cap.set(v2_v5, 8); - cap.set(v3_v5, 5); - cap.set(v4_t, 8); - cap.set(v5_t, 8); - cap.set(v2_s, 0); - - - Edmonds edmonds(flow_test); - std::vector matching(0); - std::cout<< edmonds.run(matching); - - - /* //Marci példája, maxflowvalue=23 - Node s=flow_test.addNode(); - Node v1=flow_test.addNode(); - Node v2=flow_test.addNode(); - Node v3=flow_test.addNode(); - Node v4=flow_test.addNode(); - Node t=flow_test.addNode(); - Node z=flow_test.addNode(); - - - ListGraph::NodeMap Node_name(flow_test); - Node_name.set(s, "s"); - Node_name.set(v1, "v1"); - Node_name.set(v2, "v2"); - Node_name.set(v3, "v3"); - Node_name.set(v4, "v4"); - Node_name.set(t, "t"); - Node_name.set(z, "z"); - - Edge s_v1=flow_test.addEdge(s, v1); - Edge s_v2=flow_test.addEdge(s, v2); - Edge v1_v2=flow_test.addEdge(v1, v2); - Edge v2_v1=flow_test.addEdge(v2, v1); - Edge v1_v3=flow_test.addEdge(v1, v3); - Edge v3_v2=flow_test.addEdge(v3, v2); - Edge v2_v4=flow_test.addEdge(v2, v4); - Edge v4_v3=flow_test.addEdge(v4, v3); - Edge v3_t=flow_test.addEdge(v3, t); - Edge v4_t=flow_test.addEdge(v4, t); - Edge v3_v3=flow_test.addEdge(v3, v3); - Edge s_z=flow_test.addEdge(s, z); - // Edge v2_s=flow_test.addEdge(v2, s); - - - - ListGraph::EdgeMap cap(flow_test); - cap.set(s_v1, 16); - cap.set(s_v2, 13); - cap.set(v1_v2, 10); - cap.set(v2_v1, 4); - cap.set(v1_v3, 12); - cap.set(v3_v2, 9); - cap.set(v2_v4, 14); - cap.set(v4_v3, 7); - cap.set(v3_t, 20); - cap.set(v4_t, 4); - cap.set(v3_v3, 4); - cap.set(s_z, 4); - // cap.set(v2_s, 0); - - */ - - //pelda 3, maxflowvalue=4 - /* Node s=flow_test.addNode(); - Node v1=flow_test.addNode(); - Node v2=flow_test.addNode(); - Node t=flow_test.addNode(); - Node w=flow_test.addNode(); - - NodeMap Node_name(flow_test); - Node_name.set(s, "s"); - Node_name.set(v1, "v1"); - Node_name.set(v2, "v2"); - Node_name.set(t, "t"); - Node_name.set(w, "w"); - - Edge s_v1=flow_test.addEdge(s, v1); - Edge v1_v2=flow_test.addEdge(v1, v2); - Edge v2_t=flow_test.addEdge(v2, t); - Edge v1_v1=flow_test.addEdge(v1, v1); - Edge s_w=flow_test.addEdge(s, w); - - - EdgeMap cap(flow_test); - - cap.set(s_v1, 16); - cap.set(v1_v2, 10); - cap.set(v2_t, 4); - cap.set(v1_v1, 3); - cap.set(s_w, 5); - */ - - - - /* - std::cout << "Testing reverse_bfs..." << std::endl; - - reverse_bfs bfs_test(flow_test, t); - - bfs_test.run(); - - for (EachNodeIt w=flow_test.first_Node(); w.valid(); ++w) { - std::cout <<"The distance of " << w << " is " << bfs_test.dist(w) < preflow_push_test(flow_test, s, t, cap); - - preflow_push_test.run(); - - std::cout << "Maximum flow value is: " << preflow_push_test.maxflow() << "."< flow=preflow_push_test.allflow(); - for (EachEdgeIt e=flow_test.template first(); e.valid(); ++e) { - std::cout <<"Flow on Edge " << flow_test.tail(e) <<"-" << flow_test.head(e)<< " is " < mincut=preflow_push_test.mincut(); - - for (EachNodeIt v=flow_test.template first(); v.valid(); ++v) { - if (mincut.get(v)) std::cout < max_flow_test(flow_test, s, t, cap); - - max_flow_test.run(); - - std::cout << "Maximum flow value is: " << max_flow_test.maxflow() << "."<< std::endl; - - std::cout << "A minimum cut: " < mincut2=max_flow_test.mincut(); - - for (EachNodeIt v=flow_test.template first(); v.valid(); ++v) { - if (mincut2.get(v)) std::cout < - -#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 - - - -