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);
}
Exemplo n.º 4
0
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);
        }
    }
}