Exemple #1
0
void Create2DArray(IloModel model, BoolVarMatrix m){
  IloEnv env = model.getEnv();
  for(int i = 0; i < m.getSize(); i++){
    m[i]=IloBoolVarArray(env);
  }
  return;
}
Exemple #2
0
DataVarBoolTriMatrix::DataVarBoolTriMatrix(string name, IloEnv env,int n, int m, int K){
	this->Matrix = IloArray< IloArray<IloBoolVarArray> > (env,n);
	for(int i = 0; i < n; i++){
		this->Matrix[i] = IloArray<IloBoolVarArray>(env,m);
		for(int j = 0; j < m; j++){
			this->Matrix[i][j] = IloBoolVarArray(env,K);
			for(int k = 0; k < K; k++){
				string var_name = name;
				var_name += "(";
				var_name += U::to_s(i+1);
				var_name += ",";
				var_name += U::to_s(j+1);
				var_name += ",";
				var_name += U::to_s(k);
				var_name += ")";

				this->Matrix[i][j][k] = IloBoolVar(env,var_name.c_str());
			}
		}
	}

	this->n = n;
	this->m = m;
	this->k = K;
}
Exemple #3
0
/* 
 * $v_i \in \{0, 1\}$ variables denote whether node i is active. 
 */
static IloBoolVarArray createVarArrayVs(IloEnv env, u_int n_nodes)
{
	IloBoolVarArray vs = IloBoolVarArray(env, n_nodes);
	for (u_int i = 0; i < n_nodes; i++) {
		vs[i] = IloBoolVar(env, Tools::indicesToString("v", i).c_str());
	}
	return vs;
}
Exemple #4
0
void Create3DArray(IloModel model, BoolVar3DMatrix R, int size){
  IloEnv env = model.getEnv();
  for(int p = 0; p < R.getSize(); p++)
    R[p] = BoolVarMatrix(env, E);
  for(int p = 0; p < R.getSize(); p++){
    for(int e = 0; e < size; e++)
      R[p][e]=IloBoolVarArray(env);
  }
  return;
}
Exemple #5
0
/* $x_{ij} \in \{0, 1\}$ variables denote whether edge (i, j) is active. */
static IloBoolVarArray createVarArrayXs(IloEnv env, vector<Instance::Edge> edges, u_int n_edges)
{
	IloBoolVarArray xs = IloBoolVarArray(env, n_edges);
	for (u_int k = 0; k < n_edges; k++) {
		const u_int i = edges[k].v1;
		const u_int j = edges[k].v2;
		xs[k] = IloBoolVar(env, Tools::indicesToString("x", i, j).c_str());
	}
	return xs;
}
Exemple #6
0
DataVarBoolMatrix::DataVarBoolMatrix(string name, IloEnv env,int n, int m){
	this->Matrix = IloArray<IloBoolVarArray> (env,n);
	for(int i = 0; i < n; i++){
		this->Matrix[i] = IloBoolVarArray(env,m);
		for(int j = 0; j < m; j++){
			string var_name = name;//attribut à nom de la forme x(i,j) à la variable
			var_name += "(";
			var_name += U::to_s(i+1);
			var_name += ",";
			var_name += U::to_s(j+1);
			var_name += ")";

			this->Matrix[i][j] = IloBoolVar(env,var_name.c_str());
		}
	}
	this->name = name;
	this->n = n;
	this->m = m;
}
void kMST_ILP::addTreeConstraints()
{
	edges = IloBoolVarArray(env, instance.n_edges * 2); // edges in one direction and in other

	// "to"-edges on lower indices
	for (unsigned int i=0; i<instance.n_edges; i++) {
		edges[i] = IloBoolVar(env, Tools::indicesToString("edge " , instance.edges[i].v1, instance.edges[i].v2, instance.edges[i].weight).c_str() );
		//cerr << "init: edge " << i << " from " << instance.edges[i].v1 << " to " << instance.edges[i].v2 << endl;
	}

	// edges in other direction
	for (unsigned int i=instance.n_edges; i<instance.n_edges*2; i++) {
		Instance::Edge edgeInst = instance.edges[ i % instance.n_edges ];
		edges[i] = IloBoolVar(env, Tools::indicesToString("edge " , edgeInst.v2, edgeInst.v1, edgeInst.weight).c_str() );
		//cerr << "init: edge " << i << " from " << instance.edges[i%instance.n_edges].v2 << " to " << instance.edges[i%instance.n_edges].v1 << endl;
	}

	// edges in one direction forbid edges in other direction
	for (unsigned int i=0; i<instance.n_edges; i++) {
		model.add( edges[i] + edges[i + instance.n_edges] <= 1 );
	}

	// exactly k nodes, so k-1 actual edges plus one to the pseudo node 0
	model.add(IloSum(edges) == k);

	// no 2 incoming edges per vertex
	for (unsigned int i=0; i < instance.n_nodes; i++ ){

		IloExpr incomingSum(env);

		{
			vector<u_int> incomingEdgeIds;
			getIncomingEdgeIds(incomingEdgeIds, i);


			for (unsigned int i=0; i < incomingEdgeIds.size(); i++ ){
				incomingSum += edges[incomingEdgeIds[i]];
			}
		}

		model.add(incomingSum <= 1);
		incomingSum.end();
	}

	// only 1 outgoing node from 0
	{
		IloExpr outgoingSum(env);

		bool hasOutgoing = false;
		{
			vector<u_int> outgoingEdges;
			getOutgoingEdgeIds(outgoingEdges, 0);

			for (unsigned int i=0; i<outgoingEdges.size(); i++) {
				hasOutgoing = true;
				outgoingSum += edges[outgoingEdges[i]];
			}
		}

		if (hasOutgoing) { // only true for special input files
			model.add(outgoingSum == 1);
		}
		outgoingSum.end();
	}


	// no incoming to 0
	{
		vector<u_int> incomingEdges;
		getIncomingEdgeIds(incomingEdges, 0);

		for (unsigned int i=0; i<incomingEdges.size(); i++) {
			model.add( edges[incomingEdges[i]] == 0) ;
		}

	}
}
Exemple #8
0
ILOSTLBEGIN



