[Lemon-commits] Alpar Juttner: Port lgf-gen from SVN -r3512 (#45)

Lemon HG hg at lemon.cs.elte.hu
Mon Feb 23 12:32:18 CET 2009


details:   http://lemon.cs.elte.hu/hg/lemon/rev/d9e43511d11c
changeset: 539:d9e43511d11c
user:      Alpar Juttner <alpar [at] cs.elte.hu>
date:      Mon Feb 23 11:30:15 2009 +0000
description:
	Port lgf-gen from SVN -r3512 (#45)

	 - apply the migrate script
	 - apply the source unifyer
	 - fix the compilation

diffstat:

2 files changed, 837 insertions(+), 1 deletion(-)
tools/Makefile.am |    4 
tools/lgf-gen.cc  |  834 +++++++++++++++++++++++++++++++++++++++++++++++++++++

diffs (truncated from 856 to 300 lines):

diff --git a/tools/Makefile.am b/tools/Makefile.am
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,10 +1,12 @@
 if WANT_TOOLS
 
 bin_PROGRAMS += \
-	tools/dimacs-to-lgf
+	tools/dimacs-to-lgf \
+	tools/lgf-gen
 
 dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
 
 endif WANT_TOOLS
 
 tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
+tools_lgf_gen_SOURCES = tools/lgf-gen.cc
diff --git a/tools/lgf-gen.cc b/tools/lgf-gen.cc
new file mode 100644
--- /dev/null
+++ b/tools/lgf-gen.cc
@@ -0,0 +1,834 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+/// \ingroup tools
+/// \file
+/// \brief Special plane digraph generator.
+///
+/// Graph generator application for various types of plane graphs.
+///
+/// See
+/// \verbatim
+///  lgf-gen --help
+/// \endverbatim
+/// for more info on the usage.
+///
+
+
+#include <algorithm>
+#include <set>
+#include <lemon/list_graph.h>
+#include <lemon/random.h>
+#include <lemon/dim2.h>
+#include <lemon/bfs.h>
+#include <lemon/counter.h>
+#include <lemon/suurballe.h>
+#include <lemon/graph_to_eps.h>
+#include <lemon/lgf_writer.h>
+#include <lemon/arg_parser.h>
+#include <lemon/euler.h>
+#include <lemon/math.h>
+#include <lemon/kruskal.h>
+#include <lemon/time_measure.h>
+
+using namespace lemon;
+
+typedef dim2::Point<double> Point;
+
+GRAPH_TYPEDEFS(ListGraph);
+
+bool progress=true;
+
+int N;
+// int girth;
+
+ListGraph g;
+
+std::vector<Node> nodes;
+ListGraph::NodeMap<Point> coords(g);
+
+
+double totalLen(){
+  double tlen=0;
+  for(EdgeIt e(g);e!=INVALID;++e)
+    tlen+=sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
+  return tlen;
+}
+
+int tsp_impr_num=0;
+
+const double EPSILON=1e-8;
+bool tsp_improve(Node u, Node v)
+{
+  double luv=std::sqrt((coords[v]-coords[u]).normSquare());
+  Node u2=u;
+  Node v2=v;
+  do {
+    Node n;
+    for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e) { }
+    u2=v2;
+    v2=n;
+    if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON>
+       std::sqrt((coords[u]-coords[u2]).normSquare())+
+       std::sqrt((coords[v]-coords[v2]).normSquare()))
+      {
+         g.erase(findEdge(g,u,v));
+         g.erase(findEdge(g,u2,v2));
+        g.addEdge(u2,u);
+        g.addEdge(v,v2);
+        tsp_impr_num++;
+        return true;
+      }
+  } while(v2!=u);
+  return false;
+}
+
+bool tsp_improve(Node u)
+{
+  for(IncEdgeIt e(g,u);e!=INVALID;++e)
+    if(tsp_improve(u,g.runningNode(e))) return true;
+  return false;
+}
+
+void tsp_improve()
+{
+  bool b;
+  do {
+    b=false;
+    for(NodeIt n(g);n!=INVALID;++n)
+      if(tsp_improve(n)) b=true;
+  } while(b);
+}
+
+void tsp()
+{
+  for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
+  tsp_improve();
+}
+
+class Line
+{
+public:
+  Point a;
+  Point b;
+  Line(Point _a,Point _b) :a(_a),b(_b) {}
+  Line(Node _a,Node _b) : a(coords[_a]),b(coords[_b]) {}
+  Line(const Arc &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
+  Line(const Edge &e) : a(coords[g.u(e)]),b(coords[g.v(e)]) {}
+};
+
+inline std::ostream& operator<<(std::ostream &os, const Line &l)
+{
+  os << l.a << "->" << l.b;
+  return os;
+}
+
+bool cross(Line a, Line b)
+{
+  Point ao=rot90(a.b-a.a);
+  Point bo=rot90(b.b-b.a);
+  return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 &&
+    (bo*(a.a-b.a))*(bo*(a.b-b.a))<0;
+}
+
+struct Parc
+{
+  Node a;
+  Node b;
+  double len;
+};
+
+bool pedgeLess(Parc a,Parc b)
+{
+  return a.len<b.len;
+}
+
+std::vector<Edge> arcs;
+
+namespace _delaunay_bits {
+
+  struct Part {
+    int prev, curr, next;
+
+    Part(int p, int c, int n) : prev(p), curr(c), next(n) {}
+  };
+
+  inline std::ostream& operator<<(std::ostream& os, const Part& part) {
+    os << '(' << part.prev << ',' << part.curr << ',' << part.next << ')';
+    return os;
+  }
+
+  inline double circle_point(const Point& p, const Point& q, const Point& r) {
+    double a = p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y);
+    if (a == 0) return std::numeric_limits<double>::quiet_NaN();
+
+    double d = (p.x * p.x + p.y * p.y) * (q.y - r.y) +
+      (q.x * q.x + q.y * q.y) * (r.y - p.y) +
+      (r.x * r.x + r.y * r.y) * (p.y - q.y);
+
+    double e = (p.x * p.x + p.y * p.y) * (q.x - r.x) +
+      (q.x * q.x + q.y * q.y) * (r.x - p.x) +
+      (r.x * r.x + r.y * r.y) * (p.x - q.x);
+
+    double f = (p.x * p.x + p.y * p.y) * (q.x * r.y - r.x * q.y) +
+      (q.x * q.x + q.y * q.y) * (r.x * p.y - p.x * r.y) +
+      (r.x * r.x + r.y * r.y) * (p.x * q.y - q.x * p.y);
+
+    return d / (2 * a) + sqrt((d * d + e * e) / (4 * a * a) + f / a);
+  }
+
+  inline bool circle_form(const Point& p, const Point& q, const Point& r) {
+    return rot90(q - p) * (r - q) < 0.0;
+  }
+
+  inline double intersection(const Point& p, const Point& q, double sx) {
+    const double epsilon = 1e-8;
+
+    if (p.x == q.x) return (p.y + q.y) / 2.0;
+
+    if (sx < p.x + epsilon) return p.y;
+    if (sx < q.x + epsilon) return q.y;
+
+    double a = q.x - p.x;
+    double b = (q.x - sx) * p.y - (p.x - sx) * q.y;
+    double d = (q.x - sx) * (p.x - sx) * (p - q).normSquare();
+    return (b - sqrt(d)) / a;
+  }
+
+  struct YLess {
+
+
+    YLess(const std::vector<Point>& points, double& sweep)
+      : _points(points), _sweep(sweep) {}
+
+    bool operator()(const Part& l, const Part& r) const {
+      const double epsilon = 1e-8;
+
+      //      std::cerr << l << " vs " << r << std::endl;
+      double lbx = l.prev != -1 ?
+        intersection(_points[l.prev], _points[l.curr], _sweep) :
+        - std::numeric_limits<double>::infinity();
+      double rbx = r.prev != -1 ?
+        intersection(_points[r.prev], _points[r.curr], _sweep) :
+        - std::numeric_limits<double>::infinity();
+      double lex = l.next != -1 ?
+        intersection(_points[l.curr], _points[l.next], _sweep) :
+        std::numeric_limits<double>::infinity();
+      double rex = r.next != -1 ?
+        intersection(_points[r.curr], _points[r.next], _sweep) :
+        std::numeric_limits<double>::infinity();
+
+      if (lbx > lex) std::swap(lbx, lex);
+      if (rbx > rex) std::swap(rbx, rex);
+
+      if (lex < epsilon + rex && lbx + epsilon < rex) return true;
+      if (rex < epsilon + lex && rbx + epsilon < lex) return false;
+      return lex < rex;
+    }
+
+    const std::vector<Point>& _points;
+    double& _sweep;
+  };
+
+  struct BeachIt;
+
+  typedef std::multimap<double, BeachIt> SpikeHeap;
+
+  typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
+
+  struct BeachIt {
+    Beach::iterator it;
+
+    BeachIt(Beach::iterator iter) : it(iter) {}
+  };
+
+}
+
+inline void delaunay() {
+  Counter cnt("Number of arcs added: ");
+
+  using namespace _delaunay_bits;
+
+  typedef _delaunay_bits::Part Part;
+  typedef std::vector<std::pair<double, int> > SiteHeap;
+
+
+  std::vector<Point> points;
+  std::vector<Node> nodes;
+
+  for (NodeIt it(g); it != INVALID; ++it) {
+    nodes.push_back(it);
+    points.push_back(coords[it]);
+  }
+



More information about the Lemon-commits mailing list