int IB3BReviseLeft(IBDomains d, int var, IBDmodified *dmodified, IBLocalPropagation f2b, double w, double* out) /*************************************************************************** * Returns - 0 if d is inconsistent * - 1 if the left bound of d[var] is inconsistent; in this case, * *out is equal to the reduced left bound * - 2 if the left bound of d[var] is 3B(w) consistent * * If the result is 1 and 2 then [min d[var], min d[var] + w] is consistent * If it is equal to 2, an optimization consists in saving the new computed * left bound in *out * * The proof is done by using the 2B consistency algorithm f2b */ { double right, save = IBMinI(IBDomV(d,var)); int allDomain = 0; IBRoundUp(); right = save + w; IBDMnb(dmodified) = IBVnb(variables); if( right<IBMaxI(IBDomV(d,var))) { IBMaxI(IBDomV(d,var)) = right; /* f2b is applied over the left bound of d[var]*/ } else { allDomain = 1; /* f2b is applied over d */ } /* left bound inconsistent ? */ if( !f2b(d,dmodified) ) { if( allDomain ) { return 0; /* d is inconsistent */ } else { *out = right; /* d[var] is consistent but its left bound is inconsistent */ return 1; } } else { *out = IBMinI(IBDomV(d,var)); /* optimization: the new value of the left bound of d[var] */ return 2; } }
void IBFPropagationHC4(IBPropagationListCtr *l, IBDmodified *d, int init, int onlyoccone) /*************************************************************************** * Creation of propagation list l wrt. the modified domains in d * used in Algorithm HC4 * * init=1 if l is empty => propagation is implemented by the * concatenation of the arrays of constraints * * onlyoccone=1 => propagation only wrt. constraints that contain at * least one variable occurring once * - Algorithm HC4 => no * - Algorithm BC5 => yes (since HC4 is combined with BC3 that efficiently * handles multiple occurrences of variables) */ { IBDependencyV *dep; IBProjection **proj; IBConstraint *ctr; int i, j, index, bitpos, n; unsigned long val; if( init ) /* initialization of propagation in HC4 */ { /* Flags asleep for all constraints are initialized to 1 */ for( i=0; i<IBCNbCtr(constraints); i++ ) { IBCctrAsleep(IBCCtr(constraints,i)) = 1; } if( (IBDMnb(d)>1) || ((IBDMnb(d)==1) && (IBVnb(variables)==1)) ) /* propagation wrt. all domains */ { /* All the constraints are added in the list */ IBPLCfirst(l) = IBPLCnbelem(l) = 0; for( i=0; i<IBCNbCtr(constraints); i++ ) { /* propagation wrt. the i-th constraint ? */ if( (!onlyoccone) || (onlyoccone && IBCNbProjOne(IBCCtr(constraints,i))) ) { IBPLCctr(l,IBPLCnbelem(l)) = IBCCtr(constraints,i); IBPLCnbelem(l)++; IBCctrAsleep(IBCCtr(constraints,i)) = 0; } } IBPLCend(l) = IBPLCnbelem(l) - 1; return; /* END OF PROPAGATION IN THIS CASE */ } } /*--------------------------------------------------------------------------*/ /* Otherwise, two cases : initialization with one domain or modification of several domains in HC4 */ IBRoundUp(); if( IBDMnb(d)==1 ) /* only one modified domain */ { dep = IBDepV(variables,IBDMdom(d,0)); /* dependency list of variable */ for( i=0; i<IBDVnb(dep); i++ ) /* decoding of the dependency list */ { val = IBDVval(dep,i); index = IBDVindex(dep,i); while( val!=0 ) { bitpos = (int)floor(log((double)val)/0.6931471805599453); val &= ~(1<<bitpos); ctr = IBCCtr(constraints,(bitpos+sizeof(unsigned long)*index)); /* propagation wrt. ctr ? */ if( (IBCctrAsleep(ctr)) && ((!onlyoccone) || (onlyoccone && IBCNbProjOne(IBCCtr(constraints,i)))) ) { IBCctrAsleep(ctr) = 0; IBPLCend(l) = (IBPLCend(l)+1) % IBPLCsize(l); IBPLCnbelem(l)++; IBPLCctr(l,IBPLCend(l)) = ctr; } } } } /*----------------------------------------------------------------*/ else /* several domains in d */ { /* Filtering of the constraints depending on the modified domains Consider the dependencies of all the variables in d and set propaglistglobal at the right place */ for( i=0; i<IBDMnb(d); i++ ) /* for each modified domain */ { dep = IBDepV(variables,IBDMdom(d,i)); /* dependency list */ /* propaglistglobal represents all the constraints depending on a modified domain */ for( j=0; j<IBDVnb(dep); j++ ) IBPGlobalValue(IBpropaglistglobal,IBDVindex(dep,j)) |= IBDVval(dep,j); } /* Decoding of propaglistglobal and then propagation */ for( i=0; i<IBPGlobalNb(IBpropaglistglobal); i++ ) { val = IBPGlobalValue(IBpropaglistglobal,i); while( val!=0 ) { bitpos = (int)floor(log((double)val)/0.6931471805599453); val &= ~(1<<bitpos); ctr = IBCCtr(constraints,(bitpos+sizeof(unsigned long)*i)); /* Propagation wrt. ctr ? */ if( (IBCctrAsleep(ctr)) && ((!onlyoccone) || (onlyoccone && IBCNbProjOne(IBCCtr(constraints,i)))) ) { IBCctrAsleep(ctr) = 0; IBPLCend(l) = (IBPLCend(l)+1) % IBPLCsize(l); IBPLCnbelem(l)++; IBPLCctr(l,IBPLCend(l)) = ctr; } } IBPGlobalValue(IBpropaglistglobal,i) = 0; } } }
void IBFPropagationBC3(IBPropagationList *l, IBDmodified *d, int init, int allproj) /*************************************************************************** * Creation of propagation list l wrt. the modified domains in d * used in Algorithm BC3 * * init=1 if l is empty => propagation implemented by the * concatenation of the array of projections * * allproj=1 if all the projections are considered by propagation, 0 if only * the projections with multiple occurrences of the variables are considered */ { IBDependencyV *dep; IBProjection **proj; IBConstraint *ctr; int i, j, index, bitpos, n; unsigned long val; if( init ) /* initialization of propagation in BC3 */ { /* Flags asleep for all the projections are initialized to 1 */ for( i=0; i<IBCNbCtr(constraints); i++ ) { ctr = IBCCtr(constraints,i); for( j=0; j<IBCNbProjMul(ctr); j++ ) { IBCPasleep(IBCmulprj(ctr,j)) = 1; } if( allproj ) { for( j=0; j<IBCNbProjOne(ctr); j++ ) { IBCPasleep(IBConeprj(ctr,j)) = 1; } } } if( (IBDMnb(d)>1) || ((IBDMnb(d)==1) && (IBVnb(variables)==1)) ) /* propagation wrt. all domains */ { /* Concatenation of the arrays of all constraint projections */ IBPLfirst(l) = IBPLnbelem(l) = 0; for( i=0; i<IBCNbCtr(constraints); i++ ) { ctr = IBCCtr(constraints,i); /* Propagation over projections (ctr,x) s.t. x occurs more than once in ctr */ n = IBCNbProjMul(ctr); if( n>0 ) { proj = IBCProjMul(ctr); memcpy(&(IBPLproj(l,IBPLnbelem(l))),proj,n*sizeof(IBProjection *)); IBPLnbelem(l) += n; } if( allproj ) { /* Moreover, propagation over projections (ctr,x) s.t. x occurs once in ctr */ n = IBCNbProjOne(ctr); if( n>0 ) { proj = IBCProjOne(ctr); memcpy(&(IBPLproj(l,IBPLnbelem(l))),proj,n*sizeof(IBProjection *)); IBPLnbelem(l) += n; } } } IBPLend(l) = IBPLnbelem(l) - 1; for( i=IBPLfirst(l); i<=IBPLend(l); i++ ) { IBCPasleep(IBPLproj(l,i)) = 0; } return; /* END OF PROPAGATION IN THIS CASE */ } } /*--------------------------------------------------------------------------*/ /* Otherwise, two cases : initialization with one domain or modification of one domain in BC3 -> propagation is the same with domain IBDMdom(d,0) */ dep = IBDepV(variables,IBDMdom(d,0)); /* dependency list of variable */ IBRoundUp(); for( i=0; i<IBDVnb(dep); i++ ) /* decoding of the dependency list */ { val = IBDVval(dep,i); index = IBDVindex(dep,i); while( val!=0 ) { bitpos = (int)floor(log((double)val)/0.6931471805599453); val &= ~(1<<bitpos); ctr = IBCCtr(constraints,(bitpos+sizeof(unsigned long)*index)); /* Propagation over the projections (ctr,x) s.t. x occurs more than once in ctr */ proj = IBCProjMul(ctr); n = IBCNbProjMul(ctr); for( j=0; j<n; j++ ) { if( IBCPasleep(proj[j]) ) { IBPLend(l) = (IBPLend(l)+1) % IBPLsize(l); IBPLnbelem(l)++; IBPLproj(l,IBPLend(l)) = proj[j]; IBCPasleep(proj[j]) = 0; } } if( allproj ) { /* Moreover, propagation over the projections (ctr,x) s.t. x occurs once in ctr */ proj = IBCProjOne(ctr); n = IBCNbProjOne(ctr); for( j=0; j<n; j++ ) { if( IBCPasleep(proj[j]) ) { IBPLend(l) = (IBPLend(l)+1) % IBPLsize(l); IBPLnbelem(l)++; IBPLproj(l,IBPLend(l)) = proj[j]; IBCPasleep(proj[j]) = 0; } } } } } }