[Lemon-commits] alpar: r3284 - lemon/trunk/tools
Lemon SVN
svn at lemon.cs.elte.hu
Tue Jun 5 12:59:17 CEST 2007
Author: alpar
Date: Tue Jun 5 12:59:16 2007
New Revision: 3284
Modified:
lemon/trunk/tools/lgf-gen.cc
Log:
A minimum spanning tree based TSP algorithm is added (-tsp2)
Modified: lemon/trunk/tools/lgf-gen.cc
==============================================================================
--- lemon/trunk/tools/lgf-gen.cc (original)
+++ lemon/trunk/tools/lgf-gen.cc Tue Jun 5 12:59:16 2007
@@ -26,6 +26,7 @@
#include <lemon/graph_to_eps.h>
#include <lemon/graph_writer.h>
#include <lemon/arg_parser.h>
+#include <lemon/euler.h>
#include <cmath>
#include <algorithm>
#include <lemon/unionfind.h>
@@ -47,6 +48,14 @@
std::vector<Node> nodes;
ListUGraph::NodeMap<Point> coords(g);
+
+double totalLen(){
+ double tlen=0;
+ for(UEdgeIt e(g);e!=INVALID;++e)
+ tlen+=sqrt((coords[g.source(e)]-coords[g.target(e)]).normSquare());
+ return tlen;
+}
+
int tsp_impr_num=0;
const double EPSILON=1e-8;
@@ -252,7 +261,6 @@
p.len=(coords[m]-coords[n]).normSquare();
pedges.push_back(p);
}
- en++;
if(progress && en>=pr*double(N)/100)
{
std::cout << pr << "% \r" << std::flush;
@@ -270,6 +278,7 @@
{
if ( uf.join(pi->a,pi->b) ) {
g.addEdge(pi->a,pi->b);
+ en++;
if(en>=N-1)
break;
}
@@ -277,6 +286,90 @@
std::cout << T.realTime() << "s: Done\n";
}
+Node common(UEdge e, UEdge f)
+{
+ return (g.source(e)==g.source(f)||g.source(e)==g.target(f))?
+ g.source(e):g.target(e);
+}
+
+void tsp2()
+{
+ std::cout << "Find a tree..." << std::endl;
+
+ minTree();
+
+ std::cout << "Total edge length (tree) : " << totalLen() << std::endl;
+
+ std::cout << "Make it Euler..." << std::endl;
+
+ {
+ std::vector<Node> leafs;
+ for(NodeIt n(g);n!=INVALID;++n)
+ if(countIncEdges(g,n)%2==1) leafs.push_back(n);
+ for(unsigned int i=0;i<leafs.size();i+=2)
+ g.addEdge(leafs[i],leafs[i+1]);
+ }
+
+ for(NodeIt n(g);n!=INVALID;++n)
+ if(countIncEdges(g,n)%2)
+ std::cout << "GEBASZ!!!" << std::endl;
+
+ std::cout << "Number of edges : " << countUEdges(g) << std::endl;
+
+// for(NodeIt n(g);n!=INVALID;++n)
+// if(countIncEdges(g,n)>2)
+// std::cout << "+";
+// std::cout << std::endl;
+
+ std::cout << "Total edge length (euler) : " << totalLen() << std::endl;
+
+ ListUGraph::UEdgeMap<UEdge> enext(g);
+ {
+ UEulerIt<ListUGraph> e(g);
+ UEdge eo=e;
+ UEdge ef=e;
+// std::cout << "Tour edge: " << g.id(UEdge(e)) << std::endl;
+ for(++e;e!=INVALID;++e)
+ {
+// std::cout << "Tour edge: " << g.id(UEdge(e)) << std::endl;
+ enext[eo]=e;
+ eo=e;
+ }
+ enext[eo]=ef;
+ }
+
+ std::cout << "Creating a tour from that..." << std::endl;
+
+ int nnum = countNodes(g);
+ int ednum = countUEdges(g);
+
+ for(UEdge p=UEdgeIt(g);ednum>nnum;p=enext[p])
+ {
+// std::cout << "Checking edge " << g.id(p) << std::endl;
+ UEdge e=enext[p];
+ UEdge f=enext[e];
+ Node n2=common(e,f);
+ Node n1=g.oppositeNode(n2,e);
+ Node n3=g.oppositeNode(n2,f);
+ if(countIncEdges(g,n2)>2)
+ {
+// std::cout << "Remove an Edge" << std::endl;
+ UEdge ff=enext[f];
+ g.erase(e);
+ g.erase(f);
+ UEdge ne=g.addEdge(n1,n3);
+ enext[p]=ne;
+ enext[ne]=ff;
+ ednum--;
+ }
+ }
+
+ std::cout << "Total edge length (tour) : " << totalLen() << std::endl;
+
+ tsp_improve();
+
+ std::cout << "Total edge length (2-opt tour) : " << totalLen() << std::endl;
+}
int main(int argc,const char **argv)
@@ -306,12 +399,15 @@
// .mandatoryGroup("dist")
.onlyOneGroup("dist")
.boolOption("eps", "Also generate .eps output (prefix.eps)")
+ .boolOption("dir", "Directed graph is generated (each edges are replaced by two directed ones)")
.boolOption("2con", "Create a two connected planar graph")
.optionGroup("alg","2con")
.boolOption("tree", "Create a min. cost spanning tree")
.optionGroup("alg","tree")
.boolOption("tsp", "Create a TSP tour")
.optionGroup("alg","tsp")
+ .boolOption("tsp2", "Create a TSP tour (tree based)")
+ .optionGroup("alg","tsp2")
.onlyOneGroup("alg")
.other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
.run();
@@ -372,6 +468,10 @@
tsp();
std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
}
+ if(ap["tsp2"]) {
+ tsp2();
+ std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
+ }
else if(ap["2con"]) {
std::cout << "Make triangles\n";
// triangle();
@@ -395,9 +495,14 @@
scale(600).nodeScale(.2).edgeWidthScale(.001).preScale(false).
coords(coords).run();
- UGraphWriter<ListUGraph>(prefix+".lgf",g).
- writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)).
- writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)).
- run();
+ if(ap["dir"])
+ GraphWriter<ListUGraph>(prefix+".lgf",g).
+ writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)).
+ writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)).
+ run();
+ else UGraphWriter<ListUGraph>(prefix+".lgf",g).
+ writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)).
+ writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)).
+ run();
}
More information about the Lemon-commits
mailing list