1 #include <lemon/list_graph.h>
2 #include <lemon/graph_utils.h>
3 #include <lemon/random.h>
4 #include <lemon/dim2.h>
6 #include <lemon/counter.h>
7 #include <lemon/suurballe.h>
8 #include <lemon/graph_to_eps.h>
9 #include <lemon/graph_writer.h>
10 #include <lemon/arg_parser.h>
13 #include <lemon/unionfind.h>
15 using namespace lemon;
17 typedef dim2::Point<double> Point;
19 UGRAPH_TYPEDEFS(ListUGraph);
26 std::vector<Node> nodes;
27 ListUGraph::NodeMap<Point> coords(g);
31 const double EPSILON=1e-8;
32 bool tsp_improve(Node u, Node v)
34 double luv=std::sqrt((coords[v]-coords[u]).normSquare());
39 for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e);
42 if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON>
43 std::sqrt((coords[u]-coords[u2]).normSquare())+
44 std::sqrt((coords[v]-coords[v2]).normSquare()))
46 g.erase(findUEdge(g,u,v));
47 g.erase(findUEdge(g,u2,v2));
57 bool tsp_improve(Node u)
59 for(IncEdgeIt e(g,u);e!=INVALID;++e)
60 if(tsp_improve(u,g.runningNode(e))) return true;
69 for(NodeIt n(g);n!=INVALID;++n)
70 if(tsp_improve(n)) b=true;
76 for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
85 Line(Point _a,Point _b) :a(_a),b(_b) {}
86 Line(Node _a,Node _b) : a(coords[_a]),b(coords[_b]) {}
87 Line(const Edge &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
88 Line(const UEdge &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
91 inline std::ostream& operator<<(std::ostream &os, const Line &l)
93 os << l.a << "->" << l.b;
97 bool cross(Line a, Line b)
99 Point ao=rot90(a.b-a.a);
100 Point bo=rot90(b.b-b.a);
101 return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 &&
102 (bo*(a.a-b.a))*(bo*(a.b-b.a))<0;
112 bool pedgeLess(Pedge a,Pedge b)
117 std::vector<UEdge> edges;
121 Counter cnt("Number of edges added: ");
122 std::vector<Pedge> pedges;
123 for(NodeIt n(g);n!=INVALID;++n)
124 for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
129 p.len=(coords[m]-coords[n]).normSquare();
132 std::sort(pedges.begin(),pedges.end(),pedgeLess);
133 for(std::vector<Pedge>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
135 Line li(pi->a,pi->b);
137 for(;e!=INVALID && !cross(e,li);++e) ;
140 ne=g.addEdge(pi->a,pi->b);
149 Counter cnt("Number of edges removed: ");
150 Bfs<ListUGraph> bfs(g);
151 for(std::vector<UEdge>::reverse_iterator ei=edges.rbegin();
152 ei!=edges.rend();++ei)
154 Node a=g.source(*ei);
155 Node b=g.target(*ei);
158 if(bfs.predEdge(b)==INVALID || bfs.dist(b)>d)
166 Counter cnt("Number of edges removed: ");
167 for(std::vector<UEdge>::reverse_iterator ei=edges.rbegin();
168 ei!=edges.rend();++ei)
170 Node a=g.source(*ei);
171 Node b=g.target(*ei);
173 ConstMap<Edge,int> cegy(1);
174 Suurballe<ListUGraph,ConstMap<Edge,int> > sur(g,cegy,a,b);
176 if(k<2 || sur.totalLength()>d)
179 // else std::cout << "Remove edge " << g.id(a) << "-" << g.id(b) << '\n';
183 void sparseTriangle(int d)
185 Counter cnt("Number of edges added: ");
186 std::vector<Pedge> pedges;
187 for(NodeIt n(g);n!=INVALID;++n)
188 for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
193 p.len=(coords[m]-coords[n]).normSquare();
196 std::sort(pedges.begin(),pedges.end(),pedgeLess);
197 for(std::vector<Pedge>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
199 Line li(pi->a,pi->b);
201 for(;e!=INVALID && !cross(e,li);++e) ;
204 ConstMap<Edge,int> cegy(1);
205 Suurballe<ListUGraph,ConstMap<Edge,int> >
206 sur(g,cegy,pi->a,pi->b);
208 if(k<2 || sur.totalLength()>d)
210 ne=g.addEdge(pi->a,pi->b);
219 std::vector<Pedge> pedges;
220 for(NodeIt n(g);n!=INVALID;++n)
221 for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
226 p.len=(coords[m]-coords[n]).normSquare();
229 std::sort(pedges.begin(),pedges.end(),pedgeLess);
230 ListUGraph::NodeMap<int> comp(g);
231 UnionFind<ListUGraph::NodeMap<int> > uf(comp);
232 for (NodeIt it(g); it != INVALID; ++it)
236 for(std::vector<Pedge>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
238 if ( uf.join(pi->a,pi->b) ) {
239 g.addEdge(pi->a,pi->b);
248 int main(int argc,char **argv)
250 ArgParser ap(argc,argv);
253 bool disc_d, square_d, gauss_d;
254 bool tsp_a,two_a,tree_a;
259 std::string ndist("disc");
260 ap.option("n", "Number of nodes (default is 100)", N)
261 .option("g", "Girth parameter (default is 10)", girth)
262 .option("cities", "Number of cities (default is 1)", num_of_cities)
263 .option("area", "Full relative area of the cities (default is 1)", area)
264 .option("disc", "Nodes are evenly distributed on a unit disc (default)",disc_d)
265 .optionGroup("dist", "disc")
266 .option("square", "Nodes are evenly distributed on a unit square", square_d)
267 .optionGroup("dist", "square")
269 "Nodes are located according to a two-dim gauss distribution",
271 .optionGroup("dist", "gauss")
272 // .mandatoryGroup("dist")
273 .onlyOneGroup("dist")
274 .option("eps", "Also generate .eps output (prefix.eps)",eps)
275 .option("2con", "Create a two connected planar graph",two_a)
276 .optionGroup("alg","2con")
277 .option("tree", "Create a min. cost spanning tree",tree_a)
278 .optionGroup("alg","tree")
279 .option("tsp", "Create a TSP tour",tsp_a)
280 .optionGroup("alg","tsp")
282 .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
286 switch(ap.files().size())
289 prefix="lgf-gen-out";
292 prefix=ap.files()[0];
295 std::cerr << "\nAt most one prefix can be given\n\n";
300 std::vector<double> sizes;
301 std::vector<double> cum_sizes;
302 for(int s=0;s<num_of_cities;s++)
304 // sum_sizes+=rnd.exponential();
308 cum_sizes.push_back(sum_sizes);
311 for(int s=0;s<num_of_cities;s++)
313 Point center=(num_of_cities==1?Point(0,0):rnd.disc());
315 for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
318 coords[n]=center+rnd.gauss2()*area*
319 std::sqrt(sizes[s]/sum_sizes);
322 for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
325 coords[n]=center+Point(rnd()*2-1,rnd()*2-1)*area*
326 std::sqrt(sizes[s]/sum_sizes);
328 else if(disc_d || true)
329 for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
332 coords[n]=center+rnd.disc()*area*
333 std::sqrt(sizes[s]/sum_sizes);
339 std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
342 std::cout << "Make triangles\n";
344 sparseTriangle(girth);
345 std::cout << "Make it sparser\n";
353 std::cout << "Number of nodes : " << countNodes(g) << std::endl;
354 std::cout << "Number of edges : " << countUEdges(g) << std::endl;
356 for(UEdgeIt e(g);e!=INVALID;++e)
357 tlen+=sqrt((coords[g.source(e)]-coords[g.target(e)]).normSquare());
358 std::cout << "Total edge length : " << tlen << std::endl;
360 graphToEps(g,prefix+".eps").
361 scale(600).nodeScale(.2).edgeWidthScale(.001).preScale(false).
362 coords(coords).run();
364 UGraphWriter<ListUGraph>(prefix+".lgf",g).
365 writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)).
366 writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)).