gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Port lgf-gen from SVN -r3512 (#45) - apply the migrate script - apply the source unifyer - fix the compilation
0 1 1
default
2 files changed with 837 insertions and 1 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
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

	
Ignore white space 6 line context
1 1
if WANT_TOOLS
2 2

	
3 3
bin_PROGRAMS += \
4
	tools/dimacs-to-lgf
4
	tools/dimacs-to-lgf \
5
	tools/lgf-gen
5 6

	
6 7
dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
7 8

	
8 9
endif WANT_TOOLS
9 10

	
10 11
tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
12
tools_lgf_gen_SOURCES = tools/lgf-gen.cc
0 comments (0 inline)