tools/lgf-gen.cc
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 732 bb70ad62c95f
parent 615 7c1324b35d89
permissions -rw-r--r--
Fix critical bug in preflow (#372)

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