void naryRandom::generateTernCtr( int i, int j, int k, long nogoods, Cost costMin, Cost costMax ) { int a,b,c,dice; EnumeratedVariable* x = (EnumeratedVariable*) wcsp.getVar(i); EnumeratedVariable* y = (EnumeratedVariable*) wcsp.getVar(j); EnumeratedVariable* z = (EnumeratedVariable*) wcsp.getVar(k); int mx = x->getDomainInitSize(); int my = y->getDomainInitSize(); int mz = z->getDomainInitSize(); long total_nogoods = mx*my*mz; vector<Cost> costs; for (a = 0; a < mx; a++) for (b = 0; b < my; b++) for (c = 0; c < mz; c++) costs.push_back(MIN_COST); while(nogoods>0) { dice = myrand() % total_nogoods; for(a=0;a<mx;a++) for(b=0;b<my;b++) for(c=0;c<mz;c++) { if(costs[my*mz*a + b*mz + c] == MIN_COST) { if(dice == 0) { costs[my*mz*a + b*mz + c] = ToulBar2::costMultiplier * randomCost(costMin, costMax); nogoods--; total_nogoods--; a=mx;b=my;c=mz; } dice--; } } } wcsp.postTernaryConstraint(i,j,k,costs); }
void naryRandom::generateNaryCtr( vector<int>& indexs, long nogoods, Cost costMin, Cost costMax) { int i; int arity = indexs.size(); EnumeratedVariable** scopeVars = new EnumeratedVariable * [arity]; int* scopeIndexs = new int [arity]; Char* tuple = new Char [arity+1]; Cost Top = wcsp.getUb(); if(costMax < Top) Top = costMax; for(i = 0; i<arity; i++) { scopeIndexs[i] = indexs[i]; scopeVars[i] = (EnumeratedVariable*) wcsp.getVar(indexs[i]); tuple[i] = 0 + CHAR_FIRST; } tuple[arity] = '\0'; Constraint* nctr = wcsp.getCtr( wcsp.postNaryConstraintBegin(scopeIndexs, arity, Top) ); String s(tuple); while(nogoods>0) { for(i = 0; i<arity; i++) s[i] = myrand() % scopeVars[i]->getDomainInitSize() + CHAR_FIRST; Cost c = ToulBar2::costMultiplier * randomCost(MIN_COST, costMax); nctr->setTuple(s, c, scopeVars); nogoods--; } nctr->propagate(); delete [] scopeIndexs; delete [] scopeVars; delete [] tuple; }
void naryRandom::generateSubModularBinCtr( int i, int j, Cost costMin, Cost costMax ) { int a,b; EnumeratedVariable* x = (EnumeratedVariable*) wcsp.getVar(i); EnumeratedVariable* y = (EnumeratedVariable*) wcsp.getVar(j); int mx = x->getDomainInitSize(); int my = y->getDomainInitSize(); vector<Cost> costs; for (a = 0; a < mx; a++) for (b = 0; b < my; b++) costs.push_back(MIN_COST); // row generation for (a = 0; a < mx; a++) { if(myrand() % 2) { Cost c = ToulBar2::costMultiplier * randomCost(costMin, costMax); for (b = 0; b < my; b++) costs[my*a+b] += c; } } // col generation for (b = 0; b < my; b++) { if(myrand() % 2) { Cost c = ToulBar2::costMultiplier * randomCost(costMin, costMax); for (a = 0; a < mx; a++) costs[my*a+b] += c; } } // rectangle generation int nrect = myrand() % mx; while(nrect) { Cost c = ToulBar2::costMultiplier * randomCost(costMin, costMax); int lx = myrand() % (mx-1); int ly = myrand() % (my-1); for (a = 0; a < lx; a++) for (b = 0; b < ly; b++) { costs[my*(mx-a-1) + b] += c; } nrect--; } wcsp.postBinaryConstraint(i,j,costs); }
int main(int argc, char * argv[]) { mysrand(getpid()); tb2init(); // must be call before setting specific ToulBar2 options and creating a model ToulBar2::verbose = -1; // change to 0 to see more information // uncomment if Virtual Arc Consistency (equivalent to Augmented DAG algorithm) enable // ToulBar2::vac = 1; // option -A // ToulBar2::vacValueHeuristic = true; // option -V // uncomment if partial Limited Discrepancy Search enable // ToulBar2::lds = 1; // option -l=1 // uncomment if INCOP local search enable // ToulBar2::incop_cmd = Incop_cmd; // option -i // create a problem with three 0/1 variables WeightedCSPSolver *solver = WeightedCSPSolver::makeWeightedCSPSolver(STORE_SIZE, MAX_COST); int x = solver->getWCSP()->makeEnumeratedVariable("x",0,1); // note that for efficiency issue, I assume domain values start at zero (otherwise remove flag -DWCSPFORMATONLY in Makefile) int y = solver->getWCSP()->makeEnumeratedVariable("y",0,1); int z = solver->getWCSP()->makeEnumeratedVariable("z",0,1); // add random unary cost functions on each variable { vector<Cost> costs(2, 0); costs[0] = randomCost(0,100); costs[1] = randomCost(0,100); solver->getWCSP()->postUnary(x, costs); costs[0] = randomCost(0,100); costs[1] = randomCost(0,100); solver->getWCSP()->postUnary(y, costs); costs[0] = randomCost(0,100); costs[1] = randomCost(0,100); solver->getWCSP()->postUnary(z, costs); } // add binary cost functions (Ising) on each pair of variables { vector<Cost> costs; for (unsigned int i = 0 ; i < 2; i++) { for (unsigned int j = 0 ; j < 2; j++) { costs.push_back((solver->getWCSP()->toValue(x, i) == solver->getWCSP()->toValue(y, j)) ? 0 : 30); // penalizes by a cost=30 if variables are assigned to different values } } solver->getWCSP()->postBinaryConstraint(x,y,costs); solver->getWCSP()->postBinaryConstraint(x,z,costs); solver->getWCSP()->postBinaryConstraint(y,z,costs); } // add a ternary hard constraint (x+y=z) { vector<Cost> costs; for (unsigned int i = 0 ; i < 2; i++) { for (unsigned int j = 0 ; j < 2; j++) { for (unsigned int k = 0 ; k < 2; k++) { costs.push_back((solver->getWCSP()->toValue(x, i) + solver->getWCSP()->toValue(y, j) == solver->getWCSP()->toValue(z, k)) ? 0 : MAX_COST); } } } solver->getWCSP()->postTernaryConstraint(x,y,z,costs); } solver->getWCSP()->sortConstraints(); // to be done before search solver->getWCSP()->histogram(); // to be done before search // int verbose = ToulBar2::verbose; // ToulBar2::verbose = 5; // high verbosity to see the cost functions // solver->getWCSP()->print(cout); // ToulBar2::verbose = verbose; if (solver->solve()) { // show optimal solution vector<Value> sol; Cost optimum = solver->getSolution(sol); cout << "Optimum=" << optimum << endl; cout << "Solution: x=" << sol[x] << " ,y=" << sol[y] << " ,z=" << sol[z] << endl; } else { cout << "No solution found!" << endl; } cout << "Initial problem lower bound: " << solver->getWCSP()->getLb() << endl; cout << "end." << endl; return 0; }
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); } } }