blob: 1c1eb19121a3a00efb3d40fa2c10a5d45ab13a53 [file] [log] [blame]
David Lamparter821df2c2015-09-15 01:53:09 -07001#include <zebra.h>
2
jardineb5d44e2003-12-23 08:09:43 +00003#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <values.h>
7
8#include "random.c"
9
10#define DASH '-'
11#define VERY_FAR 100000000
12
13/* generator of random networks for the shortest paths problem;
14 extended DIMACS format for output */
15
16main ( argc, argv )
17
18int argc;
19char* argv[];
20
21{
22
23char args[30];
24
25long n,
26 n0,
27 source,
28 i,
29 i0,
30 j,
31 dij;
32
33long m,
34 m0,
35 mc,
36 k;
37
38long *p,
39 p_t,
40 l,
41 lx;
42
43long seed,
44 seed1,
45 seed2;
46
47int ext=0;
48
49FILE *fout;
50
51/* variables for lengths generating */
52/* initialized by default values */
53int l_f = 0, ll_f = 0, lm_f = 0, ln_f = 0, ls_f = 0;
54long ll = 10000, /* length of the interval */
55 lm = 0; /* minimal bound of the interval */
56double ln = 0, /* l += ln * |i-j| */
57 ls = 0; /* l += ls * |i-j|^2 */
58
59/* variables for connecting cycle(s) */
60int c_f = 0, cl_f = 0, ch_f = 0, c_random = 1;
61long cl = 1; /* length of cycle arc */
62long ch; /* number of arcs in the cycle
63 n - by default */
64
65/* variables for artifical source */
66int s_f = 0, sl_f = 0, sm_f = 0;
67long sl = VERY_FAR, /* upper bound of artifical arc */
68 sm, /* lower bound of artifical arc */
69 s;
70
71/* variables for potentials */
72int p_f = 0, pl_f = 0, pm_f = 0, pn_f = 0, ps_f = 0,
73 pa_f = 0, pap_f = 0, pac_f = 0;
74long pl, /* length of the interval */
75 pm; /* minimal bound of the interval */
76double pn = 0, /* l += ln * |i-j| */
77 ps = 0, /* l += ls * |i-j|^2 */
78 pap = 0, /* part of nodes with alternative dustribution */
79 pac = -1; /* multiplier for alternative distribution */
80
81int np; /* number of parameter parsing now */
82
83#define PRINT_ARC( i, j, length )\
84{\
85l = length;\
86if ( p_f ) l += ( p[i] - p[j] );\
87printf ("a %8ld %8ld %12ld\n", i, j, l );\
88}
89
90 /* parsing parameters */
91
92if ( argc < 2 ) goto usage;
93
94np = 0;
95
96strcpy ( args, argv[1] );
97
98 if ( ( args[0] == DASH ) && ( args[1] == 'h')
99 )
100 goto help;
101
102if ( argc < 4 ) goto usage;
103
104/* first parameter - number of nodes */
105np = 1;
106if ( ( n = atoi ( argv[1] ) ) < 2 ) goto usage;
107
108/* second parameter - number of arcs */
109np = 2;
110if ( ( m = atoi ( argv[2] ) ) < n ) goto usage;
111
112/* third parameter - seed */
113np=3;
114if ( ( seed = atoi ( argv[3] ) ) <= 0 ) goto usage;
115
116/* other parameters */
117
118for ( np = 4; np < argc; np ++ )
119 {
120 strcpy ( args, argv[np] );
121 if ( args[0] != DASH ) goto usage;
122
123 switch ( args[1] )
124 {
125
126 case 'l' : /* an interval for arc length */
127 l_f = 1;
128 switch ( args[2] )
129 {
130 case 'l': /* length of the interval */
131 ll_f = 1;
132 ll = (long) atof ( &args[3] );
133 break;
134 case 'm': /* minimal bound */
135 lm_f = 1;
136 lm = (long ) atof ( &args[3] );
137 break;
138 case 'n': /* additional length: l*|i-j| */
139 ln_f = 1;
140 ln = atof ( &args[3] );
141 break;
142 case 's': /* additional length: l*|i-j|^2 */
143 ls_f = 1;
144 ls = atof ( &args[3] );
145 break;
146 default: /* unknown switch value */
147 goto usage;
148 }
149 break;
150
151 case 'c' : /* connecting cycle(s) */
152 c_f = 1;
153 switch ( args[2] )
154 {
155 case 'l':
156 c_random = 0;
157 cl_f = 1;
158 cl = (long) atof ( &args[3] );
159 if ( cl < 0 ) goto usage;
160 break;
161 case 'h':
162 ch_f = 1;
163 ch = (long) atof ( &args[3] );
164 if ( ch < 2 || ch > n ) goto usage;
165 break;
166 default: /* unknown switch value */
167 goto usage;
168 }
169 break;
170
171 case 's' : /* additional source */
172 s_f = 1;
173 if ( strlen ( args ) > 2 )
174 {
175 switch ( args[2] )
176 {
177 case 'l': /* upper bound of art. arc */
178 sl_f = 1;
179 sl = (long) atof ( &args[3] );
180 break;
181 case 'm': /* lower bound of art. arc */
182 sm_f = 1;
183 sm = (long) atof ( &args[3] );
184 break;
185 default: /* unknown switch value */
186 goto usage;
187 }
188 }
189 break;
190
191 case 'p' : /* potentials */
192 p_f = 1;
193 if ( strlen ( args ) > 2 )
194 {
195 switch ( args[2] )
196 {
197 case 'l': /* length of the interval */
198 pl_f = 1;
199 pl = (long) atof ( &args[3] );
200 break;
201 case 'm': /* minimal bound */
202 pm_f = 1;
203 pm = (long ) atof ( &args[3] );
204 break;
205 case 'n': /* additional length: l*|i-j| */
206 pn_f = 1;
207 pn = atof ( &args[3] );
208 break;
209 case 's': /* additional length: l*|i-j|^2 */
210 ps_f = 1;
211 ps = atof ( &args[3] );
212 break;
213 case 'a': /* bipolar distribution */
214 pa_f = 1;
215 switch ( args[3] )
216 {
217 case 'p': /* % of alternative potentials */
218 pap_f = 1;
219 pap = atof ( &args[4] );
220 if ( pap < 0 ) pap = 0;
221 if ( pap > 100 ) pap = 100;
222 pap /= 100;
223 break;
224 case 'c': /* multiplier */
225 pac_f = 1;
226 pac = atof ( &args[4] );
227 break;
228 default: /* unknown switch value */
229 goto usage;
230 }
231 break;
232 default: /* unknown switch value */
233 goto usage;
234 }
235 }
236 break;
237
238 default : /* unknoun case */
239 goto usage;
240 }
241 }
242
243
244/* ----- ajusting parameters ----- */
245
246n0 = n; m0 = m;
247
248/* length parameters */
249if ( ll < lm ) { lx = ll; ll = lm; lm = lx; }
250
251/* potential parameters */
252if ( p_f )
253 {
254 if ( ! pl_f ) pl = ll;
255 if ( ! pm_f ) pm = lm;
256 if ( pl < pm ) { lx = pl; pl = pm; pm = lx; }
257 }
258
259/* path(s) parameters */
260if ( ! ch_f ) ch = n;
261
262mc = n + (n-2) / (ch-1);
263if ( mc > m )
264 { fprintf ( stderr,
265 "Error: not enough arcs for generating connecting cycle(s)\n" );
266 exit (4);
267 }
268
269 /* artifical source parameters */
270if ( s_f )
271 { m0 += n; n0 ++ ;
272 if ( ! sm_f ) sm = sl;
273 if ( sl < sm ) { lx = sl; sl = sm; sm = lx; }
274 }
275
276/* printing title */
277printf ("c random network for shortest paths problem\n");
278printf ("c extended DIMACS format\nc\n" );
279
280/* name of the problem */
281printf ("t rd_%ld_%ld_%ld_", n, m, seed );
282if ( l_f )
283 printf ("%c", 'l');
284if ( c_f )
285 printf ("%c", 'c');
286if ( s_f )
287 printf ("%c", 's');
288if ( p_f )
289 printf ("%c", 'p');
290printf ("\nc\n");
291
292/* printing additional information */
293if ( l_f )
294 printf ("c length -> min: %ld max: %ld k1: %.2f k2: %.2f\n",
295 lm, ll, ln, ls );
296if ( c_f )
297 {
298 if ( c_random )
299 printf ("c cycle -> number of arcs: %ld arc length: random\n", ch);
300 else
301 printf ("c cycle -> number of arcs: %ld arc length: %ld\n",
302 ch, cl );
303 }
304if ( s_f )
305 printf ("c length of arcs from artifical source -> min: %ld max: %ld\n",
306 sm, sl );
307if ( p_f )
308 {
309 printf ("c potentials -> min: %ld max: %ld k1: %.2f k2: %.2f\n",
310 pm, pl, pn, ps );
311 if ( pa_f )
312 printf ("c potentials -> part of alternative distribution: %.2f k: %.2f\n",
313 pap, pac );
314 }
315printf ("c\n" );
316
317
318printf ("p sp %8ld %8ld\nc\n", n0, m0 );
319
320source = ( s_f ) ? n0 : 1;
321printf ("n %8ld\nc\n", source );
322
323if ( p_f ) /* generating potentials */
324 {
325 p = (long*) calloc ( n+2, sizeof (long) );
326 seed1 = 2*seed + 1;
327 init_rand ( seed1);
328 pl = pl - pm + 1;
329
330 for ( i = 0; i <= n; i ++ )
331 {
332 p_t = pm + nrand ( pl );
333 if ( pn_f ) p_t += (long) ( i * pn );
334 if ( ps_f ) p_t += (long) ( i * ( i * ps ));
335 if ( pap_f )
336 if ( rand01() < pap )
337 p_t = (long) ( p_t * pac );
338 p[i] = p_t;
339 }
340 p[n+1] = 0;
341 }
342
343
344if ( s_f ) /* additional arcs from artifical source */
345 {
346 seed2 = 3*seed + 1;
347 init_rand ( seed2 );
348 sl = sl - sm + 1;
349
350 for ( i = n; i > 1; i -- )
351 {
352 s = sm + nrand ( sl );
353 PRINT_ARC ( n0, i, s )
354 }
355
356 PRINT_ARC ( n0, 1, 0 )
357 }
358
359/* initialize random number generator */
360init_rand ( seed );
361ll = ll - lm + 1;
362
363/* generating connecting cycle(s) */
364if (c_random)
365 cl = lm + nrand ( ll );
366PRINT_ARC ( 1, 2, cl )
367if (c_random)
368 cl = lm + nrand ( ll );
369PRINT_ARC ( n, 1, cl )
370
371for ( i = 2; i < n; i ++ )
372 {
373 if (c_random)
374 cl = lm + nrand ( ll );
375
376 if ( ( (i-1) % (ch-1) ) != 0 )
377 PRINT_ARC ( i, i+1, cl )
378 else
379 { PRINT_ARC ( i, 1, cl )
380 if (c_random)
381 cl = lm + nrand ( ll );
382 PRINT_ARC ( 1, i+1, cl )
383 }
384 }
385
386/* generating random arcs */
387
388for ( k = 1; k <= m - mc; k ++ )
389 {
390 i = 1 + nrand ( n );
391
392 do
393 j = 1 + nrand ( n );
394 while ( j == i );
395
396 dij = ( i > j ) ? ( i - j ) : ( j - i );
397 l = lm + nrand ( ll );
398 if ( ln_f ) l += (long) ( dij * ln );
399 if ( ls_f ) l += (long) ( dij * ( dij * ls ) );
400 PRINT_ARC ( i, j, l );
401 }
402
403/* all is done */
404exit (ext);
405
406/* ----- wrong usage ----- */
407
408 usage:
409fprintf ( stderr,
410"\nusage: %s n m seed [ -ll#i -lm#i -cl#i -p -pl#i -pm#i ... ]\n\
411help: %s -h\n\n", argv[0], argv[0] );
412
413if ( np > 0 )
414 fprintf ( stderr, "error in parameter # %d\n\n", np );
415exit (4);
416
417/* ---- help ---- */
418
419 help:
420
421if ( args[2] == 'h') goto hhelp;
422
423fprintf ( stderr,
424"\n'%s' - random network generator for shortest paths problem.\n\
425Generates problems in extended DIMACS format.\n\
426\n\
427 %s n m seed [ -ll#i -lm#i -cl#i -p -pl#i -pm#i ... ]\n\
428 %s -hh\n\
429\n\
430 #i - integer number #f - real number\n\
431\n\
432-ll#i - #i is the upper bound on arc lengths (default 10000)\n\
433-lm#i - #i is the lower bound on arc lengths (default 0)\n\
434-cl#i - #i is length of arcs in connecting cycle(s) (default random)\n\
435-p - generate potentials \n\
436-pl#i - #i is the upper bound on potentials (default ll)\n\
437-pm#i - #i is the lower bound on potentials (default lm)\n\
438\n\
439-hh - extended help \n\n",
440argv[0], argv[0], argv[0] );
441
442exit (0);
443
444/* --------- sophisticated help ------------ */
445 hhelp:
446
447if ( argc < 3 )
448 fout = stderr;
449else
450 fout = fopen ( argv[2], "w" );
451
452if ( fout == NULL )
453{ fprintf ( stderr, "\nCan't open file '%s' for writing help\n\n", argv[2] );
454 exit ( 2 );
455}
456
457fprintf (fout,
458"\n'%s' - random network generator for shortest paths problem.\n\
459Generates problems in extended DIMACS format.\n\
460\n\
461 %s n m seed [ -ll#i -lm#i -ln#f -ls#f\n\
462 -p -pl#i -pm#i -pn#f -ps#f -pap#i -pac#f\n\
463 -cl#i -ch#i\n\
464 -s -sl#i -sm#i\n\
465 ]\n\
466 %s -hh file_name\n\
467\n\
468 #i - integer number #f - real number\n\
469\n\
470 Arc length parameters:\n\
471-ll#i - #i is the upper bound on arc lengths (default 10000)\n\
472-lm#i - #i is the lower bound on arc lengths (default 0)\n\
473-ln#f - multipliy l(i, j) by #f * |i-j| (default 0)\n\
474-ls#f - multipliy l(i, j) by #f * |i-j|^2 (default 0)\n\
475\n\
476 Potential parameters:\n\
477-p - generate potentials \n\
478-pl#i - #i is the upper bound on potentials (default ll)\n\
479-pm#i - #i is the lower bound on potentials (default lm)\n\
480-pn#f - multiply p(i) by #f * i (default 0)\n\
481-ps#f - multiply p(i) by #f * i^2 (default 0)\n\
482-pap#i - percentage of alternative potential nodes (default 0)\n\
483-pac#f - if i is alternative, multiply p(i) by #f (default -1)\n\
484\n\
485 Connecting cycle(s) parameters:\n\
486-cl#i - #i is length of arcs in connecting cycle(s) (default random)\n\
487-ch#i - #i is length of connecting cycles (default n)\n\
488\n\
489 Artificial source parameters:\n\
490-s - generate artificial source with default connecting arc lengths\n\
491-sl#i - #i is the upper bound on art. arc lengths (default 100000000)\n\
492-sm#i - #i is the lower bound on art. arc lengths (default sl)\n\
493\n\
494-hh file_name - save this help in the file 'file_name'\n\n",
495argv[0], argv[0], argv[0] );
496
497exit (0);
498}
499
500
501