@x a change file for SSXCC [not SSXCC-BINARY] @ After this program finds all solutions, it normally prints their total @y This program differs from {\mc SSXCC} by choosing the item on which to branch based on a ``weighted'' heuristic proposed by Boussemart, Hemery, Lecoutre, and Sais in {\sl Proc.\ 16th European Conference on Artificial Intelligence} (2004), 146--150: We increase the weight of a primary item when its current set of options becomes null. Items are chosen for branching based on the size of their set divided by their current weight, unless the choice is forced. @^Boussemart, Fr\'ed\'eric@> @^H\'emery, Fred@> @^Lecoutre, Christophe@> @^Sa{\"\i}s, Lakhdar@> It's the same heuristic as in {\mc SSXCC-WTD}. But that version uses binary branching, while this one (like {\mc SSXCC} itself) uses $d$-way branching. @ After this program finds all solutions, it normally prints their total @z @x done:@+if (vbose&show_profile) @; @y done:@+if (vbose&show_profile) @; if (vbose&show_final_weights) { fprintf(stderr,"Final weights:\n"); print_weights(); } @z @x @d show_max_deg 2048 /* |vbose| code for reporting maximum branching degree */ @y @d show_max_deg 2048 /* |vbose| code for reporting maximum branching degree */ @d show_final_weights 4096 /* |vbose| code to display weights at the end */ @d show_weight_bumps 8192 /* |vbose| code to show new weights */ @z @x The given options are stored sequentially in the |nd| array, with one node @y The |set| array contains a |wt| field for each primary item. This weight, initially~1, is increased by 1 whenever we run into a situation where |x| cannot be supported. The given options are stored sequentially in the |nd| array, with one node @z @x @d primextra 4 /* this many extra entries of |set| for each primary item */ @d secondextra 4 /* and this many for each secondary item */ @d maxextra 4 /* maximum of |primextra| and |secondextra| */ @y @d wt(x) set[(x)-5] /* the current weight of item |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| */ @z @x int forced; /* the number of items on that stack */ @y int forced; /* the number of items on that stack */ int tough_itm; /* an item that led to difficulty */ @z @x if (c; @y if (t==infty) @; @z @x abort:@+if (o,cur_choice+1>=best_itm+size(best_itm)) goto backup; @y goto try_again; abort:@+@; try_again:@+if (o,cur_choice+1>=best_itm+size(best_itm)) goto backup; @z @x return 0; @y tough_itm=uu; return 0; @z @x @ The ``best item'' is considered to be an item that minimizes the number of remaining choices. All candidates of size~1, if any, are put on the |force| stack. If there are several candidates of size $>1,ドル we choose the leftmost. Notice that a secondary item is active if and only if it has not been purified (that is, if and only if it hasn't yet appeared in a chosen option). (This program explores the search space in a slightly different order from {\mc DLX2}, because the ordering of items in the active list is no longer fixed. But ties are broken in the same way when $s>1$.) @= t=max_nodes,tmems=mems; if ((vbose&show_details) && level=maxl-show_choices_gap) fprintf(stderr,"Level "O"d:",level); 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"); /* |hide| missed this */ else o,force[forced++]=item[k]; }@+else if (s<=t) { if (s=maxl-show_choices_gap) { if (forced) fprintf(stderr," found "O"d forced\n",forced); else if (t==max_nodes) fprintf(stderr," solution\n"); else { fprintf(stderr," branching on"); print_item_name(best_itm,stderr); fprintf(stderr,"("O"d)\n",t); } } if (t>maxdeg && t= cmems+=2,oo,wt(tough_itm)++; if (wt(tough_itm)<=0) { fprintf(stderr,"Weight overflow (2^31)!\n"); exit(-6); } if (vbose&show_weight_bumps) { print_item_name(tough_itm,stderr); fprintf(stderr," wt "O"d\n",wt(tough_itm)); } @ @= void print_weights(void) { register int k; for (k=0;k= { register float score,tscore,w; score=finfty,t=infty,tmems=mems; if ((vbose&show_details) && level=maxl-show_choices_gap) fprintf(stderr,"Level "O"d:",level); for (k=0;k; o,force[forced++]=item[k]; }@+else { o,w=wt(item[k]); tscore=s/w; if (tscore>=finfty) tscore=dangerous; if (tscore=maxl-show_choices_gap) { print_item_name(item[k],stderr);@+ if (s==1) fprintf(stderr,"(1)"); else fprintf(stderr,"("O"d,"O"d)",s,wt(item[k])); } } if ((vbose&show_details) && level=maxl-show_choices_gap) { if (forced) fprintf(stderr," found "O"d forced\n",forced); else if (t==infty) fprintf(stderr," solution\n"); else { fprintf(stderr," branching on"); print_item_name(best_itm,stderr); fprintf(stderr,"("O"d), score "O".4f\n",t,score); } } if (t>maxdeg && tmaxdeg && t= @y @ Oops --- we've run into a case where the current choice at |level-1| has wiped out |item[k]|. Thus |item[k]| is not a ``best item'' for branching, even though it manifestly has the smallest option list; it's really a ``tough item.'' (Impossibly good.) @= { if ((vbose&show_details) && level=maxl-show_choices_gap) { fprintf(stderr,"\n--- Item "); print_item_name(item[k],stderr); fprintf(stderr," has been wiped out!\n"); } tough_itm=item[k]; cmems+=mems-tmems; @; forced=0; goto backup; } @ @= @z

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