int main (int argc, char* argv[]) {
   
 

  //get instance fileName:
  const char*  fileName;
  if(argc>1)//we passed the filename in arg
    fileName=argv[1];
  else fileName = "instances/instances_eleves/projet_5_8_1.dat";
  
  //DONNEES DE L INSTANCE

  typedef IloArray<IloNumArray> DataMatrix;
  IloEnv env;
  instance_Cplex instance ;

  
  getData(fileName,env,instance);
  cout << "Données récupérées!\n";
  
    int& n(instance.n);
  int& m(instance.m);
   try {
     
      IloModel model(env);

      BoolVarMatrix x(env,m);
      for(int i=0;i<m;i++) x[i]=IloBoolVarArray(env,n);

      NumVarMatrix u(env,m);
      for(int i=0;i<m;i++) u[i]=IloNumVarArray(env,n);

      NumVarMatrix v(env,m);
      for(int i=0;i<m;i++) v[i]=IloNumVarArray(env,n);

      IloRangeArray constraintSet(env);
      
      IloNumVar y(env);

      IloNumVar z(env);
      cout << "Variables créées!\n";
      
      setdata(model,env, instance, x,u,v,y,z, constraintSet);
      cout << " Modèle et contraintes définies!\n";

      
      IloCplex cplex(model);

      cplex.solve();
      
      IloInt solutionUnConnex;
      solutionUnConnex=cplex.getObjValue();


      DataMatrix xUnconnex(env,m) ; //Solution optimale non connexe
      for(int i=0;i<m;i++){
	xUnconnex[i]=IloNumArray(env,n);
	  cplex.getValues(xUnconnex[i], x[i]);
	  }
      
      std::string Method ="MinimizeEdges"; //connexityTree";
      if(Method=="connexityTree"){
      
	//We solve a first time the model without the connexity constraints, to get a good max bound of the height max : the value of the solution/2, then we add the connexity constraints :
	IloInt hMax;
	if(argc>2){ // we gave the hmax in argument/
	  istringstream (argv[2])>>hMax;
	  if(hMax==0)  hMax=solutionUnConnex/2+1;
	} //else we use our upper bound
	else hMax=solutionUnConnex/2+1;//(n*m/2+n/2);

	bool useCallBack=false;
	if(argc>3 && *argv[3]=='1')  useCallBack= true;
	solveTreeConnexityConstraints(cplex,model,env,instance,x,u,v,y,z,useCallBack,hMax);
      }
Exemple #9
0
Variables *kMST_ILP::modelMCF()
{
	MCFVariables *v = new MCFVariables();

	/***** generic part ***/

	const vector<Instance::Edge> edges = directed_edges(instance.edges);
	const u_int n_edges = edges.size();

	/* $x_{ij} \in \{0, 1\}$ variables denote whether edge (i, j) is active. */
	v->xs = createVarArrayXs(env, edges, n_edges);

	/* $v_i \in \{0, 1\}$ variables denote whether node i is active. */
	v->vs = createVarArrayVs(env, instance.n_nodes);

	/* add objective function */
	addObjectiveFunction(env, model, v->xs, edges, n_edges);

	/* There are exactly k - 1 edges not counting edges from the artificial root node 0. */
	addConstraint_k_minus_one_active_edges(env,model,v->xs,edges,n_edges,this->k);

    /* Exactly one node is chosen as the tree root. */
	addConstraint_one_active_outgoing_arc_for_node_zero(env,model,v->xs,edges,n_edges);
 
    /* No edge leads back to the artificial root node 0. */
	addConstraint_no_active_incoming_arc_for_node_zero(env,model,v->xs,edges,n_edges);

	IloExprArray e_in_degree = createExprArray_in_degree(env, edges, n_edges, v->xs, instance);
	IloExprArray e_out_degree = createExprArray_out_degree(env, edges, n_edges, v->xs, instance);

	/* Inactive nodes have no outgoing active edges, active ones at most k - 1. TODO: A tighter bound is to take the sum of incoming goods - 1.*/
	addConstraint_bound_on_outgoing_arcs(model,v->vs,e_out_degree,instance,this->k);

	/* Active nodes have at least one active arc.*/
	addConstraint_active_node_at_least_one_active_arc(model,v->vs,e_in_degree, e_out_degree,instance);
	
	/* Exactly one incoming edge for an active node and none for an inactive node (omitting artificial root). */
 	addConstraint_in_degree_one_for_active_node_zero_for_inactive(model,v->vs,e_in_degree,instance);
	
	//note: position matters. Tried worse positions than this one 
	/* $\sum_{i > 0} v_i = k$. Ensure that exactly k nodes are active. */
	addConstraint_k_nodes_active(env, model, v->vs, instance, this->k);
	e_in_degree.endElements();
	e_out_degree.endElements();


    /***** MCF specific part ***/

	/* $f^k_{ij} \in \{0, 1\}$ variables denote the flow on edge (i, j) for commodity k. */
	for (u_int i = 0; i < instance.n_nodes; i++) {
		v->fss.push_back(IloBoolVarArray(env, n_edges));
	}
	for (u_int k = 0; k < n_edges; k++) {
		const u_int i = edges[k].v1;
		const u_int j = edges[k].v2;
		for (u_int l = 0; l < (u_int) instance.n_nodes; l++) {
			v->fss[l][k] = IloBoolVar(env, Tools::indicesToString("f", l, i, j).c_str());
		}
	}
	
	/* 
     * Each commodity l is generated once by the artificial root node if node l is active, not at all otherwise:
	 * $\forall l \in \{1, \ldots, n\}: \sum_{j:j>0,(0,j) \in A} f^l_{0j} == v_l$ 
     */
	for (u_int c = 1; c < instance.n_nodes; c++){
		IloExpr e_one_commodity(env);		
		for (u_int m = 0; m < n_edges; m++) {
			const u_int i = edges[m].v1;
			const u_int j = edges[m].v2;
			if (i == 0 && j > 0){
				e_one_commodity += v->fss[c][m];	
			}
		} 
		model.add(e_one_commodity == v->vs[c]);
		e_one_commodity.end();
	}

	/* 
     * The artifical root generates k commodities:
     * $\forall l \in \{0,\ldots,n\}\sum_{j:j>0,(0,j) \in A} f^l_{0j} = k$. 
     */
    IloExpr e_root_generates_k(env);		
	for (u_int c = 0; c < instance.n_nodes; c++){
		for (u_int m = 0; m < n_edges; m++) {
			const u_int i = edges[m].v1;
			const u_int j = edges[m].v2;
			if (i == 0 && j > 0){
				e_root_generates_k += v->fss[c][m];	
			}
		} 
	}
	model.add(e_root_generates_k == this->k);   
	e_root_generates_k.end();


	/*
     * No commodity is generated for the artificial root:
     * $\forall i, j: f^0_{ij} = 0$. 
     */ 
	for (u_int m = 0; m < n_edges; m++) {
		model.add(v->fss[0][m] == 0);
	} 

	/* 
	 * Transmitted commodities end up at the target node:
	 * $\forall l>0: \sum_i f^l_{il} = \sum_j f^l_{0j}$. (here: = v_l) 
     */
	for (u_int c = 1; c < (u_int) instance.n_nodes; c++){
		IloExpr e_commodity_reaches_target(env);		
		for (u_int m = 0; m < n_edges; m++) {
			const u_int i = edges[m].v1;
			const u_int j = edges[m].v2;
			if (i != c && j == c){
				e_commodity_reaches_target += v->fss[c][m];	
			}
		} 
		model.add(e_commodity_reaches_target == v->vs[c]);
		e_commodity_reaches_target.end();
	}


	/* 
	 * Once reached, the commodity never leaves the target node:
	 * $\forall l>0: \sum_j f^l_{lj} = 0$.  
     */
	for (u_int c = 1; c < (u_int) instance.n_nodes; c++){
		IloExpr e_commodity_stays_at_target(env);		
		for (u_int m = 0; m < n_edges; m++) {
			const u_int i = edges[m].v1;
			const u_int j = edges[m].v2;
			if (i == c && j != c){
				e_commodity_stays_at_target += v->fss[c][m];	
			}
		} 
		model.add(e_commodity_stays_at_target == 0);
		e_commodity_stays_at_target.end();
	}


	/*
	 * Flow is conserved when not at target node. 
	 * $\forall j, l s.t. j \neq l: \sum_i f^l_{ij} = \sum_i f^l_{ji}$. 
	 */
	 for (u_int c = 0; c < (u_int) instance.n_nodes; c++){
		IloExprArray e_in_flow(env, instance.n_nodes);		
		IloExprArray e_out_flow(env, instance.n_nodes);		
		for (u_int m = 0; m < instance.n_nodes; m++){
			e_in_flow[m] = IloExpr(env);
			e_out_flow[m] = IloExpr(env);
		}
		for (u_int m = 0; m < n_edges; m++) {
			const u_int i = edges[m].v1;
			const u_int j = edges[m].v2;
			e_out_flow[i] += v->fss[c][m];	
			e_in_flow[j] += v->fss[c][m];	
		} 
		for (u_int m = 1; m < instance.n_nodes; m++){
			if (m != c) {
				model.add(e_in_flow[m] == e_out_flow[m]);
			}
		}
		e_in_flow.endElements();
		e_out_flow.endElements();
	 }

	/* 
	 * Commodities may only be transmitted on active edges:
	 * $\forall l, i, j: f^l_{ij} \leq x_{ij}$. 
     */
	for (u_int c = 0; c < (u_int) instance.n_nodes; c++){
		for (u_int m = 0; m < n_edges; m++) {
			model.add(v->fss[c][m] <= v->xs[m]);
		} 
	}

	/* 
	 * For each commodity l , the total flow is <= k if node l is active, 0 otherwise
	 * (works well for all before g05, k=n/2 which is a bit slower with this)
     */
	for (u_int c = 1; c < (u_int) instance.n_nodes; c++){
		IloExpr e_total_flow(env);		
		for (u_int m = 0; m < n_edges; m++) {
			e_total_flow += v->fss[c][m];	
		} 
		model.add(e_total_flow <= this->k * v->vs[c]);
		e_total_flow.end();
	}
	return v;
}