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 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 }
/* Min-Sum diffusion algorithm */ void VACExtension::minsumDiffusion() { for (int times = 0; times < 2; times++) { bool change = true; int maxit = ToulBar2::minsumDiffusion; cout << "MinSumDiffusion: " << endl; cout << " max iterations " << maxit << endl; cout << " C0 = " << wcsp->getLb() << endl; int ntimes = 0; while (change && (ntimes < maxit)) { change = false; int nchanged = 0; for (unsigned int i = 0; i < wcsp->numberOfVariables(); i++) if (wcsp->unassigned(i)) { VACVariable *evar = (VACVariable *) wcsp->getVar(i); if (evar->averaging()) { change = true; nchanged++; evar->findSupport(); } } ntimes++; //cout << "it " << ntimes << " changed: " << nchanged << endl; } cout << " done iterations: " << ntimes << endl; for (unsigned int i = 0; i < wcsp->numberOfVariables(); i++) if (wcsp->unassigned(i)) { EnumeratedVariable *evar = (EnumeratedVariable *) wcsp->getVar(i); evar->findSupport(); } for (unsigned int i = 0; i < wcsp->numberOfConstraints(); i++) if (wcsp->getCtr(i)->connected()) wcsp->getCtr(i)->propagate(); for (int i = 0; i < wcsp->getElimBinOrder(); i++) if (wcsp->getElimBinCtr(i)->connected() && !wcsp->getElimBinCtr(i)->isSep()) wcsp->getElimBinCtr(i)->propagate(); for (int i = 0; i < wcsp->getElimTernOrder(); i++) if (wcsp->getElimTernCtr(i)->connected() && !wcsp->getElimTernCtr(i)->isSep()) wcsp->getElimTernCtr(i)->propagate(); wcsp->propagate(); cout << " C0 = " << wcsp->getLb() << endl; // printTightMatrix(); } }
void DPGlobalConstraint::propagateStrongNIC(){ propagateNIC(); Cost ub = wcsp->getUb(); Cost lb = wcsp->getLb(); bool changed = true; for(int i = 0; i < arity_; i++){ EnumeratedVariable * x = scope[i]; if(x->assigned()) continue; bool first = true; for(EnumeratedVariable::iterator it = x->begin(); it != x->end(); ++it){ Cost cost = minCostOriginal(i, *it, changed && first) - projectedCost; changed = first = false; if(cost + x->getCost(*it) + lb >= ub) { x->remove(*it); changed = true; } } x->findSupport(); } }
void naryRandom::Input( int in_n, int in_m, vector<int>& p, bool forceSubModular ) { n = in_n; m = in_m; assert(p.size() >= 2); int i,arity; vector<int> indexs; vector<long> totalCtrs; vector<long> numCtrs; int maxa = p.size(); for(arity=0; arity <= maxa; arity++) { if(arity < 2) numCtrs.push_back(0); else numCtrs.push_back(p[arity-1]); } if (forceSubModular) { numCtrs[maxa] = (numCtrs[maxa-1] * numCtrs[maxa]) / 100; maxa--; } for(i=0;i<n;i++) { string varname = to_string(i); wcsp.makeEnumeratedVariable(varname,0,m-1); } for(arity=maxa;arity>1;arity--) { long nogoods = (long) (((double)p[0] / 100.) * pow((double)m, arity)); //long totalarraysize = (long) pow( (double)n, arity); long tCtrs = 1; set<long> scopes; for(i=0; i < arity; i++) tCtrs *= (n - i); for(i=2; i <= arity; i++) tCtrs /= i; if(numCtrs[arity] > tCtrs) { cout << numCtrs[arity] << " " << arity << "ary constraints and the maximum is " << tCtrs << endl; numCtrs[arity] = tCtrs; } while(numCtrs[arity]) { bool oneadded = false; int dice = myrand() % tCtrs; ini(indexs,arity); do { if(scopes.end() == scopes.find(toIndex(indexs))) { if(dice == 0) { scopes.insert( toIndex(indexs) ); if(arity > 1) { switch(arity) { case 2: if(!forceSubModular || numCtrs[arity] > numCtrs[maxa+1]) generateBinCtr(indexs[0],indexs[1],nogoods); else generateSubModularBinCtr(indexs[0],indexs[1],SMALL_COST,MEDIUM_COST); break; case 3: generateTernCtr(indexs[0],indexs[1],indexs[2],nogoods); break; default: generateNaryCtr(indexs,nogoods); } } tCtrs--; numCtrs[arity]--; oneadded = true; } dice--; } } while(inc(indexs) && !oneadded); } } for(i=0;i<n;i++) { EnumeratedVariable* x = (EnumeratedVariable*) wcsp.getVar(i); for (unsigned int a = 0; a < x->getDomainInitSize(); a++) { x->project(x->toValue(a), ToulBar2::costMultiplier * randomCost(MIN_COST, MEDIUM_COST)); } x->findSupport(); } if(forceSubModular) { for(i=0;i<n;i++) { EnumeratedVariable* x = (EnumeratedVariable*) wcsp.getVar(i); x->permuteDomain(10); } } }