alpar@2391
|
1 |
/* -*- C++ -*-
|
alpar@2391
|
2 |
*
|
alpar@2391
|
3 |
* This file is a part of LEMON, a generic C++ optimization library
|
alpar@2391
|
4 |
*
|
alpar@2391
|
5 |
* Copyright (C) 2003-2007
|
alpar@2391
|
6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
alpar@2391
|
7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
alpar@2391
|
8 |
*
|
alpar@2391
|
9 |
* Permission to use, modify and distribute this software is granted
|
alpar@2391
|
10 |
* provided that this copyright notice appears in all copies. For
|
alpar@2391
|
11 |
* precise terms see the accompanying LICENSE file.
|
alpar@2391
|
12 |
*
|
alpar@2391
|
13 |
* This software is provided "AS IS" with no warranty of any kind,
|
alpar@2391
|
14 |
* express or implied, and with no claim as to its suitability for any
|
alpar@2391
|
15 |
* purpose.
|
alpar@2391
|
16 |
*
|
alpar@2391
|
17 |
*/
|
alpar@2391
|
18 |
|
alpar@2390
|
19 |
#include <lemon/list_graph.h>
|
alpar@2390
|
20 |
#include <lemon/graph_utils.h>
|
alpar@2390
|
21 |
#include <lemon/random.h>
|
alpar@2390
|
22 |
#include <lemon/dim2.h>
|
alpar@2390
|
23 |
#include <lemon/bfs.h>
|
alpar@2390
|
24 |
#include <lemon/counter.h>
|
alpar@2390
|
25 |
#include <lemon/suurballe.h>
|
alpar@2390
|
26 |
#include <lemon/graph_to_eps.h>
|
alpar@2390
|
27 |
#include <lemon/graph_writer.h>
|
alpar@2390
|
28 |
#include <lemon/arg_parser.h>
|
alpar@2390
|
29 |
#include <cmath>
|
alpar@2390
|
30 |
#include <algorithm>
|
alpar@2390
|
31 |
#include <lemon/unionfind.h>
|
alpar@2390
|
32 |
|
alpar@2390
|
33 |
using namespace lemon;
|
alpar@2390
|
34 |
|
alpar@2390
|
35 |
typedef dim2::Point<double> Point;
|
alpar@2390
|
36 |
|
alpar@2390
|
37 |
UGRAPH_TYPEDEFS(ListUGraph);
|
alpar@2390
|
38 |
|
alpar@2390
|
39 |
int N;
|
alpar@2390
|
40 |
int girth;
|
alpar@2390
|
41 |
|
alpar@2390
|
42 |
ListUGraph g;
|
alpar@2390
|
43 |
|
alpar@2390
|
44 |
std::vector<Node> nodes;
|
alpar@2390
|
45 |
ListUGraph::NodeMap<Point> coords(g);
|
alpar@2390
|
46 |
|
alpar@2390
|
47 |
int tsp_impr_num=0;
|
alpar@2390
|
48 |
|
alpar@2390
|
49 |
const double EPSILON=1e-8;
|
alpar@2390
|
50 |
bool tsp_improve(Node u, Node v)
|
alpar@2390
|
51 |
{
|
alpar@2390
|
52 |
double luv=std::sqrt((coords[v]-coords[u]).normSquare());
|
alpar@2390
|
53 |
Node u2=u;
|
alpar@2390
|
54 |
Node v2=v;
|
alpar@2390
|
55 |
do {
|
alpar@2390
|
56 |
Node n;
|
alpar@2390
|
57 |
for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e);
|
alpar@2390
|
58 |
u2=v2;
|
alpar@2390
|
59 |
v2=n;
|
alpar@2390
|
60 |
if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON>
|
alpar@2390
|
61 |
std::sqrt((coords[u]-coords[u2]).normSquare())+
|
alpar@2390
|
62 |
std::sqrt((coords[v]-coords[v2]).normSquare()))
|
alpar@2390
|
63 |
{
|
alpar@2390
|
64 |
g.erase(findUEdge(g,u,v));
|
alpar@2390
|
65 |
g.erase(findUEdge(g,u2,v2));
|
alpar@2390
|
66 |
g.addEdge(u2,u);
|
alpar@2390
|
67 |
g.addEdge(v,v2);
|
alpar@2390
|
68 |
tsp_impr_num++;
|
alpar@2390
|
69 |
return true;
|
alpar@2390
|
70 |
}
|
alpar@2390
|
71 |
} while(v2!=u);
|
alpar@2390
|
72 |
return false;
|
alpar@2390
|
73 |
}
|
alpar@2390
|
74 |
|
alpar@2390
|
75 |
bool tsp_improve(Node u)
|
alpar@2390
|
76 |
{
|
alpar@2390
|
77 |
for(IncEdgeIt e(g,u);e!=INVALID;++e)
|
alpar@2390
|
78 |
if(tsp_improve(u,g.runningNode(e))) return true;
|
alpar@2390
|
79 |
return false;
|
alpar@2390
|
80 |
}
|
alpar@2390
|
81 |
|
alpar@2390
|
82 |
void tsp_improve()
|
alpar@2390
|
83 |
{
|
alpar@2390
|
84 |
bool b;
|
alpar@2390
|
85 |
do {
|
alpar@2390
|
86 |
b=false;
|
alpar@2390
|
87 |
for(NodeIt n(g);n!=INVALID;++n)
|
alpar@2390
|
88 |
if(tsp_improve(n)) b=true;
|
alpar@2390
|
89 |
} while(b);
|
alpar@2390
|
90 |
}
|
alpar@2390
|
91 |
|
alpar@2390
|
92 |
void tsp()
|
alpar@2390
|
93 |
{
|
alpar@2390
|
94 |
for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
|
alpar@2390
|
95 |
tsp_improve();
|
alpar@2390
|
96 |
}
|
alpar@2390
|
97 |
|
alpar@2390
|
98 |
class Line
|
alpar@2390
|
99 |
{
|
alpar@2390
|
100 |
public:
|
alpar@2390
|
101 |
Point a;
|
alpar@2390
|
102 |
Point b;
|
alpar@2390
|
103 |
Line(Point _a,Point _b) :a(_a),b(_b) {}
|
alpar@2390
|
104 |
Line(Node _a,Node _b) : a(coords[_a]),b(coords[_b]) {}
|
alpar@2390
|
105 |
Line(const Edge &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
|
alpar@2390
|
106 |
Line(const UEdge &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
|
alpar@2390
|
107 |
};
|
alpar@2390
|
108 |
|
alpar@2390
|
109 |
inline std::ostream& operator<<(std::ostream &os, const Line &l)
|
alpar@2390
|
110 |
{
|
alpar@2390
|
111 |
os << l.a << "->" << l.b;
|
alpar@2390
|
112 |
return os;
|
alpar@2390
|
113 |
}
|
alpar@2390
|
114 |
|
alpar@2390
|
115 |
bool cross(Line a, Line b)
|
alpar@2390
|
116 |
{
|
alpar@2390
|
117 |
Point ao=rot90(a.b-a.a);
|
alpar@2390
|
118 |
Point bo=rot90(b.b-b.a);
|
alpar@2390
|
119 |
return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 &&
|
alpar@2390
|
120 |
(bo*(a.a-b.a))*(bo*(a.b-b.a))<0;
|
alpar@2390
|
121 |
}
|
alpar@2390
|
122 |
|
alpar@2390
|
123 |
struct Pedge
|
alpar@2390
|
124 |
{
|
alpar@2390
|
125 |
Node a;
|
alpar@2390
|
126 |
Node b;
|
alpar@2390
|
127 |
double len;
|
alpar@2390
|
128 |
};
|
alpar@2390
|
129 |
|
alpar@2390
|
130 |
bool pedgeLess(Pedge a,Pedge b)
|
alpar@2390
|
131 |
{
|
alpar@2390
|
132 |
return a.len<b.len;
|
alpar@2390
|
133 |
}
|
alpar@2390
|
134 |
|
alpar@2390
|
135 |
std::vector<UEdge> edges;
|
alpar@2390
|
136 |
|
alpar@2390
|
137 |
void triangle()
|
alpar@2390
|
138 |
{
|
alpar@2390
|
139 |
Counter cnt("Number of edges added: ");
|
alpar@2390
|
140 |
std::vector<Pedge> pedges;
|
alpar@2390
|
141 |
for(NodeIt n(g);n!=INVALID;++n)
|
alpar@2390
|
142 |
for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
|
alpar@2390
|
143 |
{
|
alpar@2390
|
144 |
Pedge p;
|
alpar@2390
|
145 |
p.a=n;
|
alpar@2390
|
146 |
p.b=m;
|
alpar@2390
|
147 |
p.len=(coords[m]-coords[n]).normSquare();
|
alpar@2390
|
148 |
pedges.push_back(p);
|
alpar@2390
|
149 |
}
|
alpar@2390
|
150 |
std::sort(pedges.begin(),pedges.end(),pedgeLess);
|
alpar@2390
|
151 |
for(std::vector<Pedge>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
|
alpar@2390
|
152 |
{
|
alpar@2390
|
153 |
Line li(pi->a,pi->b);
|
alpar@2390
|
154 |
UEdgeIt e(g);
|
alpar@2390
|
155 |
for(;e!=INVALID && !cross(e,li);++e) ;
|
alpar@2390
|
156 |
UEdge ne;
|
alpar@2390
|
157 |
if(e==INVALID) {
|
alpar@2390
|
158 |
ne=g.addEdge(pi->a,pi->b);
|
alpar@2390
|
159 |
edges.push_back(ne);
|
alpar@2390
|
160 |
cnt++;
|
alpar@2390
|
161 |
}
|
alpar@2390
|
162 |
}
|
alpar@2390
|
163 |
}
|
alpar@2390
|
164 |
|
alpar@2390
|
165 |
void sparse(int d)
|
alpar@2390
|
166 |
{
|
alpar@2390
|
167 |
Counter cnt("Number of edges removed: ");
|
alpar@2390
|
168 |
Bfs<ListUGraph> bfs(g);
|
alpar@2390
|
169 |
for(std::vector<UEdge>::reverse_iterator ei=edges.rbegin();
|
alpar@2390
|
170 |
ei!=edges.rend();++ei)
|
alpar@2390
|
171 |
{
|
alpar@2390
|
172 |
Node a=g.source(*ei);
|
alpar@2390
|
173 |
Node b=g.target(*ei);
|
alpar@2390
|
174 |
g.erase(*ei);
|
alpar@2390
|
175 |
bfs.run(a,b);
|
alpar@2390
|
176 |
if(bfs.predEdge(b)==INVALID || bfs.dist(b)>d)
|
alpar@2390
|
177 |
g.addEdge(a,b);
|
alpar@2390
|
178 |
else cnt++;
|
alpar@2390
|
179 |
}
|
alpar@2390
|
180 |
}
|
alpar@2390
|
181 |
|
alpar@2390
|
182 |
void sparse2(int d)
|
alpar@2390
|
183 |
{
|
alpar@2390
|
184 |
Counter cnt("Number of edges removed: ");
|
alpar@2390
|
185 |
for(std::vector<UEdge>::reverse_iterator ei=edges.rbegin();
|
alpar@2390
|
186 |
ei!=edges.rend();++ei)
|
alpar@2390
|
187 |
{
|
alpar@2390
|
188 |
Node a=g.source(*ei);
|
alpar@2390
|
189 |
Node b=g.target(*ei);
|
alpar@2390
|
190 |
g.erase(*ei);
|
alpar@2390
|
191 |
ConstMap<Edge,int> cegy(1);
|
alpar@2390
|
192 |
Suurballe<ListUGraph,ConstMap<Edge,int> > sur(g,cegy,a,b);
|
alpar@2390
|
193 |
int k=sur.run(2);
|
alpar@2390
|
194 |
if(k<2 || sur.totalLength()>d)
|
alpar@2390
|
195 |
g.addEdge(a,b);
|
alpar@2390
|
196 |
else cnt++;
|
alpar@2390
|
197 |
// else std::cout << "Remove edge " << g.id(a) << "-" << g.id(b) << '\n';
|
alpar@2390
|
198 |
}
|
alpar@2390
|
199 |
}
|
alpar@2390
|
200 |
|
alpar@2390
|
201 |
void sparseTriangle(int d)
|
alpar@2390
|
202 |
{
|
alpar@2390
|
203 |
Counter cnt("Number of edges added: ");
|
alpar@2390
|
204 |
std::vector<Pedge> pedges;
|
alpar@2390
|
205 |
for(NodeIt n(g);n!=INVALID;++n)
|
alpar@2390
|
206 |
for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
|
alpar@2390
|
207 |
{
|
alpar@2390
|
208 |
Pedge p;
|
alpar@2390
|
209 |
p.a=n;
|
alpar@2390
|
210 |
p.b=m;
|
alpar@2390
|
211 |
p.len=(coords[m]-coords[n]).normSquare();
|
alpar@2390
|
212 |
pedges.push_back(p);
|
alpar@2390
|
213 |
}
|
alpar@2390
|
214 |
std::sort(pedges.begin(),pedges.end(),pedgeLess);
|
alpar@2390
|
215 |
for(std::vector<Pedge>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
|
alpar@2390
|
216 |
{
|
alpar@2390
|
217 |
Line li(pi->a,pi->b);
|
alpar@2390
|
218 |
UEdgeIt e(g);
|
alpar@2390
|
219 |
for(;e!=INVALID && !cross(e,li);++e) ;
|
alpar@2390
|
220 |
UEdge ne;
|
alpar@2390
|
221 |
if(e==INVALID) {
|
alpar@2390
|
222 |
ConstMap<Edge,int> cegy(1);
|
alpar@2390
|
223 |
Suurballe<ListUGraph,ConstMap<Edge,int> >
|
alpar@2390
|
224 |
sur(g,cegy,pi->a,pi->b);
|
alpar@2390
|
225 |
int k=sur.run(2);
|
alpar@2390
|
226 |
if(k<2 || sur.totalLength()>d)
|
alpar@2390
|
227 |
{
|
alpar@2390
|
228 |
ne=g.addEdge(pi->a,pi->b);
|
alpar@2390
|
229 |
edges.push_back(ne);
|
alpar@2390
|
230 |
cnt++;
|
alpar@2390
|
231 |
}
|
alpar@2390
|
232 |
}
|
alpar@2390
|
233 |
}
|
alpar@2390
|
234 |
}
|
alpar@2390
|
235 |
|
alpar@2390
|
236 |
void minTree() {
|
alpar@2390
|
237 |
std::vector<Pedge> pedges;
|
alpar@2390
|
238 |
for(NodeIt n(g);n!=INVALID;++n)
|
alpar@2390
|
239 |
for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
|
alpar@2390
|
240 |
{
|
alpar@2390
|
241 |
Pedge p;
|
alpar@2390
|
242 |
p.a=n;
|
alpar@2390
|
243 |
p.b=m;
|
alpar@2390
|
244 |
p.len=(coords[m]-coords[n]).normSquare();
|
alpar@2390
|
245 |
pedges.push_back(p);
|
alpar@2390
|
246 |
}
|
alpar@2390
|
247 |
std::sort(pedges.begin(),pedges.end(),pedgeLess);
|
alpar@2390
|
248 |
ListUGraph::NodeMap<int> comp(g);
|
alpar@2390
|
249 |
UnionFind<ListUGraph::NodeMap<int> > uf(comp);
|
alpar@2390
|
250 |
for (NodeIt it(g); it != INVALID; ++it)
|
alpar@2390
|
251 |
uf.insert(it);
|
alpar@2390
|
252 |
|
alpar@2390
|
253 |
int en=0;
|
alpar@2390
|
254 |
for(std::vector<Pedge>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
|
alpar@2390
|
255 |
{
|
alpar@2390
|
256 |
if ( uf.join(pi->a,pi->b) ) {
|
alpar@2390
|
257 |
g.addEdge(pi->a,pi->b);
|
alpar@2390
|
258 |
en++;
|
alpar@2390
|
259 |
if(en>=N-1) return;
|
alpar@2390
|
260 |
}
|
alpar@2390
|
261 |
}
|
alpar@2390
|
262 |
}
|
alpar@2390
|
263 |
|
alpar@2390
|
264 |
|
alpar@2390
|
265 |
|
alpar@2390
|
266 |
int main(int argc,char **argv)
|
alpar@2390
|
267 |
{
|
alpar@2390
|
268 |
ArgParser ap(argc,argv);
|
alpar@2390
|
269 |
|
alpar@2390
|
270 |
bool eps;
|
alpar@2390
|
271 |
bool disc_d, square_d, gauss_d;
|
alpar@2390
|
272 |
bool tsp_a,two_a,tree_a;
|
alpar@2390
|
273 |
int num_of_cities=1;
|
alpar@2390
|
274 |
double area=1;
|
alpar@2390
|
275 |
N=100;
|
alpar@2390
|
276 |
girth=10;
|
alpar@2390
|
277 |
std::string ndist("disc");
|
alpar@2390
|
278 |
ap.option("n", "Number of nodes (default is 100)", N)
|
alpar@2390
|
279 |
.option("g", "Girth parameter (default is 10)", girth)
|
alpar@2390
|
280 |
.option("cities", "Number of cities (default is 1)", num_of_cities)
|
alpar@2390
|
281 |
.option("area", "Full relative area of the cities (default is 1)", area)
|
alpar@2390
|
282 |
.option("disc", "Nodes are evenly distributed on a unit disc (default)",disc_d)
|
alpar@2390
|
283 |
.optionGroup("dist", "disc")
|
alpar@2390
|
284 |
.option("square", "Nodes are evenly distributed on a unit square", square_d)
|
alpar@2390
|
285 |
.optionGroup("dist", "square")
|
alpar@2390
|
286 |
.option("gauss",
|
alpar@2390
|
287 |
"Nodes are located according to a two-dim gauss distribution",
|
alpar@2390
|
288 |
gauss_d)
|
alpar@2390
|
289 |
.optionGroup("dist", "gauss")
|
alpar@2390
|
290 |
// .mandatoryGroup("dist")
|
alpar@2390
|
291 |
.onlyOneGroup("dist")
|
alpar@2390
|
292 |
.option("eps", "Also generate .eps output (prefix.eps)",eps)
|
alpar@2390
|
293 |
.option("2con", "Create a two connected planar graph",two_a)
|
alpar@2390
|
294 |
.optionGroup("alg","2con")
|
alpar@2390
|
295 |
.option("tree", "Create a min. cost spanning tree",tree_a)
|
alpar@2390
|
296 |
.optionGroup("alg","tree")
|
alpar@2390
|
297 |
.option("tsp", "Create a TSP tour",tsp_a)
|
alpar@2390
|
298 |
.optionGroup("alg","tsp")
|
alpar@2390
|
299 |
.onlyOneGroup("alg")
|
alpar@2390
|
300 |
.other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
|
alpar@2390
|
301 |
.run();
|
alpar@2390
|
302 |
|
alpar@2390
|
303 |
std::string prefix;
|
alpar@2390
|
304 |
switch(ap.files().size())
|
alpar@2390
|
305 |
{
|
alpar@2390
|
306 |
case 0:
|
alpar@2390
|
307 |
prefix="lgf-gen-out";
|
alpar@2390
|
308 |
break;
|
alpar@2390
|
309 |
case 1:
|
alpar@2390
|
310 |
prefix=ap.files()[0];
|
alpar@2390
|
311 |
break;
|
alpar@2390
|
312 |
default:
|
alpar@2390
|
313 |
std::cerr << "\nAt most one prefix can be given\n\n";
|
alpar@2390
|
314 |
exit(1);
|
alpar@2390
|
315 |
}
|
alpar@2390
|
316 |
|
alpar@2390
|
317 |
double sum_sizes=0;
|
alpar@2390
|
318 |
std::vector<double> sizes;
|
alpar@2390
|
319 |
std::vector<double> cum_sizes;
|
alpar@2390
|
320 |
for(int s=0;s<num_of_cities;s++)
|
alpar@2390
|
321 |
{
|
alpar@2390
|
322 |
// sum_sizes+=rnd.exponential();
|
alpar@2390
|
323 |
double d=rnd();
|
alpar@2390
|
324 |
sum_sizes+=d;
|
alpar@2390
|
325 |
sizes.push_back(d);
|
alpar@2390
|
326 |
cum_sizes.push_back(sum_sizes);
|
alpar@2390
|
327 |
}
|
alpar@2390
|
328 |
int i=0;
|
alpar@2390
|
329 |
for(int s=0;s<num_of_cities;s++)
|
alpar@2390
|
330 |
{
|
alpar@2390
|
331 |
Point center=(num_of_cities==1?Point(0,0):rnd.disc());
|
alpar@2390
|
332 |
if(gauss_d)
|
alpar@2390
|
333 |
for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
|
alpar@2390
|
334 |
Node n=g.addNode();
|
alpar@2390
|
335 |
nodes.push_back(n);
|
alpar@2390
|
336 |
coords[n]=center+rnd.gauss2()*area*
|
alpar@2390
|
337 |
std::sqrt(sizes[s]/sum_sizes);
|
alpar@2390
|
338 |
}
|
alpar@2390
|
339 |
else if(square_d)
|
alpar@2390
|
340 |
for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
|
alpar@2390
|
341 |
Node n=g.addNode();
|
alpar@2390
|
342 |
nodes.push_back(n);
|
alpar@2390
|
343 |
coords[n]=center+Point(rnd()*2-1,rnd()*2-1)*area*
|
alpar@2390
|
344 |
std::sqrt(sizes[s]/sum_sizes);
|
alpar@2390
|
345 |
}
|
alpar@2390
|
346 |
else if(disc_d || true)
|
alpar@2390
|
347 |
for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
|
alpar@2390
|
348 |
Node n=g.addNode();
|
alpar@2390
|
349 |
nodes.push_back(n);
|
alpar@2390
|
350 |
coords[n]=center+rnd.disc()*area*
|
alpar@2390
|
351 |
std::sqrt(sizes[s]/sum_sizes);
|
alpar@2390
|
352 |
}
|
alpar@2390
|
353 |
}
|
alpar@2390
|
354 |
|
alpar@2390
|
355 |
if(tsp_a) {
|
alpar@2390
|
356 |
tsp();
|
alpar@2390
|
357 |
std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
|
alpar@2390
|
358 |
}
|
alpar@2390
|
359 |
else if(two_a) {
|
alpar@2390
|
360 |
std::cout << "Make triangles\n";
|
alpar@2390
|
361 |
// triangle();
|
alpar@2390
|
362 |
sparseTriangle(girth);
|
alpar@2390
|
363 |
std::cout << "Make it sparser\n";
|
alpar@2390
|
364 |
sparse2(girth);
|
alpar@2390
|
365 |
}
|
alpar@2390
|
366 |
else if(tree_a) {
|
alpar@2390
|
367 |
minTree();
|
alpar@2390
|
368 |
}
|
alpar@2390
|
369 |
|
alpar@2390
|
370 |
|
alpar@2390
|
371 |
std::cout << "Number of nodes : " << countNodes(g) << std::endl;
|
alpar@2390
|
372 |
std::cout << "Number of edges : " << countUEdges(g) << std::endl;
|
alpar@2390
|
373 |
double tlen=0;
|
alpar@2390
|
374 |
for(UEdgeIt e(g);e!=INVALID;++e)
|
alpar@2390
|
375 |
tlen+=sqrt((coords[g.source(e)]-coords[g.target(e)]).normSquare());
|
alpar@2390
|
376 |
std::cout << "Total edge length : " << tlen << std::endl;
|
alpar@2390
|
377 |
if(eps)
|
alpar@2390
|
378 |
graphToEps(g,prefix+".eps").
|
alpar@2390
|
379 |
scale(600).nodeScale(.2).edgeWidthScale(.001).preScale(false).
|
alpar@2390
|
380 |
coords(coords).run();
|
alpar@2390
|
381 |
|
alpar@2390
|
382 |
UGraphWriter<ListUGraph>(prefix+".lgf",g).
|
alpar@2390
|
383 |
writeNodeMap("coordinates_x",scaleMap(xMap(coords),600)).
|
alpar@2390
|
384 |
writeNodeMap("coordinates_y",scaleMap(yMap(coords),600)).
|
alpar@2390
|
385 |
run();
|
alpar@2390
|
386 |
}
|
alpar@2390
|
387 |
|