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;
  }
}
Exemplo n.º 2
0
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;
        }
    }
}
Exemplo n.º 3
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;
                    }
                }
            }
        }
    }
}