Exemple #1
0
void VACExtension::printTightMatrix()
{
    ofstream ofs("problem.dat");

    Cost Top = wcsp->getUb();
    for (unsigned int i = 0; i < wcsp->numberOfVariables(); i++) {
        for (unsigned int j = 0; j < wcsp->numberOfVariables(); j++) {
            if (i != j) {
                EnumeratedVariable *x =
                        (EnumeratedVariable *) wcsp->getVar(i);
                EnumeratedVariable *y =
                        (EnumeratedVariable *) wcsp->getVar(j);
                Constraint *bctr = x->getConstr(y);
                double t = 0;
                if (bctr)
                    t = bctr->getTightness();
                if (t > to_double(Top))
                    t = to_double(Top);
                t = t * 256.0 / to_double(Top);
                ofs << t << " ";
            } else
                ofs << 0 << " ";
        }
        ofs << endl;
    }
}
void naryRandom::generateBinCtr( int i, int j, long nogoods, Cost costMin, Cost costMax )
{
    int a,b,dice;
    EnumeratedVariable* x = (EnumeratedVariable*) wcsp.getVar(i);
    EnumeratedVariable* y = (EnumeratedVariable*) wcsp.getVar(j);
    int mx = x->getDomainInitSize();
    int my = y->getDomainInitSize();
    long total_nogoods = mx*my;

    vector<Cost> costs;
    for (a = 0; a < mx; a++)
        for (b = 0; b < my; b++)
            costs.push_back(MIN_COST);

    while(nogoods>0) {
        dice = myrand() % total_nogoods;
        for(a=0;a<mx;a++)
            for(b=0;b<my;b++) {
                if(costs[my*a+b] == MIN_COST) {
                    if(dice == 0) {
                        costs[my*a+b] = ToulBar2::costMultiplier * randomCost(costMin, costMax);
                        nogoods--;
                        total_nogoods--;
                        a=mx;b=my;
                    }
                    dice--;
                }
            }
    }
    wcsp.postBinaryConstraint(i,j,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 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::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);
        }
    }

}
bool Constraint::decompose()
{
  bool sep = false;
  if(extension() && !universal() && (arity() == 3 || (arity()>=4 && (getDefCost()>MIN_COST || ((NaryConstraint *) this)->size()>1)))) {
	TSCOPE scopeinv;
	getScope(scopeinv);
	EnumeratedVariable * vx = NULL;
	EnumeratedVariable * vz = NULL;
	for(TSCOPE::reverse_iterator it1 = scopeinv.rbegin(); it1 != scopeinv.rend() && !sep; ++it1) {
	  TSCOPE::reverse_iterator it2 = it1;
	  for(++it2; it2 != scopeinv.rend() && !sep; ++it2) {
		vx = (EnumeratedVariable *) wcsp->getVar((*it2).first);
		vz = (EnumeratedVariable *) wcsp->getVar((*it1).first);
		if(ToulBar2::verbose >= 1) cout << /*"\n" <<*/ vx->getName() << " and " << vz->getName() << " are separable in ";
		sep = separability(vx,vz);
		if(sep && ToulBar2::verbose >= 1) {
			cout << " YES";
#ifndef NDEBUG
			if (!ishard()) cout << " with finite costs";
#endif
			cout << endl;
		}
		if(!sep && ToulBar2::verbose >= 1) cout << " NO" << endl;
	  }
	}
	if(sep) separate(vx,vz);
	if(ToulBar2::verbose >= 3) cout << "=====================================================" << endl;
  }
  return sep;
}
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 pushAll() {
     for (int i=0;i<arity_;i++) {
         EnumeratedVariable* x = (EnumeratedVariable*)getVar(i);
         if (x->unassigned()) {
             x->queueEAC1();
             x->queueDAC();
             x->queueAC();
         }
     }
 }
    AbstractNaryConstraint(WCSP *wcsp, EnumeratedVariable** scope_in, int arity_in) : Constraint(wcsp), arity_(arity_in)
    {
    	scope = new EnumeratedVariable* [arity_];
    	links = new DLink<ConstraintLink>* [arity_];

		for(int i=0; i < arity_; i++) {
			EnumeratedVariable* var = scope_in[i];
			scope_inv[ var->wcspIndex ] = i;
			scope[i] = var;
			links[i] = var->link(this,i);
		}
    }
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;
 }
Exemple #12
0
/* 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 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::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);
}
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;
	}

}
    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 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);

}
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);
}
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::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 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;
	}

}
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);
}
void AllDiffConstraint::decompose() {
	deconnect();
	for (int i=0;i<arity_;i++) {
		for (int j=i+1;j<arity_;j++) {
			EnumeratedVariable* x = (EnumeratedVariable*)getVar(i);
			EnumeratedVariable* y = (EnumeratedVariable*)getVar(j);
			vector<Cost> costs;
			for (unsigned int a = 0; a < x->getDomainInitSize(); a++) {
				for (unsigned int b = 0; b < y->getDomainInitSize(); b++) {
					if (a == b) {
						costs.push_back(def);
					} else {
						costs.push_back(0);
					}
				}
			}
			if(ToulBar2::vac) {
				for (unsigned int a = 0; a < x->getDomainInitSize(); a++) {
					for (unsigned int b = 0; b < y->getDomainInitSize(); b++) {
						Cost c = costs[a * y->getDomainInitSize() + b];
						wcsp->histogram(c);
					}
				}               	
			}
			BinaryConstraint* ctr = x->getConstr(y);   		
			if(ctr)	{
				ctr->reconnect();
				ctr->addCosts(x,y,costs);
				ctr->propagate();
			}
			else {
				if (!ToulBar2::vac) {
					ctr = new BinaryConstraint(wcsp, x, y, costs, &wcsp->getStore()->storeCost);
				} else {
					ctr = new VACBinaryConstraint(wcsp, x, y, costs, &wcsp->getStore()->storeCost);
				}
			}
		}
	}
}
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;
    }
}
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::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;
			}
		}
	}	

}
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);
        }
    }
}
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;
}
//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);
        }
    }
}
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;
}