blob: 28b58b30e7f192bd7618a49ab12a307c875e405a [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <values.h>
#include "random.c"
#define DASH '-'
#define VERY_FAR 100000000
/* generator of random networks for the shortest paths problem;
extended DIMACS format for output */
main ( argc, argv )
int argc;
char* argv[];
{
char args[30];
long n,
n0,
source,
i,
i0,
j,
dij;
long m,
m0,
mc,
k;
long *p,
p_t,
l,
lx;
long seed,
seed1,
seed2;
int ext=0;
FILE *fout;
/* variables for lengths generating */
/* initialized by default values */
int l_f = 0, ll_f = 0, lm_f = 0, ln_f = 0, ls_f = 0;
long ll = 10000, /* length of the interval */
lm = 0; /* minimal bound of the interval */
double ln = 0, /* l += ln * |i-j| */
ls = 0; /* l += ls * |i-j|^2 */
/* variables for connecting cycle(s) */
int c_f = 0, cl_f = 0, ch_f = 0, c_random = 1;
long cl = 1; /* length of cycle arc */
long ch; /* number of arcs in the cycle
n - by default */
/* variables for artifical source */
int s_f = 0, sl_f = 0, sm_f = 0;
long sl = VERY_FAR, /* upper bound of artifical arc */
sm, /* lower bound of artifical arc */
s;
/* variables for potentials */
int p_f = 0, pl_f = 0, pm_f = 0, pn_f = 0, ps_f = 0,
pa_f = 0, pap_f = 0, pac_f = 0;
long pl, /* length of the interval */
pm; /* minimal bound of the interval */
double pn = 0, /* l += ln * |i-j| */
ps = 0, /* l += ls * |i-j|^2 */
pap = 0, /* part of nodes with alternative dustribution */
pac = -1; /* multiplier for alternative distribution */
int np; /* number of parameter parsing now */
#define PRINT_ARC( i, j, length )\
{\
l = length;\
if ( p_f ) l += ( p[i] - p[j] );\
printf ("a %8ld %8ld %12ld\n", i, j, l );\
}
/* parsing parameters */
if ( argc < 2 ) goto usage;
np = 0;
strcpy ( args, argv[1] );
if ( ( args[0] == DASH ) && ( args[1] == 'h')
)
goto help;
if ( argc < 4 ) goto usage;
/* first parameter - number of nodes */
np = 1;
if ( ( n = atoi ( argv[1] ) ) < 2 ) goto usage;
/* second parameter - number of arcs */
np = 2;
if ( ( m = atoi ( argv[2] ) ) < n ) goto usage;
/* third parameter - seed */
np=3;
if ( ( seed = atoi ( argv[3] ) ) <= 0 ) goto usage;
/* other parameters */
for ( np = 4; np < argc; np ++ )
{
strcpy ( args, argv[np] );
if ( args[0] != DASH ) goto usage;
switch ( args[1] )
{
case 'l' : /* an interval for arc length */
l_f = 1;
switch ( args[2] )
{
case 'l': /* length of the interval */
ll_f = 1;
ll = (long) atof ( &args[3] );
break;
case 'm': /* minimal bound */
lm_f = 1;
lm = (long ) atof ( &args[3] );
break;
case 'n': /* additional length: l*|i-j| */
ln_f = 1;
ln = atof ( &args[3] );
break;
case 's': /* additional length: l*|i-j|^2 */
ls_f = 1;
ls = atof ( &args[3] );
break;
default: /* unknown switch value */
goto usage;
}
break;
case 'c' : /* connecting cycle(s) */
c_f = 1;
switch ( args[2] )
{
case 'l':
c_random = 0;
cl_f = 1;
cl = (long) atof ( &args[3] );
if ( cl < 0 ) goto usage;
break;
case 'h':
ch_f = 1;
ch = (long) atof ( &args[3] );
if ( ch < 2 || ch > n ) goto usage;
break;
default: /* unknown switch value */
goto usage;
}
break;
case 's' : /* additional source */
s_f = 1;
if ( strlen ( args ) > 2 )
{
switch ( args[2] )
{
case 'l': /* upper bound of art. arc */
sl_f = 1;
sl = (long) atof ( &args[3] );
break;
case 'm': /* lower bound of art. arc */
sm_f = 1;
sm = (long) atof ( &args[3] );
break;
default: /* unknown switch value */
goto usage;
}
}
break;
case 'p' : /* potentials */
p_f = 1;
if ( strlen ( args ) > 2 )
{
switch ( args[2] )
{
case 'l': /* length of the interval */
pl_f = 1;
pl = (long) atof ( &args[3] );
break;
case 'm': /* minimal bound */
pm_f = 1;
pm = (long ) atof ( &args[3] );
break;
case 'n': /* additional length: l*|i-j| */
pn_f = 1;
pn = atof ( &args[3] );
break;
case 's': /* additional length: l*|i-j|^2 */
ps_f = 1;
ps = atof ( &args[3] );
break;
case 'a': /* bipolar distribution */
pa_f = 1;
switch ( args[3] )
{
case 'p': /* % of alternative potentials */
pap_f = 1;
pap = atof ( &args[4] );
if ( pap < 0 ) pap = 0;
if ( pap > 100 ) pap = 100;
pap /= 100;
break;
case 'c': /* multiplier */
pac_f = 1;
pac = atof ( &args[4] );
break;
default: /* unknown switch value */
goto usage;
}
break;
default: /* unknown switch value */
goto usage;
}
}
break;
default : /* unknoun case */
goto usage;
}
}
/* ----- ajusting parameters ----- */
n0 = n; m0 = m;
/* length parameters */
if ( ll < lm ) { lx = ll; ll = lm; lm = lx; }
/* potential parameters */
if ( p_f )
{
if ( ! pl_f ) pl = ll;
if ( ! pm_f ) pm = lm;
if ( pl < pm ) { lx = pl; pl = pm; pm = lx; }
}
/* path(s) parameters */
if ( ! ch_f ) ch = n;
mc = n + (n-2) / (ch-1);
if ( mc > m )
{ fprintf ( stderr,
"Error: not enough arcs for generating connecting cycle(s)\n" );
exit (4);
}
/* artifical source parameters */
if ( s_f )
{ m0 += n; n0 ++ ;
if ( ! sm_f ) sm = sl;
if ( sl < sm ) { lx = sl; sl = sm; sm = lx; }
}
/* printing title */
printf ("c random network for shortest paths problem\n");
printf ("c extended DIMACS format\nc\n" );
/* name of the problem */
printf ("t rd_%ld_%ld_%ld_", n, m, seed );
if ( l_f )
printf ("%c", 'l');
if ( c_f )
printf ("%c", 'c');
if ( s_f )
printf ("%c", 's');
if ( p_f )
printf ("%c", 'p');
printf ("\nc\n");
/* printing additional information */
if ( l_f )
printf ("c length -> min: %ld max: %ld k1: %.2f k2: %.2f\n",
lm, ll, ln, ls );
if ( c_f )
{
if ( c_random )
printf ("c cycle -> number of arcs: %ld arc length: random\n", ch);
else
printf ("c cycle -> number of arcs: %ld arc length: %ld\n",
ch, cl );
}
if ( s_f )
printf ("c length of arcs from artifical source -> min: %ld max: %ld\n",
sm, sl );
if ( p_f )
{
printf ("c potentials -> min: %ld max: %ld k1: %.2f k2: %.2f\n",
pm, pl, pn, ps );
if ( pa_f )
printf ("c potentials -> part of alternative distribution: %.2f k: %.2f\n",
pap, pac );
}
printf ("c\n" );
printf ("p sp %8ld %8ld\nc\n", n0, m0 );
source = ( s_f ) ? n0 : 1;
printf ("n %8ld\nc\n", source );
if ( p_f ) /* generating potentials */
{
p = (long*) calloc ( n+2, sizeof (long) );
seed1 = 2*seed + 1;
init_rand ( seed1);
pl = pl - pm + 1;
for ( i = 0; i <= n; i ++ )
{
p_t = pm + nrand ( pl );
if ( pn_f ) p_t += (long) ( i * pn );
if ( ps_f ) p_t += (long) ( i * ( i * ps ));
if ( pap_f )
if ( rand01() < pap )
p_t = (long) ( p_t * pac );
p[i] = p_t;
}
p[n+1] = 0;
}
if ( s_f ) /* additional arcs from artifical source */
{
seed2 = 3*seed + 1;
init_rand ( seed2 );
sl = sl - sm + 1;
for ( i = n; i > 1; i -- )
{
s = sm + nrand ( sl );
PRINT_ARC ( n0, i, s )
}
PRINT_ARC ( n0, 1, 0 )
}
/* initialize random number generator */
init_rand ( seed );
ll = ll - lm + 1;
/* generating connecting cycle(s) */
if (c_random)
cl = lm + nrand ( ll );
PRINT_ARC ( 1, 2, cl )
if (c_random)
cl = lm + nrand ( ll );
PRINT_ARC ( n, 1, cl )
for ( i = 2; i < n; i ++ )
{
if (c_random)
cl = lm + nrand ( ll );
if ( ( (i-1) % (ch-1) ) != 0 )
PRINT_ARC ( i, i+1, cl )
else
{ PRINT_ARC ( i, 1, cl )
if (c_random)
cl = lm + nrand ( ll );
PRINT_ARC ( 1, i+1, cl )
}
}
/* generating random arcs */
for ( k = 1; k <= m - mc; k ++ )
{
i = 1 + nrand ( n );
do
j = 1 + nrand ( n );
while ( j == i );
dij = ( i > j ) ? ( i - j ) : ( j - i );
l = lm + nrand ( ll );
if ( ln_f ) l += (long) ( dij * ln );
if ( ls_f ) l += (long) ( dij * ( dij * ls ) );
PRINT_ARC ( i, j, l );
}
/* all is done */
exit (ext);
/* ----- wrong usage ----- */
usage:
fprintf ( stderr,
"\nusage: %s n m seed [ -ll#i -lm#i -cl#i -p -pl#i -pm#i ... ]\n\
help: %s -h\n\n", argv[0], argv[0] );
if ( np > 0 )
fprintf ( stderr, "error in parameter # %d\n\n", np );
exit (4);
/* ---- help ---- */
help:
if ( args[2] == 'h') goto hhelp;
fprintf ( stderr,
"\n'%s' - random network generator for shortest paths problem.\n\
Generates problems in extended DIMACS format.\n\
\n\
%s n m seed [ -ll#i -lm#i -cl#i -p -pl#i -pm#i ... ]\n\
%s -hh\n\
\n\
#i - integer number #f - real number\n\
\n\
-ll#i - #i is the upper bound on arc lengths (default 10000)\n\
-lm#i - #i is the lower bound on arc lengths (default 0)\n\
-cl#i - #i is length of arcs in connecting cycle(s) (default random)\n\
-p - generate potentials \n\
-pl#i - #i is the upper bound on potentials (default ll)\n\
-pm#i - #i is the lower bound on potentials (default lm)\n\
\n\
-hh - extended help \n\n",
argv[0], argv[0], argv[0] );
exit (0);
/* --------- sophisticated help ------------ */
hhelp:
if ( argc < 3 )
fout = stderr;
else
fout = fopen ( argv[2], "w" );
if ( fout == NULL )
{ fprintf ( stderr, "\nCan't open file '%s' for writing help\n\n", argv[2] );
exit ( 2 );
}
fprintf (fout,
"\n'%s' - random network generator for shortest paths problem.\n\
Generates problems in extended DIMACS format.\n\
\n\
%s n m seed [ -ll#i -lm#i -ln#f -ls#f\n\
-p -pl#i -pm#i -pn#f -ps#f -pap#i -pac#f\n\
-cl#i -ch#i\n\
-s -sl#i -sm#i\n\
]\n\
%s -hh file_name\n\
\n\
#i - integer number #f - real number\n\
\n\
Arc length parameters:\n\
-ll#i - #i is the upper bound on arc lengths (default 10000)\n\
-lm#i - #i is the lower bound on arc lengths (default 0)\n\
-ln#f - multipliy l(i, j) by #f * |i-j| (default 0)\n\
-ls#f - multipliy l(i, j) by #f * |i-j|^2 (default 0)\n\
\n\
Potential parameters:\n\
-p - generate potentials \n\
-pl#i - #i is the upper bound on potentials (default ll)\n\
-pm#i - #i is the lower bound on potentials (default lm)\n\
-pn#f - multiply p(i) by #f * i (default 0)\n\
-ps#f - multiply p(i) by #f * i^2 (default 0)\n\
-pap#i - percentage of alternative potential nodes (default 0)\n\
-pac#f - if i is alternative, multiply p(i) by #f (default -1)\n\
\n\
Connecting cycle(s) parameters:\n\
-cl#i - #i is length of arcs in connecting cycle(s) (default random)\n\
-ch#i - #i is length of connecting cycles (default n)\n\
\n\
Artificial source parameters:\n\
-s - generate artificial source with default connecting arc lengths\n\
-sl#i - #i is the upper bound on art. arc lengths (default 100000000)\n\
-sm#i - #i is the lower bound on art. arc lengths (default sl)\n\
\n\
-hh file_name - save this help in the file 'file_name'\n\n",
argv[0], argv[0], argv[0] );
exit (0);
}