Beispiel #1
0
void Unary::propagate()
{
    if (ToulBar2::verbose >= 3) {
        print(cout);
        cout << " dxinf=" << deltaValueXinf << " dxsup=" << deltaValueXsup << endl;
    }
    wcsp->revise(this);
    set<Value>::iterator itinf = permitted.lower_bound(x->getInf());
    set<Value>::iterator itsup = permitted.upper_bound(x->getSup());
    --itsup;
    if (itinf == permitted.end() || itsup == permitted.end()) {
        // IC0 propagatation (increase global lower bound)
        deconnect();
        projectLB(penalty);
    } else {
        // propagate hard constraint
        if (CUT(wcsp->getLb()+penalty, wcsp->getUb())) {
            if (x->getInf() < *itinf) x->increase(*itinf);
            if (x->getSup() > *itsup) x->decrease(*itsup);
        }
        // BAC* propagation (increase unary costs of domain bounds)
        Value xinf = x->getInf();
        if (xinf != deltaValueXinf && xinf != deltaValueXsup && permitted.find(xinf) == permitted.end()) {
            deltaValueXinf = xinf;
            x->projectInfCost(penalty);
        }
        Value xsup = x->getSup();
        if (xsup != deltaValueXinf && xsup != deltaValueXsup && permitted.find(xsup) == permitted.end()) {
            deltaValueXsup = xsup;
            x->projectSupCost(penalty);
        }
    }
}
 void assign(int varIndex)
 {
     assert(connected());
     deconnect(); // Warning! deconnection has to be done before the projection
     if (permitted.find(x->getValue()) == permitted.end()) {
         projectLB(penalty);
     }
 }
 void assign(int varIndex)
 {
     assert(connected());
     wcsp->revise(this);
     if (x->assigned() && y->assigned()) {
         deconnect();
         if (x->getValue() >= xinfty && y->getValue() >= yinfty && costx + costy > deltaCost) {
             projectLB(costx + costy - deltaCost);
         } else if (x->getValue() >= xinfty && y->getValue() < yinfty && costx > deltaCost) {
             projectLB(costx - deltaCost);
         } else if (y->getValue() >= yinfty && x->getValue() < xinfty && costy > deltaCost) {
             projectLB(costy - deltaCost);
         } else if (x->getValue() < xinfty && y->getValue() < yinfty && x->getValue() < y->getValue() + csty && y->getValue() < x->getValue() + cstx) {
             THROWCONTRADICTION;
         }
     } else {
         if (varIndex == 0 && x->getValue() >= xinfty) {
             if (y->getInf() == deltaValueYinf) {
                 Cost cost = deltaCostYinf;
                 deltaCostYinf = MIN_COST;
                 y->projectInfCost(-cost);
             }
             if (y->getSup() == deltaValueYsup) {
                 Cost cost = deltaCostYsup;
                 deltaCostYsup = MIN_COST;
                 y->projectSupCost(-cost);
             }
             Cost cost = costx - deltaCost;
             if (cost > MIN_COST) {
                 deltaCost += cost;
                 projectLB(cost);
             }
             if (y->getSup() < yinfty) {
                 deconnect();
             } else {
                 assert(y->getSup() == yinfty);
                 deltaValueYsup = yinfty;
                 deltaCostYsup = costy;
                 y->projectSupCost(costy);
             }
         } else if (varIndex == 1 && y->getValue() >= yinfty) {
             if (x->getInf() == deltaValueXinf) {
                 Cost cost = deltaCostXinf;
                 deltaCostXinf = MIN_COST;
                 x->projectInfCost(-cost);
             }
             if (x->getSup() == deltaValueXsup) {
                 Cost cost = deltaCostXsup;
                 deltaCostXsup = MIN_COST;
                 x->projectSupCost(-cost);
             }
             Cost cost = costy - deltaCost;
             if (cost > MIN_COST) {
                 deltaCost += cost;
                 projectLB(cost);
             }
             if (x->getSup() < xinfty) {
                 deconnect();
             } else {
                 assert(x->getSup() == xinfty);
                 deltaValueXsup = xinfty;
                 deltaCostXsup = costx;
                 x->projectSupCost(costx);
             }
         } else {
             propagate();
         }
     }
 }
