@x an experimental change file for SSXCC-BINARY (the new version of 25 Aug!) those heuristics were designed with binary branching in mind. @y those heuristics were designed with binary branching in mind. The ``{\mc FRB} heuristic'' implemented here is motivated by the paper of Li, Yin, and Li in @^Li, Hongbo@> @^Yin, Minghao@> @^Li, Zhanshan@> {\sl Leibniz International Proceedings in Informatics\/ \bf210} (2021), 9:1--9:10 [the proceedings of the 27th International Conference on Principles and Practice of Constraint Programming, CP~2021]. When the option chosen for branching on some primary item~$i$ causes another primary item~$i'$ to be wiped out, we say that a failure has occurred with respect to~$i$. We branch on an item that has a small number of options and a relatively high failure rate. Details are discussed below. @z @x @d show_weight_bumps 32 /* |vbose| code to show new weights */ @d show_final_weights 64 /* |vbose| code to display weights at the end */ @y @d show_final_stats 64 /* |vbose| code to display item stats at the end */ @z @x if (vbose&show_final_weights) { fprintf(stderr,"Final weights:\n"); print_weights(); } @y if (vbose&show_final_stats) { fprintf(stderr,"Final primary item stats:\n"); print_item_stats(); } @z @x `\.w$\langle,円$float$,円\rangle$' is the initial increment |dw| added to an item's weight (default 1.0); \item{$\bullet$} `\.W$\langle,円$float$,円\rangle$' is the factor by which |dw| changes dynamically (default 1.0); @y @z @x case 'w': k|=(sscanf(argv[j]+1,""O"f",&dw)-1);@+break; case 'W': k|=(sscanf(argv[j]+1,""O"f",&dwfactor)-1);@+break; @y @z @x " [c] [C] [l] [t] [T] [w] [W] [S] < foo.dlx\n", @y " [c] [C] [l] [t] [T] [S] < foo.dlx\n", @z @x A primary item $x$ also has a |wt| field, |set[x-5]|, initially~1. The weight is increased by |dw| whenever we backtrack because |x| cannot be covered. (Weights aren't actually {\it used} in the present program; that will come in extensions to be written later. But it will be convenient to have space ready for them in our data structures, so that those extensions will be easy to write.) @y A primary item $x$ also has two special fields called |assigns| and |failrate|, used in the {\mc FRB} heuristic. Their significance is described below. @z @x @d wt(x) set[(x)-5].f /* the current floating-point ``weight'' of |x| */ @d primextra 5 /* this many extra entries of |set| for each primary item */ @d secondextra 4 /* and this many for each secondary item */ @d maxextra 5 /* maximum of |primextra| and |secondextra| */ @y @d assigns(x) set[(x)-5].f /* number of assignments tried so far for |x| */ @d failrate(x) set[(x)-6].f /* the current ``failure rate'' of |x| */ @d primextra 6 /* this many extra entries of |set| for each primary item */ @d secondextra 4 /* and this many for each secondary item */ @d maxextra 6 /* maximum of |primextra| and |secondextra| */ @z @x fprintf(stderr," ("O"d of "O"d), length "O"d, weight "O".1f:\n", pos(c)+1,active,size(c),wt(c)); @y fprintf(stderr, " ("O"d of "O"d), length "O"d, failrate "O".1f of "O"g:\n", pos(c)+1,active,size(c),failrate(c),assigns(c)); @z @x if (k<=osecond) o,wt(j)=w0; @y if (k<=osecond) oo,assigns(j)=1.0,failrate(j)=0.5; @z @x if (!include_option(cur_choice)) goto tryagain; @;@+@; goto forward; @y if (!include_option(cur_choice)) goto abort; @; @;@+@; goto forward; abort:@+@; @z @x @ If a weight becomes dangerously large, we rescale all the weights. (That will happen only when |dwfactor| isn't 1.0. Adding a constant eventually ``converges'': For example, if the constant is 1, we have convergence to 2ドル^{17}$ after 2ドル^{17}-1=16777215$ steps. If the constant~|dw| is .250001, convergence to \.{8.38861e+06} occurs after 25165819 steps!) (Note: I threw in the parameters |dw| and |dwfactor| only to do experiments. My preliminary experiments didn't turn up any noteworthy results. But I didn't have time to do a careful study; hence there might be some settings that work unexpectedly well. The code for rescaling might be flaky, since it hasn't been tested very thoroughly at all.) @d dangerous 1e32f @d wmin 1e-30f @= cmems+=2,oo,wt(tough_itm)+=dw; if (vbose&show_record_weights && wt(tough_itm)>maxwt) { maxwt=wt(tough_itm); fprintf(stderr,""O"8.1f ",maxwt); print_item_name(tough_itm,stderr); fprintf(stderr," "O"lld\n",nodes); } if (vbose&show_weight_bumps) { print_item_name(tough_itm,stderr); fprintf(stderr," wt "O".1f\n",wt(tough_itm)); } dw*=dwfactor; if (wt(tough_itm)>=dangerous) { register int k; register float t; tmems=mems; for (k=0;k= while (forced) { o,best_itm=force[--forced]; if (o,pos(best_itm); } } @ @= void print_weights(void) { register int k; for (k=0;k @^Yin, Minghao@> @^Li, Zhanshan@> After the first assignment, |assigns(i)| will be~2.0, and |failrate(i)| will be either 0.75 or 0.25, depending on whether or not that assignment led to failure. After $k$ assignments, the possible values of |failrate(i)| are 1ドル/(2k+2),ドル 3ドル/(2k+2),ドル \dots,~$(2k+1)/(2k+2)$. @= oo,assigns(best_itm)+=1.0; oo,failrate(best_itm)-=failrate(best_itm)/assigns(best_itm); @ @= oo,assigns(best_itm)+=1.0; oo,failrate(best_itm)+=(1.0-failrate(best_itm))/assigns(best_itm); @ @= while (forced) { o,best_itm=force[--forced]; if (o,pos(best_itm); } } @ @= void print_item_stats(void) { register int k; for (k=0;k= { t=inf_size,tmems=mems; @y @d inf_size 0x7fffffff @d dangerous 1e32f @d infty 2e32f /* twice |dangerous| */ @= { register float score,tscore,w; t=inf_size,tmems=mems,score=infty; @z @x for (k=0;k=maxl-show_choices_gap) { print_item_name(item[k],stderr); fprintf(stderr,"("O"d)",s); } if (s<=1) { if (s==0) fprintf(stderr,"I'm confused.\n"); /* |include_option| missed this */ else o,force[forced++]=item[k]; }@+else if (s<=t) { if (s=infty) tscore=dangerous; if (tscore<=score) { if (tscore=maxl-show_choices_gap) { print_item_name(item[k],stderr);@+ if (s==1) fprintf(stderr,"(1)"); else fprintf(stderr,"("O"d,"O".1f)",s,w); } } @z @x fprintf(stderr,"("O"d)\n",t); @y fprintf(stderr,"("O"d), score "O".4f\n",t,score); @z

AltStyle によって変換されたページ (->オリジナル) /