@x @c #include "gb_graph.h" /* use the Stanford GraphBase conventions */ #include "gb_save.h" /* and its routine for inputting graphs */ @y Instead of finding all solutions, this variant of the program estimates the size of the search tree. {\it Warning:} At present, we handle only graphs that contain at least one vertex of degree two. @c #include "gb_graph.h" /* use the Stanford GraphBase conventions */ #include "gb_save.h" /* and its routine for inputting graphs */ #include "gb_flip.h" /* and its random number generator */ @z @x @; @; @y gb_init_rand(seed); for (r=1;r<=reps;r++) { @; @; done: while (l= if (argc>1) g=restore_graph(argv[1]);@+ else g=NULL; if (argc<3 || sscanf(argv[2],"%d",&modulus)!=1) modulus=infty; if (!g || modulus==0) { fprintf(stderr,"Usage: %s foo.gb [[-]modulus] [verbose]\n",argv[0]); exit(-1); } @y @ The given graph should be in Stanford GraphBase format, in a file like |"foo.gb"| named on the command line. The next command line argument should be the desired number of repetitions, and the third should be a seed value for the random number generator. @d max_n 1000 /* our arrays will accommodate this many vertices at most */ @d infty 1000000000 /* infinity (approximately) */ @= if (argc<4 || !(g=restore_graph(argv[1])) || sscanf(argv[2],"%d",&reps)!=1 || sscanf(argv[3],"%d",&seed)!=1) { fprintf(stderr,"Usage: %s foo.gb reps seed [verbose]\n",argv[0]); exit(-1); } @z @x if (argc>3) verbose=1; @ The |verbose| variable is declared in \.{gb\_graph.h}. @= int modulus; /* how often we should show solutions */ @y if (argc>4) verbose=1; @ The |verbose| variable is declared in \.{gb\_graph.h}. @= int r,reps,seed; double profile_est[max_n], sols_est[max_n]; double tot_nodes, tot_sols; double factor; @z @x if (d<2) { @y if (d>2) { printf("I'm sorry, but all vertices have degree >= %d;\n", d); printf("I need a vertex of degree 2 to get started!\n"); exit(-2); } if (d<2) { @z @x @ @= printf("Altogether %d solutions.\n",total); if (verbose) { for (k=1;k<=maxl;k++) printf("%3d: %d\n",k,profile[k]); } @y @ @= profile_est[0]=1.0; for (k=0;k= @; advance: @; /* here I said |sanity_check(NULL)| when debugging */ l++; if (verbose) { if (l>maxl) maxl=l; printf("Entering level %d:",l); profile[l]++; } if (ocount>=g->n-1) @; @; if (verbose) printf(" choosing %s(%d)\n",v->name,d); if (d==0) goto backup; curv[l]=v,curi[l]=1,maxi[l]=d,curb[l]=bcount,curo[l]=ocount; source[ocount]=v; w=v->mate; @; a=v->arcs; try_move:@+for (;;a=a->next) { u=a->tip; if (u->type!=inner && u!=w) break; } @y @= @; factor=1.0; advance: @; l++; if (l>maxl) maxl=l; if (verbose) { printf("Entering level %d:",l); } if (ocount>=g->n-1) @; @; if (verbose) printf(" choosing %s(%d)\n",v->name,d); if (d==0) goto done; curv[l]=v,maxi[l]=d,curb[l]=bcount,curo[l]=ocount; curi[l]=gb_unif_rand(d)+1; factor*=maxi[l]; profile_est[l]+=(factor-profile_est[l])/(double)r; source[ocount]=v; w=v->mate; @; a=v->arcs; try_move:@+for (k=curi[l]-1;;a=a->next) { u=a->tip; if (u->type!=inner && u!=w) { if (k) k--; else break; } } @z @x if (v->deg!=2) { if (verbose) printf("(oops, low degree; backing up)\n"); goto emergency_backup; /* see below */ } @; if (u->mate==w && ocount!=g->n-2) { if (verbose) printf("(oops, short cycle; backing up)\n"); goto emergency_backup; } @y if (v->deg!=2) goto done; @; if (u->mate==w && ocount!=g->n-2) goto done; @z @x total++; if (total%modulus==0 || verbose) { curo[l]=ocount; source[ocount]=head->rlink, dest[ocount]=head->llink; curi[l]=maxi[l]=1; if (modulus<0) { printf("\n%d:\n",total);@+print_state(); }@+else @; } goto backup; @y sols_est[l]+=(factor-sols_est[l])/(double)r; goto done; @z @x for (a=u->arcs;a;a=a->next) if (a->tip==v) goto yes; goto backup; @y for (a=u->arcs;a;a=a->next) if (a->tip==v) goto yes; goto done; @z