#include #include #include #include "random.c" #include #include "thread.h" #include "vty.h" #include "log.h" #include "linklist.h" #include "spgrid.h" #define DASH '-' #define VERY_FAR 100000000 #define DOUBLE_CYCLE 0 #define CYCLE 1 #define PATH 2 #define NO 0 #define YES 1 #define NODE( x, y ) (x*Y + y + 1) /* * Prototypes. */ void free_arc(void *); void help(struct vty *); void print_arc(struct vty *, struct list *, long, long, long); void hhelp(struct vty *); void usage(struct vty *); const char *graph_type[] = { "double cycle", "cycle", "path" }; struct arc *arc; char args[30]; long X, /* horizontal size of grid */ Y; /* vertical size of grid */ long x, y, y1, y2, yp, dl, dx, xn, yn, count, *mess; double n; long n0, source, i, i0, j, dij; double m; long m0, mc, k; long *p, p_t, l, lx; long seed, seed1, seed2; int ext=0; /* initialized by default values */ /* variables for generating one layer */ /* variables for generating spanning graph */ int c_f = 0, cw_f = 0, cm_f = 0, cl_f = 0; int cw = DOUBLE_CYCLE; /* type of spanning graph */ long cm = 0, /* lower bound of the interval */ cl = 100; /* upper bound of the interval */ /* variables for generating additional arcs */ int a_f = 0, ax_f = 0, am_f = 0, al_f = 0; long ax = 0, /* number of additional arcs */ am = 0, /* lower bound of the interval */ al = 100; /* upper bound of the interval */ /* variables for inter-layer arcs */ int i_f = 0, ip_f = 0, ix_f = 0, ih_f = 0, im_f = 0, il_f = 0, in_f = 0, is_f = 0; int ip = NO; /* to mess or not to mess */ long ix = 1, /* number of interlayered arcs in a NODE */ ih = 1, /* step between two layeres */ il = 10000, /* upper bound of the interval */ im = 1000; /* lower bound of the interval */ double in = 1, /* l *= in * |x1-x2| */ is = 0; /* l *= is * |x1-x2|^2 */ /* 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; long pl, /* upper bound of the interval */ pm; /* lower bound of the interval */ double pn = 0, /* p += ln * (x+1) */ ps = 0; /* p += ls * (x+1)^2 */ int np; /* number of parameter parsing now */ void free_arc (void *val) { free(val); } void print_arc (struct vty *vty, struct list *topology, long i, long j, long length) { struct arc *myarc; l = length; if ( p_f ) l += ( p[i] - p[j] ); // vty_out (vty,"a %8ld %8ld %12ld%s", i, j, l ,VTY_NEWLINE); myarc = malloc (sizeof(struct arc)); myarc->from_node = i; myarc->to_node = j; myarc->distance = l; topology->del = free_arc; listnode_add (topology, myarc); } /* ---- help ---- */ void help (struct vty *vty) { // if ( args[2] == 'h') hhelp (vty); vty_out (vty,"grid network generator for shortest paths problem.%s",VTY_NEWLINE); vty_out (vty,"Generates problems in extended DIMACS format.%s",VTY_NEWLINE); vty_out (vty,"X Y seed [ -cl#i -cm#i -c{c|d|p} -ip -il#i -im#i -p -pl#i -pm#i... ]%s",VTY_NEWLINE); vty_out (vty,"#i - integer number%s",VTY_NEWLINE); vty_out (vty,"-cl#i - #i is the upper bound on layer arc lengths (default 100)%s",VTY_NEWLINE); vty_out (vty,"-cm#i - #i is the lower bound on layer arc lengths (default 0)%s",VTY_NEWLINE); vty_out (vty,"-c#t - #t is the type of connecting graph: { c | d | p }%s",VTY_NEWLINE); vty_out (vty," c - cycle, d - double cycle, p - path (default d)%s",VTY_NEWLINE); vty_out (vty,"-ip - shuffle inter-layer arcs (default NO)%s",VTY_NEWLINE); vty_out (vty,"-il#i - #i is the upper bound on inter-layer arc lengths (default 10000)%s",VTY_NEWLINE); vty_out (vty,"-im#i - #i is the lower bound on inter-layer arc lengths (default 1000)%s",VTY_NEWLINE); vty_out (vty,"-p - generate potentials%s",VTY_NEWLINE); vty_out (vty,"-pl#i - #i is the upper bound on potentials (default il)%s",VTY_NEWLINE); vty_out (vty,"-pm#i - #i is the lower bound on potentials (default im)%s",VTY_NEWLINE); vty_out (vty,"%s",VTY_NEWLINE); vty_out (vty,"-hh - extended help%s",VTY_NEWLINE); } /* --------- sophisticated help ------------ */ void hhelp (struct vty *vty) { /* zlog_info ( "\n'%s' - grid network generator for shortest paths problem.\n\ Generates problems in extended DIMACS format.\n\ \n\ %s X Y seed [ -cl#i -cm#i -c{c|d|p}\n\ -ax#i -al#i -am#i\n\ -ip -il#i -im#i -in#i -is#i -ix#i -ih#i\n\ -p -pl#i -pm#i -pn#f -ps#f\n\ -s -sl#i -sm#i\n\ ]\n\ %s -hh file_name\n\ \n\ #i - integer number #f - real number\n\ \n\ Parameters of connecting arcs within one layer:\n\ -cl#i - #i is the upper bound on arc lengths (default 100)\n\ -cm#i - #i is the lower bound on arc lengths (default 0)\n\ -c#t - #t is the type of connecting graph: { c | d | p }\n\ c - cycle, d - double cycle, p - path (default d)\n\ \n\ Parameters of additional arcs within one layer:\n\ -ax#i - #i is the number of additional arcs (default 0)\n\ -al#i - #i is the upper bound on arc lengths (default 100)\n\ -am#i - #i is the lower bound on arc lengths (default 0)\n\ \n\ Interlayerd arc parameters:\n\ -ip - shuffle inter-layer arcs (default NO)\n\ -il#i - #i is the upper bound on arc lengths (default 10000)\n\ -im#i - #i is the lower bound on arc lengths (default 1000)\n\ -in#f - multiply l(i, j) by #f * x(j)-x(i) (default 1)\n\ if #f=0 - don't multiply\n\ -is#f - multiply l(i, j) by #f * (x(j)-x(i))^2 (default NO)\n\ -ix#i - #i - is the number of arcs from a node (default 1)\n\ -ih#i - #i - is the step between connected layers (default 1)\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 * x(i) (default NO)\n\ -ps#f - multiply p(i) by #f * x(i)^2 (default NO)\n\ \n"); zlog_info ( " 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\" );*/ } /* ----- wrong usage ----- */ void usage (struct vty *vty) { vty_out (vty,"usage: X Y seed [-ll#i -lm#i -cl#i -p -pl#i -pm#i ...]%s",VTY_NEWLINE); vty_out (vty,"help: -h or -hh%s",VTY_NEWLINE); if ( np > 0 ) zlog_err ("error in parameter # %d\n\n", np ); } /* parsing parameters */ /* checks the validity of incoming parameters */ int spgrid_check_params ( struct vty *vty, int argc, const char **argv) { /* initialized by default values */ ext=0; /* variables for generating one layer */ /* variables for generating spanning graph */ c_f = 0; cw_f = 0; cm_f = 0; cl_f = 0; cw = PATH; /* type of spanning graph */ cm = 0; /* lower bound of the interval */ cl = 63; /* upper bound of the interval */ /* variables for generating additional arcs */ a_f = 0; ax_f = 0; am_f = 0; al_f = 0; ax = 0; /* number of additional arcs */ am = 0; /* lower bound of the interval */ al = 63; /* upper bound of the interval */ /* variables for inter-layer arcs */ i_f = 0; ip_f = 0; ix_f = 0; ih_f = 0; im_f = 0; il_f = 0; in_f = 0; is_f = 0; ip = NO; /* to mess or not to mess */ ix = 1; /* number of interlayered arcs in a NODE */ ih = 1; /* step between two layeres */ il = 63; //was 10000; /* upper bound of the interval */ im = 0; //was 1000; /* lower bound of the interval */ in = 1; /* l *= in * |x1-x2| */ is = 0; /* l *= is * |x1-x2|^2 */ /* variables for artifical source */ s_f = 0; sl_f = 0; sm_f = 0; sl = VERY_FAR; /* upper bound of artifical arc */ /* variables for potentials */ p_f = 0; pl_f = 0; pm_f = 0; pn_f = 0; ps_f = 0; pn = 0; /* p += ln * (x+1) */ ps = 0; /* p += ls * (x+1)^2 */ if ( argc < 1 ) { usage (vty); return 1; } np = 0; strcpy ( args, argv[0] ); if ((args[0] == DASH) && (args[1] == 'h')) help (vty); if ( argc < 3 ) { usage (vty); return 1; } /* first parameter - horizontal size */ np = 1; if ( ( X = atoi ( argv[0] ) ) < 1 ) { usage (vty); return 1; } /* second parameter - vertical size */ np = 2; if ( ( Y = atoi ( argv[1] ) ) < 1 ) { usage (vty); return 1; } /* third parameter - seed */ np=3; if ( ( seed = atoi ( argv[2] ) ) <= 0 ) { usage (vty); return 1; } /* other parameters */ for ( np = 3; np < argc; np ++ ) { strcpy ( args, argv[np] ); if ( args[0] != DASH ) { usage (vty); return 1; } switch ( args[1] ) { case 'c' : /* spanning graph in one layer */ c_f = 1; switch ( args[2] ) { case 'l': /* upper bound of the interval */ cl_f = 1; cl = atol ( &args[3] ); break; case 'm': /* lower bound */ cm_f = 1; cm = atol ( &args[3] ); break; case 'c': /* type - cycle */ cw_f = 1; cw = CYCLE; break; case 'd': /* type - double cycle */ cw_f = 1; cw = DOUBLE_CYCLE; break; case 'p': /* type - path */ cw_f = 1; cw = PATH; break; default: /* unknown switch value */ usage (vty); return 1; } break; case 'a' : /* additional arcs in one layer */ a_f = 1; switch ( args[2] ) { case 'l': /* upper bound of the interval */ al_f = 1; al = atol ( &args[3] ); break; case 'm': /* lower bound */ am_f = 1; am = atol ( &args[3] ); break; case 'x': /* number of additional arcs */ ax_f = 1; ax = atol ( &args[3] ); if ( ax < 0 ) { usage (vty); return 1; } break; default: /* unknown switch value */ { usage (vty); return 1; } } break; case 'i' : /* interlayered arcs */ i_f = 1; switch ( args[2] ) { case 'l': /* upper bound */ il_f = 1; il = atol ( &args[3] ); break; case 'm': /* lower bound */ im_f = 1; im = atol ( &args[3] ); break; case 'n': /* additional length: l *= in*|i1-i2| */ in_f = 1; in = atof ( &args[3] ); break; case 's': /* additional length: l *= is*|i1-i2|^2 */ is_f = 1; is = atof ( &args[3] ); break; case 'p': /* mess interlayered arcs */ ip_f = 1; ip = YES; break; case 'x': /* number of interlayered arcs */ ix_f = 1; ix = atof ( &args[3] ); if ( ix < 1 ) { usage (vty); return 1; } break; case 'h': /* step between two layeres */ ih_f = 1; ih = atof ( &args[3] ); if ( ih < 1 ) { usage (vty); return 1; } break; default: /* unknown switch value */ usage (vty); return 1; } 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 = atol ( &args[3] ); break; case 'm': /* lower bound of art. arc */ sm_f = 1; sm = atol ( &args[3] ); break; default: /* unknown switch value */ usage (vty); return 1; } } break; case 'p' : /* potentials */ p_f = 1; if ( strlen ( args ) > 2 ) { switch ( args[2] ) { case 'l': /* upper bound */ pl_f = 1; pl = atol ( &args[3] ); break; case 'm': /* lower bound */ pm_f = 1; pm = atol ( &args[3] ); break; case 'n': /* additional: p *= pn*(x+1) */ pn_f = 1; pn = atof ( &args[3] ); break; case 's': /* additional: p = ps* (x+1)^2 */ ps_f = 1; ps = atof ( &args[3] ); break; default: /* unknown switch value */ usage (vty); return 1; } } break; default: /* unknoun case */ usage (vty); return 1; } } return 0; } /* generator of layered networks for the shortest paths problem; extended DIMACS format for output */ int gen_spgrid_topology (struct vty *vty, struct list *topology) { /* ----- ajusting parameters ----- */ /* spanning */ if ( cl < cm ) { lx = cl; cl = cm; cm = lx; } /* additional arcs */ if ( al < am ) { lx = al; al = am; am = lx; } /* interlayered arcs */ if ( il < im ) { lx = il; il = im; im = lx; } /* potential parameters */ if ( p_f ) { if ( ! pl_f ) pl = il; if ( ! pm_f ) pm = im; if ( pl < pm ) { lx = pl; pl = pm; pm = lx; } } /* number of nodes and arcs */ n = (double)X *(double)Y + 1; m = (double)Y; /* arcs from source */ switch ( cw ) { case PATH: mc = (double)Y - 1; break; case CYCLE: mc = (double)Y; break; case DOUBLE_CYCLE: mc = 2*(double)Y; } m += (double)X * (double)mc; /* spanning arcs */ m += (double)X * (double)ax; /* additional arcs */ /* interlayered arcs */ for ( x = 0; x < X; x ++ ) { dl = ( ( X - x - 1 ) + ( ih - 1 ) ) / ih; if ( dl > ix ) dl = ix; m += (double)Y * (double)dl; } /* artifical source parameters */ if ( s_f ) { m += n; n ++ ; if ( ! sm_f ) sm = sl; if ( sl < sm ) { lx = sl; sl = sm; sm = lx; } } if ( n >= (double)LONG_MAX || m >= (double)LONG_MAX ) { zlog_err ("Too large problem. It can't be generated\n"); exit (4); } else { n0 = (long)n; m0 = (long)m; } if ( ip_f ) mess = (long*) calloc ( Y, sizeof ( long ) ); /* printing title */ zlog_info ("Generating topology for ISIS"); source = ( s_f ) ? n0-1 : n0; if ( p_f ) /* generating potentials */ { p = (long*) calloc ( n0+1, sizeof (long) ); seed1 = 2*seed + 1; init_rand ( seed1); pl = pl - pm + 1; for ( x = 0; x < X; x ++ ) for ( y = 0; y < Y; y ++ ) { p_t = pm + nrand ( pl ); if ( pn_f ) p_t *= (long) ( (1 + x) * pn ); if ( ps_f ) p_t *= (long) ( (1 + x) * ( (1 + x) * ps )); p[ NODE ( x, y ) ] = p_t; } p[n0] = 0; if ( s_f ) p[n0-1] = 0; } if ( s_f ) /* additional arcs from artifical source */ { seed2 = 3*seed + 1; init_rand ( seed2 ); sl = sl - sm + 1; for ( x = X - 1; x >= 0; x -- ) for ( y = Y - 1; y >= 0; y -- ) { i = NODE ( x, y ); s = sm + nrand ( sl ); print_arc (vty, topology, n0, i, s ); } print_arc (vty, topology, n0, n0-1, 0 ); } /* ----- generating arcs within layers ----- */ init_rand ( seed ); cl = cl - cm + 1; al = al - am + 1; for ( x = 0; x < X; x ++ ) { /* generating arcs within one layer */ for ( y = 0; y < Y-1; y ++ ) { /* generating spanning graph */ i = NODE ( x, y ); j = NODE ( x, y+1 ); l = cm + nrand ( cl ); print_arc (vty, topology, i, j, l ); if ( cw == DOUBLE_CYCLE ) { l = cm + nrand ( cl ); print_arc (vty, topology, j, i, l ); } } if ( cw <= CYCLE ) { i = NODE ( x, Y-1 ); j = NODE ( x, 0 ); l = cm + nrand ( cl ); print_arc (vty, topology, i, j, l ); if ( cw == DOUBLE_CYCLE ) { l = cm + nrand ( cl ); print_arc (vty, topology, j, i, l ); } } /* generating additional arcs */ for ( k = ax; k > 0; k -- ) { y1 = nrand ( Y ); do y2 = nrand ( Y ); while ( y2 == y1 ); i = NODE ( x, y1 ); j = NODE ( x, y2 ); l = am + nrand ( al ); print_arc (vty, topology, i, j, l ); } } /* ----- generating interlayered arcs ------ */ il = il - im + 1; /* arcs from the source */ for ( y = 0; y < Y; y ++ ) { l = im + nrand ( il ); i = NODE ( 0, y ); print_arc (vty, topology, source, i, l ); } for ( x = 0; x < X-1; x ++ ) { /* generating arcs from one layer */ for ( count = 0, xn = x + 1; count < ix && xn < X; count ++, xn += ih ) { if ( ip_f ) for ( y = 0; y < Y; y ++ ) mess[y] = y; for ( y = 0; y < Y; y ++ ) { i = NODE ( x, y ); dx = xn - x; if ( ip_f ) { yp = nrand(Y-y); yn = mess[ yp ]; mess[ yp ] = mess[ Y - y - 1 ]; } else yn = y; j = NODE ( xn, yn ); l = im + nrand ( il ); if ( in != 0 ) l *= (long) ( in * dx ); if ( is_f ) l *= (long) ( ( is * dx ) * dx ); print_arc (vty, topology, i, j, l ); } } } /* all is done */ return ext; return 0; }