void DPGlobalConstraint::propagateDAC(){ if (ToulBar2::verbose >= 3) cout << "propagateDAC for " << *this << endl; clear(); for(int ii = 0; ii < arity_; ii++){ EnumeratedVariable * x = scope_dac[ii]; int i = scope_inv[x->wcspIndex]; for(EnumeratedVariable::iterator it = x->begin(); it != x->end(); ++it){ if (x->unassigned()) { deltaCost[i][x->toIndex(*it)] -= x->getCost(*it); preUnaryCosts[i][x->toIndex(*it)] = x->getCost(*it); } } } bool changed = true; for(int ii = 0; ii < arity_; ii++){ EnumeratedVariable * x = scope_dac[ii]; int i = scope_inv[x->wcspIndex]; if (x->unassigned()) { findSupport(i, changed); } } }
void DPGlobalConstraint::findSupport(int var, bool &changed){ EnumeratedVariable * x = scope[var]; bool first = true; vector<Value> remove; for(EnumeratedVariable::iterator it = x->begin(); it != x->end(); ++it){ Cost cost; Result r = pair<Cost, Value*>(0, NULL); if(zero[var][x->toIndex(*it)]){ cost = 0; }else{ r = minCost(var, *it, changed && first); if(changed && first) changed = false; first = false; cost = r.first; } //deltaCost[var][x->toIndex(*it)] += x->getCost(*it); deltaCost[var][x->toIndex(*it)] += preUnaryCosts[var][x->toIndex(*it)]; //Cost delta = cost - x->getCost(*it); Cost delta = cost - preUnaryCosts[var][x->toIndex(*it)]; if(delta > 0){ project(var, *it, delta, true); // NC will be delayed (avoid forward checking on binary/ternay cost functions) assert(x->canbe(*it)); } else if (delta < 0) { extend(var, *it, -delta); } if (!zero[var][x->toIndex(*it)] && x->getCost(*it) + wcsp->getLb() < wcsp->getUb()) record(r.second); } x->findSupport(); changed = true; //Detect any change in variable domain or unary costs }
void DPGlobalConstraint::propagateAC(){ bool changed = true; clear(); //Cost thisUb; //thisUb = wcsp->getUb(); for(int i = 0; i < arity(); i++){ EnumeratedVariable * x = scope[i]; bool first = true; for(EnumeratedVariable::iterator it = x->begin(); it != x->end(); ++it){ if(zero[i][x->toIndex(*it)]) continue; Result r = minCost(i, *it, changed && first); if(changed && first) changed = false; first = false; Cost cost = r.first; /*if(cost >= thisUb || cost + wcsp->getLb() + scope[i]->getCost(*it) >= thisUb){ x->remove(*it); changed = true; }else */ if(cost > 0){ project(i, *it, cost); changed = true; } else if(cost < 0) { /* Should not happen*/ printf("Warning: AC propagation get negative cost\n"); extend(i, *it, -cost); changed = true; } if(x->canbe(*it)) record(r.second); } x->findSupport(); } }
void AllDiffConstraint::buildGraph(Graph& g) { // if (g.size() == 0) g.setSize(mapval.size() + arity_ + 2); // g.clearEdge(); for (int i = 0; i < arity_; i++) { g.addEdge(0, i + 1, 0); EnumeratedVariable* x = (EnumeratedVariable*)getVar(i); for (EnumeratedVariable::iterator j = x->begin(); j != x->end(); ++j) { int index = mapval[*j]; if (index != 0) { g.addEdge(i + 1, index, -deltaCost[i][x->toIndex(*j)]); vector<Cost> weight = g.getWeight(index, g.size() - 1); Cost count = 0; if (weight.size() != 0) { if (mode == DEC) { count = *max_element(weight.begin(), weight.end()) + def; } else { count = def; } } g.addEdge(index, g.size() - 1, count); //g.print(); } } } }
Cost AmongConstraint::computeMinBarU(int var) { Cost minCost = top; EnumeratedVariable *x = (EnumeratedVariable*)getVar(var); for (EnumeratedVariable::iterator v = x->begin();v != x->end();++v) { Cost ucost = def; if (V.find(*v) == V.end()) { ucost = 0; } minCost = min(minCost, ucost - deltaCost[var][x->toIndex(*v)]); } return minCost; }
bool DPGlobalConstraint::isEAC(int var, Value val){ for(set<int>::iterator it = fullySupportedSet[var].begin(); it != fullySupportedSet[var].end(); ++it){ EnumeratedVariable *x = scope[*it]; if (x->unassigned() && (*it != var)) { for(EnumeratedVariable::iterator jt = x->begin(); jt != x->end(); ++jt){ deltaCost[*it][x->toIndex(*jt)] -= x->getCost(*jt); } } } bool ret = (minCost(var, val, true).first == 0); for(set<int>::iterator it = fullySupportedSet[var].begin(); it != fullySupportedSet[var].end(); ++it){ EnumeratedVariable *x = scope[*it]; if (x->unassigned() && (*it != var)) { for(EnumeratedVariable::iterator jt = x->begin(); jt != x->end(); ++jt){ deltaCost[*it][x->toIndex(*jt)] += x->getCost(*jt); } } } return ret; }
DPGlobalConstraint::Result AmongConstraint::minCost(int var, Value val, bool changed) { if (changed) recompute(); Cost minCost = wcsp->getUb(); Cost ucost(0), barucost(0); if (V.find(val) == V.end()) { ucost = def; } else { barucost = def; } EnumeratedVariable *x = (EnumeratedVariable*)getVar(var); ucost -= deltaCost[var][x->toIndex(val)]; barucost -= deltaCost[var][x->toIndex(val)]; minCost = f[var][0].val + barucost + invf[var+1][0].val; for (int j=1;j<=ub;j++) { Cost tmpMinCost = min(f[var][j].val + barucost + invf[var+1][j].val, f[var][j-1].val + ucost + invf[var+1][j].val); minCost = min(tmpMinCost, minCost); } return DPGlobalConstraint::Result(minCost, NULL); }
//TODO: applies DAC order when enumerating variables (fullySupportedSet does not preserve DAC order) void DPGlobalConstraint::findFullSupportEAC(int var){ assert(fullySupportedSet[var].find(var) == fullySupportedSet[var].end()); clear(); //fullySupportedSet[var].insert(var); for(set<int>::iterator it = fullySupportedSet[var].begin(); it != fullySupportedSet[var].end(); ++it){ EnumeratedVariable *x = scope[*it]; if (x->unassigned() && (*it != var)) { for(EnumeratedVariable::iterator jt = x->begin(); jt != x->end(); ++jt){ /* fix the problem in EAC */ preUnaryCosts[*it][x->toIndex(*jt)] = x->getCost(*jt); deltaCost[*it][x->toIndex(*jt)] -= x->getCost(*jt); } } } //fullySupportedSet[var].erase(var); EnumeratedVariable *cur = scope[var]; for(EnumeratedVariable::iterator jt = cur->begin(); jt != cur->end(); ++jt){ /* fix the problem in EAC */ preUnaryCosts[var][cur->toIndex(*jt)] = cur->getCost(*jt); deltaCost[var][cur->toIndex(*jt)] -= cur->getCost(*jt); } bool changed = true; findSupport(var, changed); for(set<int>::iterator it = fullySupportedSet[var].begin(); it != fullySupportedSet[var].end(); ++it) { EnumeratedVariable *x = scope[*it]; if (x->unassigned() && (*it != var)) { findSupport(*it, changed); } } }
Cost GrammarConstraint::unary(int ch, int var, Value v) { EnumeratedVariable *x = scope[var]; Cost ucost = (v == ch) ? (-deltaCost[var][x->toIndex(v)]) : top; return ucost; }