/* -*- C++ -*- * * This file is a part of LEMON, a generic C++ optimization library * * Copyright (C) 2003-2007 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Research Group on Combinatorial Optimization, EGRES). * * Permission to use, modify and distribute this software is granted * provided that this copyright notice appears in all copies. For * precise terms see the accompanying LICENSE file. * * This software is provided "AS IS" with no warranty of any kind, * express or implied, and with no claim as to its suitability for any * purpose. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace lemon; typedef dim2::Point Point; UGRAPH_TYPEDEFS(ListUGraph); bool progress=true; int N; // int girth; ListUGraph g; std::vector nodes; ListUGraph::NodeMap coords(g); int tsp_impr_num=0; const double EPSILON=1e-8; bool tsp_improve(Node u, Node v) { double luv=std::sqrt((coords[v]-coords[u]).normSquare()); Node u2=u; Node v2=v; do { Node n; for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e); u2=v2; v2=n; if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON> std::sqrt((coords[u]-coords[u2]).normSquare())+ std::sqrt((coords[v]-coords[v2]).normSquare())) { g.erase(findUEdge(g,u,v)); g.erase(findUEdge(g,u2,v2)); g.addEdge(u2,u); g.addEdge(v,v2); tsp_impr_num++; return true; } } while(v2!=u); return false; } bool tsp_improve(Node u) { for(IncEdgeIt e(g,u);e!=INVALID;++e) if(tsp_improve(u,g.runningNode(e))) return true; return false; } void tsp_improve() { bool b; do { b=false; for(NodeIt n(g);n!=INVALID;++n) if(tsp_improve(n)) b=true; } while(b); } void tsp() { for(int i=0;i" << l.b; return os; } bool cross(Line a, Line b) { Point ao=rot90(a.b-a.a); Point bo=rot90(b.b-b.a); return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 && (bo*(a.a-b.a))*(bo*(a.b-b.a))<0; } struct Pedge { Node a; Node b; double len; }; bool pedgeLess(Pedge a,Pedge b) { return a.len edges; void triangle() { Counter cnt("Number of edges added: "); std::vector pedges; for(NodeIt n(g);n!=INVALID;++n) for(NodeIt m=++(NodeIt(n));m!=INVALID;++m) { Pedge p; p.a=n; p.b=m; p.len=(coords[m]-coords[n]).normSquare(); pedges.push_back(p); } std::sort(pedges.begin(),pedges.end(),pedgeLess); for(std::vector::iterator pi=pedges.begin();pi!=pedges.end();++pi) { Line li(pi->a,pi->b); UEdgeIt e(g); for(;e!=INVALID && !cross(e,li);++e) ; UEdge ne; if(e==INVALID) { ne=g.addEdge(pi->a,pi->b); edges.push_back(ne); cnt++; } } } void sparse(int d) { Counter cnt("Number of edges removed: "); Bfs bfs(g); for(std::vector::reverse_iterator ei=edges.rbegin(); ei!=edges.rend();++ei) { Node a=g.source(*ei); Node b=g.target(*ei); g.erase(*ei); bfs.run(a,b); if(bfs.predEdge(b)==INVALID || bfs.dist(b)>d) g.addEdge(a,b); else cnt++; } } void sparse2(int d) { Counter cnt("Number of edges removed: "); for(std::vector::reverse_iterator ei=edges.rbegin(); ei!=edges.rend();++ei) { Node a=g.source(*ei); Node b=g.target(*ei); g.erase(*ei); ConstMap cegy(1); Suurballe > sur(g,cegy,a,b); int k=sur.run(2); if(k<2 || sur.totalLength()>d) g.addEdge(a,b); else cnt++; // else std::cout << "Remove edge " << g.id(a) << "-" << g.id(b) << '\n'; } } void sparseTriangle(int d) { Counter cnt("Number of edges added: "); std::vector pedges; for(NodeIt n(g);n!=INVALID;++n) for(NodeIt m=++(NodeIt(n));m!=INVALID;++m) { Pedge p; p.a=n; p.b=m; p.len=(coords[m]-coords[n]).normSquare(); pedges.push_back(p); } std::sort(pedges.begin(),pedges.end(),pedgeLess); for(std::vector::iterator pi=pedges.begin();pi!=pedges.end();++pi) { Line li(pi->a,pi->b); UEdgeIt e(g); for(;e!=INVALID && !cross(e,li);++e) ; UEdge ne; if(e==INVALID) { ConstMap cegy(1); Suurballe > sur(g,cegy,pi->a,pi->b); int k=sur.run(2); if(k<2 || sur.totalLength()>d) { ne=g.addEdge(pi->a,pi->b); edges.push_back(ne); cnt++; } } } } void minTree() { int en=0; int pr=0; std::vector pedges; Timer T; std::cout << T.realTime() << "s: Setting up the edges...\n"; for(NodeIt n(g);n!=INVALID;++n) { for(NodeIt m=++(NodeIt(n));m!=INVALID;++m) { Pedge p; p.a=n; p.b=m; p.len=(coords[m]-coords[n]).normSquare(); pedges.push_back(p); } en++; if(progress && en>=pr*double(N)/100) { std::cout << pr << "% \r" << std::flush; pr++; } } std::cout << T.realTime() << "s: Sorting the edges...\n"; std::sort(pedges.begin(),pedges.end(),pedgeLess); std::cout << T.realTime() << "s: Creating the tree...\n"; ListUGraph::NodeMap comp(g); UnionFind > uf(comp); for (NodeIt it(g); it != INVALID; ++it) uf.insert(it); for(std::vector::iterator pi=pedges.begin();pi!=pedges.end();++pi) { if ( uf.join(pi->a,pi->b) ) { g.addEdge(pi->a,pi->b); if(en>=N-1) break; } } std::cout << T.realTime() << "s: Done\n"; } int main(int argc,const char **argv) { ArgParser ap(argc,argv); // bool eps; bool disc_d, square_d, gauss_d; // bool tsp_a,two_a,tree_a; int num_of_cities=1; double area=1; N=100; // girth=10; std::string ndist("disc"); ap.refOption("n", "Number of nodes (default is 100)", N) .intOption("g", "Girth parameter (default is 10)", 10) .refOption("cities", "Number of cities (default is 1)", num_of_cities) .refOption("area", "Full relative area of the cities (default is 1)", area) .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",disc_d) .optionGroup("dist", "disc") .refOption("square", "Nodes are evenly distributed on a unit square", square_d) .optionGroup("dist", "square") .refOption("gauss", "Nodes are located according to a two-dim gauss distribution", gauss_d) .optionGroup("dist", "gauss") // .mandatoryGroup("dist") .onlyOneGroup("dist") .boolOption("eps", "Also generate .eps output (prefix.eps)") .boolOption("2con", "Create a two connected planar graph") .optionGroup("alg","2con") .boolOption("tree", "Create a min. cost spanning tree") .optionGroup("alg","tree") .boolOption("tsp", "Create a TSP tour") .optionGroup("alg","tsp") .onlyOneGroup("alg") .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'") .run(); std::string prefix; switch(ap.files().size()) { case 0: prefix="lgf-gen-out"; break; case 1: prefix=ap.files()[0]; break; default: std::cerr << "\nAt most one prefix can be given\n\n"; exit(1); } double sum_sizes=0; std::vector sizes; std::vector cum_sizes; for(int s=0;s(prefix+".lgf",g). writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)). writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)). run(); }