Beispiel #4
0
void SpecialDisjunction::propagate()
{
    if (ToulBar2::verbose >= 3) {
        print(cout);
        cout << "deltaCost= " << deltaCost << " dxinf=" << deltaValueXinf << " dxsup=" << deltaValueXsup << " dyinf=" << deltaValueYinf << " dysup=" << deltaValueYsup << endl;
    }
    wcsp->revise(this);
    if (x->getSup()>xinfty) x->decrease(xinfty);
    if (y->getSup()>yinfty) y->decrease(yinfty);
    if ((x->getSup() < xinfty && y->getSup() < yinfty &&
            (x->getInf() >= y->getSup() + csty || y->getInf() >= x->getSup() + cstx)) ||
            (x->getInf() >= xinfty && y->getSup() < yinfty) ||
            (y->getInf() >= yinfty && x->getSup() < xinfty)) {
        // deconnect the constraint if always satisfied
        assert(x->getInf() < xinfty || y->getSup() >= yinfty || deltaCost == costx);
        assert(y->getInf() < yinfty || x->getSup() >= xinfty || deltaCost == costy);
        deconnect();
    } else if (x->getSup() < xinfty && y->getSup() < yinfty &&
            x->getSup() < y->getInf() + csty && y->getSup() < x->getInf() + cstx) {
        // backtrack if the constraint if always unsatisfied
        THROWCONTRADICTION;
    } else {
        if (x->getInf() < xinfty && y->getInf() < yinfty) {
            // IC0 propagatation (increase global lower bound)
            if (min(x->getSup(),xinfty-1) < y->getInf() + csty &&
                    min(y->getSup(),yinfty-1) < x->getInf() + cstx) {
                Cost cost = min(costx,costy) - deltaCost;
                if (cost > MIN_COST) {
                    deltaCost += cost;
                    projectLB(cost);
                }
            }
            // propagate hard constraint
            if ((x->getSup() < xinfty || CUT(wcsp->getLb()+costx-deltaCost, wcsp->getUb())) &&
                    min(x->getSup(),xinfty-1) < y->getInf() + csty) {
                Value newInf = min(x->getInf() + cstx, yinfty);
                if (y->getInf() < newInf) y->increase(newInf);
                if (y->getSup() < yinfty) {
                    Value newSup = y->getSup() - cstx;
                    if (x->getSup() > newSup) x->decrease(newSup);
                }
            }
            if ((y->getSup() < yinfty || CUT(wcsp->getLb()+costy-deltaCost, wcsp->getUb())) &&
                    min(y->getSup(),yinfty-1) < x->getInf() + cstx) {
                Value newInf = min(y->getInf() + csty, xinfty);
                if (x->getInf() < newInf) x->increase(newInf);
                if (x->getSup() < xinfty) {
                    Value newSup = x->getSup() - csty;
                    if (y->getSup() > newSup) y->decrease(newSup);
                }
            }
            // BAC* propagation (increase unary costs of domain bounds)
            if (x->unassigned() && y->getInf() < yinfty) {
                Value xinf = x->getInf();
                Cost cost = -((Cost) deltaCost);
                if (xinf < y->getInf() + csty && xinf > min(y->getSup(),yinfty-1) - cstx) cost += costy;
                if (xinf == deltaValueXinf) {
                    Cost delta = cost - deltaCostXinf;
                    if (delta != MIN_COST) {
                        deltaCostXinf = cost;
                        x->projectInfCost(delta);
                    }
                } else {
                    deltaValueXinf = xinf;
                    deltaCostXinf = cost;
                    x->projectInfCost(cost);
                }
            }
            if (x->unassigned() && y->getInf() < yinfty) {
                Value xsup = x->getSup();
                Cost cost = -((Cost) deltaCost);
                if (xsup==xinfty) cost += costx;
                else if (xsup < y->getInf() + csty && xsup > min(y->getSup(),yinfty-1) - cstx) cost += costy;
                if (xsup == deltaValueXsup) {
                    Cost delta = cost - deltaCostXsup;
                    if (delta != MIN_COST) {
                        deltaCostXsup = cost;
                        x->projectSupCost(delta);
                    }
                } else {
                    deltaValueXsup = xsup;
                    deltaCostXsup = cost;
                    x->projectSupCost(cost);
                }
            }
            if (y->unassigned() && x->getInf() < xinfty) {
                Value yinf = y->getInf();
                Cost cost = -((Cost) deltaCost);
                if (yinf < x->getInf() + cstx && yinf > min(x->getSup(),xinfty-1) - csty) cost += costx;
                if (yinf == deltaValueYinf) {
                    Cost delta = cost - deltaCostYinf;
                    if (delta != MIN_COST) {
                        deltaCostYinf = cost;
                        y->projectInfCost(delta);
                    }
                } else {
                    deltaValueYinf = yinf;
                    deltaCostYinf = cost;
                    y->projectInfCost(cost);
                }
            }
            if (y->unassigned() && x->getInf() < xinfty) {
                Value ysup = y->getSup();
                Cost cost = -((Cost) deltaCost);
                if (ysup==yinfty) cost += costy;
                else if (ysup < x->getInf() + cstx && ysup > min(x->getSup(),xinfty-1) - csty) cost += costx;
                if (ysup == deltaValueYsup) {
                    Cost delta = cost - deltaCostYsup;
                    if (delta != MIN_COST) {
                        deltaCostYsup = cost;
                        y->projectSupCost(delta);
                    }
                } else {
                    deltaValueYsup = ysup;
                    deltaCostYsup = cost;
                    y->projectSupCost(cost);
                }
            }
        }
    }
}
Beispiel #5
0
void Disjunction::propagate()
{
    if (ToulBar2::verbose >= 3) {
        print(cout);
        cout << " dxinf=" << deltaValueXinf << " dxsup=" << deltaValueXsup << " dyinf=" << deltaValueYinf << " dysup=" << deltaValueYsup << endl;
    }
    wcsp->revise(this);
    // deconnect the constraint if always satisfied
    if (x->getInf() >= y->getSup() + csty || y->getInf() >= x->getSup() + cstx) {
        deconnect();
    } else if (x->getSup() < y->getInf() + csty && y->getSup() < x->getInf() + cstx) {
        // IC0 propagatation (increase global lower bound if always unsatisfied)
        deconnect();
        if (x->unassigned()) {
            if (x->getInf() == deltaValueXinf) x->projectInfCost(-penalty);
            if (x->getSup() == deltaValueXsup) x->projectSupCost(-penalty);
        }
        if (y->unassigned()) {
            if (y->getInf() == deltaValueYinf) y->projectInfCost(-penalty);
            if (y->getSup() == deltaValueYsup) y->projectSupCost(-penalty);
        }
        projectLB(penalty);
    } else {
        // propagate hard constraint
        if (CUT(wcsp->getLb()+penalty, wcsp->getUb())) {
            if (x->getSup() < y->getInf() + csty) {
                Value newInf = x->getInf() + cstx;
                if (y->getInf() < newInf) y->increase(newInf);
                Value newSup = y->getSup() - cstx;
                if (x->getSup() > newSup) x->decrease(newSup);
            } else if (y->getSup() < x->getInf() + cstx) {
                Value newInf = y->getInf() + csty;
                if (x->getInf() < newInf) x->increase(newInf);
                Value newSup = x->getSup() - csty;
                if (y->getSup() > newSup) y->decrease(newSup);
            }
        }

        // BAC* propagation (increase unary costs of domain bounds)
        if (x->unassigned()) {
            Value xinf = x->getInf();
            if (xinf != deltaValueXinf && xinf != deltaValueXsup && xinf < y->getInf() + csty && xinf > y->getSup() - cstx) {
                deltaValueXinf = xinf;
                x->projectInfCost(penalty);
            }
            Value xsup = x->getSup();
            if (xsup != deltaValueXsup && xsup != deltaValueXinf && xsup < y->getInf() + csty && xsup > y->getSup() - cstx) {
                deltaValueXsup = xsup;
                x->projectSupCost(penalty);
            }
        }
        if (y->unassigned()) {
            Value yinf = y->getInf();
            if (yinf != deltaValueYinf && yinf != deltaValueYsup && yinf < x->getInf() + cstx && yinf > x->getSup() - csty) {
                deltaValueYinf = yinf;
                y->projectInfCost(penalty);
            }
            Value ysup = y->getSup();
            if (ysup != deltaValueYsup && ysup != deltaValueYinf && ysup < x->getInf() + cstx && ysup > x->getSup() - csty) {
                deltaValueYsup = ysup;
                y->projectSupCost(penalty);
            }
        }
    }
}
Beispiel #6
0
void Supxyc::propagate()
{
    if (ToulBar2::verbose >= 3) {
        print(cout);
        cout << " delta=" << deltaCost << " dxinf=" << deltaValueXinf << " dxcost=" << deltaCostXinf << " dysup=" << deltaValueYsup << " dycost=" << deltaCostYsup << endl;
    }
    wcsp->revise(this);
    // deconnect the constraint if always satisfied
    if (x->getInf() >= y->getSup() + cst) {
        deconnect();
    } else {
        // propagate hard constraint
        Cost gap = wcsp->getUb() - wcsp->getLb() - 1 + deltaCost;
        Value newInf = ceil(y->getInf() + cst - ((gap < deltamax)?gap:deltamax));
        if (x->getInf() < newInf) x->increase(newInf);

        Value newSup = floor(x->getSup() - cst + ((gap < deltamax)?gap:deltamax));
        if (y->getSup() > newSup) y->decrease(newSup);

        // IC0 propagatation (increase global lower bound)
        Cost cost = y->getInf() + cst - x->getSup() - deltaCost;
        if (cost > MIN_COST) {
            deltaCost += cost;
            projectLB(cost);
        }

        // BAC* propagation (increase unary costs of domain bounds for unassigned variables)
        if (x->unassigned()) {
            Value xinf = x->getInf();
            Value yinf = y->getInf();
            cost = max(yinf + cst - xinf - deltaCost, MIN_COST);
            if (xinf == deltaValueXinf) {
                Cost delta = cost - deltaCostXinf;
                if (delta != MIN_COST) {
                    deltaCostXinf = cost;
                    x->projectInfCost(delta);
                }
            } else {
                deltaValueXinf = xinf;
                deltaCostXinf = cost;
                x->projectInfCost(cost);
            }
        }

        if (y->unassigned()) {
            Value xsup = x->getSup();
            Value ysup = y->getSup();
            cost = max(ysup + cst - xsup - deltaCost, MIN_COST);
            if (ysup == deltaValueYsup) {
                Cost delta = cost - deltaCostYsup;
                if (delta != MIN_COST) {
                    deltaCostYsup = cost;
                    y->projectSupCost(delta);
                }
            } else {
                deltaValueYsup = ysup;
                deltaCostYsup = cost;
                y->projectSupCost(cost);
            }
        }
    }
}