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