COIN-OR::LEMON - Graph Library

source: lemon-0.x/tools/lgf-gen.cc @ 2465:df09310da558

Last change on this file since 2465:df09310da558 was 2453:2800d9efb01d, checked in by Balazs Dezso, 17 years ago

Correction for multiple point on starting sweep line

File size: 21.3 KB
Line 
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
35using namespace lemon;
36
37typedef dim2::Point<double> Point;
38
39UGRAPH_TYPEDEFS(ListUGraph);
40
41bool progress=true;
42
43int N;
44// int girth;
45
46ListUGraph g;
47
48std::vector<Node> nodes;
49ListUGraph::NodeMap<Point> coords(g);
50
51
52double 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
59int tsp_impr_num=0;
60
61const double EPSILON=1e-8;
62bool 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
87bool 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
94void 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
104void tsp()
105{
106  for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
107  tsp_improve();
108}
109
110class Line
111{
112public:
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 
121inline std::ostream& operator<<(std::ostream &os, const Line &l)
122{
123  os << l.a << "->" << l.b;
124  return os;
125}
126
127bool 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
135struct Pedge
136{
137  Node a;
138  Node b;
139  double len;
140};
141
142bool pedgeLess(Pedge a,Pedge b)
143{
144  return a.len<b.len;
145}
146
147std::vector<UEdge> edges;
148
149namespace _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
248inline 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
443void 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
460void 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
479void 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
514template <typename UGraph, typename CoordMap>
515class LengthSquareMap {
516public:
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
528private:
529
530  const UGraph& _ugraph;
531  const CoordMap& _coords;
532};
533
534void 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
554void 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
661int 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
Note: See TracBrowser for help on using the repository browser.