COIN-OR::LEMON - Graph Library

source: lemon-0.x/tools/lgf-gen.cc @ 2453:2800d9efb01d

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

Correction for multiple point on starting sweep line

File size: 21.3 KB
RevLine 
[2391]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
[2390]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>
[2446]29#include <lemon/euler.h>
[2390]30#include <cmath>
31#include <algorithm>
[2447]32#include <lemon/kruskal.h>
[2402]33#include <lemon/time_measure.h>
[2390]34
35using namespace lemon;
36
37typedef dim2::Point<double> Point;
38
39UGRAPH_TYPEDEFS(ListUGraph);
40
[2402]41bool progress=true;
42
[2390]43int N;
[2402]44// int girth;
[2390]45
46ListUGraph g;
47
48std::vector<Node> nodes;
49ListUGraph::NodeMap<Point> coords(g);
50
[2446]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
[2390]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
[2447]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() {
[2390]249  Counter cnt("Number of edges added: ");
[2447]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
[2453]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  }
[2447]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
[2390]362      {
[2447]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        }
[2390]382      }
[2447]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));
[2390]407      }
[2447]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     
[2390]421    }
[2447]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  }
[2390]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
[2447]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
[2390]534void minTree() {
535  std::vector<Pedge> pedges;
[2402]536  Timer T;
[2447]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  }
[2402]551  std::cout << T.realTime() << "s: Done\n";
[2390]552}
553
[2446]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);
[2448]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);
[2446]589  }
590
591  for(NodeIt n(g);n!=INVALID;++n)
[2448]592    if(countIncEdges(g,n)%2 || countIncEdges(g,n)==0 )
[2446]593      std::cout << "GEBASZ!!!" << std::endl;
594 
[2448]595  for(UEdgeIt e(g);e!=INVALID;++e)
596    if(g.source(e)==g.target(e))
597      std::cout << "LOOP GEBASZ!!!" << std::endl;
598 
[2446]599  std::cout << "Number of edges : " << countUEdges(g) << std::endl;
600 
601  std::cout << "Total edge length (euler) : " << totalLen() << std::endl;
602
[2448]603  ListUGraph::UEdgeMap<Edge> enext(g);
[2446]604  {
605    UEulerIt<ListUGraph> e(g);
[2448]606    Edge eo=e;
607    Edge ef=e;
[2446]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  }
[2448]617   
[2446]618  std::cout << "Creating a tour from that..." << std::endl;
619 
620  int nnum = countNodes(g);
621  int ednum = countUEdges(g);
622 
[2448]623  for(Edge p=enext[UEdgeIt(g)];ednum>nnum;p=enext[p])
[2446]624    {
625//       std::cout << "Checking edge " << g.id(p) << std::endl;     
[2448]626      Edge e=enext[p];
627      Edge f=enext[e];
628      Node n2=g.source(f);
[2446]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;
[2448]634          Edge ff=enext[f];
[2446]635          g.erase(e);
636          g.erase(f);
[2448]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          }
[2446]648        }
649    }
650
651  std::cout << "Total edge length (tour) : " << totalLen() << std::endl;
652
[2448]653  std::cout << "2-opt the tour..." << std::endl;
654 
[2446]655  tsp_improve();
656 
657  std::cout << "Total edge length (2-opt tour) : " << totalLen() << std::endl;
658}
[2390]659
660
[2410]661int main(int argc,const char **argv)
[2390]662{
663  ArgParser ap(argc,argv);
664
[2402]665//   bool eps;
[2390]666  bool disc_d, square_d, gauss_d;
[2402]667//   bool tsp_a,two_a,tree_a;
[2390]668  int num_of_cities=1;
669  double area=1;
670  N=100;
[2402]671//   girth=10;
[2390]672  std::string ndist("disc");
[2402]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)
[2390]678    .optionGroup("dist", "disc")
[2402]679    .refOption("square", "Nodes are evenly distributed on a unit square", square_d)
[2390]680    .optionGroup("dist", "square")
[2402]681    .refOption("gauss",
[2390]682            "Nodes are located according to a two-dim gauss distribution",
683            gauss_d)
684    .optionGroup("dist", "gauss")
685//     .mandatoryGroup("dist")
686    .onlyOneGroup("dist")
[2402]687    .boolOption("eps", "Also generate .eps output (prefix.eps)")
[2446]688    .boolOption("dir", "Directed graph is generated (each edges are replaced by two directed ones)")
[2402]689    .boolOption("2con", "Create a two connected planar graph")
[2390]690    .optionGroup("alg","2con")
[2402]691    .boolOption("tree", "Create a min. cost spanning tree")
[2390]692    .optionGroup("alg","tree")
[2402]693    .boolOption("tsp", "Create a TSP tour")
[2390]694    .optionGroup("alg","tsp")
[2446]695    .boolOption("tsp2", "Create a TSP tour (tree based)")
696    .optionGroup("alg","tsp2")
[2447]697    .boolOption("dela", "Delaunay triangulation graph")
698    .optionGroup("alg","dela")
[2390]699    .onlyOneGroup("alg")
[2447]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")
[2390]705    .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
706    .run();
[2447]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  }
[2390]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    }
[2447]770
771//   for (ListUGraph::NodeIt n(g); n != INVALID; ++n) {
772//     std::cerr << coords[n] << std::endl;
773//   }
[2390]774 
[2402]775  if(ap["tsp"]) {
[2390]776    tsp();
777    std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
778  }
[2446]779  if(ap["tsp2"]) {
780    tsp2();
781    std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
782  }
[2402]783  else if(ap["2con"]) {
[2390]784    std::cout << "Make triangles\n";
785    //   triangle();
[2402]786    sparseTriangle(ap["g"]);
[2390]787    std::cout << "Make it sparser\n";
[2402]788    sparse2(ap["g"]);
[2390]789  }
[2402]790  else if(ap["tree"]) {
[2390]791    minTree();
792  }
[2447]793  else if(ap["dela"]) {
794    delaunay();
795  }
[2390]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;
[2448]804
[2402]805  if(ap["eps"])
[2453]806    graphToEps(g,prefix+".eps").scaleToA4().
[2390]807      scale(600).nodeScale(.2).edgeWidthScale(.001).preScale(false).
808      coords(coords).run();
[2448]809 
[2446]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();
[2390]819}
820
Note: See TracBrowser for help on using the repository browser.