예제 #1
0
bool HC4Revise::backward(const Domain& y) {

	Domain& root=*d.top;

	if (root.is_empty())
		throw EmptyBoxException();

	switch(y.dim.type()) {
	case Dim::SCALAR:       if (root.i().is_subset(y.i())) return true; break;
	case Dim::ROW_VECTOR:
	case Dim::COL_VECTOR:   if (root.v().is_subset(y.v())) return true; break;
	case Dim::MATRIX:       if (root.m().is_subset(y.m())) return true; break;
	}

	root &= y;

	if (root.is_empty())
		throw EmptyBoxException();

	// may throw an EmptyBoxException().
	eval.f.backward<HC4Revise>(*this);

	return false;
	//std::cout << "backward:" << std::endl; f.cf.print();
}
예제 #2
0
void HC4Revise::gen1_bwd(int x, int y) {
	assert(dynamic_cast<const ExprGenericUnaryOp*>(&(f.node(y))));

	const ExprGenericUnaryOp& e = (const ExprGenericUnaryOp&) f.node(y);
	e.bwd(d[y], d[x]);
	if (d[x].is_empty()) throw EmptyBoxException();
}
예제 #3
0
void CtcPolytopeHull::contract(IntervalVector& box) {

	if (!(limit_diam_box.contains(box.max_diam()))) return;
	// is it necessary?  YES (BNE) Soplex can give false infeasible results with large numbers
	//       	cout << " box before LR " << box << endl;


	try {
		// Update the bounds the variables
		mylinearsolver->initBoundVar(box);

		//returns the number of constraints in the linearized system
		int cont = lr.linearization(box,mylinearsolver);

		if(cont<1)  return;
		optimizer(box);

		//	mylinearsolver->writeFile("LP.lp");
		//		system ("cat LP.lp");
		//		cout << " box after  LR " << box << endl;
		mylinearsolver->cleanConst();


	}
	catch(EmptyBoxException&) {
		box.set_empty(); // empty the box before exiting in case of EmptyBoxException
		mylinearsolver->cleanConst();
		throw EmptyBoxException();
	}

}
예제 #4
0
void HC4Revise::vector_bwd(const ExprVector& v, ExprLabel** compL, const ExprLabel& y) {
	if (v.dim.is_vector()) {
		for (int i=0; i<v.length(); i++)
			if ((compL[i]->d->i() &= y.d->v()[i]).is_empty()) throw EmptyBoxException();
	}
	else {
		if (v.row_vector())
			for (int i=0; i<v.length(); i++) {
				if ((compL[i]->d->v()&=y.d->m().col(i)).is_empty()) throw EmptyBoxException();
			}
		else
			for (int i=0; i<v.length(); i++) {
				if ((compL[i]->d->v()&=y.d->m().row(i)).is_empty()) throw EmptyBoxException();
			}
	}
}
예제 #5
0
void CtcInteger::contract(IntervalVector& box) {
	for (int i=0; i<nb_var; i++) {
		if (!is_int[i]) continue;
		proj_integer(box[i]);
		if (box[i].is_empty()) {
			box.set_empty();
			throw EmptyBoxException();
		}
	}
}
예제 #6
0
void CtcInteger::contract(IntervalVector& box, const BoolMask& impact) {
	for (int i=0; i<nb_var; i++) {
		if (is_int[i] && impact[i]) {
			proj_integer(box[i]);
			if (box[i].is_empty()) {
				box.set_empty();
				throw EmptyBoxException();
			}
		}
	}
}
예제 #7
0
void Optimizer::update_entailed_ctr(const IntervalVector& box) {
	for (int j=0; j<m; j++) {
		if (entailed->normalized(j)) {
			continue;
		}
		Interval y=sys.f[j].eval(box);
		if (y.lb()>0) throw EmptyBoxException();
		else if (y.ub()<=0) {
			entailed->set_normalized_entailed(j);
		}
	}
}
예제 #8
0
void CtcUnion::contract(IntervalVector& box) {
	IntervalVector savebox(box);
	IntervalVector result(IntervalVector::empty(box.size()));

	for (int i=0; i<list.size(); i++) {
		if (i>0) box=savebox;
		try {
			list[i].contract(box);
			result |= box;
		}
		catch(EmptyBoxException&) {
		}
	}
	box = result;
	if (box.is_empty()) throw EmptyBoxException();
} // end namespace ibex
예제 #9
0
void CtcQInterCoreF::contract(IntervalVector& box) {
	Array<IntervalVector> refs(list.size());

	for (int i=0; i<list.size(); i++) {
		try {
			boxes[i]=box;
			list[i].contract(boxes[i]);
		} catch(EmptyBoxException&) {
			assert(boxes[i].is_empty());
		}
		refs.set_ref(i,boxes[i]);
	}

	box = qinter_coref(refs,q);

	if (box.is_empty()) throw EmptyBoxException();
}
예제 #10
0
void CtcNotIn::contract(IntervalVector& box) {

	// it's simpler here to use direct computation, but
	// we could also have used CtCunion of two CtcFwdBwd

	IntervalVector savebox(box);
	try {
		HC4Revise().proj(f,d1,box);
	} catch (EmptyBoxException& ) {box.set_empty(); }
	try {
		HC4Revise().proj(f,d2,savebox);
	} catch (EmptyBoxException& ) {savebox.set_empty(); }

	box |= savebox;
	if (box.is_empty()) throw EmptyBoxException();

}
예제 #11
0
void HC4Revise::vector_bwd(int* x, int y) {
	assert(dynamic_cast<const ExprVector*>(&(f.node(y))));

	const ExprVector& v = (const ExprVector&) f.node(y);

	assert(v.type()!=Dim::SCALAR);

	int j=0;

	if (v.dim.is_vector()) {
		for (int i=0; i<v.length(); i++) {
			if (v.arg(i).dim.is_vector()) {
				if ((d[x[i]].v() &= d[y].v().subvector(j,j+v.arg(i).dim.vec_size())).is_empty())
						throw EmptyBoxException();
				j+=v.arg(i).dim.vec_size();
			} else {
				if ((d[x[i]].i() &= d[y].v()[j]).is_empty())
					throw EmptyBoxException();
				j++;
			}
		}

		assert(j==v.dim.vec_size());
	}
	else {
		if (v.row_vector()) {
			for (int i=0; i<v.length(); i++) {
				if (v.arg(i).dim.is_matrix()) {
					if ((d[x[i]].m()&=d[y].m().submatrix(0,v.dim.nb_rows(),j,v.arg(i).dim.nb_cols())).is_empty())
						throw EmptyBoxException();
					j+=v.arg(i).dim.nb_cols();
				} else if (v.arg(i).dim.is_vector()) {
					if ((d[x[i]].v()&=d[y].m().col(j)).is_empty())
						throw EmptyBoxException();
					j++;
				}
			}
		} else {
			for (int i=0; i<v.length(); i++) {
				if (v.arg(i).dim.is_matrix()) {
					if ((d[x[i]].m()&=d[y].m().submatrix(j,v.arg(i).dim.nb_rows(),0,v.dim.nb_cols())).is_empty())
						throw EmptyBoxException();
					j+=v.arg(i).dim.nb_rows();
				} else if (v.arg(i).dim.is_vector()) {
					if ((d[x[i]].v()&=d[y].m().row(j)).is_empty())
						throw EmptyBoxException();
					j++;
				}
			}
		}
	}
}
예제 #12
0
// called with the box without the objective
void Optimizer::firstorder_contract(  IntervalVector& box, const  IntervalVector& init_box) {
	if (m==0) {
		// for unconstrained optimization  contraction with gradient=0
		if (box.is_strict_subset(init_box)) {
			// may throw an EmptyBoxException:
			if (n==1)
				df.backward(Interval::ZERO,box);
			else
				df.backward(IntervalVector(n,Interval::ZERO),box);
		}
	}

	else {
		PdcFirstOrder p(user_sys,init_box);
		p.set_entailed(entailed);
		if (p.test(box)==NO) throw EmptyBoxException();
	}

}
예제 #13
0
void CtcForAll::contract(IntervalVector& x) {
	assert(x.size()==nb_var);

	IntervalVector  box(nb_var+_init.size());
	IntervalVector * sub;
	bool mdiam; int iter =0;
	box.put(0, x);

	std::list<IntervalVector> l;
	l.push_back(_init);
	std::pair<IntervalVector,IntervalVector> cut(_init,_init);

	while ((!l.empty())&&(iter<_max_iter)) {
		cut = _bsc.bisect(l.front());
		l.pop_front();
		sub = &(cut.first);
		for (int j=1;j<=2;j++) {
			if (j==2) sub = &(cut.second);

			for(int i=0; i< _init.size(); i++) {
				box[i+nb_var] = (*sub)[i].mid();
			}
			// it is enough to contract only with the middle, it is more precise and faster.
			try {
				_ctc.contract(box);
			} catch (EmptyBoxException& e) {
				x.set_empty(); throw e;
			}

			mdiam=true;
			for (int i=0;mdiam&&(i<_init.size()); i++) 	mdiam = mdiam&&((*sub)[i].diam()<= _prec);
			if (!mdiam) {
				l.push_back(*sub);
				iter++;
			}
		}
	}
	for(int i=0; i< nb_var; i++)  x[i] &= box[i];
	if (x.is_empty()) throw EmptyBoxException();
}
예제 #14
0
int LinearRelaxXTaylor::X_Linearization(const IntervalVector& savebox,
		int ctr, corner_point cpoint, CmpOp op, 
		IntervalVector& G2, int id_point, int& nb_nonlinear_vars, LinearSolver& lp_solver) {

	IntervalVector G = G2;
	int n = sys.nb_var;
	int nonlinear_var = 0;

	if (id_point != 0 && linear_ctr[ctr])
		return 0; // only one corner for a linear constraint

	/*
	 bool* corner=NULL;
	 if(!linear[ctr]){
	 // best not implemented in version 2.0 BNE

	 if(cpoint==BEST){
	 corner= new bool[n];
	 best_corner(ctr, op, G, corner);
	 }

	 }
	 */
	IntervalVector box(savebox);
	Interval ev(0.0);
	Interval tot_ev(0.0);
	Vector row1(n);


	for (int j=0; j< n; j++) {
		//cout << "[LinearRelaxXTaylor] variable n°" << j << endl;
	  if (sys.ctrs[ctr].f.used(j)) {
		  if (lmode == HANSEN && !linear[ctr][j])
			  // get the partial derivative of ctr w.r.t. var n°j
	    	  G[j]=df[ctr*n+j].eval(box);
	  }
	  else
		  continue;
	  //cout << "[LinearRelaxXTaylor] coeffs=" << G[j] << endl;

	  if (G[j].diam() > max_diam_deriv) {
	   // box = savebox; // [gch] where box has been modified?  at the end of the loop (for Hansen computation) [bne]
	    return 0;      // To avoid problems with SoPleX
	  }

	  if (linear[ctr][j])
	    cpoint = INF_X;
	  else if (G[j].diam() > 1e-10)
	    nonlinear_var++;

	  bool inf_x;

		/*  for GREEDY heuristics :not implemented in v2
		 IntervalVector save;
		 double fh_inf, fh_sup;
		 double D;
		 */

	  switch (cpoint) {
		/*
		 case BEST:
		 inf_x=corner[j]; last_rnd[j]=inf_x? 0:1;  break;
		 */
		case INF_X:
			inf_x = true;
			break;
		case SUP_X:
			inf_x = false;
			break;
		case RANDOM:
			last_rnd[j] = rand();
			inf_x = (last_rnd[j] % 2 == 0);
			break;
		case K4:

			if (id_point == 0) {
				inf_x = (rand() % 2 == 0);
				base_coin[j] = inf_x;
			} else if (nb_nonlinear_vars < 3) {
				if (id_point == 1)
					inf_x = !base_coin[j];
				else
					return 0;
			} else if (G[j].diam() <= 1e-10) {
				inf_x = (rand() % 2 == 0);
			} else if (id_point == 1) {
				if (((double) nonlinear_var) <= (((double) nb_nonlinear_vars)/ 3.0))
					inf_x = base_coin[j];
				else
					inf_x = !base_coin[j];
			} else if (id_point == 2) {
				if (((double) nonlinear_var )> ((double) nb_nonlinear_vars)/ 3.0
						&& (double) nonlinear_var
						<= 2 * (double) nb_nonlinear_vars / 3.0)
					inf_x = base_coin[j];
				else
					inf_x = !base_coin[j];
			} else if (id_point == 3) {
				if (((double) nonlinear_var)
						> 2 * ((double) nb_nonlinear_vars) / 3.0)
					inf_x = base_coin[j];
				else
					inf_x = !base_coin[j];
			}
			break;
		case RANDOM_INV:
			inf_x = (last_rnd[j] % 2 != 0);
			break;
		case NEG:
			inf_x = (last_rnd[j] % 2 != 0);
			break;
			/*  not implemented in v2.0
             case GREEDY1:
	       inf_x=((abs(Inf(G(j+1))) < abs(Sup(G(j+1))) && (op == LEQ || op== LT)) ||
                        (abs(Inf(G(j+1))) >= abs(Sup(G(j+1))) && (op == GEQ || op== GT))  )? true:false;
	       break;
	  case MONO:
	    if (ctr==goal_ctr && ((Inf(G(j+1)) >0 && (op == LEQ || op== LT)) || 
				  (Sup (G(j+1)) < 0 && (op == GEQ || op== GT))))
	      inf_x = true;
	    else if 
	      (ctr == goal_ctr  &&
	      ((Sup(G(j+1)) <0 && (op == LEQ || op== LT)) || 
	       (Inf(G(j+1)) > 0 && (op == GEQ || op== GT))))
	      inf_x=false;
	    else inf_x = (rand()%2==0);
	    last_rnd[j]=inf_x? 0:1;
	    break;
	  case NEGMONO:
	    if ((Inf(G(j+1)) >0 && (op == LEQ || op== LT)) || 
		(Sup (G(j+1)) < 0 && (op == GEQ || op== GT)))
	      inf_x = false;
	    else if 
	      ((Sup(G(j+1)) <0 && (op == LEQ || op== LT)) || 
	       (Inf(G(j+1)) > 0 && (op == GEQ || op== GT)))
	      inf_x=true;
	    else inf_x = (rand()%2==0);
	    last_rnd[j]=inf_x? 0:1;
	    break;

			 */


			/*
              case GREEDY7:
                 //select the coin nearest to the loup 
                 if(goal_ctr!=-1 && Dimension(Optimizer::global_optimizer())>0){
//                     if(j==0)cout<< Optimizer::global_optimizer()<<end;
                    inf_x=(abs(Optimizer::global_optimizer()(j+1)-Inf(savebox(j+1))) <
                      abs(Optimizer::global_optimizer()(j+1)-Sup(savebox(j+1))))? true:false;
                 }else{ 
                   inf_x=(rand()%2==0);
		   }
                 break;
			 */
			/*
             case GREEDY6:
                 save=space.box;
                 fh_inf, fh_sup;
                 D=Diam(savebox(j+1));
                 space.box=Mid(space.box);
                 space.box(j+1)=Inf(savebox(j+1));
                 fh_inf=Mid(sys.ctr(ctr).eval(space));
                 space.box(j+1)=Sup(savebox(j+1));
                 fh_sup=Mid(sys.ctr(ctr).eval(space));
                 if (op == LEQ || op== LT)
                    inf_x=((fh_sup-fh_inf)/(REAL)(n-1) - 0.5*D*(Inf(G(j+1))+Sup(G(j+1)))  > 0)? false:true;
                 else
                    inf_x=((fh_sup-fh_inf)/(REAL)(n-1) - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) < 0)? false:true;
		 last_rnd[j]=inf_x? 0:1;  
		 space.box=save;
              break;
             case GREEDY5:
                 save=space.box;
                 fh_inf, fh_sup;
                 D=Diam(savebox(j+1));
                 space.box=Mid(space.box);
                 space.box(j+1)=Inf(savebox(j+1));
                 fh_inf=Mid(sys.ctr(ctr).eval(space));
                 space.box(j+1)=Sup(savebox(j+1));
                 fh_sup=Mid(sys.ctr(ctr).eval(space));
                 if (op == LEQ || op== LT)
                    inf_x=(fh_sup-fh_inf - 0.5*D*(Inf(G(j+1))+Sup(G(j+1)))  > 0)? false:true;
                 else
                    inf_x=(fh_sup-fh_inf - 0.5*D*(Inf(G(j+1))+Sup(G(j+1))) < 0)? false:true;
		 last_rnd[j]=inf_x? 0:1;  
		 space.box=save;
              break;
			 */
		default:
			last_rnd[j] = rand();
			inf_x = (last_rnd[j] % 2 == 0);
			break;

		}

		//      cout << " j " << j <<  " " << savebox[j] << G[j] << endl;
	  box[j]=inf_x? savebox[j].lb():savebox[j].ub();
	  Interval a = ((inf_x && (op == LEQ || op== LT)) ||
			(!inf_x && (op == GEQ || op== GT)))	? G[j].lb() : G[j].ub();
	  row1[j] =  a.mid();
	  ev -= a*box[j];

	}

	//	cout << " ev  " << ev << endl;
	/*  used in BEST not implemented in v2.0
	if(corner) delete[] corner;
	 */

	ev+= sys.ctrs[ctr].f.eval(box);

	if(id_point==0) nb_nonlinear_vars=nonlinear_var;

	for(int j=0;j<n;j++)
		tot_ev+=row1[j]*savebox[j]; //natural evaluation of the left side of the linear constraint



	bool added=false;
	if (op == LEQ || op == LT) {
		//g(xb) + a1' x1 + ... + an xn <= 0
		if(tot_ev.lb()>(-ev).ub())
			throw EmptyBoxException();  // the constraint is not satisfied
		if((-ev).ub()<tot_ev.ub()) {    // otherwise the constraint is satisfied for any point in the box
			lp_solver.addConstraint( row1, LEQ, (-ev).ub());
			added=true;
		}
	} else {
		if(tot_ev.ub()<(-ev).lb())
			throw EmptyBoxException();
		if ((-ev).lb()>tot_ev.lb()) {
			lp_solver.addConstraint( row1, GEQ, (-ev).lb() );
			added=true;
		}
	}

	//box=savebox;

	return (added)? 1:0;

}
예제 #15
0
void CtcAcid::contract(IntervalVector& box) {

	int nb_CID_var=cid_vars.size();                    // [gch]
	impact.clear();                                    // [gch]
	int nbvarmax=5*nb_CID_var;                         //  au plus 5*nbvar
	double *ctstat = new double[nbvarmax];

	int nbinitcalls=50;                                // longueur du réglage
	int factor = 20;                                   // détermine la période entre les débuts de 2 régalages  successifs : factor*nbinitcalls
	int nbcall1= nbcalls% (factor*nbinitcalls);        // pour savoir si on est dans une phase de réglage (nbcall1 < nbinitcalls )

	IntervalVector initbox (box);

	if (nbcall1 < nbinitcalls) {                       // réglage


		if (nbcalls < nbinitcalls) vhandled =nb_CID_var;     // premier réglage 3BCID une fois sur toutes les variables
		else	vhandled = 2* nbcidvar;                       //  réglages suivants : sur 2 fois le réglage précédent

		if (vhandled< 2) vhandled= 2;                  // réglage minimum  à 2

		for (int i =0; i< nbvarmax; i++)               // initialisation du tableau des gains:
			ctstat[i]=0;                               // ctstat[i] gain moyen dû à l'appel de varcid sur la variable i
	}
	else
		vhandled = nbcidvar;                           // en dehors du réglage , on prend nbcidvar   ( la valeur réglée)

	if (vhandled > nbvarmax) vhandled=nbvarmax;        // pour rester raisonnable et dans les limites du tableau ctstat

	if (vhandled > 0) compute_smearorder(box);         // l'ordre sur les variables est calculé avec la smearsumrel
	if (optim) putobjfirst();                         // pour l'optim (si optim mis à true dans le constructeur, la dernière variable (objectf) est mise en premier
	for (int v=0; v<vhandled; v++) {
		int v1=v%nb_CID_var;                               // [gch] how can v be < nb_var?? [bne]  vhandled can be between 0 and nbvarmax
		int v2=smearorder[v1];
		impact.add(v2);
		var3BCID(box, v2);                             // appel 3BCID sur la variable v2
		impact.remove(v2);
		if(box.is_empty())
			throw EmptyBoxException();
		if (nbcall1 < nbinitcalls) {                   // on fait des stats pour le réglage courant
			for (int i=0; i<initbox.size(); i++)
			{//cout << i << " initbox " << initbox[i].diam() << " box " << box[i].diam() << endl;
				if  (initbox[i].diam() !=0 && box[i].diam()!= POS_INFINITY)
					// gain sur la ième dimension de la boîte courante après var3BCID sur la v-ième variable
					ctstat[v] += 1  - box[i].diam() / initbox[i].diam();}
			ctstat[v]=ctstat[v]/ initbox.size();   // gain moyen
		}

		initbox=box;
	}

	int nvar=0;

	nbcalls++;
	nbcall1++;
	// pendant la phase de réglage
	if (nbcall1 <= nbinitcalls) {
		// : on part de la dernière variable.
		// on s'arrête dès qu'on a trouvé une variable ayant gagné plus que ctratio, ce qui nous donne le nbre nvar de variables itéressantes.
		for (int v=vhandled-1 ; v>=0; v--)
			if (ctstat[v] > ctratio) {
				nvar=v+1;
				break;
			}
		// calcul incrémental de la moyenne du nbre de variables intéressantes
		nbctvar= (nbctvar * (nbcall1 - 1) + nvar ) / nbcall1;
	}

	if (nbcall1==nbinitcalls) {                        // fin de la phase de réglage  - détermination de nbcidvar
		nbcidvar= (int) (nbctvar + 0.5);               // - calcul incrémental de la moyenne
		nbtuning++;
		nbvarstat = (nbvarstat * (nbtuning-1) + nbcidvar) / nbtuning;
	}

	delete [] ctstat;
}
예제 #16
0
void CtcPolytopeHull::optimizer(IntervalVector& box) {

	Interval opt(0.0);
	int* inf_bound = new int[nb_var]; // indicator inf_bound = 1 means the inf bound is feasible or already contracted, call to simplex useless (cf Baharev)
	int* sup_bound = new int[nb_var]; // indicator sup_bound = 1 means the sup bound is feasible or already contracted, call to simplex useless

	if (cmode==ONLY_Y) {
		for (int i=0; i<nb_var; i++) {
			// in the case of lower_bounding, only the left bound of y is contracted
			inf_bound[i]=1;
			sup_bound[i]=1;
		}
		if (goal_var>-1) inf_bound[goal_var]=0;
	}
	else {
		for (int i=0; i<nb_var; i++) {
			// in case of optimization, the right bound of y is not contracted
			inf_bound[i]=0;
			sup_bound[i]=0;
		}
		if (goal_var>-1) sup_bound[goal_var]=1;
	}

	int nexti=-1;   // the next variable to be contracted
	int infnexti=0; // the bound to be contracted contract  infnexti=0 for the lower bound, infnexti=1 for the upper bound
	LinearSolver::Status_Sol stat=LinearSolver::UNKNOWN;

	for(int ii=0; ii<(2*nb_var); ii++) {  // at most 2*n calls

		int i= ii/2;
		if (nexti != -1) i=nexti;
		//		cout << " i "<< i << " infnexti " << infnexti << " infbound " << inf_bound[i] << " supbound " << sup_bound[i] << endl;
		//		cout << " box avant simplex " << box << endl;
		if (infnexti==0 && inf_bound[i]==0)  // computing the left bound : minimizing x_i
		{
			inf_bound[i]=1;
			stat = run_simplex(box, LinearSolver::MINIMIZE, i, opt,box[i].lb());
			//			cout << " stat " << stat <<  " opt " << opt << endl;
			if (stat == LinearSolver::OPTIMAL) {
				if(opt.lb()>box[i].ub()) {
					throw EmptyBoxException();
				}

				if(opt.lb() > box[i].lb()) {
					box[i]=Interval(opt.lb(),box[i].ub());
					mylinearsolver->setBoundVar(i,box[i]);
				}

				if (!choose_next_variable(box,nexti,infnexti, inf_bound, sup_bound)) {
					break;
				}
			}
			else if (stat == LinearSolver::INFEASIBLE) {
				// the infeasibility is proved, the EmptyBox exception is raised
				throw EmptyBoxException();
			}

			else if (stat == LinearSolver::INFEASIBLE_NOTPROVED) {
				// the infeasibility is found but not proved, no other call is needed
				break;
			}

			else if (stat == LinearSolver::UNKNOWN) {
				int next=-1;
				for (int j=0;j<nb_var;j++) {
					if (inf_bound[j]==0) {
						nexti=j;  next=0;  infnexti=0;
						break;
					}
					else if  (sup_bound[j]==0) {
						nexti=j;  next=0;  infnexti=1;
						break;
					}
				}
				if (next==-1)  break;
			}

		}
		else if (infnexti==1 && sup_bound[i]==0) { // computing the right bound :  maximizing x_i
			sup_bound[i]=1;
			stat= run_simplex(box, LinearSolver::MAXIMIZE, i, opt, box[i].ub());
			//			cout << " stat " << stat <<  " opt " << opt << endl;
			if( stat == LinearSolver::OPTIMAL) {
				if(opt.ub() <box[i].lb()) {
					throw EmptyBoxException();
				}

				if (opt.ub() < box[i].ub()) {
					box[i] =Interval( box[i].lb(), opt.ub());
					mylinearsolver->setBoundVar(i,box[i]);
				}

				if (!choose_next_variable(box,nexti,infnexti, inf_bound, sup_bound)) {
					break;
				}
			}
			else if(stat == LinearSolver::INFEASIBLE) {
				// the infeasibility is proved,  the EmptyBox exception is raised
				throw EmptyBoxException();
			}
			else if (stat == LinearSolver::INFEASIBLE_NOTPROVED) {
				// the infeasibility is found but not proved, no other call is needed
				break;
			}

			else if (stat == LinearSolver::UNKNOWN) {
				int next=-1;
				for (int j=0;j<nb_var;j++) {
					if (inf_bound[j]==0) {
						nexti=j;  next=0;  infnexti=0;
						break;
					}
					else if (sup_bound[j]==0) {
						nexti=j;  next=0;  infnexti=1;
						break;
					}
				}
				if (next==-1) break;
			}
		}
		else break; // in case of stat==MAX_ITER  we do not recall the simplex on a another variable  (for efficiency reason)
	}
	delete[] inf_bound;
	delete[] sup_bound;


}
예제 #17
0
/*********generation of the linearized system*********/
int LinearRelaxAffine2::linearization(IntervalVector & box, LinearSolver *mysolver) {

	Affine2 af2;
	Vector rowconst(sys.nb_var);
	Interval ev(0.0);
	Interval center(0.0);
	Interval err(0.0);
	CmpOp op;
	int cont = 0;
	LinearSolver::Status stat = LinearSolver::FAIL;


	// Create the linear relaxation of each constraint
	for (int ctr = 0; ctr < sys.nb_ctr; ctr++) {

		af2 = 0.0;
		ev = sys.ctrs[ctr].f.eval_affine2(box, af2);
		op = sys.ctrs[ctr].op;

		if (af2.size() == sys.nb_var) { // if the affine2 form is valid

			// convert the epsilon variables to the original box
			double tmp=0;
			center =0;
			err =0;
			for (int i =0; i <sys.nb_var; i++) {
				tmp = box[i].rad();
				//		if (tmp> mysolver->getEpsilon()) {
				rowconst[i] =af2.val(i+1) / tmp;
				center += rowconst[i]*box[i].mid();
				err += fabs(rowconst[i])*  pow(2,-50); // TODO to check
				//		} else {
				//			rowconst[i] = 0;
				//			err += tmp;
				//		}
			}

			switch (op) {
			case LEQ:
				if (0.0 == ev.lb())
					throw EmptyBoxException();
			case LT: {
				if (0.0 < ev.lb())
					throw EmptyBoxException();
				else if (0.0 < ev.ub()) {
					stat = mysolver->addConstraint(rowconst, LEQ,	((af2.err()+err) - (af2.val(0)-center)).ub());
					if (stat == LinearSolver::OK)	cont++;
				}
				break;
			}
			case GEQ:
				if (ev.ub() == 0.0)
					throw EmptyBoxException();
				break;
			case GT: {
				if (ev.ub() < 0.0)
					throw EmptyBoxException();
				else if (ev.lb() < 0.0) {
					stat = mysolver->addConstraint(rowconst, GEQ,	(-(af2.err()+err) - (af2.val(0)-center)).lb());
					if (stat == LinearSolver::OK)	cont++;
				}
				break;
			}
			case EQ: {
				if (!ev.contains(0.0)) {
					throw EmptyBoxException();
				}
				else {
					if (ev.diam()>2*mysolver->getEpsilon()) {
						stat = mysolver->addConstraint(rowconst, GEQ,	(-(af2.err()+err) - (af2.val(0)-center)).lb());
						if (stat == LinearSolver::OK)	cont++;
						stat = mysolver->addConstraint(rowconst, LEQ,	((af2.err()+err) - (af2.val(0)-center)).ub());
						if (stat == LinearSolver::OK)	cont++;
					}
				}
				break;
			}
			}
		}

	}
	return cont;

}
예제 #18
0
void CtcEmpty::contract(IntervalVector& box) {
	if (pdc.test(box)==YES) {
		box.set_empty();
		throw EmptyBoxException();
	}
}
예제 #19
0
void Optimizer::contract_and_bound(Cell& c, const IntervalVector& init_box) {
	//         cout << "box " <<c.box << endl;
	/*======================== contract y with y<=loup ========================*/
	Interval& y=c.box[ext_sys.goal_var()];

	double ymax;
	if (loup==POS_INFINITY) ymax=POS_INFINITY;
	else ymax= compute_ymax();

	y &= Interval(NEG_INFINITY,ymax);
	if (y.is_empty()) {
		c.box.set_empty();
		throw EmptyBoxException();
	}

	/*================ contract x with f(x)=y and g(x)<=0 ================*/
	//	cout << "y=f(x) and g(x)<=0 " << endl;
	//		cout << "   x before=" << c.box << endl;
	//		cout << "   y before=" << y << endl;

	contract(c.box, init_box);

	//		cout << "   x after=" << c.box << endl;
	//		cout << "   y after=" << y << endl;
	// TODO: no more cell in argument here (just a box). Does it matter?
	/*====================================================================*/


	/*========================= update loup =============================*/
	IntervalVector tmp_box(n);
	read_ext_box(c.box,tmp_box);

	entailed = &c.get<EntailedCtr>();
	update_entailed_ctr(tmp_box);

	update_loup(tmp_box);
	/*====================================================================*/
	// [gch] TODO: the case (!c.box.is_bisectable()) seems redundant
	// with the case of a NoBisectableVariableException in
	// optimize(). Is update_uplo_of_epsboxes called twice in this case?
	// (bn] NO , the NoBisectableVariableException is raised by the bisector, 
	// there are actually 2 different cases of a non bisected box that may cause an update 
	// of uplo_of_epsboxes
	double tmp_diam =tmp_box.max_diam();
	if ((tmp_diam<=prec && y.diam() <=goal_abs_prec) || !c.box.is_bisectable()) {
		// rem1: tmp_box and not c.box because y is handled with goal_rel_prec and goal_abs_prec
		// rem2: do not use a precision contractor here since it would make the box empty (and y==(-inf,-inf)!!)
		// rem 3 : the extended  boxes with no bisectable  domains  should be catched for avoiding infinite bisections
		if  (!(tmp_box.is_unbounded())) {
			// rem4: this case can append if the interval [1.79769e+308,inf] is in c.box.
			// It is only numerical degenerated case
			update_uplo_of_epsboxes(y.lb());
		}
		throw EmptyBoxException();
	}

	//gradient=0 contraction for unconstrained optimization ; 
	//first order test for constrained optimization (useful only when there are no equations replaced by inequalities) 
	//works with the box without the objective (tmp_box)
	firstorder_contract(tmp_box,init_box);
	// the current extended box in the cell is updated
	write_ext_box(tmp_box,c.box);

}