void LinearConstraint::checkRemoved(MIP &mip, Cost &cost, vector<int> &rmv) { pair<Cost, bool> result; vector<int> cDomain, cDomain2; //bool deleted = false; bool flag = false; for (int i=0;i<arity_;i++) { cDomain.clear(); getDomainFromMIP(mip, i, cDomain); // getDomain sort(cDomain.begin(), cDomain.end()); EnumeratedVariable* y = (EnumeratedVariable*)getVar(i); for (EnumeratedVariable::iterator v = y->begin(); v != y->end();++v) { vector<int>::iterator it = find(cDomain.begin(), cDomain.end(), *v); if (it == cDomain.end()) { cout << "non exist a value ?" << endl; for (vector<int>::iterator v=cDomain.begin();v != cDomain.end();v++) { cout << *v << " "; } cout << endl; for (EnumeratedVariable::iterator v = y->begin(); v != y->end();++v) { cout << *v << " "; } cout << endl; exit(0); } cDomain.erase(it); //deleted = true; } if (!cDomain.empty()) { cDomain2.clear(); rmv.push_back(i); for (vector<int>::iterator v=cDomain.begin();v != cDomain.end();v++) { int var1 = mapvar[i][*v]; if (mip.sol(var1) == 1){ // checking if this value is being used flag = true; } mip.colUpperBound(var1, 0); // removeDomain } //deleted = true; } } if (flag){ cost = solveMIP(); // solve } }
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][*j]); vector<Cost> weight = g.getWeight(index, graph.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, graph.size()-1, count); } } } }
void GrammarConstraint::initMemoization() { if (mode == VAR) { set<int> allValues; for (int i = 0; i < arity(); i++) { EnumeratedVariable *x = scope[i]; for (EnumeratedVariable::iterator it = x->begin(); it != x->end(); ++it) { allValues.insert(*it); } } for (set<int>::iterator it=allValues.begin(); it != allValues.end(); ++it) { if (cfg.toIndex(*it) == -1) cfg.addRedundantRuleTo(*it); } cfg.addVariableMeasure(def); } top = max(wcsp->getUb(), MAX_COST); //Create tables resizeTable(f); resizeTable(up); resizeTable(curf); resizeTable(marked); u = new Cost*[arity()+1]; for (int i = 0; i < arity(); i++) { u[i] = new Cost[cfg.getNumNonTerminals()]; } }
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::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 }
Cost AmongConstraint::minCostOriginal() { int n = arity(); minBarU[0].val = minU[0].val = -1; for (int i = 1; i <= n; i++) { int minu, minbaru; minu = minbaru = wcsp->getUb(); EnumeratedVariable *x = (EnumeratedVariable*)getVar(i-1); for (EnumeratedVariable::iterator v = x->begin();v != x->end();++v) { int uCost(0), baruCost(def); if (V.find(*v) == V.end()) { uCost = def; baruCost = 0; } minu = min(minu, uCost); minbaru = min(minbaru, baruCost); } minBarU[i].val = minbaru; minU[i].val = minu; } recomputeTable(curf); int minCost = wcsp->getUb(); for (int j=lb;j<=ub;j++) { minCost = min(minCost, curf[n][j].val); } return minCost; }
void BinaryConstraint::permute(EnumeratedVariable* xin, Value a, Value b) { EnumeratedVariable* yin = y; if (xin != x) yin = x; vector<Cost> aux; for (EnumeratedVariable::iterator ity = yin->begin(); ity != yin->end(); ++ity) aux.push_back(getCost(xin, yin, a, *ity)); for (EnumeratedVariable::iterator ity = yin->begin(); ity != yin->end(); ++ity) setcost(xin, yin, a, *ity, getCost(xin, yin, b, *ity)); vector<Cost>::iterator itc = aux.begin(); for (EnumeratedVariable::iterator ity = yin->begin(); ity != yin->end(); ++ity) { setcost(xin, yin, b, *ity, *itc); ++itc; } }
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; }
virtual void showCostProvidingPartition(int i) { cout << getVar(i)->getName() << ": "; for (set<int>::iterator j = fullySupportedSet[i].begin(); j != fullySupportedSet[i].end();j++) { if (getVar(*j)->unassigned()) { cout << getVar(*j)->getName() << " "; } } cout << endl; EnumeratedVariable* x = (EnumeratedVariable*)getVar(i); for (EnumeratedVariable::iterator v = x->begin();v != x->end();++v) { cout << EACCost[*v] << " "; } cout << endl; }
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; }
void AllDiffConstraint::buildIndex() { vector<Value> D; for (int i=0;i<arity_;i++) { EnumeratedVariable* x = (EnumeratedVariable*)getVar(i); for (EnumeratedVariable::iterator iterx = x->begin(); iterx != x->end(); ++iterx) { D.push_back(*iterx); } } sort(D.begin(), D.end()); D.erase(unique(D.begin(), D.end()), D.end()); for (vector<Value>::iterator i = D.begin(); i != D.end();i++) { mapval[*i] = arity_+(int)(i-D.begin())+1; } graph.setSize(arity_+D.size()+2); }
//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); } } }
set<Constraint *> subConstraint(){ set <Constraint *> subcstr; set<int> scope; for(int k=0; k < arity(); k++) { scope.insert(getVar(k)->wcspIndex); } for(set<int>::iterator itx = scope.begin(); itx != scope.end(); ++itx){ ConstraintList* xctrs = (wcsp->getVar(*itx))->getConstrs(); for (ConstraintList::iterator it=xctrs->begin(); it != xctrs->end(); ++it){ Constraint * ctr = (*it).constr; if(ctr->arity() < arity() && scopeIncluded(ctr)) subcstr.insert(ctr); } } return subcstr; }
void LinearConstraint::findProjection(MIP &mip, Cost &cost, int varindex, map<Value, Cost> &delta) { pair<Cost, bool> result; delta.clear(); EnumeratedVariable* x = (EnumeratedVariable*)getVar(varindex); for (EnumeratedVariable::iterator j = x->begin(); j != x->end(); ++j) { int var1 = mapvar[varindex][*j]; int tmp = cost; cost = tmp = mip.augment(var1); // make sure this value is used... assert(tmp >= 0); delta[*j] = tmp; } }
void GrammarConstraint::recompute() { int n = arity(); for (int i = 0; i < n; i++) { for (int j = 0; j < cfg.getNumTerminals(); j++) { u[i][j] = top; EnumeratedVariable *x = scope[i]; for (EnumeratedVariable::iterator it = x->begin(); it != x->end(); ++it) { if (u[i][j] > unary(cfg.toValue(j), i, *it)) { u[i][j] = unary(cfg.toValue(j), i, *it); } } } } recomputeTable(f, up); }
Cost GrammarConstraint::minCostOriginal() { int n = arity(); for (int i = 0; i < n; i++) { for (int j = 0; j < cfg.getNumTerminals(); j++) { u[i][j] = top; EnumeratedVariable *x = scope[i]; for (EnumeratedVariable::iterator it = x->begin(); it != x->end(); ++it) { if (u[i][j] > unary(cfg.toValue(j), i, *it)) u[i][j] = unary(cfg.toValue(j), i, *it); } } } recomputeTable(curf); int minCost = curf[0][n - 1][cfg.getStartSymbol()]; return minCost; }
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 FlowBasedGlobalConstraint::findProjection(Graph &graph, StoreCost &cost, int varindex, map<Value, Cost> &delta) { //if (ToulBar2::GCLevel == LC_NC) return; pair<Cost, bool> result; delta.clear(); EnumeratedVariable* x = (EnumeratedVariable*)getVar(varindex); for (EnumeratedVariable::iterator j = x->begin(); j != x->end(); ++j) { pair<int,int> edge = mapto(varindex, *j); Cost tmp = cost; //vector<Cost> weight = graph.getWeight(edge.first, edge.second); //if (!weight.empty()) { if (graph.edgeExist(edge.first, edge.second)) { if (zeroEdges[edge.first][edge.second]) { //cout << "good\n"; tmp = cost; } else { vector<pair<int, int> > edges; result = graph.augment(edge.second, edge.first, false, edges); /*if (!result.second) { printf("error! no shortest path\n"); exit(0); }*/ //tmp = cost+result.first+weight[0]; tmp = cost+result.first + graph.getMinWeight(edge.first, edge.second); zeroEdges[edge.first][edge.second] = true; for (vector<pair<int,int> >::iterator i = edges.begin();i != edges.end();i++) { zeroEdges[i->first][i->second] = true; } } } assert(tmp >= 0); delta[*j] = tmp; } }
void FlowBasedGlobalConstraint::checkRemoved(Graph &graph, StoreCost &cost, vector<int> &rmv) { //if (ToulBar2::GCLevel == LC_NC) return; pair<Cost, bool> result; vector<int> cDomain, cDomain2; bool deleted = false; for (int i=0;i<arity_;i++) { cDomain.clear(); getDomainFromGraph(graph, i, cDomain); sort(cDomain.begin(), cDomain.end()); EnumeratedVariable* y = (EnumeratedVariable*)getVar(i); for (EnumeratedVariable::iterator v = y->begin(); v != y->end();++v) { vector<int>::iterator it = find(cDomain.begin(), cDomain.end(), *v); if (it == cDomain.end()) { cout << "non exist a value ?" << endl; for (vector<int>::iterator v=cDomain.begin();v != cDomain.end();v++) { cout << *v << " "; } cout << endl; for (EnumeratedVariable::iterator v = y->begin(); v != y->end();++v) { cout << *v << " "; } cout << endl; graph.print(); exit(0); } cDomain.erase(it); deleted = true; } if (!cDomain.empty()) { //bool flag = false; cDomain2.clear(); rmv.push_back(i); for (vector<int>::iterator v=cDomain.begin();v != cDomain.end();v++) { pair<int, int> edge = mapto(i, *v); if (!graph.removeEdge(edge.first, edge.second)) { cDomain2.push_back(*v); } } for (vector<int>::iterator v=cDomain2.begin();v != cDomain2.end();v++) { pair<int, int> edge = mapto(i, *v); vector<Cost> weight = graph.getWeight(edge.second, edge.first); if (weight.size() == 0) { cout << "error for non-existence of egde (" << edge.second << "," << edge.first << ")\n"; graph.print(); exit(0); } result = graph.augment(edge.first, edge.second, true); if (result.second) { //flag = true; cost += weight[0]+result.first; result.second = graph.removeEdge(edge.first, edge.second); } if (!result.second) { cout << "ERROR cannot delete egde (" << edge.second << "," << edge.first << ")\n"; graph.print(); exit(0); } } if (cost > 0) graph.removeNegativeCycles(cost); deleted = true; } } if (deleted) { for (int i=0;i<graph.size() && (zeroEdges != NULL);i++) { for (int j=0;j<graph.size();j++) { zeroEdges[i][j] = false; } } } }
bool VACVariable::averaging() { Cost Top = wcsp->getUb(); bool change = false; EnumeratedVariable* x; EnumeratedVariable* y; Constraint* ctr = NULL; ConstraintList::iterator itc = getConstrs()->begin(); if (itc != getConstrs()->end()) ctr = (*itc).constr; while (ctr) { if (ctr->isBinary() && !ctr->isSep()) { BinaryConstraint* bctr = (BinaryConstraint*)ctr; x = (EnumeratedVariable*)bctr->getVarDiffFrom((Variable*)this); for (iterator it = begin(); it != end(); ++it) { Cost cu = getCost(*it); Cost cmin = Top; for (iterator itx = x->begin(); itx != x->end(); ++itx) { Cost cbin = bctr->getCost(this, x, *it, *itx); if (cbin < cmin) cmin = cbin; } assert(cmin < Top); Double mean = to_double(cmin + cu) / 2.; Double extc = to_double(cu) - mean; if (abs(extc) >= 1) { Cost costi = (Long)extc; for (iterator itx = x->begin(); itx != x->end(); ++itx) { bctr->addcost(this, x, *it, *itx, costi); } if (mean > to_double(cu)) project(*it, -costi); else extend(*it, costi); change = true; } } } else if (ctr->isTernary() && !ctr->isSep()) { TernaryConstraint* tctr = (TernaryConstraint*)ctr; x = (EnumeratedVariable*)tctr->getVar(0); if (x == this) x = (EnumeratedVariable*)tctr->getVar(1); y = (EnumeratedVariable*)tctr->getVarDiffFrom((Variable*)this, (Variable*)x); for (iterator it = begin(); it != end(); ++it) { Cost cu = getCost(*it); Cost cmin = Top; for (iterator itx = x->begin(); itx != x->end(); ++itx) { for (iterator ity = y->begin(); ity != y->end(); ++ity) { Cost ctern = tctr->getCost(this, x, y, *it, *itx, *ity); if (ctern < cmin) cmin = ctern; } } assert(cmin < Top); Double mean = to_double(cmin + cu) / 2.; Double extc = to_double(cu) - mean; if (abs(extc) >= 1) { Cost costi = (Long)extc; for (iterator itx = x->begin(); itx != x->end(); ++itx) { for (iterator ity = y->begin(); ity != y->end(); ++ity) { tctr->addCost(this, x, y, *it, *itx, *ity, costi); } } if (mean > to_double(cu)) project(*it, -costi); else extend(*it, costi); change = true; } } } else if (ctr->isNary() && !ctr->isSep()) { NaryConstraint* nctr = (NaryConstraint*)ctr; for (iterator it = begin(); it != end(); ++it) { Cost cu = getCost(*it); Cost cmin = Top; int tindex = nctr->getIndex(this); String tuple; Cost cost; Long nbtuples = 0; nctr->first(); while (nctr->next(tuple, cost)) { nbtuples++; if (toValue(tuple[tindex] - CHAR_FIRST) == (*it) && cost < cmin) cmin = cost; } if (nctr->getDefCost() < cmin && nbtuples < nctr->getDomainSizeProduct() / getDomainSize()) cmin = nctr->getDefCost(); // assert(cmin < Top); Double mean = to_double(cmin + cu) / 2.; Double extc = to_double(cu) - mean; if (abs(extc) >= 1) { Cost costi = (Cost)extc; nctr->addtoTuples(this, *it, costi); if (mean > to_double(cu)) project(*it, -costi); else extend(*it, costi); change = true; } } } ++itc; if (itc != getConstrs()->end()) ctr = (*itc).constr; else ctr = NULL; } return change; }