示例#1
0
static int
minimal_ladders(ladders_rec_t *rec)
{
    Vertex *uu, *vv;
    int rc = 0;
    char *start = rec->start;
    char *goal = rec->goal;

    /* build the amplified graph gg */
    gg = gb_new_graph(0L);
    gg->vertices = __g->vertices;
    gg->n = __g->n;

    (gg->vertices + gg->n)->name = start;
    uu = find_word(start, plant_new_edge);
    if (!uu) {
        uu = gg->vertices + gg->n++;
    }

    if (strncmp(start, goal, 5) == 0) {
        vv = uu;
    } else {
        (gg->vertices + gg->n)->name = goal;
        vv = find_word(goal, plant_new_edge);
        if (!vv) {
            vv = gg->vertices + gg->n++;
        }
    }

    if (gg->n == __g->n + 2) {
        if (hamm_dist(start, goal) == 1) {
            gg->n--;
            plant_new_edge(uu);
            gg->n++;
        }
    }

    /* print the answer */
    if (dijkstra(uu, vv, gg, NULL) < 0) {
        strbuf_append_printf(&rec->path,
                             "Sorry, there's no ladder from %s to %s.", 
                             start, goal);
    } else {
        rc = dijkstra_result(rec, vv);
    }

    /* remove all traces of gg */
    for (uu = __g->vertices + gg->n-1; uu >= __g->vertices+__g->n; uu--) {
        register Arc *a;
        for (a = uu->arcs; a; a = a->next) {
            vv = a->tip;
            vv->arcs = vv->arcs->next;
        }
        uu->arcs = NULL;
    }

    gb_recycle(gg);

    return rc;
}
示例#2
0
//#line 6 "../PROTOTYPES/ladders.ch"
int main(int argc, char *argv[])
//#line 94 "../ladders.w"
{
/*5:*/
//#line 120 "../ladders.w"

    while (--argc) {

        if (strcmp(argv[argc], "-v") == 0)
            verbose = 1;
        else if (strcmp(argv[argc], "-a") == 0)
            alph = 1;
        else if (strcmp(argv[argc], "-f") == 0)
            freq = 1;
        else if (strcmp(argv[argc], "-h") == 0)
            heur = 1;
        else if (strcmp(argv[argc], "-e") == 0)
            echo = 1;
        else if (sscanf(argv[argc], "-n%lu", &n) == 1)
            randm = 0;
        else if (sscanf(argv[argc], "-r%lu", &n) == 1)
            randm = 1;
        else if (sscanf(argv[argc], "-s%ld", &seed) == 1);
        else {
            fprintf(stderr, "Usage: %s [-v][-a][-f][-h][-e][-nN][-rN][-sN]\n", argv[0]);
            return -2;
        }
    }
    if (alph || randm)
        freq = 0;
    if (freq)
        heur = 0;

/*:5*/
//#line 95 "../ladders.w"
    ;
/*6:*/
//#line 149 "../ladders.w"

    g = words(n, (randm ? zero_vector : NULL), 0L, seed);
    quit_if(g == NULL, panic_code);
/*8:*/
//#line 165 "../ladders.w"

    if (verbose) {
        if (alph)
            printf("(alphabetic distance selected)\n");
        if (freq)
            printf("(frequency-based distances selected)\n");
        if (heur)
            printf("(lowerbound heuristic will be used to focus the search)\n");
        if (randm)
            printf("(random selection of %ld words with seed %ld)\n", g->n, seed);
        else
            printf("(the graph has %ld words)\n", g->n);
    }

/*:8*/
//#line 152 "../ladders.w"
    ;
/*9:*/
//#line 183 "../ladders.w"

    if (alph) {
        register Vertex *u;

        for (u = g->vertices + g->n - 1; u >= g->vertices; u--) {
            register Arc *a;
            register char *p = u->name;

            for (a = u->arcs; a; a = a->next) {
                register char *q = a->tip->name;

                a->len = a_dist(a->loc);
            }
        }
    } else if (freq) {
        register Vertex *u;

        for (u = g->vertices + g->n - 1; u >= g->vertices; u--) {
            register Arc *a;

            for (a = u->arcs; a; a = a->next)
                a->len = freq_cost(a->tip);
        }
    }

/*:9*/
//#line 153 "../ladders.w"
    ;
/*10:*/
//#line 202 "../ladders.w"

    if (alph || freq || heur) {
        init_queue = init_128;
        del_min = del_128;
        enqueue = enq_128;
        requeue = req_128;
    }

/*:10*/
//#line 154 "../ladders.w"
    ;

/*:6*/
//#line 96 "../ladders.w"
    ;
    while (1) {
/*26:*/
//#line 373 "../ladders.w"

        putchar('\n');
      restart:

        if (prompt_for_five("Starting", start) != 0)
            break;
        if (prompt_for_five("    Goal", goal) != 0)
            goto restart;

/*:26*/
//#line 98 "../ladders.w"
        ;
/*13:*/
//#line 245 "../ladders.w"

/*14:*/
//#line 251 "../ladders.w"

        gg = gb_new_graph(0L);
        quit_if(gg == NULL, no_room + 5);
        gg->vertices = g->vertices;
        gg->n = g->n;
/*15:*/
//#line 266 "../ladders.w"

        (gg->vertices + gg->n)->name = start;
        uu = find_word(start, plant_new_edge);
        if (!uu)
            uu = gg->vertices + gg->n++;

/*:15*/
//#line 256 "../ladders.w"
        ;
/*16:*/
//#line 272 "../ladders.w"

        if (strncmp(start, goal, 5) == 0)
            vv = uu;
        else {
            (gg->vertices + gg->n)->name = goal;
            vv = find_word(goal, plant_new_edge);
            if (!vv)
                vv = gg->vertices + gg->n++;
        }

/*:16*/
//#line 257 "../ladders.w"
        ;
        if (gg->n == g->n + 2)  /*19: */
            //#line 311 "../ladders.w"

            if (hamm_dist(start, goal) == 1) {
                gg->n--;
                plant_new_edge(uu);
                gg->n++;
            }

/*:19*/
//#line 258 "../ladders.w"
        ;
        quit_if(gb_trouble_code, no_room + 6);

/*:14*/
//#line 246 "../ladders.w"
        ;
/*21:*/
//#line 333 "../ladders.w"

        if (!heur)
            min_dist = dijkstra(uu, vv, gg, NULL);
        else if (alph)
            min_dist = dijkstra(uu, vv, gg, alph_heur);
        else
            min_dist = dijkstra(uu, vv, gg, hamm_heur);

/*:21*/
//#line 247 "../ladders.w"
        ;
/*24:*/
//#line 350 "../ladders.w"

        if (min_dist < 0)
            printf("Sorry, there's no ladder from %s to %s.\n", start, goal);
        else
            print_dijkstra_result(vv);

/*:24*/
//#line 248 "../ladders.w"
        ;
/*25:*/
//#line 360 "../ladders.w"

        for (uu = g->vertices + gg->n - 1; uu >= g->vertices + g->n; uu--) {
            register Arc *a;

            for (a = uu->arcs; a; a = a->next) {
                vv = a->tip;
                vv->arcs = vv->arcs->next;
            }
            uu->arcs = NULL;
        }
        gb_recycle(gg);

/*:25*/
//#line 249 "../ladders.w"
        ;

/*:13*/
//#line 100 "../ladders.w"
        ;
    }
    return 0;
}
示例#3
0
文件: itm.c 项目: gitter-badger/TFWC
char *
makegraph(char *iname)
{
    FILE *infile;
    Graph *G = NULL;
    char inbuf[LINE],outfilename[LINE];
    register char *cp;
    char *method;
    int count, lineno=0, numlevels, nerrors;
    int i, m=0, prefixlen;
    int edgeConnMeth, haux, stubsPerTrans, tsEdges, ssEdges;
    long seed;
    geo_parms	parmsbuf[MAXLEVEL];	/* make sure MAXLEVEL >= 3 */

    if ((infile = fopen(iname, "r")) == NULL) {
        sprintf(errstr, "can't open input file %s", iname);
        die(errstr);
    }

    /* set up output file name */

    sprintf(outfilename,"%s-",iname);
    prefixlen = strlen(outfilename);

    do {
        fgets(inbuf, LINE - 1, infile);
        lineno++;
        method = strtok(inbuf, delim);
    } while (((method == NULL) || (*method == '#'))
             && !feof(infile));
    /* skip over comments  and blank lines */

    if ((cp = strtok(NULL, delim))==NULL)
        return "missing <number of graphs>";

    count = atoi(cp);

    if ((cp = strtok(NULL, delim))==NULL)
        seed = 0;
    else
        seed = atol(cp);

    if (strcmp(method,GEO_KW)==0) {

        if (cp = get_geoparms(infile,parmsbuf))
            return cp;
        m = GEO;

    } else if (strcmp(method,HIER_KW)==0) {

        if (cp = get_hierparms(infile,
                               &numlevels, &edgeConnMeth, &haux, parmsbuf))
            return cp;
        m = HIER;

    } else if (strcmp(method,TS_KW)==0) {

        if (cp = get_tsparms(infile,
                             &stubsPerTrans, &tsEdges, &ssEdges, parmsbuf))
            return cp;
        m = TS;
    } else {
        sprintf(errstr,"Unknown generation method %s",method);
        return errstr;
    }


    if (seed)
        gb_init_rand(seed);
    else
        gb_init_rand(DEFAULT_SEED);

    for (i=0; i<count; i++) {
        sprintf(outfilename+prefixlen,"%d.gb",i);
        switch(m) {
        case GEO:
            do {
                gb_recycle(G);
                G = geo(0,parmsbuf);
            } while (G != NULL && !isconnected(G));
            break;
        case HIER:
            G = geo_hier(0,numlevels,edgeConnMeth,haux,parmsbuf);
            break;
        case TS:
            G = transtub(0,stubsPerTrans,tsEdges,ssEdges,&parmsbuf[0],
                         &parmsbuf[1],&parmsbuf[2]);
            break;
        default:
            return "This can't happen!";

        }	/* switch */

        if (G==NULL) {
            sprintf(errstr,"Error creating graph %d, trouble code=%d",i,
                    gb_trouble_code);
            return errstr;
        }

        nerrors = save_graph(G, outfilename);
        if (nerrors > 0)
            fprintf(stderr, "%s had %d anomalies\n", outfilename,nerrors);
        gb_recycle(G);
    }	/* for */

    return NULL;
}
示例#4
0
文件: geog.c 项目: liuxfiu/primogeni
Graph *
geo_hier(long seed,
	int nlevels,	/* number of levels (=size of following array) */
	int edgemeth,	/* method of attaching edges */
	int aux,	/* auxiliary parameter for edge method (threshold) */
	geo_parms *pp)	/* array of parameter structures, one per level */
{
Graph *newG, *tG, *GG, *srcG, *dstG;
long *numv;		/* array of sizes of lower-level graphs */
geo_parms *curparms, workparms[MAXLEVEL];
register i,k,indx;
long dst;
int temp,total,lowsize,otherend,blen,level;
long maxP[MAXLEVEL], maxDiam[MAXLEVEL], wt[MAXLEVEL];
Vertex *np,*vp,*up,*base;
Arc *ap;
char vnamestr[MAXNAMELEN];


     if (seed)		/* convention: zero seed means don't use */
	gb_init_rand(seed);

     if (nlevels < 1 || nlevels > MAXLEVEL) {
	gb_trouble_code = bad_specs+HIER_TRBL;
	return NULL;
     }

     /* 1 <= nlevels <= MAXLEVEL */

     /* copy the parameters so we can modify them, and caller doesn't
      * see the changes.
      */
     for (level=0; level<nlevels; level++)
	bcopy((char *)&pp[level],&workparms[level],sizeof(geo_parms));

     level = 0;

     gb_trouble_code = 0;
     
     tG = NULL;
     do {
	gb_recycle(tG);
        tG = geo(0L,workparms);
     } while (tG != NULL && !isconnected(tG));

     if (tG==NULL)
	return tG;

     maxDiam[0] = fdiam(tG);
     maxP[0] = maxDiam[0];
     wt[0] = 1;

     for (i=1; i<nlevels; i++)
       maxDiam[i] = -1;

     curparms = workparms;

     while (++level < nlevels) {
       long tdiam;

	curparms++;	/* parameters for graphs @ next level */

        /* spread out the numbers of nodes per graph at this level */
	numv = (long *) calloc(tG->n,sizeof(long));
	lowsize = curparms->n;
        randomize(numv,tG->n,curparms->n,3*tG->n);

	/* create a subordinate graph for each vertex in the "top" graph,
         * and add it into the new graph as a whole.
	 * We construct the subgraphs all at once to ensure that each
	 * has a unique address.
	 */
	for (i=0,vp=tG->vertices; i<tG->n; i++,vp++) {
	    curparms->n = numv[i];
	    do {
		newG = geo(0L,curparms);
		if (newG==NULL) return NULL;
	    } while (!isconnected(newG));
	    vp->sub = newG;
	    tdiam = fdiam(newG);
	    if (tdiam>maxDiam[level])
	      maxDiam[level] = tdiam;
	}

	/* do some calculations before "flattening" the top Graph */

	total = 0;

	for (i=0; i<tG->n; i++) {	/* translate node numbers */
	    temp = numv[i];		
	    numv[i]= total;
	    total += temp;
	}

	if (total != tG->n*lowsize) {
	    fprintf(stderr,"bad size of new graph!\n");
	    fprintf(stderr,"total %d tG->n %ld lowsize %d\n",total,tG->n,lowsize);
	    gb_trouble_code = impossible+HIER_TRBL;
	    return NULL;
	}

	/* now create what will become the "new" top-level graph */
	newG = gb_new_graph(total);
	if (newG==NULL) {
	    gb_trouble_code += HIER_TRBL;
	    return NULL;
	}

	/* resolution of the new graph */
	newG->Gscale = tG->Gscale * curparms->scale;

       /* compute edge weights for this level */

       wt[level] = maxP[level-1] + 1;
       maxP[level] = (maxDiam[level]*wt[level])
	 + (maxDiam[level-1]*maxP[level-1]);

       for (i=0,vp=tG->vertices; i<tG->n; i++,vp++) {
	 strcpy(vnamestr,vp->name);	/* base name for all "offspring" */
	 blen = strlen(vnamestr);
	 vnamestr[blen] = '.';
	    
	 GG = tG->vertices[i].sub;
	 base = newG->vertices + numv[i];	/* start of this node's */
	 for (k=0,np=base,up=GG->vertices; k<GG->n; k++,np++,up++) {

	   /* add the node's edges */
	   for (ap=up->arcs; ap; ap=ap->next)  {
	     otherend = ap->tip - GG->vertices;
	     if (k < otherend)
	       gb_new_edge(np,base+otherend,ap->len);
	     
	   }

	   /* now set the new node's position */
	   np->xpos = tG->vertices[i].xpos * curparms->scale + up->xpos;
	   np->ypos = tG->vertices[i].ypos * curparms->scale + up->ypos;

	   /* give the "new" node a name by catenating top & bot names */
	   strcpy(vnamestr+blen+1,up->name);
	   np->name = gb_save_string(vnamestr);

	 } /* loop over GG's vertices */
       }  /* loop over top-level vertices */

       /*
	* Now we have to transfer the top-level edges to new graph.
	* This is done by one of three methods:
	*    0: choose a random node in each subgraph
	*    1: attach to the smallest-degree non-leaf node in each
	*    2: attach to smallest-degree node
	*    3: attach to first node with degree less than aux
	*/
       for (i=0; i<tG->n; i++) {
	 Vertex *srcp, *dstp;
	 Graph *srcG, *dstG;

	 srcG = tG->vertices[i].sub;

	 if (srcG == NULL) {	/* paranoia */
	   gb_trouble_code = impossible+HIER_TRBL+1;
	   return NULL;
	 }

	 for (ap=tG->vertices[i].arcs; ap; ap=ap->next) {

	   dst = ap->tip - tG->vertices;

	   if (i > dst)	/* consider each edge only ONCE */
	     continue;

	   dstG = ap->tip->sub;

	   if (dstG == NULL) {	/* paranoia */
	     gb_trouble_code = impossible+HIER_TRBL+1;
	     return NULL;
	   }

	   /* choose endpoints of the top-level edge */

	   switch (edgemeth) {
	   case 0:	/* choose random node in each */
	     srcp = srcG->vertices + gb_next_rand()%srcG->n;
	     dstp = dstG->vertices + gb_next_rand()%dstG->n;
	     break;

	   case 1:	/* find nonleaf node of least degree in each */
	     /* This causes problems with graph size < 3 */
	     if (srcG->n > 2)
	       srcp = find_small_deg(srcG,NOLEAF);
	     else
	       srcp = find_small_deg(srcG,LEAFOK);
	     if (dstG->n > 2)
	       dstp = find_small_deg(dstG,NOLEAF);
	     else
	       dstp = find_small_deg(dstG,LEAFOK);
	     break;

	   case 2: /* find node of smallest degree */
	     srcp = find_small_deg(srcG,LEAFOK);
	     dstp = find_small_deg(dstG,LEAFOK);
	     break;

	   case 3: /* first node w/degree < aux */
	     srcp = find_thresh_deg(srcG,aux);
	     dstp = find_thresh_deg(dstG,aux);
	   default:
	     gb_trouble_code = bad_specs+HIER_TRBL;
	     return NULL;

	   }	/* switch on edgemeth */

	   /* pointer arithmetic: isn't it fun?
	      printf("Copying edge from %d to %d\n",
	      numv[i]+(srcp - srcG->vertices),
	      numv[dst] + (dstp - dstG->vertices));
	      */
	   if (srcp==NULL || dstp==NULL) {
	     gb_trouble_code = impossible + HIER_TRBL+2;
	     return NULL;
	   }
		
	   srcp = newG->vertices + numv[i] + (srcp - srcG->vertices);
	   dstp = newG->vertices + numv[dst] + (dstp - dstG->vertices);

	   gb_new_edge(srcp,dstp,idist(srcp,dstp));

	 } /* for each arc */
       } /* for each vertex of top graph */

        /* now make the "new" graph the "top" graph and recycle others */
       for (i=0,vp=tG->vertices; i<tG->n; i++,vp++)
	 gb_recycle(vp->sub);

       gb_recycle(tG);

       tG = newG;

       free(numv);
     }	/* while more levels */

/* Finally, go back and add the policy weights,
 * based upon the computed max diameters
 * and Max Path lengths.
 */
   for (i=0; i<tG->n; i++)
     for (ap=tG->vertices[i].arcs; ap; ap=ap->next) {
       dst = ap->tip - tG->vertices;
       if (i > dst)	/* consider each edge only ONCE */
	 continue;

       assert(i != dst); /* no self loops */

       /* i < dst: it is safe to refer to ap's mate by ap+1.  */
       level = edge_level(&tG->vertices[i],&tG->vertices[dst],nlevels);
       ap->policywt = (ap+1)->policywt = wt[level];

     }

/* construct the utility and id strings for the new graph.
 * Space constraints will restrict us to keeping about 4 levels'
 * worth of info.
 */
  {
    char buf[ID_FIELD_SIZE+1];
    register char *cp;
    int len, nextlen, left;

    strcpy(tG->util_types,GEO_UTIL);	/* same for all geo graphs,	*/
					/* defined in geo.h		*/
    cp = tG->id;
    sprintf(cp,"geo_hier(%ld,%d,%d,%d,[",seed,nlevels,edgemeth,aux);
    len = strlen(cp);
    left = ID_FIELD_SIZE - len;
    cp += len;
    
    for (i=0; (i < nlevels) && (left > 0); i++) {
      nextlen = printparms(buf,&pp[i]);
      strncpy(cp,buf,left);
      left -= nextlen;
      cp += nextlen;
    }
    if (left > 0) {
      sprintf(buf,"])");
      nextlen = strlen(buf);
      strncpy(cp,buf,left);
    }
  }

  return tG;
}	/* geo_hier() */