# HG changeset patch # User alpar # Date 1181041156 0 # Node ID dd20d76eed133615ed3293d38103a145f33b8361 # Parent aaf5787f4d5d3cf31391299a6f9274ab3c6d8ca6 A minimum spanning tree based TSP algorithm is added (-tsp2) diff -r aaf5787f4d5d -r dd20d76eed13 tools/lgf-gen.cc --- a/tools/lgf-gen.cc Tue Jun 05 10:57:26 2007 +0000 +++ b/tools/lgf-gen.cc Tue Jun 05 10:59:16 2007 +0000 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,14 @@ std::vector nodes; ListUGraph::NodeMap 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 leafs; + for(NodeIt n(g);n!=INVALID;++n) + if(countIncEdges(g,n)%2==1) leafs.push_back(n); + for(unsigned int i=0;i2) +// std::cout << "+"; +// std::cout << std::endl; + + std::cout << "Total edge length (euler) : " << totalLen() << std::endl; + + ListUGraph::UEdgeMap enext(g); + { + UEulerIt 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(prefix+".lgf",g). - writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)). - writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)). - run(); + if(ap["dir"]) + GraphWriter(prefix+".lgf",g). + writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)). + writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)). + run(); + else UGraphWriter(prefix+".lgf",g). + writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)). + writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)). + run(); }