tools/lgf-gen.cc
author deba
Tue, 09 Oct 2007 16:22:04 +0000
changeset 2490 31a93dd6f714
parent 2448 ab899ae3505f
child 2491 b63ae56979ef
permissions -rw-r--r--
Minor bug fixes in documentation
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2007
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #include <lemon/list_graph.h>
    20 #include <lemon/graph_utils.h>
    21 #include <lemon/random.h>
    22 #include <lemon/dim2.h>
    23 #include <lemon/bfs.h>
    24 #include <lemon/counter.h>
    25 #include <lemon/suurballe.h>
    26 #include <lemon/graph_to_eps.h>
    27 #include <lemon/graph_writer.h>
    28 #include <lemon/arg_parser.h>
    29 #include <lemon/euler.h>
    30 #include <cmath>
    31 #include <algorithm>
    32 #include <lemon/kruskal.h>
    33 #include <lemon/time_measure.h>
    34 
    35 using namespace lemon;
    36 
    37 typedef dim2::Point<double> Point;
    38 
    39 UGRAPH_TYPEDEFS(ListUGraph);
    40 
    41 bool progress=true;
    42 
    43 int N;
    44 // int girth;
    45 
    46 ListUGraph g;
    47 
    48 std::vector<Node> nodes;
    49 ListUGraph::NodeMap<Point> coords(g);
    50 
    51 
    52 double totalLen(){
    53   double tlen=0;
    54   for(UEdgeIt e(g);e!=INVALID;++e)
    55     tlen+=sqrt((coords[g.source(e)]-coords[g.target(e)]).normSquare());
    56   return tlen;
    57 }
    58 
    59 int tsp_impr_num=0;
    60 
    61 const double EPSILON=1e-8; 
    62 bool tsp_improve(Node u, Node v)
    63 {
    64   double luv=std::sqrt((coords[v]-coords[u]).normSquare());
    65   Node u2=u;
    66   Node v2=v;
    67   do {
    68     Node n;
    69     for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e);
    70     u2=v2;
    71     v2=n;
    72     if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON>
    73        std::sqrt((coords[u]-coords[u2]).normSquare())+
    74        std::sqrt((coords[v]-coords[v2]).normSquare()))
    75       {
    76  	g.erase(findUEdge(g,u,v));
    77  	g.erase(findUEdge(g,u2,v2));
    78 	g.addEdge(u2,u);
    79 	g.addEdge(v,v2);
    80 	tsp_impr_num++;
    81 	return true;
    82       }
    83   } while(v2!=u);
    84   return false;
    85 }
    86 
    87 bool tsp_improve(Node u)
    88 {
    89   for(IncEdgeIt e(g,u);e!=INVALID;++e)
    90     if(tsp_improve(u,g.runningNode(e))) return true;
    91   return false;
    92 }
    93 
    94 void tsp_improve()
    95 {
    96   bool b;
    97   do {
    98     b=false;
    99     for(NodeIt n(g);n!=INVALID;++n)
   100       if(tsp_improve(n)) b=true;
   101   } while(b);
   102 }
   103 
   104 void tsp()
   105 {
   106   for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
   107   tsp_improve();
   108 }
   109 
   110 class Line
   111 {
   112 public:
   113   Point a;
   114   Point b;
   115   Line(Point _a,Point _b) :a(_a),b(_b) {}
   116   Line(Node _a,Node _b) : a(coords[_a]),b(coords[_b]) {}
   117   Line(const Edge &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
   118   Line(const UEdge &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
   119 };
   120   
   121 inline std::ostream& operator<<(std::ostream &os, const Line &l)
   122 {
   123   os << l.a << "->" << l.b;
   124   return os;
   125 }
   126 
   127 bool cross(Line a, Line b) 
   128 {
   129   Point ao=rot90(a.b-a.a);
   130   Point bo=rot90(b.b-b.a);
   131   return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 &&
   132     (bo*(a.a-b.a))*(bo*(a.b-b.a))<0;
   133 }
   134 
   135 struct Pedge
   136 {
   137   Node a;
   138   Node b;
   139   double len;
   140 };
   141 
   142 bool pedgeLess(Pedge a,Pedge b)
   143 {
   144   return a.len<b.len;
   145 }
   146 
   147 std::vector<UEdge> edges;
   148 
   149 namespace _delaunay_bits {
   150 
   151   struct Part {
   152     int prev, curr, next;
   153 
   154     Part(int p, int c, int n) : prev(p), curr(c), next(n) {} 
   155   };
   156 
   157   inline std::ostream& operator<<(std::ostream& os, const Part& part) {
   158     os << '(' << part.prev << ',' << part.curr << ',' << part.next << ')';
   159     return os;
   160   }
   161 
   162   inline double circle_point(const Point& p, const Point& q, const Point& r) {
   163     double a = p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y);
   164     if (a == 0) return std::numeric_limits<double>::quiet_NaN();
   165 
   166     double d = (p.x * p.x + p.y * p.y) * (q.y - r.y) +
   167       (q.x * q.x + q.y * q.y) * (r.y - p.y) +
   168       (r.x * r.x + r.y * r.y) * (p.y - q.y);
   169 
   170     double e = (p.x * p.x + p.y * p.y) * (q.x - r.x) +
   171       (q.x * q.x + q.y * q.y) * (r.x - p.x) +
   172       (r.x * r.x + r.y * r.y) * (p.x - q.x);
   173 
   174     double f = (p.x * p.x + p.y * p.y) * (q.x * r.y - r.x * q.y) +
   175       (q.x * q.x + q.y * q.y) * (r.x * p.y - p.x * r.y) +
   176       (r.x * r.x + r.y * r.y) * (p.x * q.y - q.x * p.y);
   177 
   178     return d / (2 * a) + sqrt((d * d + e * e) / (4 * a * a) + f / a);
   179   }
   180 
   181   inline bool circle_form(const Point& p, const Point& q, const Point& r) {
   182     return rot90(q - p) * (r - q) < 0.0;
   183   }
   184 
   185   inline double intersection(const Point& p, const Point& q, double sx) {
   186     const double epsilon = 1e-8;
   187 
   188     if (p.x == q.x) return (p.y + q.y) / 2.0;
   189 
   190     if (sx < p.x + epsilon) return p.y;
   191     if (sx < q.x + epsilon) return q.y;
   192     
   193     double a = q.x - p.x;
   194     double b = (q.x - sx) * p.y - (p.x - sx) * q.y;    
   195     double d = (q.x - sx) * (p.x - sx) * (p - q).normSquare();
   196     return (b - sqrt(d)) / a;
   197   }
   198 
   199   struct YLess {
   200 
   201 
   202     YLess(const std::vector<Point>& points, double& sweep) 
   203       : _points(points), _sweep(sweep) {}
   204 
   205     bool operator()(const Part& l, const Part& r) const {
   206       const double epsilon = 1e-8;
   207 
   208       //      std::cerr << l << " vs " << r << std::endl;
   209       double lbx = l.prev != -1 ?
   210 	intersection(_points[l.prev], _points[l.curr], _sweep) :
   211 	- std::numeric_limits<double>::infinity();
   212       double rbx = r.prev != -1 ?
   213 	intersection(_points[r.prev], _points[r.curr], _sweep) :
   214 	- std::numeric_limits<double>::infinity();
   215       double lex = l.next != -1 ?
   216 	intersection(_points[l.curr], _points[l.next], _sweep) :
   217 	std::numeric_limits<double>::infinity();
   218       double rex = r.next != -1 ?
   219 	intersection(_points[r.curr], _points[r.next], _sweep) :
   220 	std::numeric_limits<double>::infinity();
   221 
   222       if (lbx > lex) std::swap(lbx, lex);
   223       if (rbx > rex) std::swap(rbx, rex);
   224 
   225       if (lex < epsilon + rex && lbx + epsilon < rex) return true;
   226       if (rex < epsilon + lex && rbx + epsilon < lex) return false;
   227       return lex < rex;
   228     }
   229     
   230     const std::vector<Point>& _points;
   231     double& _sweep;
   232   };
   233   
   234   struct BeachIt;
   235   
   236   typedef std::multimap<double, BeachIt> SpikeHeap;
   237 
   238   typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
   239 
   240   struct BeachIt {
   241     Beach::iterator it;
   242 
   243     BeachIt(Beach::iterator iter) : it(iter) {}
   244   };
   245 
   246 }
   247 
   248 inline void delaunay() {
   249   Counter cnt("Number of edges added: ");
   250   
   251   using namespace _delaunay_bits;
   252 
   253   typedef _delaunay_bits::Part Part;
   254   typedef std::vector<std::pair<double, int> > SiteHeap;
   255 
   256 
   257   std::vector<Point> points;
   258   std::vector<Node> nodes;
   259 
   260   for (NodeIt it(g); it != INVALID; ++it) {
   261     nodes.push_back(it);
   262     points.push_back(coords[it]);
   263   }
   264 
   265   SiteHeap siteheap(points.size());
   266 
   267   double sweep;
   268 
   269 
   270   for (int i = 0; i < int(siteheap.size()); ++i) {
   271     siteheap[i] = std::make_pair(points[i].x, i);
   272   }
   273   
   274   std::sort(siteheap.begin(), siteheap.end());
   275   sweep = siteheap.front().first;
   276   
   277   YLess yless(points, sweep);
   278   Beach beach(yless);
   279 
   280   SpikeHeap spikeheap;
   281 
   282   std::set<std::pair<int, int> > edges;
   283 
   284   int siteindex = 0;
   285   {
   286     SiteHeap front;
   287 
   288     while (siteindex < int(siteheap.size()) &&
   289 	   siteheap[0].first == siteheap[siteindex].first) {
   290       front.push_back(std::make_pair(points[siteheap[siteindex].second].y,
   291 				     siteheap[siteindex].second));
   292       ++siteindex;
   293     }
   294     
   295     std::sort(front.begin(), front.end());
   296 
   297     for (int i = 0; i < int(front.size()); ++i) {
   298       int prev = (i == 0 ? -1 : front[i - 1].second);
   299       int curr = front[i].second;
   300       int next = (i + 1 == int(front.size()) ? -1 : front[i + 1].second);
   301 
   302       beach.insert(std::make_pair(Part(prev, curr, next), 
   303 				  spikeheap.end()));      
   304     }
   305   }
   306 
   307   while (siteindex < int(points.size()) || !spikeheap.empty()) {
   308 
   309     SpikeHeap::iterator spit = spikeheap.begin();
   310 
   311     if (siteindex < int(points.size()) && 
   312 	(spit == spikeheap.end() || siteheap[siteindex].first < spit->first)) {
   313       int site = siteheap[siteindex].second;
   314       sweep = siteheap[siteindex].first;
   315           
   316       Beach::iterator bit = beach.upper_bound(Part(site, site, site));
   317       
   318       if (bit->second != spikeheap.end()) {
   319 	spikeheap.erase(bit->second);	
   320       }
   321 
   322       int prev = bit->first.prev;
   323       int curr = bit->first.curr;
   324       int next = bit->first.next;
   325 
   326       beach.erase(bit);
   327       
   328       SpikeHeap::iterator pit = spikeheap.end();
   329       if (prev != -1 && 
   330 	  circle_form(points[prev], points[curr], points[site])) {
   331 	double x = circle_point(points[prev], points[curr], points[site]);
   332 	pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
   333 	pit->second.it =
   334 	  beach.insert(std::make_pair(Part(prev, curr, site), pit));
   335       } else {
   336 	beach.insert(std::make_pair(Part(prev, curr, site), pit));
   337       }
   338 
   339       beach.insert(std::make_pair(Part(curr, site, curr), spikeheap.end()));
   340       
   341       SpikeHeap::iterator nit = spikeheap.end();
   342       if (next != -1 && 
   343 	  circle_form(points[site], points[curr],points[next])) {
   344 	double x = circle_point(points[site], points[curr], points[next]);
   345 	nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
   346 	nit->second.it =
   347 	  beach.insert(std::make_pair(Part(site, curr, next), nit));
   348       } else {
   349 	beach.insert(std::make_pair(Part(site, curr, next), nit));
   350       }
   351       
   352       ++siteindex;
   353     } else {
   354       sweep = spit->first;      
   355 
   356       Beach::iterator bit = spit->second.it;
   357 
   358       int prev = bit->first.prev;
   359       int curr = bit->first.curr;
   360       int next = bit->first.next;
   361 
   362       {
   363 	std::pair<int, int> edge;
   364 
   365 	edge = prev < curr ? 
   366 	  std::make_pair(prev, curr) : std::make_pair(curr, prev);
   367 	
   368 	if (edges.find(edge) == edges.end()) {
   369 	  edges.insert(edge);
   370 	  g.addEdge(nodes[prev], nodes[curr]);
   371 	  ++cnt;
   372 	}
   373 
   374 	edge = curr < next ? 
   375 	  std::make_pair(curr, next) : std::make_pair(next, curr);
   376 	
   377 	if (edges.find(edge) == edges.end()) {
   378 	  edges.insert(edge);
   379 	  g.addEdge(nodes[curr], nodes[next]);
   380 	  ++cnt;
   381 	}
   382       }
   383       
   384       Beach::iterator pbit = bit; --pbit;
   385       int ppv = pbit->first.prev;
   386       Beach::iterator nbit = bit; ++nbit;
   387       int nnt = nbit->first.next;
   388 
   389       if (bit->second != spikeheap.end()) spikeheap.erase(bit->second);
   390       if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
   391       if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second);
   392 
   393       beach.erase(nbit);
   394       beach.erase(bit);
   395       beach.erase(pbit);
   396 
   397       SpikeHeap::iterator pit = spikeheap.end();
   398       if (ppv != -1 && ppv != next && 
   399 	  circle_form(points[ppv], points[prev], points[next])) {
   400 	double x = circle_point(points[ppv], points[prev], points[next]);
   401 	if (x < sweep) x = sweep;
   402 	pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
   403 	pit->second.it =
   404 	  beach.insert(std::make_pair(Part(ppv, prev, next), pit));
   405       } else {
   406 	beach.insert(std::make_pair(Part(ppv, prev, next), pit));
   407       }
   408 
   409       SpikeHeap::iterator nit = spikeheap.end();
   410       if (nnt != -1 && prev != nnt &&
   411 	  circle_form(points[prev], points[next], points[nnt])) {
   412 	double x = circle_point(points[prev], points[next], points[nnt]);
   413 	if (x < sweep) x = sweep;
   414 	nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
   415 	nit->second.it =
   416 	  beach.insert(std::make_pair(Part(prev, next, nnt), nit));
   417       } else {
   418 	beach.insert(std::make_pair(Part(prev, next, nnt), nit));
   419       }
   420       
   421     }
   422   }
   423 
   424   for (Beach::iterator it = beach.begin(); it != beach.end(); ++it) {
   425     int curr = it->first.curr;
   426     int next = it->first.next;
   427 
   428     if (next == -1) continue;
   429 
   430     std::pair<int, int> edge;
   431 
   432     edge = curr < next ? 
   433       std::make_pair(curr, next) : std::make_pair(next, curr);
   434     
   435     if (edges.find(edge) == edges.end()) {
   436       edges.insert(edge);
   437       g.addEdge(nodes[curr], nodes[next]);
   438       ++cnt;
   439     }
   440   }
   441 }
   442 
   443 void sparse(int d) 
   444 {
   445   Counter cnt("Number of edges removed: ");
   446   Bfs<ListUGraph> bfs(g);
   447   for(std::vector<UEdge>::reverse_iterator ei=edges.rbegin();
   448       ei!=edges.rend();++ei)
   449     {
   450       Node a=g.source(*ei);
   451       Node b=g.target(*ei);
   452       g.erase(*ei);
   453       bfs.run(a,b);
   454       if(bfs.predEdge(b)==INVALID || bfs.dist(b)>d)
   455 	g.addEdge(a,b);
   456       else cnt++;
   457     }
   458 }
   459 
   460 void sparse2(int d) 
   461 {
   462   Counter cnt("Number of edges removed: ");
   463   for(std::vector<UEdge>::reverse_iterator ei=edges.rbegin();
   464       ei!=edges.rend();++ei)
   465     {
   466       Node a=g.source(*ei);
   467       Node b=g.target(*ei);
   468       g.erase(*ei);
   469       ConstMap<Edge,int> cegy(1);
   470       Suurballe<ListUGraph,ConstMap<Edge,int> > sur(g,cegy,a,b);
   471       int k=sur.run(2);
   472       if(k<2 || sur.totalLength()>d)
   473 	g.addEdge(a,b);
   474       else cnt++;
   475 //       else std::cout << "Remove edge " << g.id(a) << "-" << g.id(b) << '\n';
   476     }
   477 }
   478 
   479 void sparseTriangle(int d)
   480 {
   481   Counter cnt("Number of edges added: ");
   482   std::vector<Pedge> pedges;
   483   for(NodeIt n(g);n!=INVALID;++n) 
   484     for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
   485       {
   486 	Pedge p;
   487 	p.a=n;
   488 	p.b=m;
   489 	p.len=(coords[m]-coords[n]).normSquare();
   490 	pedges.push_back(p);
   491       }
   492   std::sort(pedges.begin(),pedges.end(),pedgeLess);
   493   for(std::vector<Pedge>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
   494     {
   495       Line li(pi->a,pi->b);
   496       UEdgeIt e(g);
   497       for(;e!=INVALID && !cross(e,li);++e) ;
   498       UEdge ne;
   499       if(e==INVALID) {
   500 	ConstMap<Edge,int> cegy(1);
   501 	Suurballe<ListUGraph,ConstMap<Edge,int> >
   502 	  sur(g,cegy,pi->a,pi->b);
   503 	int k=sur.run(2);
   504 	if(k<2 || sur.totalLength()>d)
   505 	  {
   506 	    ne=g.addEdge(pi->a,pi->b);
   507 	    edges.push_back(ne);
   508 	    cnt++;
   509 	  }
   510       }
   511     }
   512 }
   513 
   514 template <typename UGraph, typename CoordMap>
   515 class LengthSquareMap {
   516 public:
   517   typedef typename UGraph::UEdge Key;
   518   typedef typename CoordMap::Value::Value Value;
   519 
   520   LengthSquareMap(const UGraph& ugraph, const CoordMap& coords)
   521     : _ugraph(ugraph), _coords(coords) {}
   522 
   523   Value operator[](const Key& key) const {
   524     return (_coords[_ugraph.target(key)] -
   525 	    _coords[_ugraph.source(key)]).normSquare();
   526   }
   527 
   528 private:
   529 
   530   const UGraph& _ugraph;
   531   const CoordMap& _coords;
   532 };
   533 
   534 void minTree() {
   535   std::vector<Pedge> pedges;
   536   Timer T;
   537   std::cout << T.realTime() << "s: Creating delaunay triangulation...\n";
   538   delaunay();
   539   std::cout << T.realTime() << "s: Calculating spanning tree...\n";
   540   LengthSquareMap<ListUGraph, ListUGraph::NodeMap<Point> > ls(g, coords);
   541   ListUGraph::UEdgeMap<bool> tree(g);
   542   kruskal(g, ls, tree);
   543   std::cout << T.realTime() << "s: Removing non tree edges...\n";
   544   std::vector<UEdge> remove;
   545   for (UEdgeIt e(g); e != INVALID; ++e) {
   546     if (!tree[e]) remove.push_back(e);
   547   }
   548   for(int i = 0; i < int(remove.size()); ++i) {
   549     g.erase(remove[i]);
   550   }
   551   std::cout << T.realTime() << "s: Done\n";
   552 }
   553 
   554 void tsp2() 
   555 {
   556   std::cout << "Find a tree..." << std::endl;
   557 
   558   minTree();
   559 
   560   std::cout << "Total edge length (tree) : " << totalLen() << std::endl;
   561 
   562   std::cout << "Make it Euler..." << std::endl;
   563 
   564   {
   565     std::vector<Node> leafs;
   566     for(NodeIt n(g);n!=INVALID;++n)
   567       if(countIncEdges(g,n)%2==1) leafs.push_back(n);
   568 
   569 //    for(unsigned int i=0;i<leafs.size();i+=2)
   570 //       g.addEdge(leafs[i],leafs[i+1]);
   571 
   572     std::vector<Pedge> pedges;
   573     for(unsigned int i=0;i<leafs.size()-1;i++)
   574       for(unsigned int j=i+1;j<leafs.size();j++)
   575 	{
   576 	  Node n=leafs[i];
   577 	  Node m=leafs[j];
   578 	  Pedge p;
   579 	  p.a=n;
   580 	  p.b=m;
   581 	  p.len=(coords[m]-coords[n]).normSquare();
   582 	  pedges.push_back(p);
   583 	}
   584     std::sort(pedges.begin(),pedges.end(),pedgeLess);
   585     for(unsigned int i=0;i<pedges.size();i++)
   586       if(countIncEdges(g,pedges[i].a)%2 &&
   587 	 countIncEdges(g,pedges[i].b)%2)
   588 	g.addEdge(pedges[i].a,pedges[i].b);
   589   }
   590 
   591   for(NodeIt n(g);n!=INVALID;++n)
   592     if(countIncEdges(g,n)%2 || countIncEdges(g,n)==0 )
   593       std::cout << "GEBASZ!!!" << std::endl;
   594   
   595   for(UEdgeIt e(g);e!=INVALID;++e)
   596     if(g.source(e)==g.target(e))
   597       std::cout << "LOOP GEBASZ!!!" << std::endl;
   598   
   599   std::cout << "Number of edges : " << countUEdges(g) << std::endl;
   600   
   601   std::cout << "Total edge length (euler) : " << totalLen() << std::endl;
   602 
   603   ListUGraph::UEdgeMap<Edge> enext(g);
   604   {
   605     UEulerIt<ListUGraph> e(g);
   606     Edge eo=e;
   607     Edge ef=e;
   608 //     std::cout << "Tour edge: " << g.id(UEdge(e)) << std::endl;      
   609     for(++e;e!=INVALID;++e)
   610       {
   611 // 	std::cout << "Tour edge: " << g.id(UEdge(e)) << std::endl;      
   612 	enext[eo]=e;
   613 	eo=e;
   614       }
   615     enext[eo]=ef;
   616   }
   617     
   618   std::cout << "Creating a tour from that..." << std::endl;
   619   
   620   int nnum = countNodes(g);
   621   int ednum = countUEdges(g);
   622   
   623   for(Edge p=enext[UEdgeIt(g)];ednum>nnum;p=enext[p]) 
   624     {
   625 //       std::cout << "Checking edge " << g.id(p) << std::endl;      
   626       Edge e=enext[p];
   627       Edge f=enext[e];
   628       Node n2=g.source(f);
   629       Node n1=g.oppositeNode(n2,e);
   630       Node n3=g.oppositeNode(n2,f);
   631       if(countIncEdges(g,n2)>2)
   632 	{
   633 // 	  std::cout << "Remove an Edge" << std::endl;
   634 	  Edge ff=enext[f];
   635 	  g.erase(e);
   636 	  g.erase(f);
   637 	  if(n1!=n3)
   638 	    {
   639 	      Edge ne=g.direct(g.addEdge(n1,n3),n1);
   640 	      enext[p]=ne;
   641 	      enext[ne]=ff;
   642 	      ednum--;
   643 	    }
   644 	  else {
   645 	    enext[p]=ff;
   646 	    ednum-=2;
   647 	  }
   648 	}
   649     }
   650 
   651   std::cout << "Total edge length (tour) : " << totalLen() << std::endl;
   652 
   653   std::cout << "2-opt the tour..." << std::endl;
   654   
   655   tsp_improve();
   656   
   657   std::cout << "Total edge length (2-opt tour) : " << totalLen() << std::endl;
   658 }
   659 
   660 
   661 int main(int argc,const char **argv) 
   662 {
   663   ArgParser ap(argc,argv);
   664 
   665 //   bool eps;
   666   bool disc_d, square_d, gauss_d;
   667 //   bool tsp_a,two_a,tree_a;
   668   int num_of_cities=1;
   669   double area=1;
   670   N=100;
   671 //   girth=10;
   672   std::string ndist("disc");
   673   ap.refOption("n", "Number of nodes (default is 100)", N)
   674     .intOption("g", "Girth parameter (default is 10)", 10)
   675     .refOption("cities", "Number of cities (default is 1)", num_of_cities)
   676     .refOption("area", "Full relative area of the cities (default is 1)", area)
   677     .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",disc_d)
   678     .optionGroup("dist", "disc")
   679     .refOption("square", "Nodes are evenly distributed on a unit square", square_d)
   680     .optionGroup("dist", "square")
   681     .refOption("gauss",
   682 	    "Nodes are located according to a two-dim gauss distribution",
   683 	    gauss_d)
   684     .optionGroup("dist", "gauss")
   685 //     .mandatoryGroup("dist")
   686     .onlyOneGroup("dist")
   687     .boolOption("eps", "Also generate .eps output (prefix.eps)")
   688     .boolOption("dir", "Directed graph is generated (each edges are replaced by two directed ones)")
   689     .boolOption("2con", "Create a two connected planar graph")
   690     .optionGroup("alg","2con")
   691     .boolOption("tree", "Create a min. cost spanning tree")
   692     .optionGroup("alg","tree")
   693     .boolOption("tsp", "Create a TSP tour")
   694     .optionGroup("alg","tsp")
   695     .boolOption("tsp2", "Create a TSP tour (tree based)")
   696     .optionGroup("alg","tsp2")
   697     .boolOption("dela", "Delaunay triangulation graph")
   698     .optionGroup("alg","dela")
   699     .onlyOneGroup("alg")
   700     .boolOption("rand", "Use time seed for random number generator")
   701     .optionGroup("rand", "rand")
   702     .intOption("seed", "Random seed", -1)
   703     .optionGroup("rand", "seed")
   704     .onlyOneGroup("rand")
   705     .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
   706     .run();
   707 
   708   if (ap["rand"]) {
   709     int seed = time(0);
   710     std::cout << "Random number seed: " << seed << std::endl;
   711     rnd = Random(seed);
   712   }
   713   if (ap.given("seed")) {
   714     int seed = ap["seed"];
   715     std::cout << "Random number seed: " << seed << std::endl;
   716     rnd = Random(seed);
   717   }
   718   
   719   std::string prefix;
   720   switch(ap.files().size()) 
   721     {
   722     case 0:
   723       prefix="lgf-gen-out";
   724       break;
   725     case 1:
   726       prefix=ap.files()[0];
   727       break;
   728     default:
   729       std::cerr << "\nAt most one prefix can be given\n\n";
   730       exit(1);
   731     }
   732   
   733   double sum_sizes=0;
   734   std::vector<double> sizes;
   735   std::vector<double> cum_sizes;
   736   for(int s=0;s<num_of_cities;s++) 
   737     {
   738       // 	sum_sizes+=rnd.exponential();
   739       double d=rnd();
   740       sum_sizes+=d;
   741       sizes.push_back(d);
   742       cum_sizes.push_back(sum_sizes);
   743     }
   744   int i=0;
   745   for(int s=0;s<num_of_cities;s++) 
   746     {
   747       Point center=(num_of_cities==1?Point(0,0):rnd.disc());
   748       if(gauss_d)
   749 	for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
   750 	  Node n=g.addNode();
   751 	  nodes.push_back(n);
   752 	  coords[n]=center+rnd.gauss2()*area*
   753 	    std::sqrt(sizes[s]/sum_sizes);
   754 	}
   755       else if(square_d)
   756 	for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
   757 	  Node n=g.addNode();
   758 	  nodes.push_back(n);
   759 	  coords[n]=center+Point(rnd()*2-1,rnd()*2-1)*area*
   760 	    std::sqrt(sizes[s]/sum_sizes);
   761 	}
   762       else if(disc_d || true)
   763 	for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
   764 	  Node n=g.addNode();
   765 	  nodes.push_back(n);
   766 	  coords[n]=center+rnd.disc()*area*
   767 	    std::sqrt(sizes[s]/sum_sizes);
   768 	}
   769     }
   770 
   771 //   for (ListUGraph::NodeIt n(g); n != INVALID; ++n) {
   772 //     std::cerr << coords[n] << std::endl;
   773 //   }
   774   
   775   if(ap["tsp"]) {
   776     tsp();
   777     std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
   778   }
   779   if(ap["tsp2"]) {
   780     tsp2();
   781     std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
   782   }
   783   else if(ap["2con"]) {
   784     std::cout << "Make triangles\n";
   785     //   triangle();
   786     sparseTriangle(ap["g"]);
   787     std::cout << "Make it sparser\n";
   788     sparse2(ap["g"]);
   789   }
   790   else if(ap["tree"]) {
   791     minTree();
   792   }
   793   else if(ap["dela"]) {
   794     delaunay();
   795   }
   796   
   797 
   798   std::cout << "Number of nodes    : " << countNodes(g) << std::endl;
   799   std::cout << "Number of edges    : " << countUEdges(g) << std::endl;
   800   double tlen=0;
   801   for(UEdgeIt e(g);e!=INVALID;++e)
   802     tlen+=sqrt((coords[g.source(e)]-coords[g.target(e)]).normSquare());
   803   std::cout << "Total edge length  : " << tlen << std::endl;
   804 
   805   if(ap["eps"])
   806     graphToEps(g,prefix+".eps").scaleToA4().
   807       scale(600).nodeScale(.2).edgeWidthScale(.001).preScale(false).
   808       coords(coords).run();
   809   
   810   if(ap["dir"])
   811     GraphWriter<ListUGraph>(prefix+".lgf",g).
   812       writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)).
   813       writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)).
   814       run();
   815   else UGraphWriter<ListUGraph>(prefix+".lgf",g).
   816 	 writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)).
   817 	 writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)).
   818 	 run();
   819 }
   820