int IBFiltering3B(IBDomains d, IBDmodified *dmodified, IBLocalPropagation f2b) /*************************************************************************** * 3B consistency, using the 2B consistency algorithm f2b * * Returns - 0 if d is inconsistent * - 1 if d is consistent (and reduced or not) */ { int i, n, fixedPoint; double bound, wRatio = 5.0; /* 5.0 originates from the experiments */ IBDomains dcopy; IBDMnb(dmodified) = IBVnb(variables); if( !f2b(d,dmodified) ) /* reduction of d */ { return( 0 ); } /* Initialization of widths used for the precision at bounds */ for( i=0; i<IBVnb(variables); i++ ) { IBwidth3B[i] = IBWidthI(IBDomV(d,i)); } dcopy = IBNewD(IBVnb(variables)); fixedPoint = 0; while( (!fixedPoint) && (IBClockObserve(IBClockSolve)<=IBPragmaMaxTime) ) { /* Detection of fixed-point: d is consistent and all the parameters IBwidth3B[i] are small enough, i.e., <= IBPragmaPrecision3B */ fixedPoint = 1; if( !(n=IBFiltering3BOneStep(d,dmodified,f2b,dcopy,IBwidth3B)) ) { IBFreeD(dcopy); return( 0 ); /* inconsistency */ } else if( n==1 ) { fixedPoint = 0; } else /* n==2: no reduction of d, n==1: reduction of d */ { i = 0; while( fixedPoint && (i<IBVnb(variables)) ) { if( IBwidth3B[i]>IBPragmaPrecision3B ) { fixedPoint = 0; } else i++; } } } IBFreeD(dcopy); return( 1 ); }
int IBFiltering3BOneStep(IBDomains d, IBDmodified *dmodified, IBLocalPropagation f2b, IBDomains dcopy, double *w) /*************************************************************************** * One step of 3B consistency for each variable bound * Returns - 0 if d is inconsistent * - 1 if d is reduced and it is not 3B(w) consistent * - 2 if d is reduced and it is 3B(w) consistent */ { int i, n, result = 2; /* a priori, d is 3B(w) consistent */ double bound, wRatio = 5.0; /* Contraction of all domains */ for( i=0; i<IBVnb(variables) && (IBClockObserve(IBClockSolve)<=IBPragmaMaxTime); i++ ) { w[i] /= wRatio; if( w[i]<IBPragmaPrecision3B ) w[i] = IBPragmaPrecision3B; /* Copy of d in dcopy, d must not be modified by the call to IB3BReviseLeft */ IBCopyD(dcopy,d,IBVnb(variables)); if( !(n=IB3BReviseLeft(dcopy,i,dmodified,f2b,IBwidth3B[i],&bound)) ) { return 0; /* d is inconsistent */ } else if( n==1 ) { IBMinI(IBDomV(d,i)) = bound; result = 1; /* modification, left bound not 3B(w) consistent */ } else { IBMinI(IBDomV(d,i)) = bound; /* optimization */ } IBCopyD(dcopy,d,IBVnb(variables)); if( !(n=IB3BReviseRight(dcopy,i,dmodified,f2b,IBwidth3B[i],&bound)) ) { return 0; /* d is inconsistent */ } else if( n==1 ) { IBMaxI(IBDomV(d,i)) = bound; result = 1; /* modification, right bound not 3B(w) consistent */ } else { IBMaxI(IBDomV(d,i)) = bound; /* optimization */ } } return( result ); }
int IBFilteringBC4(IBDomains d, IBDmodified *dmodified) /*************************************************************************** * Propagation algorithm BC4 that enforces box consistency * => combination of BC3revise and HC4revise narrowing operators * * IBDmodified contains the variable domains previously modified * and it is used to intialize the propagation */ { int notfixedpoint; int dom, i; IBDomains dsave = IBNewD(IBVnb(variables)); IBCopyD(dsave,d,IBVnb(variables)); /* domains are saved */ if( IBDMnb(dmodified)==1 ) dom = IBDMdom(dmodified,0); /* one domain modified */ else dom = -1; /* all domains modified */ /* first application of HC4 (3rd argument=1 since only the constraints containing at least one variable occurring once are considered) )*/ if( IBFilteringHC4in(d,dmodified,1) ) { if( dom==-1 ) { IBDMnb(dmodified) = IBVnb(variables); /* initialization used for BC3 */ } else { IBDMnb(dmodified) = 1; IBDMdom(dmodified,0) = 0; } /* first application of BC3 (3rd argument=0 since only the constraint projections (c,x) s.t. x occurs one in c are considered */ if( !IBFilteringBC3in(d,dmodified,0) ) { IBFreeD(dsave); return( 0 ); /* FAILURE OF FILTERING from BC3 */ } } else { IBFreeD(dsave); return( 0 ); /* FAILURE OF FILTERING from HC4 */ } /* Creation of the list of modified domains */ IBDMnb(dmodified) = 0; for( i=0; i<IBVnb(variables); i++ ) { if( IBIdiffI(IBDomV(d,i),IBDomV(dsave,i)) ) { IBDMdom(dmodified,IBDMnb(dmodified)) = i; IBDMnb(dmodified)++; } } while( IBDMnb(dmodified) && (IBClockObserve(IBClockSolve)<=IBPragmaMaxTime) ) { IBCopyD(dsave,d,IBVnb(variables)); /* domains are saved */ /* Call of HC4 */ if( IBFilteringHC4in(d,dmodified,1) ) { /* Creation of dmodified */ IBDMnb(dmodified) = 0; for( i=0; i<IBVnb(variables); i++ ) { if( IBIdiffI(IBDomV(d,i),IBDomV(dsave,i)) ) { IBDMdom(dmodified,IBDMnb(dmodified)) = i; IBDMnb(dmodified)++; } } if( IBDMnb(dmodified) ) { IBCopyD(dsave,d,IBVnb(variables)); /* Call of BC3 */ if( IBFilteringBC3in(d,dmodified,0) ) { /* Creation of dmodified */ IBDMnb(dmodified) = 0; for( i=0; i<IBVnb(variables); i++ ) { if( IBIdiffI(IBDomV(d,i),IBDomV(dsave,i)) ) { IBDMdom(dmodified,IBDMnb(dmodified)) = i; IBDMnb(dmodified)++; } } } else { IBFreeD(dsave); return( 0 ); /* FAILURE OF FILTERING from BC3 */ } } } else { IBFreeD(dsave); return( 0 ); /* FAILURE OF FILTERING from HC4 */ } } IBFreeD(dsave); return( 1 ); /* SUCCESS OF FILTERING */ }
int IBFilteringHC3(IBDomains d, IBDmodified *dmodified) /*************************************************************************** * Propagation algorithm HC4 that enforces hull consistency * * IBDmodified contains the variable domains previously modified * and it is used to intialize the propagation * * Equivalent to HC4 where HC4revise is replaced with HC3revise * HC4revise uses unions of intervals while HC3revise uses only intervals */ { IBConstraint *ctr; int i, j, globvar; int onlyoccone = 0; IBDomains dsave = IBNewD(IBVnb(variables)); #if SOFTWARE_PROFILE IBClockBegin(IBClockHC3); #endif /* Propagation wrt. all the constraints */ IBFPropagationHC4(IBpropaglistctr,dmodified,1,onlyoccone); while( IBPLCnbelem(IBpropaglistctr) && (IBClockObserve(IBClockSolve)<=IBPragmaMaxTime) ) { ctr = IBPLCctr(IBpropaglistctr,IBPLCfirst(IBpropaglistctr)); IBCopyD(dsave,d,IBVnb(variables)); /* domains are saved */ /* HC3revise narrowing operator */ if( IBNarrowHC3revise(ctr,d) ) { /* which domains have been modified ? */ i = j = 0; for( i=0; i<IBCNbVar(ctr); i++ ) { globvar = IBCVglobvar(ctr,i); if( IBIdiffI(IBDomV(dsave,globvar),IBDomV(d,globvar)) ) { if( ((IBWidthI(IBDomV(d,globvar)) < IBPragmaImprovement*IBWidthI(IBDomV(dsave,globvar))) || (IBInfiniteI(IBDomV(d,globvar)))) && ( (!onlyoccone) || (onlyoccone && (IBCVnbocc(ctr,i)==1))) ) { IBDMdom(dmodified,j) = globvar; j++; } } } IBDMnb(dmodified) = j; /* PROPAGATION */ if( IBDMnb(dmodified) ) { /* ctr is not added in the list since is is already in the list */ IBFPropagationHC4(IBpropaglistctr,dmodified,0,onlyoccone); /* ctr is removed from the list */ IBPLCfirst(IBpropaglistctr) = (IBPLCfirst(IBpropaglistctr)+1) % IBPLCsize(IBpropaglistctr); /* ctr is added at the end of the list since HC4revise is not idempotent */ IBCctrAsleep(ctr) = 0; IBPLCend(IBpropaglistctr) = (IBPLCend(IBpropaglistctr)+1) % IBPLCsize(IBpropaglistctr); IBPLCctr(IBpropaglistctr,IBPLCend(IBpropaglistctr)) = ctr; /* Remark: the number of elements does not change */ } else /* no domain modified, then no propagation */ { IBPLCnbelem(IBpropaglistctr)--; IBPLCfirst(IBpropaglistctr) = (IBPLCfirst(IBpropaglistctr)+1) % IBPLCsize(IBpropaglistctr); IBCctrAsleep(ctr) = 1; } } else { #if SOFTWARE_PROFILE IBClockEnd(IBClockHC3); #endif IBFreeD(dsave); return( 0 ); /* FAILURE OF FILTERING */ } } #if SOFTWARE_PROFILE IBClockEnd(IBClockHC3); #endif IBFreeD(dsave); return( 1 ); /* SUCCESS OF FILTERING */ }
int IBFilteringHC4in(IBDomains d, IBDmodified *dmodified, int onlyoccone) /*************************************************************************** * Propagation algorithm HC4 that enforces hull consistency * * IBDmodified contains the variable domains previously modified * and it is used to initialize the propagation * * onlyoccone=1 if only the constraints with at least one variable occurring * once are considered => in this case, propagation is stopped when no domain * of such a variable is contracted * onlyoccone=0 if all constraints are considered */ { IBConstraint *ctr; int i, j, globvar; IBDomains dsave = IBNewD(IBVnb(variables)); #if SOFTWARE_PROFILE IBClockBegin(IBClockHC4); #endif IBFPropagationHC4(IBpropaglistctr,dmodified,1,onlyoccone); while( IBPLCnbelem(IBpropaglistctr) && (IBClockObserve(IBClockSolve)<=IBPragmaMaxTime) ) { ctr = IBPLCctr(IBpropaglistctr,IBPLCfirst(IBpropaglistctr)); IBCopyD(dsave,d,IBVnb(variables)); /* domains are saved */ /* HC4revise narrowing operator */ if( IBNarrowHC4revise(ctr,d) ) { /* which domains have been modified ? */ i = j = 0; for( i=0; i<IBCNbVar(ctr); i++ ) { globvar = IBCVglobvar(ctr,i); if( IBIdiffI(IBDomV(dsave,globvar),IBDomV(d,globvar)) ) { /* propagation only if the width of domain has been reduced enough, i.e., improvement factor = e.g. 10% => domain 10% tighter the improvement factor can be used only if the domain is finite, otherwise the width is infinite and the test below does not succeed */ if( ((IBWidthI(IBDomV(d,globvar)) < IBPragmaImprovement*IBWidthI(IBDomV(dsave,globvar))) || (IBInfiniteI(IBDomV(d,globvar)))) && ( (!onlyoccone) || (onlyoccone && (IBCVnbocc(ctr,i)==1))) ) { IBDMdom(dmodified,j) = globvar; j++; } } } IBDMnb(dmodified) = j; /* number of modified domains */ /* Propagation */ if( IBDMnb(dmodified) ) { /* ctr is not added in the list since it is already in the list */ IBFPropagationHC4(IBpropaglistctr,dmodified,0,onlyoccone); /* ctr is removed from the list */ IBPLCfirst(IBpropaglistctr) = (IBPLCfirst(IBpropaglistctr)+1) % IBPLCsize(IBpropaglistctr); /* whether ctr is kept in the list ? */ if( IBCNbProjMul(ctr)>0 ) /* HC4revise is not idempotent */ { IBCctrAsleep(ctr) = 0; IBPLCend(IBpropaglistctr) = (IBPLCend(IBpropaglistctr)+1) % IBPLCsize(IBpropaglistctr); IBPLCctr(IBpropaglistctr,IBPLCend(IBpropaglistctr)) = ctr; } else /* HC4revise is idempotent */ { IBPLCnbelem(IBpropaglistctr)--; IBCctrAsleep(ctr) = 1; } /* Remark: the number of elements does not change */ } else /* no domain modified, then no propagation */ { IBPLCnbelem(IBpropaglistctr)--; IBPLCfirst(IBpropaglistctr) = (IBPLCfirst(IBpropaglistctr)+1) % IBPLCsize(IBpropaglistctr); IBCctrAsleep(ctr) = 1; } } else { #if SOFTWARE_PROFILE IBClockEnd(IBClockHC4); #endif IBFreeD(dsave); return( 0 ); /* FAILURE OF FILTERING */ } } #if SOFTWARE_PROFILE IBClockEnd(IBClockHC4); #endif IBFreeD(dsave); return( 1 ); /* SUCCESS OF FILTERING */ }
int IBFilteringBC3in(IBDomains d, IBDmodified *dmodified, int allproj) /*************************************************************************** * Propagation algorithm BC3 for box consistency: this algorithm is * an adaptation of AC3 using box consistency narrowing operators * * IBDmodified contains the variable domains previously modified and * it is used to initialize propagation */ { IBItv out; int locvar, globvar; IBConstraint *ctr; #if SOFTWARE_PROFILE IBClockBegin(IBClockBC3); #endif IBFPropagationBC3(IBpropaglist,dmodified,1,allproj); IBDMnb(dmodified) = 1; /* during propagation in BC3, only one domain is modified at each step */ while( IBPLnbelem(IBpropaglist) && (IBClockObserve(IBClockSolve)<=IBPragmaMaxTime) ) { ctr = IBCCtr(constraints,IBCPctr(IBPLproj(IBpropaglist,IBPLfirst(IBpropaglist)))); locvar = IBCPvar(IBPLproj(IBpropaglist,IBPLfirst(IBpropaglist))); globvar = IBCVglobvar(ctr,locvar); /* BC3revise over projection (ctr,globvar/locvar) */ if( IBNarrowBC3revise(ctr,locvar,globvar,d,out,IBPragmaPrecisionShrink) ) { if( IBIdiffI(IBDomV(d,globvar),out) ) /* the domain has changed */ { /* Improvement factor, e.g. 10% (1-0.9) ; can be used only if out is finite */ if( (IBWidthI(out) < IBPragmaImprovement*IBWidthI(IBDomV(d,globvar))) || (IBInfiniteI(out)) ) { IBDMdom(dmodified,0) = globvar; /* then propagation */ IBFPropagationBC3(IBpropaglist,dmodified,0,allproj); } IBCopyI(IBDomV(d,globvar),out); /* copy of new domain */ if (IBPragmaPrecisionShrink==0.0) /* idempotent narrowing operator */ { IBCPasleep(IBPLproj(IBpropaglist,IBPLfirst(IBpropaglist))) = 1; } } else /* no contraction */ { IBCPasleep(IBPLproj(IBpropaglist,IBPLfirst(IBpropaglist))) = 1; } IBPLnbelem(IBpropaglist)--; IBPLfirst(IBpropaglist) = (IBPLfirst(IBpropaglist)+1) % IBPLsize(IBpropaglist); } else { #if SOFTWARE_PROFILE IBClockEnd(IBClockBC3); #endif return( 0 ); /* FAILURE OF FILTERING */ } } #if SOFTWARE_PROFILE IBClockEnd(IBClockBC3); #endif return( 1 ); /* SUCCESS OF FILTERING */ }