예제 #1
0
//*******************************************************************
CPXLPptr CSolver::LoadProblem(bool bMip) {


   m_lp = CPXcreateprob (m_env, &m_status, m_pszProbname);

   CPXchgobjsen (m_env, m_lp, m_nObjSense );

   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }


   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }

   m_status = CPXnewrows( m_env, m_lp, m_nRhsItems, m_pRhs,
                          m_pRhsSense, 0, m_rname);

   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }

   if (!bMip)
     m_status = CPXnewcols( m_env, m_lp, m_nObjItems, m_pObj,
                            m_pBdl, m_pBdu, NULL, m_cname);
   else
     m_status = CPXnewcols( m_env, m_lp, m_nObjItems, m_pObj,
                            m_pBdl, m_pBdu, m_pCtype, m_cname);

   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }

   m_status = CPXchgcoeflist(m_env, m_lp, m_nCoefItems,
                             m_pRowNdx, m_pColNdx, m_pCoef);
   if ( m_status != 0 ) {
        CPXgeterrorstring(m_env, m_status, m_error );
        return 0;
   }

   FreeMemory();

   return m_lp;

}
예제 #2
0
Solution cplex_init(TSP tsp, CPLEX cplex) {
  int n = tsp.n;
  int cols = tsp.cols;
  double *dists = tsp.distances;
  
  int *visits = malloc(sizeof(int) * n * n - n);
  double *rmatval = malloc(sizeof(double) * n * n - n);
  
  char **headers = malloc(sizeof(char *) * cols);
  double *lb = malloc(sizeof(double) * cols);
  double *ub = malloc(sizeof(double) * cols);
  char *ctype = malloc(sizeof(char) * cols);
  
  char **contraints = malloc(sizeof(char *) * n);
  double *rhs = malloc(sizeof(double) * n);
  char *senses = malloc(sizeof(char) * n);
  int *rmatbeg = malloc(sizeof(int) * n);
  
  char str[16];
  
  for (int i = 0; i < n; ++i) {
    sprintf(str, "visit(%d)", i+1);
    contraints[i] = strdup(str);
    rhs[i] = 2;
    senses[i] = 'E';
    rmatbeg[i] = i * (n-1);
  }
  
  for (int pos = 0; pos < cols; ++pos) {
    Pair pair = tsp.pairs[pos];
    
    int first  = (pair.i.id * (n-1)) + (pair.j.id-1);
    int second = (pair.j.id * (n-1)) + pair.i.id;
    visits[first] = visits[second] = pos;
    rmatval[first] = rmatval[second] = 1;
    
    sprintf(str, "x(%d,%d)", pair.i.num, pair.j.num);
    headers[pos] = strdup(str);
    
    lb[pos] = 0;
    ub[pos] = 1;
    ctype[pos] = CPX_BINARY; // set the var to binary (value of 1 or 0)
  }
  
  CPXnewcols(cplex.env, cplex.lp, cols, dists, lb, ub, ctype, headers);
  CPXaddrows(cplex.env, cplex.lp, 0, n, n*n-n, rhs, senses, rmatbeg,
             visits, rmatval, NULL, contraints);
  
  Solution solution;
  solution.i = 0;
  solution.n = -1;
  
  return solution;
}
static int
populatebyrow (CPXENVptr env, CPXLPptr lp)
{
   int      status    = 0;
   double   obj[NUMCOLS];
   double   lb[NUMCOLS];
   double   ub[NUMCOLS];
   char     *colname[NUMCOLS];
   int      rmatbeg[NUMROWS];
   int      rmatind[NUMNZ];
   double   rmatval[NUMNZ];
   double   rhs[NUMROWS];
   char     sense[NUMROWS];
   char     *rowname[NUMROWS];

   status = CPXchgobjsen (env, lp, CPX_MAX);  /* Problem is maximization */
   if ( status )  goto TERMINATE;

   /* Now create the new columns.  First, populate the arrays. */

       obj[0] = 1.0;      obj[1] = 2.0;          obj[2] = 3.0;

        lb[0] = 0.0;       lb[1] = 0.0;           lb[2] = 0.0;
        ub[0] = 40.0;      ub[1] = CPX_INFBOUND;  ub[2] = CPX_INFBOUND;

   colname[0] = "x1"; colname[1] = "x2";     colname[2] = "x3";

   status = CPXnewcols (env, lp, NUMCOLS, obj, lb, ub, NULL, colname);
   if ( status )  goto TERMINATE;

   /* Now add the constraints.  */

   rmatbeg[0] = 0;     rowname[0] = "c1";

   rmatind[0] = 0;     rmatind[1] = 1;    rmatind[2] = 2;    sense[0] = 'L';
   rmatval[0] = -1.0;  rmatval[1] = 1.0;  rmatval[2] = 1.0;  rhs[0]   = 20.0;

   rmatbeg[1] = 3;     rowname[1] = "c2";
   rmatind[3] = 0;     rmatind[4] = 1;    rmatind[5] = 2;    sense[1] = 'L';
   rmatval[3] = 1.0;   rmatval[4] = -3.0; rmatval[5] = 1.0;  rhs[1]   = 30.0;

   status = CPXaddrows (env, lp, 0, NUMROWS, NUMNZ, rhs, sense, rmatbeg,
                        rmatind, rmatval, NULL, rowname);
   if ( status )  goto TERMINATE;

TERMINATE:

   return (status);

}  /* END populatebyrow */
예제 #4
0
파일: diet.c 프로젝트: annaPolytech/PRD
static int
populatebyrow (CPXENVptr env, CPXLPptr lp,
               int nfoods, double *cost, double *lb, double *ub, 
               int nnutr, double *nutrmin, double *nutrmax,
               double **nutrper)
{
   int status = 0;

   int zero = 0;
   int *ind = NULL;
   int i, j;

   ind = (int*) malloc(nfoods * sizeof(int));
   if ( ind == NULL ) {
      status = CPXERR_NO_MEMORY;
      goto TERMINATE;
   }
   for (j = 0; j < nfoods; j++) {
      ind[j] = j;
   }

   status = CPXnewcols (env, lp, nfoods, cost, lb, ub, NULL, NULL);
   if ( status )  goto TERMINATE;

   for (i = 0; i < nnutr; i++) {
      double rng  = nutrmax[i] - nutrmin[i];

      status = CPXaddrows (env, lp, 0, 1, nfoods, nutrmin+i, "R",
                           &zero, ind, nutrper[i], NULL, NULL);
      if ( status )  goto TERMINATE;

      status = CPXchgrngval (env, lp, 1, &i, &rng);
      if ( status )  goto TERMINATE;
   }

TERMINATE:

   free_and_null ((char **)&ind);

   return (status);

}  /* END populatebyrow */
예제 #5
0
// ends up objective function construction
int cplex_solver::end_objectives(void) {
	if (objectives.size() > 0) {
		int status = 0, nb_coeffs = 0;

		// Set the first objective as the actual objective
		for (int k = 0; k < nb_vars; k++) coefficients[k] = 0;
		for (; first_objective < (int)objectives.size(); first_objective++)
			if ((nb_coeffs = objectives[first_objective]->nb_coeffs) > 0) break;
		if (nb_coeffs > 0)
			for (int k = 0; k < nb_coeffs; k++)
				coefficients[objectives[first_objective]->sindex[k]] = objectives[first_objective]->coefficients[k];
		else
			if (first_objective == (int)objectives.size()) first_objective--; // So that we solve at least one pbs
		status = CPXnewcols (env, lp, nb_vars, coefficients, lb, ub, vartype, varname);
		if (status) {
			fprintf(stderr, "cplex_solver: end_objective: cannot create objective function.\n");
			exit(-1);
		}
	}

	return 0;
}
예제 #6
0
파일: main.cpp 프로젝트: germanromano/invop
int main(int argc, char *argv[]) {
	
	if(argc < 3){
		cerr << "Uso: input_file max_iteraciones" << endl;
		exit(1);
	}
	
	srand(time(NULL));
	string archivo_entrada(argv[1]);
	int max_iteraciones = atoi(argv[2]);

//----------------------- PARSEO DE ENTRADA	
	pair <int, pair<vector<vector<bool> >*, vector<vector<bool> >* > > grafo = parsear_entrada(archivo_entrada);
	int cant_ejes = grafo.first;
	vector<vector<bool> > *adyacencias = grafo.second.first; // matriz de adyacencia
	vector<vector<bool> > *particion = grafo.second.second;	// filas: subconjuntos de la particion. columnas: nodos.
	
	// Variables binarias:
	//		* X_n_j = nodo n pintado con el color j? (son cant_nodos * cant_colores_disp variables)
	//		* W_j	= hay algun nodo pintado con el color j? (son cant_colores_disp variables)
	//			=> TOTAL: (cant_nodos * cant_colores_disp + cant_colores_disp) variables
	//
	// Orden de las variables:
	//		X_0_0, X_0_1, ... , X_0_(cant_col_disp), X_1_0, ... , X_(cant_nodos)_(cant_col_disp), W_0, ... , W(cant_col_disp)

	int cant_nodos = adyacencias->size();
	int cant_subconj_particion = particion->size(); //cant de subconjuntos de la particion
	int cant_colores_disp = particion->size(); // cant colores usados <= cant de subconjuntos de la particion
	
	int n = cant_nodos * cant_colores_disp + cant_colores_disp; // n = cant de variables

//----------------------- CARGA DE LP
	// Genero el problema de cplex.
	int status;
	CPXENVptr env; // Puntero al entorno.
	CPXLPptr lp; // Puntero al LP
	 
	// Creo el entorno.
	env = CPXopenCPLEX(&status);
		
	if (env == NULL) {
		cerr << "Error creando el entorno" << endl;
		exit(1);
	}
		
	// Creo el LP.
	lp = CPXcreateprob(env, &status, "Coloreo Particionado");

		
	if (lp == NULL) {
		cerr << "Error creando el LP" << endl;
		exit(1);
	}
	
	//TUNNING
	//Para que haga Branch & Cut:
	CPXsetintparam(env, CPX_PARAM_MIPSEARCH, CPX_MIPSEARCH_TRADITIONAL);
	//Para que no se adicionen planos de corte: ( => Branch & Bound)
	CPXsetintparam(env,CPX_PARAM_EACHCUTLIM, 0);
	CPXsetintparam(env, CPX_PARAM_FRACCUTS, -1);
	//Para facilitar la comparación evitamos paralelismo:
	CPXsetintparam(env, CPX_PARAM_THREADS, 1);
	//Para desactivar preprocesamiento
	CPXsetintparam(env, CPX_PARAM_PRESLVND, -1);
	CPXsetintparam(env, CPX_PARAM_REPEATPRESOLVE, 0);
	CPXsetintparam(env, CPX_PARAM_RELAXPREIND, 0);
	CPXsetintparam(env, CPX_PARAM_REDUCE, 0);
	CPXsetintparam(env, CPX_PARAM_LANDPCUTS, -1);
	//Otros parámetros
	// Para desactivar la salida poner CPX_OFF. Para activar: CPX_ON.
	status = CPXsetintparam(env, CPX_PARAM_SCRIND, CPX_OFF);
		if (status) {
			cerr << "Problema seteando SCRIND" << endl;
			exit(1);
		}
	//Setea el tiempo limite de ejecucion.
	status = CPXsetdblparam(env, CPX_PARAM_TILIM, 3600);
		if (status) {
			cerr << "Problema seteando el tiempo limite" << endl;
			exit(1);
		}

	double *ub, *lb, *objfun; // Cota superior, cota inferior, coeficiente de la funcion objetivo.
	char *xctype, **colnames; // tipo de la variable (por ahora son siempre continuas), string con el nombre de la variable.
	ub = new double[n]; 
	lb = new double[n];
	objfun = new double[n];
	xctype = new char[n];
	colnames = new char*[n];
	
	// Defino las variables X_n_j
	for (int i = 0; i < n - cant_colores_disp; i++) {
		ub[i] = 1;
		lb[i] = 0;
		objfun[i] = 0; // Estas var no figuran en la funcion objetivo
		xctype[i] = 'C';
		colnames[i] = new char[10];
		sprintf(colnames[i], "X_%d_%d", i / cant_colores_disp, i % cant_colores_disp);
	}

	// Defino las variables W_j
	for (int i = n - cant_colores_disp; i < n; i++) {
		ub[i] = 1;
		lb[i] = 0;
		objfun[i] = 1;
		xctype[i] = 'C';
		colnames[i] = new char[10];
		sprintf(colnames[i], "W_%d", i - (n - cant_colores_disp));
	}
	
	// Agrego las columnas.
	status = CPXnewcols(env, lp, n, objfun, lb, ub, NULL, colnames);
	
	if (status) {
		cerr << "Problema agregando las variables CPXnewcols" << endl;
		exit(1);
	}
	
	// Libero las estructuras.
	for (int i = 0; i < n; i++) {
		delete[] colnames[i];
	}
	
	delete[] ub;
	delete[] lb;
	delete[] objfun;
	delete[] xctype;
	delete[] colnames;

	// Restricciones:
	//	(1) Nodos adyacentes tienen distinto color (cant_ejes * cant_colores_disp restricciones por <=)
	//	(2) Cada nodo tiene a lo sumo un color (cant_nodos restricciones por <=)
	//	(3) Solo un nodo de cada subconj. de la particion tiene color (cant. de subconj. de la particion restricciones por =)
	//	(4) W_j = 1 sii "X_i_j = 1 para algún i" (cant_colores_disp restricciones por >=)
	//	(5) W_j >= W_(j+1) (cant_colores_disp - 1 restricciones por >=)
	//		=> TOTAL: (cant_ejes * cant_colores_disp + cant_nodos + cant_subconj_particion + cant_colores_disp + cant_colores_disp - 1) restricciones

	int ccnt = 0; //numero nuevo de columnas en las restricciones.
	int rcnt = cant_ejes * cant_colores_disp + cant_nodos + cant_subconj_particion + cant_colores_disp + cant_colores_disp - 1; //cuantas restricciones se estan agregando.
	int nzcnt = 0; //# de coeficientes != 0 a ser agregados a la matriz. Solo se pasan los valores que no son cero.

	char sense[rcnt]; // Sentido de la desigualdad. 'G' es mayor o igual y 'E' para igualdad.
	for(unsigned int i = 0; i < cant_ejes * cant_colores_disp; i++)
		sense[i] = 'L';
	for(unsigned int i = cant_ejes * cant_colores_disp; i < cant_ejes * cant_colores_disp + cant_nodos; i++)
		sense[i] = 'L';
	for(unsigned int i = cant_ejes * cant_colores_disp + cant_nodos; i < cant_ejes * cant_colores_disp + cant_nodos + cant_subconj_particion; i++)
		sense[i] = 'E';
	for(unsigned int i = cant_ejes * cant_colores_disp + cant_nodos + cant_subconj_particion; i < rcnt; i++)
		sense[i] = 'G';

	double *rhs = new double[rcnt]; // Termino independiente de las restricciones.
	int *matbeg = new int[rcnt]; //Posicion en la que comienza cada restriccion en matind y matval.
	int *matind = new int[rcnt*n]; // Array con los indices de las variables con coeficientes != 0 en la desigualdad.
	double *matval = new double[rcnt*n]; // Array que en la posicion i tiene coeficiente ( != 0) de la variable cutind[i] en la restriccion.

	//El termino indep. de restr (1), (2) y (3) es 1
	for(unsigned int i = 0; i < cant_ejes * cant_colores_disp + cant_nodos + cant_subconj_particion; i++)
		rhs[i] = 1;
		
	//El termino indep. de restr (4) y (5) es 0
	for(unsigned int i = cant_ejes * cant_colores_disp + cant_nodos + cant_subconj_particion; i < rcnt; i++)
		rhs[i] = 0;
	
	unsigned int indice = 0; //numero de restriccion actual
	
	//Restricciones (1)
	for(unsigned int i = 0; i < cant_nodos; i++) //itero nodo 1
		for(unsigned int j = i+1; j < cant_nodos; j++) //itero nodo 2
			if((*adyacencias)[i][j])
				for(unsigned int p = 0; p < cant_colores_disp; p++){ //itero color
					matbeg[indice] = nzcnt;
					indice++;
					//cargo una de las variables participantes de la restr.
					matind[nzcnt] = cant_colores_disp*i + p; //var1: X_nodo1_color
					matval[nzcnt] = 1;
					nzcnt++;
					//idem con la otra variable
					matind[nzcnt] = cant_colores_disp*j + p; //var2: X_nodo2_color
					matval[nzcnt] = 1;
					nzcnt++;
				}
				
	//Restricciones (2)
	for(unsigned int i = 0; i < cant_nodos; i++){ //itero nodo
		matbeg[indice] = nzcnt;
		indice++;
		for(unsigned int p = 0; p < cant_colores_disp; p++){ //itero color
			matind[nzcnt] = cant_colores_disp*i + p; //var: X_nodo_color
			matval[nzcnt] = 1;
			nzcnt++;
		}
	}
	
	//Restricciones (3)
	for(unsigned int v = 0; v < cant_subconj_particion; v++){ //itero subconjunto de la particion
		matbeg[indice] = nzcnt;
		indice++;
		for(unsigned int i = 0; i < cant_nodos; i++) //itero nodo
			if((*particion)[v][i])
				for(unsigned int p = 0; p < cant_colores_disp; p++){ //itero color
					matind[nzcnt] = cant_colores_disp*i + p; //var: X_nodo_color
					matval[nzcnt] = 1;
					nzcnt++;
				}
	}
	
	//Restricciones (4)
	for(unsigned int p = 0; p < cant_colores_disp; p++){ //itero color
		matbeg[indice] = nzcnt;
		indice++;
		matind[nzcnt] = cant_nodos * cant_colores_disp + p; //var: W_color
		matval[nzcnt] = cant_nodos;
		nzcnt++;
		for(unsigned int i = 0; i < cant_nodos; i++){ //itero nodo
			matind[nzcnt] = cant_colores_disp*i + p; //var: X_nodo_color
			matval[nzcnt] = -1;
			nzcnt++;
		}
	}
	
	//Restricciones (5)
	for(unsigned int p = 0; p < cant_colores_disp - 1; p++){ //itero color
		matbeg[indice] = nzcnt;
		indice++;
		matind[nzcnt] = cant_nodos * cant_colores_disp + p; //var: W_color
		matval[nzcnt] = 1;
		nzcnt++;
		matind[nzcnt] = cant_nodos * cant_colores_disp + p + 1; //var: W_(color+1)
		matval[nzcnt] = -1;
		nzcnt++;
	}
	
	// Esta rutina agrega la restriccion al lp.
	status = CPXaddrows(env, lp, ccnt, rcnt, nzcnt, rhs, sense, matbeg, matind, matval, NULL, NULL);
	
	if (status) {
		cerr << "Problema agregando restricciones." << endl;
		exit(1);
	}
	
	delete[] rhs;
	delete[] matbeg;
	delete[] matind;
	delete[] matval;

	// Escribimos el problema a un archivo .lp
	status = CPXwriteprob(env, lp, "output.lp", NULL);
		
	if (status) {
		cerr << "Problema escribiendo modelo" << endl;
		exit(1);
	}
	
//----------------------- PRIMER ITERACION DE RESOLUCIÓN DEL LP
	
	// Tomamos el tiempo de resolucion utilizando CPXgettime.
	double inittime, endtime, fractpart, intpart, opt_anterior, opt_actual;
	int cant_iteraciones = 0;
	status = CPXgettime(env, &inittime);
	
	bool criterio_de_corte, todas_enteras, hubo_plano = true;
	
	status = CPXlpopt(env, lp);
	if (status) {
		cerr << "Problema optimizando CPLEX" << endl;
		exit(1);
	}
	
	status = CPXgetobjval(env, lp, &opt_actual);
	if (status) {
		cerr << "Problema obteniendo valor de mejor solucion." << endl;
		exit(1);
	}
	
	cout << "Optimo Inicial: " << opt_actual << endl << endl;
	
	double *sol = new double[n];
	status = CPXgetx(env, lp, sol, 0, n - 1);
	if (status) {
		cerr << "Problema obteniendo la solucion del LP." << endl;
		exit(1);
	}

	// Chequeo si la solución es entera
	for (int i = 0; i < n; i++){
		fractpart = modf(sol[i] , &intpart);
		if (fractpart > TOL){
			todas_enteras = false;
			break;
			}
		}
	
	criterio_de_corte = todas_enteras || max_iteraciones==0;

//----------------------- INICIO CICLO DE RESOLUCIÓN DEL LP
	while(!criterio_de_corte){
		opt_anterior = opt_actual;
		
		hubo_plano = agregar_restricciones_clique(adyacencias, sol, env, lp, cant_colores_disp, n);
		hubo_plano = agregar_restricciones_ciclos(adyacencias, sol, env, lp, cant_colores_disp, n) || hubo_plano;
		
		if(hubo_plano){
			status = CPXlpopt(env, lp);
			if (status) {
				cerr << "Problema optimizando CPLEX" << endl;
				exit(1);
			}
			
			status = CPXgetx(env, lp, sol, 0, n - 1);
			if (status) {
				cerr << "Problema obteniendo la solucion del LP." << endl;
				exit(1);
			}
			
			for (int i = 0; i < n; i++){
				fractpart = modf(sol[i] , &intpart);
				if (fractpart > TOL){
					todas_enteras = false;
					break;
				}
			}
		}
		
		status = CPXgetobjval(env, lp, &opt_actual);
		if (status) {
			cerr << "Problema obteniendo valor de mejor solucion." << endl;
			exit(1);
		}
		
		cant_iteraciones++;
		criterio_de_corte = todas_enteras || (cant_iteraciones >= max_iteraciones)
								|| !hubo_plano;// || abs(opt_actual - opt_anterior) < TOL;
	}

	status = CPXgettime(env, &endtime);
//----------------------- FIN CICLO DE RESOLUCIÓN DEL LP

	int solstat;
	char statstring[510];
	CPXCHARptr p;
	solstat = CPXgetstat(env, lp);
	p = CPXgetstatstring(env, solstat, statstring);
	string statstr(statstring);
	cout << endl << "Resultado de la optimizacion: " << statstring << endl;
	
	if(solstat!=CPX_STAT_OPTIMAL) exit(1);
	
	double objval;
	status = CPXgetobjval(env, lp, &objval);
		
	if (status) {
		cerr << "Problema obteniendo valor de mejor solucion." << endl;
		exit(1);
	}
		
	cout << "Optimo: " << objval << "\t(Time: " << (endtime - inittime) << " sec)" << endl; 

	// Tomamos los valores de la solucion y los escribimos a un archivo.
	std::string outputfile = "output.sol";
	ofstream solfile(outputfile.c_str());

	// Tomamos los valores de todas las variables. Estan numeradas de 0 a n-1.
	status = CPXgetx(env, lp, sol, 0, n - 1);

	if (status) {
		cerr << "Problema obteniendo la solucion del LP." << endl;
		exit(1);
	}

	// Solo escribimos las variables distintas de cero (tolerancia, 1E-05).
	solfile << "Status de la solucion: " << statstr << endl;
	// Imprimo var X_n_j
	for (int i = 0; i < n - cant_colores_disp; i++) {
		if (sol[i] > TOL) {
			solfile << "X_" << i / cant_colores_disp << "_" << i % cant_colores_disp << " = " << sol[i] << endl;
		}
	}
	// Imprimo var W_j
	for (int i = n - cant_colores_disp; i < n; i++) {
		if (sol[i] > TOL) {
			solfile << "W_" << i - (n - cant_colores_disp) << " = " << sol[i] << endl;
		}
	}

	solfile.close();
	delete [] sol;
	delete adyacencias;
	delete particion;
	
	return 0;
}
예제 #7
0
int CPLEXLoadVariables(MFAVariable* InVariable, bool RelaxIntegerVariables,bool UseTightBounds) {
	int Status = 0;
	
	//First I check the number of columns. If it's larger than the index, then this variable already exists and is only being changed
	int NumberColumns = CPXgetnumcols (CPLEXenv, CPLEXModel);
	if (NumberColumns <= InVariable->Index) {
		string StrName = GetMFAVariableName(InVariable);
		
		double* LB = new double;
		LB[0] = InVariable->LowerBound;
		double* UB = new double;
		UB[0] = InVariable->UpperBound;
		if (UseTightBounds) {
			LB[0] = InVariable->Min;
			UB[0] = InVariable->Max;
		}
		double* Obj = new double;
		Obj[0] = 0;
		char* Temp = new char;
		char** Name = new char*;
		Name[0] = new char[StrName.length()+1];
		strcpy(Name[0],StrName.data());
		
		if (InVariable->Binary && !RelaxIntegerVariables) {
			Temp[0] = CPX_BINARY;
			Status = CPXnewcols (CPLEXenv, CPLEXModel, 1, Obj, LB, UB, Temp, Name);
		} else if (InVariable->Integer && !RelaxIntegerVariables) {
			Temp[0] = CPX_INTEGER;
			Status = CPXnewcols (CPLEXenv, CPLEXModel, 1, Obj, LB, UB, Temp, Name);
		} else {
			Temp[0] = CPX_CONTINUOUS;
			Status = CPXnewcols (CPLEXenv, CPLEXModel, 1, Obj, LB, UB, Temp, Name);
		}

		delete LB;
		delete UB;
		delete Obj;
		delete Temp;
		delete [] Name[0];
		delete Name;

		if (Status ) {
			FErrorFile() << "Could not add variable " << InVariable->Index << endl;
			FlushErrorFile();
			return FAIL;
		}
	} else {
		double* Bounds = new double[2];
		Bounds[0] = InVariable->LowerBound;
		Bounds[1] = InVariable->UpperBound;
		
		int* Indices = new int[2];
		Indices[0] = InVariable->Index;
		Indices[1] = InVariable->Index;

		Status = CPXchgbds (CPLEXenv, CPLEXModel, 2, Indices, "LU", Bounds);
		
		delete [] Bounds;
		delete [] Indices;

		if (Status) {
			FErrorFile() << "Could not change bounds on variable " << InVariable->Index << endl;
			FlushErrorFile();
			return FAIL;
		}
	}

	return SUCCESS;
}
예제 #8
0
 int main(int argc, char **argv)
 {
    int status = 0;
    CPXENVptr env = NULL;
    CPXLPptr lp = NULL;

    double obj[NUMCOLS];
    double lb[NUMCOLS];
    double ub[NUMCOLS];
    double x[NUMCOLS];
    int rmatbeg[NUMROWS];
    int rmatind[NUMNZ];
    double rmatval[NUMNZ];
    double rhs[NUMROWS];
    char sense[NUMROWS];
    char ctype[NUMCOLS];

    int solstat;
    double objval;

    env = CPXopenCPLEX (&status);


    CPXsetintparam(env, CPX_PARAM_MIPCBREDLP, CPX_OFF);
    CPXsetintparam(env, CPX_PARAM_PRELINEAR, CPX_OFF);
    /* Turn on traditional search for use with control callbacks */

    // status = CPXsetintparam (env, CPXPARAM_MIP_Strategy_Search,
    //                        CPX_MIPSEARCH_TRADITIONAL);


    lp = CPXcreateprob(env, &status, "lpex1");
    //CPXchgprobtype(env, lp, CPXPROB_MILP);

    CPXchgobjsen (env, lp, CPX_MAX);

    status = CPXsetlazyconstraintcallbackfunc (env, callback,
                                      NULL);


    lb[0] = 0.0;
    ub[0] = 40.0;

    lb[1] = 0.0;
    ub[1] = CPX_INFBOUND;

    lb[2] = 0.0;
    ub[2] = CPX_INFBOUND;

    obj[0] = 1.0;
    obj[1] = 2.0;
    obj[2] = 3.0;

    status = CPXnewcols (env, lp, NUMCOLS, obj, lb, ub, NULL, NULL);

    rmatbeg[0] = 0;
    rmatind[0] = 0;     rmatind[1] = 1;     rmatind[2] = 2;
    rmatval[0] = -1.0;  rmatval[1] = 1.0;   rmatval[2] = 1.0;   sense[0] = 'L';     rhs[0] = 20.0;

    rmatbeg[1] = 3;
    rmatind[3] = 0;     rmatind[4] = 1;     rmatind[5] = 2;
    rmatval[3] = 1.0;   rmatval[4] = -3.0;  rmatval[5] = 1.0;   sense[1] = 'L';     rhs[1] = 30.0;

    ctype[0] = 'I'; ctype[1] = 'C'; ctype[2] = 'I';

    // status = CPXaddusercuts (env, lp, cutcnt, cutnzcnt, cutrhs,
    //                      cutsense, cutbeg, cutind, cutval, NULL);
    //status = CPXaddusercuts(env, lp, NUMROWS, NUMNZ, rhs, sense, rmatbeg, rmatind, rmatval, NULL );

    status = CPXaddrows (env, lp, 0, NUMROWS, NUMNZ, rhs, sense, rmatbeg, rmatind, rmatval, NULL, NULL);
    status = CPXcopyctype (env, lp, ctype);

    // cuts
    int cmatbeg[1] = {0};
    int cmatind[3] = {0,1,2};
    double cmatval[3] = {1,0,0};
    char csense[1] = {'L'};
    double crhs[1] = {20};

    //CPXaddusercuts doesnt work for some f*****g reason

    //status = CPXaddlazyconstraints(env, lp, 1, 3, crhs, csense, cmatbeg, cmatind, cmatval, NULL );
    if ( status ) {
      fprintf (stderr, "Some f*****g error, status = %d.\n", status);
   }



    status = CPXmipopt (env, lp);



   /* Write the output to the screen. */
    // solstat = CPXgetstat (env, lp);
    // printf ("\nSolution status = %d\n", solstat);
    // status = CPXgetobjval (env, lp, &objval);
    // printf ("Solution value  = %f\n\n", objval);

    status = CPXsolution (env, lp, &solstat, &objval, x, NULL, NULL, NULL);
    printf ("\nSolution status = %d\n", solstat);
    printf ("Solution value = %f\n", objval);
    printf ("Solution= [%f, %f, %f]\n\n", x[0], x[1], x[2]);

    printf("This is great stuff\n");


    return 0;
 }
inline int
populatebynonzero (CPXENVptr env, CPXLPptr lp, int m, int n, int timeout,
		sched_nodeinfo_t *node_array, solver_job_list_t *job_array)
{
	int NUMCOLS = n * (2 * m + 2);
	int NUMROWS = n * 3 + m * 2 + m * n * 2;
	int NUMNZ = 2 * n * (4 * m + 1); 
	int NZc = 0; /* nonzero counter */
	
	int status = 0;
	double *obj = NULL;
	obj = (double*)malloc(NUMCOLS * sizeof(double));
	double *lb = (double*)malloc(NUMCOLS * sizeof(double));
	double *ub = (double*)malloc(NUMCOLS * sizeof(double));
	double *rhs = (double*)malloc(NUMROWS * sizeof(double));
	char *sense = (char*)malloc(NUMROWS * sizeof(char));
	/*
	char **colname = (char**)malloc(NUMCOLS * sizeof(char*));
	char **rowname = (char**)malloc(NUMROWS * sizeof(char[10]));
	char str[10];
	*/
	int *rowlist = (int*)malloc(NUMNZ * sizeof(int));
	int *collist = (int*)malloc(NUMNZ * sizeof(int));
	double *vallist = (double*)malloc(NUMNZ * sizeof(double));
	int i, j, d;
	/*int rc = 0, cc = 0;*/

	CPXchgobjsen (env, lp, CPX_MAX);  /* Problem is maximization */

	/* row definitions */
	
	for (j = 0; j < n; j++) {
		sense[j] = 'E';
		rhs[j] = 0.0;
		/*debug3("cpueq row counter: %d, no: %d",rc++, j);*/
		/*sprintf(str,"CPUeq_%d",j+1);
		rowname[j] = str;*/
	}
	for (i = 0; i < m; i++) {
		sense[n + i] = 'L';
		rhs[n + i] = (double)(node_array[i].rem_cpus);
		/*sprintf(str,"NODEeq_%d",i+1);
		rowname[n + i] = str;*/
		/*debug3("nodeeq row counter: %d, no: %d",rc++, n+i);*/

		sense[n + m + i] = 'L';
		rhs[n + m + i] = (double)(node_array[i].rem_gpus);
		/*debug3("gpueq row counter: %d, no: %d",rc++, n+m+i);*/
		/*sprintf(str,"GPUeq_%d",i+1);
		rowname[n + m + i] = str;*/
	}

	for (j = 0; j < n; j++) {
		for (i = 0; i < m; i++) {
			d = n + 2 * m + j * m * 2 + i * 2;
			sense[d] = 'L';
			rhs[d] = 0.0;
			/*debug3("t_i_j_le row counter: %d, no: %d",rc++,d);*/
			/*sprintf(rowname[d],"t_%d_%d_LE",j+1,i+1);
			rowname[d] = str;*/
			sense[d + 1] = 'G';
			rhs[d + 1] = 0.0;
			/*debug3("t_i_j_ge row counter: %d, no: %d",rc++,d+1);*/
			/*sprintf(rowname[d+1],"t_%d_%d_GE",j+1,i+1);
			rowname[d+1] = str;*/
		}
	}

	for (j = 0; j < n; j++) {
		sense[n + 2 * m + n * m * 2 + j * 2] = 'L';
		rhs[n + 2 * m + n * m * 2 + j * 2] = 0.0;
		/*debug3("minmax row counter: %d, no: %d",rc++,n + 2 * m + n * m * 2 + j * 2);*/
		sense[n + 2 * m + n * m * 2 + j * 2 + 1] = 'G';
		rhs[n + 2 * m + n * m * 2 + j * 2 + 1] = 0.0;
		/*debug3("minmax row counter: %d, no: %d",rc++,n + 2 * m + n * m * 2 + j * 2 + 1);*/
		/*sprintf(str,"minmax_%d",j+1);
		rowname[n + 4 * m + n * m * 2 + j] = str;*/
	}

	status = CPXnewrows (env, lp, NUMROWS, rhs, sense, NULL, NULL);
	if ( status ) goto TERMINATE;

	/*debug3("ROWS: %d, column def starting",NUMROWS);*/
	/* column definitions */	
	for (j = 0; j < n; j++) {
		/*sprintf(str, "s_%d",j+1);
		colname[j] = str;*/
		lb[j] = 0.0;
		ub[j] = 1.0;
		/*debug3("s_j col counter: %d, no: %d",cc++,j);*/
	}

	/*debug3("defined s_j");*/
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			/*sprintf(str, "x_%d_%d",i+1,j+1);
			colname[(i + 1) * n + j] = str;*/
			lb[(i + 1) * n + j] = 0.0;
			ub[(i + 1) * n + j] = CPX_INFBOUND;
			/*debug3("x_i_j col counter: %d, no: %d",cc++,(i+1)*n+j);*/
		}
	}
	/*debug3("defined x_i_j");*/

	for (j = 0; j < n; j++) {
		/*sprintf(str, "c_%d",j+1);
		colname[n * (m + 1) + j] = str;*/
		/* min_nodes_j <= c_j <= max_nodes_j */
		lb[n * (m + 1) + j] = (m + 1) * (job_array[j].min_nodes);
		ub[n * (m + 1) + j] = (m + 1) * (job_array[j].max_nodes);
		/*debug3("c_j col counter: %d, no: %d",cc++,n*(m+1)+j);*/
	}
	/*debug3("defined c_j");*/

	for (j = 0; j < n; j++) {
		for (i = 0; i < m; i++) {
			/*sprintf(str, "t_%d_%d",j+1,i+1);
			colname[n * (m + 2) + j * m + i] = str;*/
			lb[n * (m + 2) + j * m + i] = 0.0;
			ub[n * (m + 2) + j * m + i] = 1.0;
			/*debug3("t_i_j col counter: %d, no: %d",cc++,n*(m+2)+j*m+i);*/
		}
	}
	/*debug3("defined t_i_j");*/
	
	for (j = 0; j < NUMCOLS; j++) {
		obj[j] = 0;
	}
	for (j = 0; j < n; j++) {
		obj[j] = (job_array[j].priority);
		obj[n * (m + 1) + j] = (-1.0)*(job_array[j].priority);
	}

	status = CPXnewcols (env, lp, NUMCOLS, obj, lb, ub, NULL, NULL);
	if ( status )  goto TERMINATE;

	/*debug3("constraint coefficients");*/
	/* constraints */
	/* sum over nodes should be equal to job's required cpu */
	/* sum_i(x_ij) = r_j * s_j */
	for (j = 0; j < n; j++) {
		for (i = 0; i < m; i++) {
			rowlist[NZc] = j;			
			vallist[NZc] = 1.0;
			collist[NZc++] = (i + 1) * n + j;
			/*debug3("con1 collist %d",(i + 1) * n + j);*/
		}
		rowlist[NZc] = j;
		vallist[NZc] = (int)(-job_array[j].min_cpus);
		collist[NZc++] = j;
		/*debug3("con1 collist %d",j);*/
	}	
	/* nzc = m*n+n */

	/* sum over jobs for cpu should be available on nodes */
	/* sum_j(x_ij) <= R_i */
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			/*debug3("con2 collist %d",(i + 1) * n + j);*/
			rowlist[NZc] = n + i;
			vallist[NZc] = 1.0;
			collist[NZc++] = (i + 1) * n + j;
		}
	}
	/* nzc = 2*m*n+n */

	/* sum over jobs for gpu should be available on nodes */
	/* sum_j(t_ji * g_j) <= G_i */
	for (i = 0; i < m; i++) {
		for (j = 0; j < n; j++) {
			rowlist[NZc] = n + m + i;
			vallist[NZc] = job_array[j].gpu;
			collist[NZc++] = n * (m + 2) + j * m + i;
			/*debug3("con3 collist %d",n * (m + 2) + j * m + i);*/
		}
	}
	/* nzc = 3*m*n+n */

	status = CPXchgcoeflist (env, lp, NZc, rowlist, collist, vallist);   
	if ( status )  goto TERMINATE;

TERMINATE:
	free_and_null ((char **) &obj);
	free_and_null ((char **) &lb);
	free_and_null ((char **) &ub);
	free_and_null ((char **) &rhs);
	free_and_null ((char **) &sense);
	return (status);
} 
예제 #10
0
void PartitionedColoringModel::addVariables() {
	int status;
	double *upperBound, *lowerBound, *targetFunctionCoefficients;
	char *variableTypes, **variableNames;
	
	int amountOfNodes = this->graph->amountOfNodes();
	this->amountOfVariables = (amountOfNodes * amountOfNodes) + amountOfNodes;
	
	upperBound = new double[this->amountOfVariables]; 
	lowerBound = new double[this->amountOfVariables];
	targetFunctionCoefficients = new double[this->amountOfVariables];
	variableTypes = new char[this->amountOfVariables];
	variableNames = new char*[this->amountOfVariables];
  
	for(int variableNumber = 0; variableNumber < this->amountOfVariables; variableNumber++) {
		upperBound[variableNumber] = CPX_INFBOUND;
		lowerBound[variableNumber] = 0.0;
		
		if(this->variablePositionIsW(variableNumber)) {
			targetFunctionCoefficients[variableNumber] = 1.0;
		} else {
			targetFunctionCoefficients[variableNumber] = 0.0;
		}
		
		// Las seteo continuas, luego las convierto a integer cuando corresponda dependiendo del algoritmo
		variableTypes[variableNumber] = 'C';	
		variableNames[variableNumber] = new char[10];
		
		if(this->variablePositionIsW(variableNumber)) {
			sprintf(variableNames[variableNumber], "w_%d", this->wModelIndexFromVariablePosition(variableNumber));
		} else {
			int nodeNumber = this->xIModelIndexFromVariablePosition(variableNumber);
			int colorNumber = this->xJModelIndexFromVariablePosition(variableNumber);
			sprintf(variableNames[variableNumber], "x_%d_%d", nodeNumber, colorNumber);
		}
	}
  
	status = CPXnewcols(this->cplexEnvironment,
						this->linearProblem,
						this->amountOfVariables,
						targetFunctionCoefficients,
						lowerBound,
						upperBound,
						variableTypes,
						variableNames);

	if(status) {
		cerr << "Problema agregando las variables CPXnewcols" << endl;
		exit(1);
	}
	
	for(int i = 0; i < this->amountOfVariables; i++) {
		delete[] variableNames[i];
	}

	delete[] upperBound;
	delete[] lowerBound;
	delete[] targetFunctionCoefficients;
	delete[] variableTypes;
	delete[] variableNames;
}
예제 #11
0
void
DDSIP_DetEqu ()
{
    CPXLPptr det_equ;

    int status, scen, i, j, k, nzcnt_row, ranged = 0;
    char probname[] = "sipout/det_equ.lp.gz";
    double *scaled_obj_coef = NULL;
    char *sense = NULL, *sense_sorted = NULL;
    char **scen_spec_rowname = NULL;
    char **scen_spec_colname = NULL;
    char **rowname = NULL, *rownamestore = NULL;
    char **colname = NULL, *colnamestore = NULL;
    int rowstorespace, rowsurplus;
    int colstorespace, colsurplus;
    char *string1 = NULL, *string2 = NULL;
    double *lb = NULL, *lb_sorted = NULL;
    double *ub = NULL, *ub_sorted = NULL;
    double *rng = NULL, *rng_sorted = NULL;
    char *vartype = NULL, *vartype_sorted = NULL;
    int *colindex_sorted = NULL, *colindex_revers = NULL;
    double *value = NULL;
    double *det_equ_rhs = NULL;
    double *base_rhs = NULL;
    int nzcnt=0, *rmatbeg=NULL, *rmatind=NULL, *rmatbeg_stage=NULL, *rmatind_stage=NULL, *rowindex=NULL;
    double *rmatval=NULL, *rmatval_stage=NULL;
    double time_start, time_end;
    time_start = DDSIP_GetCpuTime ();
    k = abs(DDSIP_param->riskmod);
    if (k > 2 && k != 4)
    {
        fprintf (stderr,
             "\nNot building deterministic equivalent, not available for risk model %d\n",DDSIP_param->riskmod);
        fprintf (DDSIP_outfile,
             "\nNot building deterministic equivalent, not available for risk model %d\n",DDSIP_param->riskmod);
        return;
    }
    if (DDSIP_data->seccon)
        det_equ_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_Imax(DDSIP_Imax(DDSIP_data->seccon, DDSIP_param->scenarios), DDSIP_data->firstcon),"det_equ_rhs(DetEqu)");
    else
    {
        fprintf (stderr,"XXX ERROR: no second stage contraints, got DDSIP_data->seccon=%d.\n",DDSIP_data->seccon);
        return;
    }

    fprintf (stderr,
             "\nBuilding deterministic equivalent.\nWorks only for expectation-based models.\n");

    colstorespace = DDSIP_data->novar * 255;
    rowstorespace = DDSIP_data->nocon * 255;
    if (!(sense = (char *) DDSIP_Alloc (sizeof (char), DDSIP_data->nocon, "sense(DetEqu)")) ||
        !(sense_sorted = (char *) DDSIP_Alloc (sizeof (char), DDSIP_Imax(DDSIP_param->scenarios, DDSIP_Imax(DDSIP_data->firstcon,DDSIP_data->seccon)), "sense_sorted(DetEqu)")) ||
        !(base_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_data->nocon,"base_rhs(DetEqu)")) ||
        !(scaled_obj_coef = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar, DDSIP_data->secvar), "base_rhs(DetEqu)")) ||
        !(colname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_data->novar,"base_rhs(DetEqu)")) ||
        !(scen_spec_colname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "scen_spec_colname(DetEqu)")) ||
        !(colnamestore = (char *) DDSIP_Alloc (sizeof (char), colstorespace, "colnamestore(DetEqu)")) ||
        !(rowname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_data->nocon, "rowname(DetrEqu)")) ||
        !(scen_spec_rowname = (char **) DDSIP_Alloc (sizeof (char *), DDSIP_Imax(DDSIP_param->scenarios, DDSIP_Imax(DDSIP_data->firstcon,DDSIP_data->seccon)), "scen_spec_rowname(DetEqu)")) ||
        !(rownamestore = (char *) DDSIP_Alloc (sizeof (char), rowstorespace, "rownamestore(DetEqu)")) ||
        !(lb = (double *) DDSIP_Alloc (sizeof (double), DDSIP_data->novar, "lb(DetEqu)")) ||
        !(lb_sorted = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "lb_sorted(DetEqu)")) ||
        !(ub = (double *) DDSIP_Alloc (sizeof (double), DDSIP_data->novar, "ub(DetEqu)")) ||
        !(ub_sorted = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "ub_sorted(DetEqu)")) ||
        !(vartype = (char *) DDSIP_Alloc (sizeof (char), DDSIP_data->novar, "vartype(DetEqu)")) ||
        !(vartype_sorted = (char *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstvar,DDSIP_data->secvar), "vartype_sorted(DetEqu)")) ||
        !(colindex_sorted = (int *) DDSIP_Alloc (sizeof (int), DDSIP_data->novar, "colindex_sorted(DetEqu)")) ||
        !(rowindex = (int *) DDSIP_Alloc (sizeof (int), DDSIP_Imax(DDSIP_data->firstcon, DDSIP_data->seccon), "rowindex(DetEqu)")))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }

    // get problem data
    /*____________________________________________________________________________________*/
    if((status = CPXgetcolname (DDSIP_env, DDSIP_lp, colname, colnamestore,
                            colstorespace, &colsurplus, 0, DDSIP_data->novar - 1)) ||
       (status = CPXgetrowname (DDSIP_env, DDSIP_lp, rowname, rownamestore,
                            rowstorespace, &rowsurplus, 0, DDSIP_data->nocon - 1)) ||
       (status = CPXgetsense (DDSIP_env, DDSIP_lp, sense, 0, DDSIP_data->nocon - 1)) ||
       (status = CPXgetrhs (DDSIP_env, DDSIP_lp, base_rhs, 0, DDSIP_data->nocon - 1)) ||
       (status = CPXgetlb (DDSIP_env, DDSIP_lp, lb, 0, DDSIP_data->novar - 1)) ||
       (status = CPXgetub (DDSIP_env, DDSIP_lp, ub, 0, DDSIP_data->novar - 1)) ||
       (status = CPXgetctype (DDSIP_env, DDSIP_lp, vartype, 0, DDSIP_data->novar - 1)))
    {
        fprintf (stderr, "Coud not get problem data, returned %d\n", status);
        goto FREE;
    }
    // check whether there are ranged rows
    for (j=0; j<DDSIP_data->nocon; j++)
    {
        if (sense[j] == 'R')
        {
            ranged = 1;
	    break;
        }
    } 
    if (ranged)
    {
        if (!(rng = (double *) DDSIP_Alloc (sizeof (double), DDSIP_data->nocon, "rng(DetEqu)")) ||
            !(rng_sorted = (double *) DDSIP_Alloc (sizeof (double), DDSIP_Imax(DDSIP_data->firstcon,DDSIP_data->seccon), "rng_sorted(DetEqu)")))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        if ((status = CPXgetrngval (DDSIP_env, DDSIP_lp, rng, 0, DDSIP_data->nocon-1)))
        {
            fprintf (stderr, "Coud not get problem ranges, returned %d\n", status);
            goto FREE;
        }
    }
    /*____________________________________________________________________________________*/

    // create empty problem
    det_equ = CPXcreateprob (DDSIP_env, &status, probname);
    if (status)
    {
        fprintf (stderr, "CPXcreateprob returned %d\n", status);
        goto FREE;
    }
    // add (original) first-stage variables
    for (j = 0; j < DDSIP_data->firstvar; j++)
    {
        vartype_sorted[j]   = vartype[DDSIP_bb->firstindex[j]];
        lb_sorted[j]        = lb[DDSIP_bb->firstindex[j]];
        ub_sorted[j]        = ub[DDSIP_bb->firstindex[j]];
        if (DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
            scaled_obj_coef[j]  = DDSIP_data->obj_coef[DDSIP_bb->firstindex[j]];
        scen_spec_colname[j]= colname[DDSIP_bb->firstindex[j]];
    }
    if ((status = CPXnewcols (DDSIP_env, det_equ, DDSIP_data->firstvar, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
    {
        fprintf (stderr, "CPXnewcols returned %d for first-stage variables\n", status);
        goto FREE;
    }
    // add (original) second-stage variables for all scenarios
    for (j = 0; j < DDSIP_data->secvar; j++)
    {
        vartype_sorted[j] = vartype[DDSIP_bb->secondindex[j]];
        lb_sorted[j]      = lb[DDSIP_bb->secondindex[j]];
        ub_sorted[j]      = ub[DDSIP_bb->secondindex[j]];
    }
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        for (j = 0; j < DDSIP_data->secvar; j++)
        {
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                goto FREE;
            }
            // append scenario index to colname
            string1 = colname[DDSIP_bb->secondindex[j]];
            sprintf (string2, "%sSC%.3d", string1, scen+1);
            scen_spec_colname[j] = string2;
            if (DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
                scaled_obj_coef[j] = DDSIP_data->prob[scen] * DDSIP_data->obj_coef[DDSIP_bb->secondindex[j]];
        }
        if ((status = CPXnewcols (DDSIP_env, det_equ, DDSIP_data->secvar, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
        {
            fprintf (stderr, "CPXnewcols returned %d for second-stage variables of scenario %d\n", status, scen+1);
            goto FREE;
        }
        for (j = 0; j < DDSIP_data->secvar; j++)
            DDSIP_Free ((void **) &(scen_spec_colname[j]));
    }
    // add second-stage variable for objective value of the scenarios
    if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }
    scen_spec_colname[0] = string2;
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        vartype_sorted[0] = 'C';
        lb_sorted[0]      = -DDSIP_infty;
        ub_sorted[0]      =  DDSIP_infty;
        sprintf (string2, "DDSIPobj_SC%.3d", scen+1);
        if (!DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
            scaled_obj_coef[0] = DDSIP_data->prob[scen];
        else
            scaled_obj_coef[0] = 0.;
        if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
        {
            fprintf (stderr, "CPXnewcols returned %d for second-stage variable  DDSIPobj_SC%.3d\n", status, scen+1);
            goto FREE;
        }
    }
    // add the additional variables needed for risk models ///////////////////////////////////////
    if (DDSIP_param->riskmod)
    {
        switch (abs(DDSIP_param->riskmod))
        {
          case 1:  // Expected excess
             // one continuous second-stage variable for each scenario
             for (scen = 0; scen < DDSIP_param->scenarios; scen++)
             {
                vartype_sorted[0] = 'C';
                lb_sorted[0]      = 0.;
                ub_sorted[0]      = DDSIP_infty;
                sprintf (string2, "DDSIP_expexc_SC%.3d", scen+1);
                if (DDSIP_param->riskmod > 0)
                    scaled_obj_coef[0] = DDSIP_param->riskweight*DDSIP_data->prob[scen];
                else if (DDSIP_param->riskmod < 0)
                    scaled_obj_coef[0] = DDSIP_data->prob[scen];
                else
                    scaled_obj_coef[0] = 0.;
                if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                                lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
                {
                    fprintf (stderr, "CPXnewcols returned %d for second-stage variable  %s\n", status, string2);
                    goto FREE;
                }
             }  
             break;
          case 2:  // Excess Probability
             // one binary second-stage variable for each scenario
             for (scen = 0; scen < DDSIP_param->scenarios; scen++)
             {
                vartype_sorted[0] = 'B';
                lb_sorted[0]      = 0.;
                ub_sorted[0]      = 1.;
                sprintf (string2, "DDSIP_excprob_SC%.3d", scen+1);
                if (DDSIP_param->riskmod > 0)
                    scaled_obj_coef[0] = DDSIP_param->riskweight*DDSIP_data->prob[scen];
                else if (DDSIP_param->riskmod < 0)
                    scaled_obj_coef[0] = DDSIP_data->prob[scen];
                else
                    scaled_obj_coef[0] = 0.;
                if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                                lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
                {
                    fprintf (stderr, "CPXnewcols returned %d for second-stage variable  %s\n", status, string2);
                    goto FREE;
                }
             }  
             break;
          case 4:  // Worst Case Costs
             // one continuous first-stage variable
                vartype_sorted[0] = 'C';
                lb_sorted[0]      = -DDSIP_infty;
                ub_sorted[0]      =  DDSIP_infty;
                if (DDSIP_param->prefix)
                {
                    if (!(strlen(DDSIP_param->prefix)))
                    {
                        fprintf (stderr," *** ERROR: The prefix for the first stage variables has to have a positive length.\n");
                        exit (1);
                    }
                    sprintf (string2, "%sDDSIP_n_aux01",DDSIP_param->prefix);
                }
                else
                {
                    if (!(strlen(DDSIP_param->postfix)))
                    {
                        fprintf (stderr," *** ERROR: The postfix for the first stage variables has to have a positive length.\n");
                        exit (1);
                    }
                    sprintf (string2, "DDSIP_worstc_%s",DDSIP_param->postfix);
                }
                if (DDSIP_param->riskmod > 0)
                    scaled_obj_coef[0] = DDSIP_param->riskweight;
                else if (DDSIP_param->riskmod < 0)
                    scaled_obj_coef[0] = 1.;
                else
                    scaled_obj_coef[0] = 0.;
                if ((status = CPXnewcols (DDSIP_env, det_equ, 1, scaled_obj_coef,
                                lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname)))
                {
                    fprintf (stderr, "CPXnewcols returned %d for second-stage variable  %s\n", status, string2);
                    goto FREE;
                }
        }
    }
    DDSIP_Free ((void **) &(scen_spec_colname[0]));
        
    ///////enter stochastic cost coefficients in case of deteqType 1 //////////////////////////////
    if (DDSIP_param->stoccost && DDSIP_param->deteqType && DDSIP_param->riskmod >= 0)
    {
        for (j = 0; j < DDSIP_param->stoccost; j++)
        {
            scaled_obj_coef[j] = 0.0;
            if ((colindex_sorted[j] = DDSIP_bb->firstindex_reverse[DDSIP_data->costind[j]]))
                 colindex_sorted[j] = DDSIP_data->firstvar + DDSIP_bb->secondindex_reverse[DDSIP_data->costind[j]];
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    scaled_obj_coef[j] = DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
                else
                    scaled_obj_coef[j] += DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
            }
            status = CPXchgobj (DDSIP_env, det_equ, DDSIP_param->stoccost, colindex_sorted, scaled_obj_coef);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu: %s\n", errmsg);
            }
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    colindex_sorted[j] += DDSIP_data->secvar;
            }
        }
    }
    //
    // free arrays needeed only for columns
    DDSIP_Free ((void **) &(vartype));
    DDSIP_Free ((void **) &(colname));
    DDSIP_Free ((void **) &(colnamestore));
    DDSIP_Free ((void **) &(lb));
    DDSIP_Free ((void **) &(ub));
    DDSIP_Free ((void **) &(vartype_sorted));
    DDSIP_Free ((void **) &(lb_sorted));
    DDSIP_Free ((void **) &(ub_sorted));
    DDSIP_Free ((void **) &(scaled_obj_coef));
    //
    // get problem matrix coefficients
    // query the length needed for storage of coefficients
    CPXgetrows(DDSIP_env, DDSIP_lp, &nzcnt, rmatbeg, rmatind, rmatval, 0, &rowsurplus, 0, DDSIP_data->nocon-1);
    nzcnt = -rowsurplus;
    if (!(rmatbeg = (int *) DDSIP_Alloc (sizeof (int), DDSIP_data->nocon, "rmatbeg(DetEqu)")) ||
        !(rmatind = (int *) DDSIP_Alloc (sizeof (int), DDSIP_Imax(nzcnt, DDSIP_param->stocmat), "rmatind(DetEqu)")) ||
        !(rmatval = (double *) DDSIP_Alloc (sizeof (double), nzcnt, "rmatval(DetEqu)")))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }
    CPXgetrows(DDSIP_env, DDSIP_lp, &nzcnt, rmatbeg, rmatind, rmatval, nzcnt, &rowsurplus, 0, DDSIP_data->nocon-1);

    printf(" got %d elements of the matrix\n", nzcnt);

    k = DDSIP_Imax(nzcnt + DDSIP_param->stocmat, DDSIP_param->scenarios*(DDSIP_data->novar+1));
    if (!(rmatbeg_stage = (int *) DDSIP_Alloc (sizeof (int), DDSIP_Imax(DDSIP_param->scenarios, DDSIP_Imax(DDSIP_data->firstcon, DDSIP_data->seccon)), "rmatbeg_stage(DetEqu)")) ||
        !(rmatind_stage = (int *) DDSIP_Alloc (sizeof (int), k, "rmatind_stage(DetEqu)")) ||
        !(rmatval_stage = (double *) DDSIP_Alloc (sizeof (double), k, "rmatval_stage(DetEqu)")))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        goto FREE;
    }

    // add first-stage constraints
    k = 0;
    for (j = 0; j < DDSIP_data->firstcon; j++)
    {
        sense_sorted[j] = sense[DDSIP_bb->firstrowind[j]];
        det_equ_rhs[j] = base_rhs[DDSIP_bb->firstrowind[j]];
        scen_spec_rowname[j] = rowname[DDSIP_bb->firstrowind[j]];
	rmatbeg_stage[j] = k;
	if (DDSIP_bb->firstrowind[j] == DDSIP_data->nocon -1)
            nzcnt_row = nzcnt - rmatbeg[DDSIP_data->nocon -1];
        else
            nzcnt_row = rmatbeg[DDSIP_bb->firstrowind[j]+1] - rmatbeg[DDSIP_bb->firstrowind[j]];
	for (i = 0; i < nzcnt_row; i++)
        {
            rmatind_stage[k + i] = DDSIP_bb->firstindex_reverse[rmatind[rmatbeg[DDSIP_bb->firstrowind[j]] + i]];
            rmatval_stage[k + i] = rmatval[rmatbeg[DDSIP_bb->firstrowind[j]] + i];
        }
	k += nzcnt_row;
    }
    if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_data->firstcon, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
    {
        fprintf (stderr, "CPXaddrows returned %d for first-stage constraints\n", status);
        goto FREE;
    }
    if (ranged)
    {
        for (j = 0; j < DDSIP_data->firstcon; j++)
        {
            rng_sorted[j] = rng[DDSIP_bb->firstrowind[j]];
            rowindex[j]   = j;
        }
        if((status = CPXchgrngval(DDSIP_env, det_equ, DDSIP_data->firstcon, rowindex, rng_sorted)))
        {
            fprintf (stderr, "CPXchgrngval returned %d for first-stage constraints\n", status);
            goto FREE;
        }
    }

    // add second-stage constraints
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        k = 0;
        for (j = 0; j < DDSIP_data->seccon; j++)
        {
            sense_sorted[j] = sense[DDSIP_bb->secondrowind[j]];
            det_equ_rhs[j] = base_rhs[DDSIP_bb->secondrowind[j]];
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                goto FREE;
            }
            // append scenario index to colname
            string1 = rowname[DDSIP_bb->secondrowind[j]];
            sprintf (string2, "%sSC%.3d", string1, scen+1);
            scen_spec_rowname[j] = string2;
            rmatbeg_stage[j] = k;
            if (DDSIP_bb->secondrowind[j] == DDSIP_data->nocon -1)
                nzcnt_row = nzcnt - rmatbeg[DDSIP_data->nocon -1];
            else
            {
                nzcnt_row = rmatbeg[DDSIP_bb->secondrowind[j]+1] - rmatbeg[DDSIP_bb->secondrowind[j]];

            }
            for (i = 0; i < nzcnt_row; i++)
            {
                if (DDSIP_bb->firstindex_reverse[rmatind[rmatbeg[DDSIP_bb->secondrowind[j]] + i]] < 0)
                    rmatind_stage[k + i] = DDSIP_data->firstvar + scen*DDSIP_data->secvar + DDSIP_bb->secondindex_reverse[rmatind[rmatbeg[DDSIP_bb->secondrowind[j]] + i]];
                else
                    rmatind_stage[k + i] = DDSIP_bb->firstindex_reverse[rmatind[rmatbeg[DDSIP_bb->secondrowind[j]] + i]];
                rmatval_stage[k + i] = rmatval[rmatbeg[DDSIP_bb->secondrowind[j]] + i];
            }
            k += nzcnt_row;
        }
        ///////enter stochastic rhs entries//////////////////////////////////////////////////////
        for (j=0; j< DDSIP_param->stocrhs; j++)
        {
            det_equ_rhs[DDSIP_bb->secondrowind_reverse[DDSIP_data->rhsind[j]]] = DDSIP_data->rhs[scen * DDSIP_param->stocrhs + j];
        }

        if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_data->seccon, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
        {
            fprintf (stderr, "CPXaddrows returned %d for second-stage constraints scenario %d\n", status, scen+1);
            goto FREE;
        }
        for (j = 0; j < DDSIP_data->seccon; j++)
            DDSIP_Free ((void **) &(scen_spec_rowname[j]));
        if (ranged)
        {
            for (j = 0; j < DDSIP_data->seccon; j++)
            {
                rng_sorted[j] = rng[DDSIP_bb->secondrowind[j]];
                rowindex[j]   = DDSIP_data->firstcon + scen * DDSIP_data->seccon + j;
            }
            if ((status = CPXchgrngval(DDSIP_env, det_equ, DDSIP_data->seccon, rowindex, rng_sorted)))
            {
                fprintf (stderr, "CPXchgrngval returned %d for first-stage constraints\n", status);
                goto FREE;
            }
        }
    }
    ///////enter stochastic matrix entries//////////////////////////////////////////////////////
    if (DDSIP_param->stocmat)
    {

        if (!(value = (double *) calloc (DDSIP_param->stocmat, sizeof (double))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        for (j = 0; j < DDSIP_param->stocmat; j++)
        {
            if ((colindex_sorted[j] = DDSIP_bb->firstindex_reverse[DDSIP_data->matcol[j]]))
                 colindex_sorted[j] = DDSIP_data->firstvar + DDSIP_bb->secondindex_reverse[DDSIP_data->matcol[j]];
            rmatind[j] = DDSIP_data->firstcon + DDSIP_bb->secondrowind_reverse[DDSIP_data->matrow[j]];
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                value[j] = DDSIP_data->matval[scen * DDSIP_param->stocmat + j];
            }
            status = CPXchgcoeflist (DDSIP_env, det_equ, DDSIP_param->stocmat, rmatind, colindex_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu chgcoeflist returned %d: %s\n", status, errmsg);
            }
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                rmatind[j] += DDSIP_data->seccon;
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    colindex_sorted[j] += DDSIP_data->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
    }

    // add second-stage equations for the objective values of the scenarios
    k = 0;
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        sense_sorted[scen] = 'E';
        det_equ_rhs[scen] = 0.;
        if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        sprintf (string2, "DDSIP_o_SC%.3d", scen+1);
        scen_spec_rowname[scen] = string2;
        rmatbeg_stage[scen] = k;
        nzcnt_row = DDSIP_data->novar + 1;
        for (i = 0; i < DDSIP_data->novar; i++)
        {
            if (DDSIP_bb->firstindex_reverse[i] < 0)
            {
                rmatind_stage[k + i] = DDSIP_data->firstvar + scen*DDSIP_data->secvar + DDSIP_bb->secondindex_reverse[i];
            }
            else
            {
                rmatind_stage[k + i] = DDSIP_bb->firstindex_reverse[i];
            }
            rmatval_stage[k + i] = DDSIP_data->obj_coef[i];
        }
        rmatind_stage[k + DDSIP_data->novar] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen;
        rmatval_stage[k + DDSIP_data->novar] = -1.;
        k += nzcnt_row;
    }
    if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
    {
        fprintf (stderr, "CPXaddrows returned %d for second-stage objective constraints\n", status);
        goto FREE;
    }
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        DDSIP_Free ((void **) &(scen_spec_rowname[scen]));
    }
    ///////enter stochastic cost coefficients in the objective equations //////////////////////////////
    if (DDSIP_param->stoccost)
    {
        if (!(value = (double *) calloc (DDSIP_param->stoccost, sizeof (double))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            goto FREE;
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if ((colindex_sorted[j] = DDSIP_bb->firstindex_reverse[DDSIP_data->costind[j]]) < 0)
                     colindex_sorted[j] = DDSIP_data->firstvar + scen * DDSIP_data->secvar +DDSIP_bb->secondindex_reverse[DDSIP_data->costind[j]];
                rmatind[j] = DDSIP_data->firstcon + DDSIP_param->scenarios*DDSIP_data->seccon + scen;
                value[j] = DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
            }
            status = CPXchgcoeflist (DDSIP_env, det_equ, DDSIP_param->stoccost, rmatind, colindex_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu chgcoeflist returned %d: %s\n", status, errmsg);
            }
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                rmatind[j] += DDSIP_data->seccon;
                if (colindex_sorted[j] >= DDSIP_data->firstvar)
                    colindex_sorted[j] += DDSIP_data->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
    }
    // add second-stage equations for the risk models //////////////////////////////////
    switch (abs(DDSIP_param->riskmod))
    {
      case 1:  // Expected excess
         k = 0;
         for (scen = 0; scen < DDSIP_param->scenarios; scen++)
         {
             sense_sorted[scen] = 'L';
             det_equ_rhs[scen]  = DDSIP_param->risktarget;
             if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
             {
                 fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                 goto FREE;
             }
             sprintf (string2, "DDSIP_exp_excess_SC%.3d", scen+1);
             scen_spec_rowname[scen] = string2;
             rmatbeg_stage[scen] = k;
             nzcnt_row = 2;
             rmatind_stage[k]     = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen; 
             rmatval_stage[k]     = 1.;
             rmatind_stage[k + 1] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + DDSIP_param->scenarios + scen; 
             rmatval_stage[k + 1] = -1.;
             k += nzcnt_row;
         }
         if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
         {
             fprintf (stderr, "CPXaddrows returned %d for second-stage risk constraints\n", status);
             goto FREE;
         }
         break;
      case 2:  // Excess probability
         k = 0;
         for (scen = 0; scen < DDSIP_param->scenarios; scen++)
         {
             sense_sorted[scen] = 'L';
             det_equ_rhs[scen]  = DDSIP_param->risktarget;
             if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
             {
                 fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                 goto FREE;
             }
             sprintf (string2, "DDSIP_excess_prob_SC%.3d", scen+1);
             scen_spec_rowname[scen] = string2;
             rmatbeg_stage[scen] = k;
             nzcnt_row = 2;
             rmatind_stage[k]     = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen; 
             rmatval_stage[k]     = 1.;
             rmatind_stage[k + 1] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + DDSIP_param->scenarios + scen; 
             rmatval_stage[k + 1] = -DDSIP_param->riskM;
             k += nzcnt_row;
         }
         if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
         {
             fprintf (stderr, "CPXaddrows returned %d for second-stage risk constraints\n", status);
             goto FREE;
         }
         break;
      case 4:  // Worst case cost
         k = 0;
         for (scen = 0; scen < DDSIP_param->scenarios; scen++)
         {
             sense_sorted[scen] = 'L';
             det_equ_rhs[scen]  = 0.;
             if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
             {
                 fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                 goto FREE;
             }
             sprintf (string2, "DDSIP_worst_case_SC%.3d", scen+1);
             scen_spec_rowname[scen] = string2;
             rmatbeg_stage[scen] = k;
             nzcnt_row = 2;
             rmatind_stage[k]     = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + scen; 
             rmatval_stage[k]     = 1.;
             rmatind_stage[k + 1] = DDSIP_data->firstvar + DDSIP_param->scenarios*DDSIP_data->secvar + DDSIP_param->scenarios; 
             rmatval_stage[k + 1] = -1.;
             k += nzcnt_row;
         }
         if ((status = CPXaddrows(DDSIP_env, det_equ, 0, DDSIP_param->scenarios, k, det_equ_rhs, sense_sorted, rmatbeg_stage, rmatind_stage, rmatval_stage, NULL, scen_spec_rowname)))
         {
             fprintf (stderr, "CPXaddrows returned %d for second-stage risk constraints\n", status);
             goto FREE;
         }
         break;
    }
    for (j = 0; j < DDSIP_param->scenarios; j++)
        DDSIP_Free ((void **) &(scen_spec_rowname[j]));

    time_end = DDSIP_GetCpuTime ();
    fprintf (DDSIP_outfile, " %6.2f sec  for building deterministic equivalent\n",time_end-time_start);

    status = CPXwriteprob (DDSIP_env, det_equ, probname, NULL);
    if (status)
    {
        fprintf (DDSIP_outfile, " *** Deterministic equivalent not written successfully, status = %d\n", status);
        printf  (" *** Deterministic equivalent not written successfully, status = %d\n", status);
    }
    else
    {
        fprintf (DDSIP_outfile, " *** Deterministic equivalent %s written successfully\n", probname);
        printf  (" *** Deterministic equivalent %s written successfully\n", probname);
    }
    status = CPXfreeprob (DDSIP_env, &det_equ);
    time_start = DDSIP_GetCpuTime ();
    fprintf (DDSIP_outfile, " %6.2f sec  for writing deterministic equivalent\n",time_start-time_end);

FREE:
    DDSIP_Free ((void **) &(sense));
    DDSIP_Free ((void **) &(sense_sorted));
    DDSIP_Free ((void **) &(vartype));
    DDSIP_Free ((void **) &(rowname));
    DDSIP_Free ((void **) &(rownamestore));
    DDSIP_Free ((void **) &(colname));
    DDSIP_Free ((void **) &(colnamestore));
    DDSIP_Free ((void **) &(det_equ_rhs));
    DDSIP_Free ((void **) &(base_rhs));
    DDSIP_Free ((void **) &(lb));
    DDSIP_Free ((void **) &(ub));
    DDSIP_Free ((void **) &(vartype_sorted));
    DDSIP_Free ((void **) &(lb_sorted));
    DDSIP_Free ((void **) &(ub_sorted));
    DDSIP_Free ((void **) &(scaled_obj_coef));
    DDSIP_Free ((void **) &(colindex_sorted));
    DDSIP_Free ((void **) &(colindex_revers));
    DDSIP_Free ((void **) &(scen_spec_rowname));
    DDSIP_Free ((void **) &(scen_spec_colname));
    DDSIP_Free ((void **) &(rmatbeg));
    DDSIP_Free ((void **) &(rmatind));
    DDSIP_Free ((void **) &(rmatval));
    DDSIP_Free ((void **) &(rmatbeg_stage));
    DDSIP_Free ((void **) &(rmatind_stage));
    DDSIP_Free ((void **) &(rmatval_stage));
    DDSIP_Free ((void **) &(rowindex));
    if (ranged)
    {
        DDSIP_Free ((void **) &(rng));
        DDSIP_Free ((void **) &(rng_sorted));
    }
    return;
}
예제 #12
0
long GenModelCplex::CreateModel()
{
    if(!binit)
        return ThrowError("CreateModel() not available : Problem not initialized yet");
    CplexData* d = (CplexData*)solverdata;
    int status = 0;
    d->nc = nc;
    d->nc = nc;
    d->onc = nc;
    d->onr = nr;

    if(boolParam.count("maximize") > 0 && boolParam["maximize"])
        CPXchgobjsen (d->env, d->lp, CPX_MAX);
    else
        CPXchgobjsen (d->env, d->lp, CPX_MIN);
    d->lrhs = new double[nr];
    d->urhs = new double[nr];
    d->sense = new char[nr];
    d->ub = new double[nc];
    d->lb = new double[nc];
    d->obj = new double[nc];
    d->type = new char[nc];
    d->mat_r = new int[nz];
    d->mat_c = new int[nz];
    d->mat_v = new double[nz];
    d->cname = new char*[nc];
    d->rname = new char*[nr];


    nz=0;
    for(unsigned long i = 0; i < nr; i++)
    {
        d->rname[i] = new char[consts[i].name.length()+1];
        snprintf(d->rname[i], consts[i].name.length()+1, "%s", consts[i].name.c_str());
        //printf("%ld %s: ", i, consts[i].name.c_str());
        for(unsigned long j = 0; j < consts[i].nz; j++)
        {
            d->mat_r[nz] = i;
            d->mat_c[nz] = consts[i].cols[j];
            d->mat_v[nz] = consts[i].coefs[j];
            //if(i >= 198)
                //printf("(%ld,%ld(%s),%f) ", d->mat_r[nz], d->mat_c[nz], vars.name[d->mat_c[nz]].c_str(), d->mat_v[nz]);
            nz++;
        }

        if(consts[i].lrhs == numeric_limits<double>::infinity())
            d->lrhs[i] = CPX_INFBOUND;
        else if(consts[i].lrhs == -numeric_limits<double>::infinity())
            d->lrhs[i] = -CPX_INFBOUND;
        else
            d->lrhs[i] = consts[i].lrhs;
        if(consts[i].urhs == numeric_limits<double>::infinity())
            d->urhs[i] = CPX_INFBOUND;
        else if(consts[i].urhs == -numeric_limits<double>::infinity())
            d->urhs[i] = -CPX_INFBOUND;
        else
            d->urhs[i] = consts[i].urhs-consts[i].lrhs;
        d->sense[i] = consts[i].sense;
    //	printf("%ld/%ld -> %c\n", i, nr, d->sense[i]);
    }
    for(unsigned long i = 0; i < nc; i++)
    {
        d->cname[i] = new char[vars.name[i].length()+1];
        snprintf(d->cname[i], vars.name[i].length()+1, "%s", vars.name[i].c_str());
        d->obj[i] = vars.obj[i];
        if(vars.ub[i] == numeric_limits<double>::infinity())
            d->ub[i] = CPX_INFBOUND;
        else if(vars.ub[i] == -numeric_limits<double>::infinity())
            d->ub[i] = -CPX_INFBOUND;
        else
            d->ub[i] = vars.ub[i];
        if(vars.lb[i] == numeric_limits<double>::infinity())
            d->lb[i] = CPX_INFBOUND;
        else if(vars.lb[i] == -numeric_limits<double>::infinity())
            d->lb[i] = -CPX_INFBOUND;
        else
            d->lb[i] = vars.lb[i];
        d->type[i] = vars.type[i];

        //printf("%ld (%s) -> %f %f %f %c\n", i, vars.name[i].c_str(), d->obj[i], d->lb[i], d->ub[i], d->type[i]);
    }
    status = CPXnewrows (d->env, d->lp, nr, d->lrhs, d->sense, d->urhs, d->rname);
    if ( status )
    {
        char  errmsg[1024];
        fprintf (stderr, "Could not create new rows.\n");
        CPXgeterrorstring (d->env, status, errmsg);
        fprintf (stderr, "%s", errmsg);
        return 1;
    }
    //else
        //printf("Row added!\n");

    if(boolParam.count("mip") > 0 && boolParam["mip"])
        status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, d->type, d->cname);
    else
        status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, NULL, NULL);
    if ( status )
    {
        char  errmsg[1024];
        fprintf (stderr, "Could not create new cols.\n");
        CPXgeterrorstring (d->env, status, errmsg);
        fprintf (stderr, "%s", errmsg);
        return 1;
    }
    //status = CPXnewcols (env, lp, nc, obj, lb, ub, NULL, colname);
    if ( status )
        return 1;
    //else
        //printf("Col added!\n");
    status = CPXchgcoeflist (d->env, d->lp, nz, d->mat_r, d->mat_c, d->mat_v);
    if ( status )
        return 1;

    vector<long>::iterator iti;
    vector<long>::iterator itj = vars.qj.begin();
    vector<double>::iterator itv = vars.qobj.begin();

    vector<vector<pair<int,double> > > qptemp;
    qptemp.resize(nc);
    int* qpbeg = NULL;
    int* qpnum = NULL;
    int* qpind = NULL;
    double* qpv = NULL;
    int qpnz = 0;

    if(!vars.qi.empty())
    {
        boolParam["qp"] = true;
        qpbeg = new int[nc];
        qpnum = new int[nc];
    }
    if(boolParam.count("qp_mat") == 0 || boolParam["qp_mat"])
    {
        for(iti = vars.qi.begin(); iti != vars.qi.end(); iti++, itj++, itv++)
        {
            qptemp[*iti].push_back(pair<int, double>(*itj,*itv));
            qpnz++;
            if(*iti != *itj)
            {
                qptemp[*itj].push_back(pair<int, double>(*iti,*itv));
                qpnz++;
            }
        }
        if(!vars.qi.empty())
        {
            qpv = new double[qpnz];
            qpind = new int[qpnz];
            
            qpnz=0;
            for(int i = 0; i < int(nc); i++)
            {
                qpbeg[i] = qpnz;
                qpnum[i] = int(qptemp[i].size());
                for(int j = 0; j < int(qptemp[i].size()); j++)
                {
                    qpind[qpnz] = qptemp[i][j].first;
                    qpv[qpnz] = 2.0*qptemp[i][j].second;
                    qpnz++;
                }
            }
            status = CPXcopyquad(d->env, d->lp, qpbeg, qpnum, qpind, qpv);
            delete[] qpbeg;
            delete[] qpnum;
            delete[] qpind;
            delete[] qpv;
        }
        if ( status )
        {
            printf("QP problem!\n");
            return 1;
        }
    }
    //else
        //printf("Coefs added!\n");
    bcreated = true;

    return 0;
}
예제 #13
0
void IPBuild()
{
 int status;
 char *pVarType;
 double *pdLB, *pdUB, *pdObj, *pdrhs, *pdVal;
 unsigned int NbPyr=PYRGetNumbers(),TotJob=0, *puiBeg, *puiInd,uiJob,NbJobBefore;
 unsigned int uiLoop,uiLoop2,uiLoop3,uiIndice;

 // Initialize and configure the IP environment
 IPInitialize();

 // We now create the model
 //strcpy (probname, "1riLmax");
 lp = CPXcreateprob (env, &status, "");
 if ( lp == NULL ) {
      printf ("Failed to create LP.\n");
	  getch();
	  exit(-1);
 }
 // We create the variables
 printf("\t Variable creation\n");
 pVarName=(char **)malloc(sizeof(char *)*(1+2*NbPyr+2*NbPyr*(NbJobs-NbPyr)));
 for (uiLoop=0;uiLoop<(1+2*NbPyr+2*NbPyr*(NbJobs-NbPyr));uiLoop++)
	 pVarName[uiLoop]=(char *)malloc(sizeof(char)*700);
 pVarType=(char *)malloc(sizeof(char )*(1+2*NbPyr+2*NbPyr*(NbJobs-NbPyr)));
 pdLB=(double *)malloc(sizeof(double)*(1+2*NbPyr+2*NbPyr*(NbJobs-NbPyr)));
 pdUB=(double *)malloc(sizeof(double)*(1+2*NbPyr+2*NbPyr*(NbJobs-NbPyr)));
 pdObj=(double *)malloc(sizeof(double)*(1+2*NbPyr+2*NbPyr*(NbJobs-NbPyr)));
 strcpy(pVarName[0],"Lmax");
 pVarType[0]='C';
 pdLB[0]=-INFTY;
 pdUB[0]=INFTY;
 pdObj[0]=1;
 for (uiLoop=0;uiLoop<NbPyr;uiLoop++)
 {
	 char cBuf[10000];
	 strcpy(pVarName[1+2*uiLoop],"R");
	 sprintf(cBuf,"%d",uiLoop);
	 strcat(pVarName[1+2*uiLoop],cBuf);
	 pVarType[1+2*uiLoop]='C';
	 pdLB[1+2*uiLoop]=(double)ri(PYRGetTopJob(uiLoop));
	 pdUB[1+2*uiLoop]=INFTY;
	 pdObj[1+2*uiLoop]=0;
	 strcpy(pVarName[1+2*uiLoop+1],"D");
	 sprintf(cBuf,"%d",uiLoop);
	 strcat(pVarName[1+2*uiLoop+1],cBuf);
	 pVarType[1+2*uiLoop+1]='C';
	 pdLB[1+2*uiLoop+1]=-INFTY;
	 pdUB[1+2*uiLoop+1]=(double)di(PYRGetTopJob(uiLoop));
	 pdObj[1+2*uiLoop+1]=0;
 }
 TotJob=0;
 for (uiLoop=0;uiLoop<NbPyr;uiLoop++)
 {
	 for (uiLoop2=0;uiLoop2<PYRGetNumberJobs(uiLoop);uiLoop2++)
     {
	    char cBuf[10000];
	    strcpy(pVarName[1+2*NbPyr+TotJob+2*uiLoop2],"xm");
	    sprintf(cBuf,"%d,%d",uiLoop,PYRGetJobsInPyr(uiLoop,uiLoop2));
	    strcat(pVarName[1+2*NbPyr+TotJob+2*uiLoop2],cBuf);
		//printf("%s \n",pVarName[1+2*NbPyr+TotJob+2*uiLoop2]);
		pVarType[1+2*NbPyr+TotJob+2*uiLoop2]='B';
		pdLB[1+2*NbPyr+TotJob+2*uiLoop2]=-INFTY;
	    pdUB[1+2*NbPyr+TotJob+2*uiLoop2]=INFTY;
	    pdObj[1+2*NbPyr+TotJob+2*uiLoop2]=0;
	    strcpy(pVarName[1+2*NbPyr+TotJob+2*uiLoop2+1],"xp");
		sprintf(cBuf,"%d,%d",uiLoop,PYRGetJobsInPyr(uiLoop,uiLoop2));
	    strcat(pVarName[1+2*NbPyr+TotJob+2*uiLoop2+1],cBuf);
		//printf("%s \n",pVarName[1+2*NbPyr+TotJob+2*uiLoop2+1]);
		pVarType[1+2*NbPyr+TotJob+2*uiLoop2+1]='B';
		pdLB[1+2*NbPyr+TotJob+2*uiLoop2+1]=-INFTY;
	    pdUB[1+2*NbPyr+TotJob+2*uiLoop2+1]=INFTY;
	    pdObj[1+2*NbPyr+TotJob+2*uiLoop2+1]=0;
     }
     TotJob+=2*PYRGetNumberJobs(uiLoop);
 }
 
 uiNbVar=1+2*NbPyr+TotJob;

 status = CPXnewcols (env, lp, uiNbVar, pdObj, pdLB, pdUB, pVarType, pVarName);

 // We now create constraints
 // First: Lmax>=Rk+ptk-Dk, forall k=1..NbPyr
 printf("\t Creating constraints 1\n");
 pdrhs=(double *)malloc(sizeof(double)*1);
 puiBeg=(unsigned int *)malloc(sizeof(unsigned int)*1);
 puiBeg[0]=0;
 puiInd=(unsigned int *)malloc(sizeof(unsigned int)*3);
 pdVal=(double *)malloc(sizeof(double)*3);
 for (uiLoop=0;uiLoop<NbPyr;uiLoop++)
 {
   puiInd[0]=0;
   pdVal[0]=-1.0;
   puiInd[1]=1+2*uiLoop;
   pdVal[1]=1.0;
   puiInd[2]=1+2*uiLoop+1;
   pdVal[2]=-1.0;
   pdrhs[0]=-1.0*(double)pi(PYRGetTopJob(uiLoop));
   status = CPXaddrows (env, lp, 0, 1, 3, pdrhs, "L", (const int *)puiBeg, (const int*)puiInd, (const double *)pdVal, NULL, NULL);
 }
 free(pdrhs);
 free(puiBeg);
 free(puiInd);
 free(pdVal);
 // Second: Rk>=ri+sum pjxpkj, forall i|k=U(i)
 printf("\t Creating constraints 2\n");
 pdrhs=(double *)malloc(sizeof(double)*1);
 puiBeg=(unsigned int *)malloc(sizeof(unsigned int)*1);
 puiBeg[0]=0;
 NbJobBefore=0;
 for(uiLoop=0;uiLoop<NbPyr;uiLoop++)
 {
  puiInd=(unsigned int *)malloc(sizeof(unsigned int)*(1+PYRGetNumberJobs(uiLoop)));
  pdVal=(double *)malloc(sizeof(double)*(1+PYRGetNumberJobs(uiLoop)));
  for (uiLoop2=0;uiLoop2<NbJobs;uiLoop2++)
	  if (U[uiLoop2]==(signed int)uiLoop)
	  { // We add the constraint
		  puiInd[0]=1+2*uiLoop;
		  pdVal[0]=-1.0;
		  pdrhs[0]=-1.0*(double)ri(uiLoop2);
		  TotJob=0;
		  for (uiLoop3=0;uiLoop3<PYRGetNumberJobs(uiLoop);uiLoop3++)
		  {
			  uiJob=PYRGetJobsInPyr(uiLoop,uiLoop3);
			  if ((ri(uiJob)>ri(uiLoop2))||(ri(uiJob)==ri(uiLoop2) && di(uiJob)>di(uiLoop2))||(ri(uiJob)==ri(uiLoop2) && di(uiJob)==di(uiLoop2) && uiLoop2<=uiJob))
			  {
				  TotJob++;
				  puiInd[TotJob]=1+2*NbPyr+2*NbJobBefore+2*uiLoop3+1;
				  pdVal[TotJob]=(double)pi(uiJob);
			  }
		  }
          status = CPXaddrows (env, lp, 0, 1, 1+TotJob, pdrhs, "L", (const int *)puiBeg, (const int*)puiInd, (const double *)pdVal, NULL, NULL);
	  }

  NbJobBefore+=PYRGetNumberJobs(uiLoop);
  free(pdVal);
  free(puiInd);
 }
 free(pdrhs);
 free(puiBeg);
  // Third: Dk<=di-sum pjxmkj, forall i|k=V(i)
 printf("\t Creating constraints 3\n");
 pdrhs=(double *)malloc(sizeof(double)*1);
 puiBeg=(unsigned int *)malloc(sizeof(unsigned int)*1);
 puiBeg[0]=0;
 NbJobBefore=0;
 for(uiLoop=0;uiLoop<NbPyr;uiLoop++)
 {
  puiInd=(unsigned int *)malloc(sizeof(unsigned int)*(1+PYRGetNumberJobs(uiLoop)));
  pdVal=(double *)malloc(sizeof(double)*(1+PYRGetNumberJobs(uiLoop)));
  for (uiLoop2=0;uiLoop2<NbJobs;uiLoop2++)
	  if (V[uiLoop2]==(signed int) uiLoop)
	  { // We add the constraint
		  puiInd[0]=1+2*uiLoop+1;
		  pdVal[0]=1.0;
		  pdrhs[0]=(double)di(uiLoop2);
		  TotJob=0;
		  for (uiLoop3=0;uiLoop3<PYRGetNumberJobs(uiLoop);uiLoop3++)
		  {
			  uiJob=PYRGetJobsInPyr(uiLoop,uiLoop3);
			  if ((di(uiJob)<di(uiLoop2))||(di(uiJob)==di(uiLoop2) && ri(uiJob)<ri(uiLoop2))||(ri(uiJob)==ri(uiLoop2) && di(uiJob)==di(uiLoop2) && uiLoop2>=uiJob))
			  {
				  TotJob++;
				  puiInd[TotJob]=1+2*NbPyr+2*NbJobBefore+2*uiLoop3;
				  pdVal[TotJob]=(double)pi(uiJob);
			  }
		  }
          status = CPXaddrows (env, lp, 0, 1, 1+TotJob, pdrhs, "L", (const int *)puiBeg, (const int*)puiInd, (const double *)pdVal, NULL, NULL);
	  }

  NbJobBefore+=PYRGetNumberJobs(uiLoop);
  free(pdVal);
  free(puiInd);
 }
 free(pdrhs);
 free(puiBeg);
 // Fourth: sum xpkj+xmkj=1, forall i
 printf("\t Creating constraints 4\n");
 pdrhs=(double *)malloc(sizeof(double)*1);
 pdrhs[0]=1;
 puiBeg=(unsigned int *)malloc(sizeof(unsigned int)*1);
 puiBeg[0]=0;
 for(uiLoop=0;uiLoop<NbJobs;uiLoop++)
 if (U[uiLoop]!=-1)
 {
  puiInd=(unsigned int *)malloc(sizeof(unsigned int)*2*(V[uiLoop]-U[uiLoop]+1));
  pdVal=(double *)malloc(sizeof(double)*2*(V[uiLoop]-U[uiLoop]+1));
  NbJobBefore=0;
  for (uiLoop2=0;uiLoop2<U[uiLoop];uiLoop2++)
	  NbJobBefore+=PYRGetNumberJobs(uiLoop2);
  uiIndice=0;
  for (uiLoop2=U[uiLoop];uiLoop2<=V[uiLoop];uiLoop2++)
  {
	  puiInd[uiIndice]=1+2*PYRGetNumbers()+2*NbJobBefore+PYRGetJobPos(uiLoop2,uiLoop)*2;
	  pdVal[uiIndice]=1.0;
	  uiIndice++;
	  puiInd[uiIndice]=1+2*PYRGetNumbers()+2*NbJobBefore+PYRGetJobPos(uiLoop2,uiLoop)*2+1;
	  pdVal[uiIndice]=1.0;
	  uiIndice++;
	  NbJobBefore+=PYRGetNumberJobs(uiLoop2);
  }
  status = CPXaddrows (env, lp, 0, 1, 2*(V[uiLoop]-U[uiLoop]+1), pdrhs, "E", (const int *)puiBeg, (const int*)puiInd, (const double *)pdVal, NULL, NULL);
  free(puiInd);
  free(pdVal);
 }
 free(puiBeg);
 free(pdrhs);
 
 // Fifth: Rk>=Rk-1 + sum pjxm(k-1)j + ptk-1 + sum pjxpkj, forall k=2...NbPyr
 printf("\t Creating constraints 5\n");
 pdrhs=(double *)malloc(sizeof(double)*1);
 puiBeg=(unsigned int *)malloc(sizeof(unsigned int)*1);
 puiBeg[0]=0;
 NbJobBefore=0;
 for(uiLoop=1;uiLoop<NbPyr;uiLoop++)
 {
  puiInd=(unsigned int *)malloc(sizeof(unsigned int)*(2+PYRGetNumberJobs(uiLoop-1)+PYRGetNumberJobs(uiLoop)));
  pdVal=(double *)malloc(sizeof(double)*(2+PYRGetNumberJobs(uiLoop-1)+PYRGetNumberJobs(uiLoop)));
  pdrhs[0]=-1.0*(double)pi(PYRGetTopJob(uiLoop-1));
  puiInd[0]=1+2*(uiLoop-1);
  pdVal[0]=1.0;
  puiInd[1]=1+2*uiLoop;
  pdVal[1]=-1.0;
  for (uiLoop2=0;uiLoop2<PYRGetNumberJobs(uiLoop-1);uiLoop2++)
	  { 
		  puiInd[2+uiLoop2]=1+2*NbPyr+2*NbJobBefore+2*uiLoop2;
		  pdVal[2+uiLoop2]=(double)pi(PYRGetJobsInPyr(uiLoop-1,uiLoop2));
	  }
  NbJobBefore+=PYRGetNumberJobs(uiLoop-1);
  for (uiLoop2=0;uiLoop2<PYRGetNumberJobs(uiLoop);uiLoop2++)
	  { 
		  puiInd[2+PYRGetNumberJobs(uiLoop-1)+uiLoop2]=1+2*NbPyr+2*NbJobBefore+2*uiLoop2+1;
		  pdVal[2+PYRGetNumberJobs(uiLoop-1)+uiLoop2]=(double)pi(PYRGetJobsInPyr(uiLoop,uiLoop2));
	  }
  status = CPXaddrows (env, lp, 0, 1, 2+PYRGetNumberJobs(uiLoop)+PYRGetNumberJobs(uiLoop-1), pdrhs, "L", (const int *)puiBeg, (const int*)puiInd, (const double *)pdVal, NULL, NULL);
  free(pdVal);
  free(puiInd);
 }
 free(pdrhs);
 free(puiBeg);
 // Sixth: Dk<=Dk+1 - sum pjxp(k+1)j - ptk+1 - sum pjxmkj, forall k=1...NbPyr-1
 printf("\t Creating constraints 6\n");
 pdrhs=(double *)malloc(sizeof(double)*1);
 puiBeg=(unsigned int *)malloc(sizeof(unsigned int)*1);
 puiBeg[0]=0;
 NbJobBefore=0;
 for(uiLoop=0;uiLoop<NbPyr-1;uiLoop++)
 {
  puiInd=(unsigned int *)malloc(sizeof(unsigned int)*(2+PYRGetNumberJobs(uiLoop)+PYRGetNumberJobs(uiLoop+1)));
  pdVal=(double *)malloc(sizeof(double)*(2+PYRGetNumberJobs(uiLoop)+PYRGetNumberJobs(uiLoop+1)));
  pdrhs[0]=(double)pi(PYRGetTopJob(uiLoop+1));
  puiInd[0]=1+2*(uiLoop+1)+1;
  pdVal[0]=1.0;
  puiInd[1]=1+2*uiLoop+1;
  pdVal[1]=-1.0;
  for (uiLoop2=0;uiLoop2<PYRGetNumberJobs(uiLoop);uiLoop2++)
	  { 
		  puiInd[2+uiLoop2]=1+2*NbPyr+2*NbJobBefore+2*uiLoop2;
		  pdVal[2+uiLoop2]=-1.0*(double)pi(PYRGetJobsInPyr(uiLoop,uiLoop2));
	  }
  NbJobBefore+=PYRGetNumberJobs(uiLoop);
  for (uiLoop2=0;uiLoop2<PYRGetNumberJobs(uiLoop+1);uiLoop2++)
	  { 
		  puiInd[2+PYRGetNumberJobs(uiLoop)+uiLoop2]=1+2*NbPyr+2*NbJobBefore+2*uiLoop2+1;
		  pdVal[2+PYRGetNumberJobs(uiLoop)+uiLoop2]=-1.0*(double)pi(PYRGetJobsInPyr(uiLoop+1,uiLoop2));
	  }
  status = CPXaddrows (env, lp, 0, 1, 2+PYRGetNumberJobs(uiLoop)+PYRGetNumberJobs(uiLoop+1), pdrhs, "G", (const int *)puiBeg, (const int*)puiInd, (const double *)pdVal, NULL, NULL);
  free(pdVal);
  free(puiInd);
 }
 free(pdrhs);
 free(puiBeg);
}
int
main (void)
{
   int status, solstat;
   CPXENVptr env;
   CPXLPptr lp;
   int i;
   double x[NUMCOLS];
   double cpi[NUMCOLS];
   double rpi[NUMROWS];
   double qpi[NUMQS];
   double slack[NUMROWS], qslack[NUMQS];
   double kktsum[NUMCOLS];

   /* ********************************************************************** *
    *                                                                        *
    *    S E T U P   P R O B L E M                                           *
    *                                                                        *
    * ********************************************************************** */

   /* Create CPLEX environment and enable screen output.
    */
   env = CPXopenCPLEX (&status);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status != 0 )
      goto TERMINATE;

   /* Create the problem object and populate it.
    */
   lp = CPXcreateprob (env, &status, "qcpdual");
   if ( status != 0 )
      goto TERMINATE;
   status = CPXnewcols (env, lp, NUMCOLS, obj, lb, ub, NULL, cname);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXaddrows (env, lp, 0, NUMROWS, NUMNZS, rhs, sense,
                        rmatbeg, rmatind, rmatval, NULL, rname);
   if ( status != 0 )
      goto TERMINATE;
   for (i = 0; i < NUMQS; ++i) {
      int const linend = (i == NUMQS - 1) ? NUMLINNZ : linbeg[i + 1];
      int const quadend = (i == NUMQS - 1) ? NUMQUADNZ : quadbeg[i + 1];

      status = CPXaddqconstr (env, lp, linend - linbeg[i],
                              quadend - quadbeg[i], qrhs[i], qsense[i],
                              &linind[linbeg[i]], &linval[linbeg[i]],
                              &quadrow[quadbeg[i]], &quadcol[quadbeg[i]],
                              &quadval[quadbeg[i]], qname[i]);
      if ( status != 0 )
         goto TERMINATE;
   }

   /* ********************************************************************** *
    *                                                                        *
    *    O P T I M I Z E   P R O B L E M                                     *
    *                                                                        *
    * ********************************************************************** */
   status = CPXsetdblparam (env, CPXPARAM_Barrier_QCPConvergeTol, 1e-10);
   if ( status != 0 )
      goto TERMINATE;

   /* Solve the problem.
    */
   status = CPXbaropt (env, lp);
   if ( status != 0 )
      goto TERMINATE;

   solstat = CPXgetstat (env, lp);

   if ( solstat != CPX_STAT_OPTIMAL ) {
      fprintf (stderr, "No optimal solution found!\n");
      goto TERMINATE;
   }

   /* ********************************************************************** *
    *                                                                        *
    *    Q U E R Y   S O L U T I O N                                         *
    *                                                                        *
    * ********************************************************************** */

   /* Optimal solution and slacks for linear and quadratic constraints. */
   status = CPXgetx (env, lp, x, 0, NUMCOLS - 1);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXgetslack (env, lp, slack, 0, NUMROWS - 1);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXgetqconstrslack (env, lp, qslack, 0, NUMQS - 1);
   if ( status != 0 )
      goto TERMINATE;
   /* Dual multipliers for linear constraints and bound constraints. */
   status = CPXgetdj (env, lp, cpi, 0, NUMCOLS - 1);
   if ( status != 0 )
      goto TERMINATE;
   status = CPXgetpi (env, lp, rpi, 0, NUMROWS - 1);
   if ( status != 0 )
      goto TERMINATE;
   status = getqconstrmultipliers (env, lp, x, qpi, ZEROTOL);
   if ( status != 0 )
      goto TERMINATE;

   /* ********************************************************************** *
    *                                                                        *
    *    C H E C K   K K T   C O N D I T I O N S                             *
    *                                                                        *
    *    Here we verify that the optimal solution computed by CPLEX (and     *
    *    the qpi[] values computed above) satisfy the KKT conditions.        *
    *                                                                        *
    * ********************************************************************** */

   /* Primal feasibility: This example is about duals so we skip this test. */

   /* Dual feasibility: We must verify
    * - for <= constraints (linear or quadratic) the dual
    *   multiplier is non-positive.
    * - for >= constraints (linear or quadratic) the dual
    *   multiplier is non-negative.
    */
   for (i = 0; i < NUMROWS; ++i) {
      switch (sense[i]) {
      case 'E': /* nothing */ break;
      case 'R': /* nothing */ break;
      case 'L':
         if ( rpi[i] > ZEROTOL ) {
            fprintf (stderr,
                     "Dual feasibility test failed for <= row %d: %f\n",
                     i, rpi[i]);
            status = -1;
            goto TERMINATE;
         }
         break;
      case 'G':
         if ( rpi[i] < -ZEROTOL ) {
            fprintf (stderr,
                     "Dual feasibility test failed for >= row %d: %f\n",
                     i, rpi[i]);
            status = -1;
            goto TERMINATE;
         }
         break;
      }
   }
   for (i = 0; i < NUMQS; ++i) {
      switch (qsense[i]) {
      case 'E': /* nothing */ break;
      case 'L':
         if ( qpi[i] > ZEROTOL ) {
            fprintf (stderr,
                     "Dual feasibility test failed for <= quad %d: %f\n",
                     i, qpi[i]);
            status = -1;
            goto TERMINATE;
         }
         break;
      case 'G':
         if ( qpi[i] < -ZEROTOL ) {
            fprintf (stderr,
                     "Dual feasibility test failed for >= quad %d: %f\n",
                     i, qpi[i]);
            status = -1;
            goto TERMINATE;
         }
         break;
      }
   }

   /* Complementary slackness.
    * For any constraint the product of primal slack and dual multiplier
    * must be 0.
    */
   for (i = 0; i < NUMROWS; ++i) {
      if ( sense[i] != 'E' && fabs (slack[i] * rpi[i]) > ZEROTOL ) {
         fprintf (stderr,
                  "Complementary slackness test failed for row %d: %f\n",
                  i, fabs (slack[i] * rpi[i]));
         status = -1;
         goto TERMINATE;
      }
   }
   for (i = 0; i < NUMQS; ++i) {
      if ( qsense[i] != 'E' && fabs (qslack[i] * qpi[i]) > ZEROTOL ) {
         fprintf (stderr,
                  "Complementary slackness test failed for quad %d: %f\n",
                  i, fabs (qslack[i] * qpi[i]));
         status = -1;
         goto TERMINATE;
      }
   }
   for (i = 0; i < NUMCOLS; ++i) {
      if ( ub[i] < CPX_INFBOUND ) {
         double const slk = ub[i] - x[i];
         double const dual = cpi[i] < -ZEROTOL ? cpi[i] : 0.0;
         if ( fabs (slk * dual) > ZEROTOL ) {
            fprintf (stderr,
                     "Complementary slackness test failed for ub %d: %f\n",
                     i, fabs (slk * dual));
            status = -1;
            goto TERMINATE;
         }
      }
      if ( lb[i] > -CPX_INFBOUND ) {
         double const slk = x[i] - lb[i];
         double const dual = cpi[i] > ZEROTOL ? cpi[i] : 0.0;
         if ( fabs (slk * dual) > ZEROTOL ) {
            printf ("lb=%f, x=%f, cpi=%f\n", lb[i], x[i], cpi[i]);
            fprintf (stderr,
                     "Complementary slackness test failed for lb %d: %f\n",
                     i, fabs (slk * dual));
            status = -1;
            goto TERMINATE;
         }
      }
   }

   /* Stationarity.
    * The difference between objective function and gradient at optimal
    * solution multiplied by dual multipliers must be 0, i.e., for the
    * optimal solution x
    * 0 == c
    *      - sum(r in rows)  r'(x)*rpi[r]
    *      - sum(q in quads) q'(x)*qpi[q]
    *      - sum(c in cols)  b'(x)*cpi[c]
    * where r' and q' are the derivatives of a row or quadratic constraint,
    * x is the optimal solution and rpi[r] and qpi[q] are the dual
    * multipliers for row r and quadratic constraint q.
    * b' is the derivative of a bound constraint and cpi[c] the dual bound
    * multiplier for column c.
    */

   /* Objective function. */
   for (i = 0; i < NUMCOLS; ++i)
      kktsum[i] = obj[i];

   /* Linear constraints.
    * The derivative of a linear constraint ax - b (<)= 0 is just a.
    */
   for (i = 0; i < NUMROWS; ++i) {
      int const end = (i == NUMROWS - 1) ? NUMNZS : rmatbeg[i + 1];
      int k;

      for (k = rmatbeg[i]; k < end; ++k)
         kktsum[rmatind[k]] -= rpi[i] * rmatval[k];
   }

   /* Quadratic constraints.
    * The derivative of a constraint xQx + ax - b <= 0 is
    * Qx + Q'x + a.
    */
   for (i = 0; i < NUMQS; ++i) {
      int j;
      int k;

      for (j = linbeg[i]; j < linbeg[i] + linnzcnt[i]; ++j)
         kktsum[linind[j]] -= qpi[i] * linval[j];
      for (k = quadbeg[i]; k < quadbeg[i] + quadnzcnt[i]; ++k) {
         kktsum[quadrow[k]] -= qpi[i] * x[quadcol[k]] * quadval[k];
         kktsum[quadcol[k]] -= qpi[i] * x[quadrow[k]] * quadval[k];
      }
   }

   /* Bounds.
    * The derivative for lower bounds is -1 and that for upper bounds
    * is 1.
    * CPLEX already returns dj with the appropriate sign so there is
    * no need to distinguish between different bound types here.
    */
   for (i = 0; i < NUMCOLS; ++i) {
      kktsum[i] -= cpi[i];
   }

   for (i = 0; i < NUMCOLS; ++i) {
      if ( fabs (kktsum[i]) > ZEROTOL ) {
         fprintf (stderr, "Stationarity test failed at index %d: %f\n",
                  i, kktsum[i]);
         status = -1;
         goto TERMINATE;
      }
   }

   /* KKT conditions satisfied. Dump out the optimal solutions and
    * the dual values.
    */

   printf ("Optimal solution satisfies KKT conditions.\n");
   printf ("  x[] =");
   for (i = 0; i < NUMCOLS; ++i)
      printf (" %7.3f", x[i]);
   printf ("\n");
   printf ("cpi[] =");
   for (i = 0; i < NUMCOLS; ++i)
      printf (" %7.3f", cpi[i]);
   printf ("\n");
   printf ("rpi[] =");
   for (i = 0; i < NUMROWS; ++i)
      printf (" %7.3f", rpi[i]);
   printf ("\n");
   printf ("qpi[] =");
   for (i = 0; i < NUMQS; ++i)
      printf (" %7.3f", qpi[i]);
   printf ("\n");
   
 TERMINATE:
   /* ********************************************************************** *
    *                                                                        *
    *    C L E A N U P                                                       *
    *                                                                        *
    * ********************************************************************** */

   status = CPXfreeprob (env, &lp);
   if ( status != 0 ) {
      fprintf (stderr, "WARNING: Failed to free problem: %d\n", status);
   }
   status = CPXcloseCPLEX (&env);
   if ( status != 0 ) {
      fprintf (stderr, "WARNING: Failed to close CPLEX: %d\n", status);
   }

   return status;
}
예제 #15
0
SSCplex::SSCplex( string InstanceFile )
{
 num_vm = 0; // number of virtual machines
 num_vf = 0; // number of virtual function
 int offset;
 
 ifstream in;
 in.open(InstanceFile.c_str());
 if( !in.is_open() )
 {
  cout<<"Cannot open instance file.\n";
  exit(1);
 }
	
 //leggo da file il numero di macchine e di funzioni virtuali
 in >> num_vm;
 in >> num_vf;

 cout << "Num VM " << num_vm << " Num VF " << num_vf << endl;

 lev_card = num_vm; // the number of nodes in each level
 h_len = num_vf;

 int lev_card_arcs = lev_card*lev_card;

 //number of nodes and arcs 
 NNodes = lev_card * h_len + 2;
 NArcs = lev_card * lev_card * (h_len-1) + 2*lev_card;
 
 // array used to store the solution
 Y = array(NArcs);

 tempi_lat = new double *[num_vm];

 for (int i=0; i<num_vm; i++)
   tempi_lat[i] = new double[num_vm];

 cap = new int[ num_vm ];
 
 // fill the distance matrix 
 for (int i=0; i<num_vm; i++)
  for (int j=0; j<num_vm; j++)
    //   if( j >= i )
    in >> tempi_lat[i][j];
 //   else  (in input is supposed to be symmetric)
 //    tempi_lat[i][j] = tempi_lat[j][i];

 // fill the capacity array
 for (int i=0; i<num_vm; i++)
  in >> cap[ i ];

 incom = new int *[num_vf];
 for (int i=0; i<num_vf; i++)
  incom[i] = new int[num_vm+1];

 proc_time = new double *[num_vf];
 for (int i=0; i<num_vf; i++)
  proc_time[i] = new double[num_vm];

 for( int i = 0; i < num_vf; i++ )
 {
   string dummy;
   int cnt;
   in >> dummy >> incom[i][0];
   cnt = incom[i][0];
   for( int j = 1; j <= cnt; j++ )
     in >> incom[i][j];

   for( int j = 0; j < num_vm; j++ )
     in >> proc_time[i][j];
 }

 source_dist = new double[ num_vm ];
 dest_dist = new double[ num_vm ];

 for( int j = 0; j < num_vm; j++ )
   in >> source_dist[j];
 for( int j = 0; j < num_vm; j++ )
   in >> dest_dist[j];


 in.close();

 /* Initialize the CPLEX environment */
 env = CPXopenCPLEX (&status);
 if ( env == NULL ) {
   stop("Could not open CPLEX environment.\n", status);
 }

 /* Create the problem */
 lp = CPXcreateprob( env , &status , "HCP" );
 if ( lp == NULL ) {
   stop("Failed to create LP.\n", status);
 }
 if( DEBUG ) {
   CPXout.open("DEBUG.txt", ios::out); 	
 }

 // Turn on debugging routines
 status = CPXsetintparam (env, CPX_PARAM_DATACHECK, CPX_ON);
 if ( status ) {
    stop("Failure to turn on debugging, error %d.\n", status);
 }
  
 // Turn on output to the screen     
 status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON);
 if ( status ) {
   stop("Failure to turn on screen indicator, error %d.\n", status);
 }

  double  *obj = NULL;
  double  *ub = NULL;
  double  *lb = NULL;
  char	*ctype = NULL;
	
  int nzcnt;
  double *rhs = NULL;
  char *sense = NULL;
  int *matbeg;
  int *matind;
  double *matval;

  // variable counters
  int y_var = NArcs; // flow variables

  // creating variables
  ub = array(y_var);
  lb = array(y_var);

  for( int k = 0; k < y_var; k++ ){
    lb[k] = 0.0;
    ub[ k ] = 1.0;
  }
#if( MIP )
  ctype = arraychar(y_var);	
  for( int h = 0; h < y_var; h++)
    ctype[h] = 'B';
#endif

  obj = array(NArcs);
  for(int i = 0; i < lev_card; i++ )
    obj[i] = proc_time[0][i] + source_dist[i];

  offset = lev_card * lev_card * (h_len-1) + lev_card;
  for(int i = 0; i < lev_card; i++ )
    obj[offset+i] = dest_dist[i];

  offset = lev_card;
  for( int h = 0; h < h_len - 1; h++ )
   for( int i = 0; i < lev_card; i++ )
    for( int j = 0; j < lev_card; j++ )
    {
     int k = offset + h * (lev_card * lev_card) + i * lev_card + j;
     obj[k] = tempi_lat[i][j] + proc_time[h+1][j];
    }

  status = CPXnewcols(env, lp, y_var, obj, lb, ub, ctype, NULL);
  if ( status )
    stop("Failure to create y cols.", status);

  nzcnt = NArcs;
  matind = arrayint(nzcnt);
  matval = array(nzcnt);
  matbeg = arrayint(2);
  
  rhs = array(1);       // at most one constraint is loaded 
  sense = arraychar(1); // in one shot

  matbeg[0] = 0;
  
  // flow conservation constraint relative to source node
  rhs[0] = 1.0;
  sense[0] = 'E';

  for( int h = 0; h < lev_card; h++ )
  {
   matind[h] = h;
   matval[h] = 1.0;
  }

  matbeg[1] = lev_card;
  status = CPXaddrows(env, lp, 0, 1, lev_card, rhs, sense, 
		      matbeg, matind, matval, NULL, NULL);

  if ( status ) {
    stop("Failed to insert cons.\n", status);	
  }

  offset = lev_card + (h_len - 1) * (lev_card * lev_card);
    // flow conservation constraint relative to destination node
  for( int h = 0; h < lev_card; h++ )
  {
   matind[h] = offset + h;
   matval[h] = 1.0;
  }

  matbeg[1] = lev_card;
  status = CPXaddrows(env, lp, 0, 1, lev_card, rhs, sense, 
		      matbeg, matind, matval, NULL, NULL);
  if ( status ) {
    stop("Failed to insert cons.\n", status);	
  }
  
  // flow conservation constraints relative to intermediate nodes
  rhs[0] = 0.0;
  for( int h = 0; h < h_len; h++ )
  {
   for( int i = 0; i < lev_card; i++ )
   {
    int k = 0; // insert a constraint for each intermediate node
    // incoming flow
    if( h == 0 )
    {
     matind[k] = i;
     matval[k] = -1.0;
     k++;
    }
    else
    {
     offset = lev_card + lev_card*lev_card*(h-1);
     for( int j = 0; j < lev_card; j++ )
     {
      matind[k] = offset + j * lev_card + i;
      matval[k] = -1.0;
      k++;
     } 
    }
    // outcoming flow
    if( h == h_len - 1)
    {
     offset = lev_card + lev_card*lev_card*h;
     matind[k] = offset +  i;
     matval[k] = 1.0;
     k++;
    }
    else
    {
     offset = lev_card + lev_card*lev_card*h;
     for( int j = 0; j < lev_card; j++ )
     {
      matind[k] = offset + i*lev_card + j;
      matval[k] = 1.0;
      k++;
     } 

    }
    
    matbeg[1] = k;
    assert( k <= nzcnt );
    status = CPXaddrows(env, lp, 0, 1, k, rhs, sense, 
			matbeg, matind, matval, NULL, NULL);
    if ( status ) {
      stop("Failed to insert cons.\n", status);	
    }
   }
  }

  // VM capacity constraints 
  sense[0] = 'L';
  for( int i = 0; i < lev_card; i++ )
  {
   int k = 0; // insert a constraint for each VM
   rhs[0] = cap[i];

   for( int h = 0; h < h_len - 1; h++ )
   {
    offset = lev_card + lev_card*lev_card*h;
    for( int j = 0; j < lev_card; j++ )
    {
     matind[k] = offset + i*lev_card + j;
     matval[k] = 1.0;
     k++;
    }
   }
   offset = lev_card + lev_card*lev_card*(h_len-1);
   matind[k] = offset +  i;
   matval[k] = 1.0;
   k++;

   matbeg[1] = k;
   assert( k <= nzcnt );
   status = CPXaddrows(env, lp, 0, 1, k, rhs, sense, 
		       matbeg, matind, matval, NULL, NULL);
   if ( status ) {
     stop("Failed to insert cons.\n", status);	
   }
  }

  // incompatibilities management
  // vf_0
  int cnt = incom[0][0];
  for( int j = 0; j < cnt; j++ )
  {
   int arc_index = incom[0][j+1];
   ChgBds(arc_index, 0.0);
  }
  // other vf_h
  for( int h = 1; h < num_vf; h++ )
  {
   int cnt = incom[h][0];
   int offset = lev_card + (h-1) * (lev_card*lev_card);
   for( int j = 0; j < cnt; j++ )
    for( int i = 0; i < lev_card; i++ )
    {
     int arc_index = offset + i * lev_card + incom[h][j+1];
     ChgBds(arc_index, 0.0);
    }
  }

#if DEBUG
	status = CPXwriteprob(env, lp, "SS.lp", "LP");
	if ( status ) stop("Failed to write LP to disk.", status);
#endif

/* Set limit to emphasize feasibility */    
 status = CPXsetintparam (env, CPX_PARAM_MIPEMPHASIS, MIPEMPH);
 if ( status ) 
   stop("Failure to set parameter emphasizing feasibility.\n", status);


// Turn on output to the screen     
 status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON);
 if ( status ) {
   stop("Failure to turn on screen indicator, error %d.\n", status);
 }

 status = CPXsetdblparam (env, CPX_PARAM_TILIM, TIMELIMIT);

 free_arraychar(sense);
 free_array(rhs);
 free_arrayint(matbeg);
 free_array(matval);
 free_arrayint(matind);
 free_array(obj);
#if( MIP )
 free_arraychar(ctype);
#endif
 free_array(lb);
 free_array(ub);
} //END SSCplex
예제 #16
0
void
DDSIP_DetEqu ()
{
    CPXLPptr det_equ;

    int status, scen, i, j, k;
    char probname[] = "sipout/det_equ.lp.gz";
    double *obj_coef;
    double *scaled_obj_coef;
    char *sense;
    char **scen_spec_rowname;
    char **scen_spec_colname;
    char **rowname, *rownamestore;
    char **colname, *colnamestore;
    int rowstorespace, rowsurplus_p;
    int colstorespace, colsurplus_p;
    char *string1, *string2;
    double coef;
    double *lb, *lb_sorted;
    double *ub, *ub_sorted;
    char *vartype, *vartype_sorted;
    int *colindex_sorted, *colindex_revers, *matcol_sorted;
    double *value;
    double *det_equ_rhs = NULL;
    double *non_stoc_rhs = NULL;
    if (DDSIP_param->seccon)
        det_equ_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_param->seccon,"det_equ_rhs(DetEqu)");
    else
    {
        fprintf (stderr,"XXX ERROR: no second stage contraints, got DDSIP_param->seccon=%d.\n",DDSIP_param->seccon);
        exit (1);
    }
    if (DDSIP_param->seccon - DDSIP_param->stocrhs>0)
        non_stoc_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_param->seccon - DDSIP_param->stocrhs,"non_stoc_rhs(DetEqu)");

    fprintf (stderr,
             "\nBuilding deterministic equivalent. This may take some time.\nWorks only for expectation-based model so far.\n");

    if (!(sense = (char *) calloc (DDSIP_param->seccon, sizeof (char))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }

    if (!(obj_coef = (double *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (double))) ||
            !(scaled_obj_coef = (double *) calloc (DDSIP_bb->secvar, sizeof (double))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }


    det_equ = CPXcloneprob (DDSIP_env, DDSIP_lp, &status);
    CPXchgprobname (DDSIP_env, det_equ, probname);

    if (!(rowname = (char **) calloc (DDSIP_param->seccon, sizeof (char *)))
            || !(scen_spec_rowname = (char **) calloc (DDSIP_param->seccon, sizeof (char *)))
            || !(rownamestore = (char *) calloc (DDSIP_param->seccon * 255, sizeof (char))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }
    rowstorespace = DDSIP_param->seccon * 255;
    status = CPXgetrowname (DDSIP_env, DDSIP_lp, rowname, rownamestore,
                            rowstorespace, &rowsurplus_p, DDSIP_param->firstcon, DDSIP_param->firstcon + DDSIP_param->seccon - 1);


    if (!(colname = (char **) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (char *)))
            || !(scen_spec_colname = (char **) calloc (DDSIP_param->secvar, sizeof (char *)))
            || !(colnamestore = (char *) calloc (DDSIP_param->secvar * 255, sizeof (char))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }
    colstorespace = (DDSIP_param->firstvar + DDSIP_param->secvar) * 255;
    status = CPXgetcolname (DDSIP_env, DDSIP_lp, colname, colnamestore,
                            colstorespace, &colsurplus_p, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);

    /*____________________________________________________________________________________*/
    status = CPXgetsense (DDSIP_env, DDSIP_lp, sense, DDSIP_param->firstcon, DDSIP_param->firstcon + DDSIP_param->seccon - 1);
    /*____________________________________________________________________________________*/
    status = CPXgetrhs (DDSIP_env, DDSIP_lp, non_stoc_rhs, DDSIP_param->firstcon + DDSIP_param->stocrhs, DDSIP_param->firstcon + DDSIP_param->seccon - 1);
    /*____________________________________________________________________________________*/
    status = CPXgetobj (DDSIP_env, DDSIP_lp, obj_coef, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);
    /*____________________________________________________________________________________*/
    //copy rownames scenario many times, append scenario index
    //and enter sense and rhs
    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        for (j = 0; j < DDSIP_param->seccon; j++)
        {
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                return;
            }
            string1 = rowname[j];
            sprintf (string2, "%sSC%.3d", string1, scen);
            scen_spec_rowname[j] = string2;

            if (j < DDSIP_param->stocrhs)
                det_equ_rhs[j] = DDSIP_data->rhs[DDSIP_param->stocrhs * scen + j];
            else
                det_equ_rhs[j] = non_stoc_rhs[j - DDSIP_param->stocrhs];
        }
        status = CPXnewrows (DDSIP_env, det_equ, DDSIP_param->seccon, det_equ_rhs, sense, NULL, scen_spec_rowname);
        for (j = 0; j < DDSIP_param->seccon; j++)
            DDSIP_Free ((void **) &(scen_spec_rowname[j]));
    }

    //copy colnames scenario many times, append scenario index
    //and enter into constraint matrix
    if (!(lb = (double *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (double)))
            || !(lb_sorted = (double *) calloc (DDSIP_param->secvar, sizeof (double)))
            || !(ub = (double *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (double)))
            || !(ub_sorted = (double *) calloc (DDSIP_param->secvar, sizeof (double)))
            || !(vartype = (char *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (char)))
            || !(vartype_sorted = (char *) calloc (DDSIP_param->secvar, sizeof (double)))
            || !(colindex_revers = (int *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (int)))
            || !(colindex_sorted = (int *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (int))))
    {
        fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
        return;
    }

    status = CPXgetlb (DDSIP_env, det_equ, lb, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);
    status = CPXgetub (DDSIP_env, det_equ, ub, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);
    status = CPXgetctype (DDSIP_env, det_equ, vartype, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1);
    for (j = 0; j < DDSIP_param->secvar; j++)
    {
        vartype_sorted[j] = vartype[DDSIP_bb->secondindex[j]];
        lb_sorted[j] = lb[DDSIP_bb->secondindex[j]];
        ub_sorted[j] = ub[DDSIP_bb->secondindex[j]];
    }


    for (scen = 0; scen < DDSIP_param->scenarios; scen++)
    {
        for (j = 0; j < DDSIP_param->secvar; j++)
        {
            if (!(string2 = (char *) calloc (1, 255 * sizeof (char))))
            {
                fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
                return;
            }
            string1 = colname[DDSIP_bb->secondindex[j]];
            sprintf (string2, "%sSC%.3d", string1, scen);
            scen_spec_colname[j] = string2;
            scaled_obj_coef[j] = DDSIP_data->prob[scen] * obj_coef[DDSIP_bb->secondindex[j]];
        }

        status =
            CPXnewcols (DDSIP_env, det_equ, DDSIP_param->secvar, scaled_obj_coef,
                        lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname);
        for (j = 0; j < DDSIP_param->secvar; j++)
            DDSIP_Free ((void **) &(scen_spec_colname[j]));

    }

    /////////////////////////////////////////////////
    for (j = 0; j < DDSIP_param->firstvar; j++)
    {
        colindex_sorted[j] = DDSIP_bb->firstindex[j];
    }
    for (j = 0; j < DDSIP_param->secvar; j++)
    {
        colindex_sorted[DDSIP_param->firstvar + j] = DDSIP_bb->secondindex[j];
    }
    for (j = 0; j < DDSIP_param->firstvar + DDSIP_param->secvar; j++)
    {
        colindex_revers[colindex_sorted[j]] = j;
    }

    k = DDSIP_param->seccon / 60;
    printf ("\n0%%                                                         100%%\n");
    for (i = 0; i < DDSIP_param->seccon; i++)
    {
        for (j = 0; j < DDSIP_param->firstvar; j++)
        {
            if ((status = CPXgetcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + i, colindex_sorted[j], &coef)))
            {
                fprintf (stderr, " Build det. equivalent: Error retrieving coefficient of first-stage Variable %d.\n", j);
                exit (1);
            }
            if (coef)
            {
                for (scen = 0; scen < DDSIP_param->scenarios; scen++)
                {
                    status =
                        CPXchgcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + DDSIP_bb->seccon + scen * DDSIP_param->seccon + i, colindex_sorted[j], coef);
                    if (status)
                    {
                        fprintf (stderr, " Build det. equivalent: Error setting coefficient of first-stage Variable %d.\n", j);
                        exit (1);
                    }
                }
            }
        }
        for (j = DDSIP_param->firstvar; j < DDSIP_param->firstvar + DDSIP_param->secvar; j++)
        {
            if ((status = CPXgetcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + i, colindex_sorted[j], &coef)))
            {
                fprintf (stderr,
                         " Build det. equivalent: Error retrieving coefficient of second-stage Variable %d.\n",
                         j - DDSIP_param->firstvar);
                exit (1);
            }
            if (coef)
            {
                for (scen = 0; scen < DDSIP_param->scenarios; scen++)
                {
                    status =
                        CPXchgcoef (DDSIP_env, det_equ,
                                    DDSIP_param->firstcon + DDSIP_bb->seccon + scen * DDSIP_param->seccon + i, (scen + 1) * DDSIP_param->secvar + j, coef);
                }
                if (status)
                {
                    fprintf (stderr,
                             " Build det. equivalent: Error setting coefficient of second-stage Variable %d.\n",
                             j - DDSIP_param->firstvar);
                    exit (1);
                }
            }
        }
        if (!k)
        {
            for (j = 0; j <= 60 / DDSIP_param->seccon; j++)
                printf ("#");
        }
        else if (i % k == k - 1)
            printf ("#");
    }
    printf ("\n\n");

    ///////delete original second stage rows & cols ////////////////////////////////////////////

    status = CPXdelrows (DDSIP_env, det_equ, DDSIP_param->firstcon, DDSIP_param->firstcon + DDSIP_bb->seccon - 1);
    j = 0;
    for (i = 0; i < DDSIP_param->secvar; i++)
    {
        status = CPXdelcols (DDSIP_env, det_equ, DDSIP_bb->secondindex[i] - j, DDSIP_bb->secondindex[i] - j);
        j++;
    }

    ///////enter stochastic matrix entries//////////////////////////////////////////////////////
    if (DDSIP_param->stocmat)
    {

        if (!(value = (double *) calloc (DDSIP_param->stocmat, sizeof (double)))
                || !(matcol_sorted = (int *) calloc (DDSIP_param->stocmat, sizeof (int))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            return;
        }
        for (j = 0; j < DDSIP_param->stocmat; j++)
        {
            matcol_sorted[j] = colindex_revers[DDSIP_data->matcol[j]];
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                value[j] = DDSIP_data->matval[scen * DDSIP_param->stocmat + j];
            }
            status = CPXchgcoeflist (DDSIP_env, det_equ, DDSIP_param->stocmat, DDSIP_data->matrow, matcol_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu: %s\n", errmsg);
            }
            for (j = 0; j < DDSIP_param->stocmat; j++)
            {
                DDSIP_data->matrow[j] += DDSIP_param->seccon;
                if (matcol_sorted[j] >= DDSIP_param->firstvar)
                    matcol_sorted[j] += DDSIP_param->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
        DDSIP_Free ((void **) &(matcol_sorted));
        //set matrow to the old values
        for (j = 0; j < DDSIP_param->stocmat; j++)
        {
            DDSIP_data->matrow[j] -= DDSIP_param->scenarios * DDSIP_param->seccon;
        }

    }
    ///////enter stochastic cost coefficients //////////////////////////////////////////////////
    if (DDSIP_param->stoccost)
    {

        if (!(value = (double *) calloc (DDSIP_param->stoccost, sizeof (double)))
                || !(matcol_sorted = (int *) calloc (DDSIP_param->stoccost, sizeof (int))))
        {
            fprintf (stderr, "Not enough memory for building deterministic equivalent\n");
            return;
        }
        for (j = 0; j < DDSIP_param->stoccost; j++)
        {
            value[j] = 0.0;
            matcol_sorted[j] = colindex_revers[DDSIP_data->costind[j]];
        }
        for (scen = 0; scen < DDSIP_param->scenarios; scen++)
        {
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if (matcol_sorted[j] >= DDSIP_param->firstvar)
                    value[j] = DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
                else
                    value[j] += DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j];
            }
            status = CPXchgobj (DDSIP_env, det_equ, DDSIP_param->stoccost, matcol_sorted, value);
            if (status)
            {
                char errmsg[1024];
                CPXgeterrorstring (DDSIP_env, status, errmsg);
                fprintf (stderr, "in DetEqu: %s\n", errmsg);
            }
            for (j = 0; j < DDSIP_param->stoccost; j++)
            {
                if (matcol_sorted[j] >= DDSIP_param->firstvar)
                    matcol_sorted[j] += DDSIP_param->secvar;
            }
        }
        DDSIP_Free ((void **) &(value));
        DDSIP_Free ((void **) &(matcol_sorted));

    }
    ////////////////////////////////////////////////////////////////////////////////////////////

    status = CPXwriteprob (DDSIP_env, det_equ, probname, NULL);
    if (status)
        fprintf (DDSIP_outfile, " *** Deterministic equivalent not written successfully, status = %d\n", status);
    else
        fprintf (DDSIP_outfile, " *** Deterministic equivalent written successfully\n");
    status = CPXfreeprob (DDSIP_env, &det_equ);

    DDSIP_Free ((void **) &(sense));
    DDSIP_Free ((void **) &(vartype));
    DDSIP_Free ((void **) &(rowname));
    DDSIP_Free ((void **) &(rownamestore));
    DDSIP_Free ((void **) &(colname));
    DDSIP_Free ((void **) &(colnamestore));
    DDSIP_Free ((void **) &(det_equ_rhs));
    DDSIP_Free ((void **) &(non_stoc_rhs));
    DDSIP_Free ((void **) &(lb));
    DDSIP_Free ((void **) &(ub));
    DDSIP_Free ((void **) &(vartype_sorted));
    DDSIP_Free ((void **) &(lb_sorted));
    DDSIP_Free ((void **) &(ub_sorted));
    DDSIP_Free ((void **) &(obj_coef));
    DDSIP_Free ((void **) &(scaled_obj_coef));
    DDSIP_Free ((void **) &(colindex_sorted));
    DDSIP_Free ((void **) &(colindex_revers));
    DDSIP_Free ((void **) &(scen_spec_rowname));
    DDSIP_Free ((void **) &(scen_spec_colname));
    return;
}
예제 #17
0
파일: socpex1.c 프로젝트: annaPolytech/PRD
/* This function creates the following model:
 *   Minimize
 *    obj: x1 + x2 + x3 + x4 + x5 + x6
 *   Subject To
 *    c1: x1 + x2      + x5      = 8
 *    c2:           x3 + x5 + x6 = 10
 *    q1: [ -x1^2 + x2^2 + x3^2 ] <= 0
 *    q2: [ -x4^2 + x5^2 ] <= 0
 *   Bounds
 *    x2 Free
 *    x3 Free
 *    x5 Free
 *   End
 * which is a second order cone program in standard form.
 * The function returns a true value on success and false on error.
 * The function also sets up *cone_p as follows:
 * (*cone_p)[j] >= 0              Column j is contained in a cone constraint
 *                                and is the cone head variable of that
 *                                constraint. The index of the respective
 *                                quadratic constraint is given by (*cone_p)[j].
 * (*cone_p)[j] = NOT_CONE_HEAD   Column j is contained in a cone constraint
 *                                but is not the cone head variable of that
 *                                constraint.
 * (*cone_p)[j] = NOT_IN_CONE     Column j is not contained in any cone
 *                                constraint.
 */
static int
createmodel (CPXENVptr env, CPXLPptr lp, int **cone_p)
{
   /* Column data. */
   static double const obj[]        = {  1.0,  1.0,  1.0,  1.0,  1.0,  1.0 };
   static double const lb[]         = {  0.0, -INF, -INF,  0.0, -INF,  0.0 };
   static double const ub[]         = {  INF,  INF,  INF,  INF,  INF,  INF };
   static char const *const cname[] = { "x1", "x2", "x3", "x4", "x5", "x6" };

   /* Row data. */
   static double const rval[]       = { 1.0, 1.0, 1.0,    1.0, 1.0, 1.0 };
   static int const rind[]          = {   0,   1,   4,      2,   4,   5 };
   static int const rbeg[]          = {   0,                3           };
   static double const rhs[]        = { 8.0,             10.0           };
   static char const sense[]        = { 'E',              'E'           };
   static char const *const rname[] = { "c1",             "c2"          };

   /* Data for second order cone constraints. */
   static double const qval[]  = { -1.0, 1.0, 1.0 }; /* Same for all Q cons. */
   static double const qrhs    = 0.0;                /* Same for all Q cons. */
   static char const qsense    = 'L';                /* Same for all Q cons. */
   static int const qind1[] = { 0, 1, 2 };
   static int const qind2[] = { 3, 4 };

   int status;
   int ok = 0;
   int *cone = NULL;

   CPXCHANNELptr errc;

   /* Get the channel for printing error messages. */
   if ( (status = CPXgetchannels (env, NULL, NULL, &errc, NULL)) != 0 )
      goto TERMINATE;

   cone = malloc ((sizeof (obj) / sizeof (obj[0])) * sizeof (*cone));
   if ( cone == NULL ) {
      CPXmsg (errc, "Out of memory!\n");
      goto TERMINATE;
   }

   status = CPXchgobjsen (env, lp, CPX_MIN);
   if ( status != 0 )
      goto TERMINATE;

   status = CPXnewcols (env, lp, sizeof (obj) / sizeof (obj[0]),
                        obj, lb, ub, NULL, (char **)cname);
   if ( status != 0 )
      goto TERMINATE;

   status = CPXaddrows (env, lp, 0, sizeof (rhs) / sizeof (rhs[0]),
                        sizeof (rval) / sizeof (rval[0]), rhs, sense,
                        rbeg, rind, rval, NULL, (char **)rname);
   if ( status != 0 )
      goto TERMINATE;

   status = CPXaddqconstr (env, lp, 0, sizeof (qind1) / sizeof (qind1[0]),
                           qrhs, qsense, NULL, NULL,
                           qind1, qind1, qval, "q1");
   if ( status != 0 )
      goto TERMINATE;
   cone[0] = 0;
   cone[1] = NOT_CONE_HEAD;
   cone[2] = NOT_CONE_HEAD;
   status = CPXaddqconstr (env, lp, 0, sizeof (qind2) / sizeof (qind2[0]),
                           qrhs, qsense, NULL, NULL,
                           qind2, qind2, qval, "q2");
   if ( status != 0 )
      goto TERMINATE;
   cone[3] = 1;
   cone[4] = NOT_CONE_HEAD;

   cone[5] = NOT_IN_CONE;

   ok = 1;
 TERMINATE:
   if ( !ok )
      free (cone);

   *cone_p = cone;

   return ok;
}
예제 #18
0
int cg_solver(int m, MyRow* rows)
{
   CPXENVptr     env = NULL;
   CPXLPptr      model = NULL;
   int           status = 0;
   int           error = 0;
   int           i, j;
   int           cur_numrows, cur_numcols;
   int           n_cuts, cut;

   int       solstat;
   double    objval;
   double   *x;
   double   *z;
   int      *cstat;
 
   int      n0 = rows[0].n;      
   int      n1 = rows[0].n+m-1;  /// One slack variable for constraint
   int      h = (m-1)*n0 + m-1;  /// Number of nonzeros

   double   obj[n1];

   double   rhs[m-1];    /// The first row is for the cost vector
   char     sense[m-1];

   int      jnd[h];
   int      ind[h];
   double   val[h];

   int      idx = 0;

   int*     rmatbeg;
   int*     rmatind;
   double*  rmatval;
   double*  b_bar;
   char*    gc_sense;
   double*  gc_rhs;

   /// Create environment
   env = CPXopenCPLEX (&status);
   if ( env == NULL ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment. Status: %d\n", status);
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto QUIT;
   }

   /// Disable presolve
   POST_CMD( CPXsetintparam (env, CPX_PARAM_PREIND, CPX_OFF) );
   
   /// Create problem
   model = CPXcreateprob (env, &error, "gomory");
   if (error) goto QUIT;

   /// Minimization problem
   POST_CMD( CPXchgobjsen (env, model, CPX_MIN) );
   
   /// Add rows (remember first row is cost vector)
   for ( i = 0; i < m-1; ++i ) {
      sense[i]='E';
      rhs[i] = rows[i+1].rhs;
   }
   POST_CMD( CPXnewrows(env, model, m-1, rhs, sense, NULL, NULL) );
   
   /// Add problem variables 
   for ( j = 0; j < n0; ++j ) 
      obj[j] = rows[0].lhs[j];
   /// Add slack variables 
   for ( j = n0; j < n1; ++j ) 
      obj[j] = 0;
   POST_CMD( CPXnewcols(env, model, n1, obj, NULL, NULL, NULL, NULL) );

   /// Write the full matrix A into the LP (WARNING: should use only nonzeros entries)
   for ( i = 1; i < m; ++i ) {
      for ( j = 0; j < n0; ++j ) {
         jnd[idx] = i-1;
         ind[idx] = rows[i].ind[j];
         val[idx] = rows[i].lhs[j];
         idx++;
      }
      /// Add a slack variable per constraint
      jnd[idx] = i-1;
      ind[idx] = n0+i-1;
      val[idx] = 1.0;
      idx++;
   }
   POST_CMD( CPXchgcoeflist(env, model, idx, jnd, ind, val) );

   /// Optimize the problem
   POST_CMD( CPXlpopt(env, model) );

   /// Check the results
   cur_numrows = CPXgetnumrows (env, model);
   cur_numcols = CPXgetnumcols (env, model);

   x =  (double *) malloc (cur_numcols * sizeof(double));
   z =  (double *) malloc (cur_numcols * sizeof(double));
   cstat = (int *) malloc (cur_numcols * sizeof(int));

   b_bar = (double *) malloc (cur_numrows * sizeof(double));

   POST_CMD( CPXsolution (env, model, &solstat, &objval, x, NULL, NULL, NULL) );
   if ( solstat != 1 ) {
      printf("The solver did not find an optimal solution\nSolver status code: %d\n",solstat);
      exit(0);
   }

   /// Write the output to the screen 
   printf ("\nSolution status = %d\t\t", solstat);
   printf ("Solution value  = %f\n\n", objval);

   /// If the solution is integer, is the optimum -> exit the loop
   if ( isInteger(cur_numcols, x) ) {
      fprintf(stdout,"The solution is already integer!\n");
      goto QUIT;
   }

   /// Dump the problem model to 'gomory.lp' for debbuging
   POST_CMD( CPXwriteprob(env, model, "gomory.lp", NULL) );

   /// Get the base statuses
   POST_CMD( CPXgetbase(env, model, cstat, NULL) );

   print_solution(cur_numcols, x, cstat);

   printf("\nOptimal base inverted matrix:\n");
   for ( i = 0; i < cur_numrows; ++i ) {
      b_bar[i] = 0;
      POST_CMD( CPXbinvrow(env, model, i, z) );
      for ( j = 0; j < cur_numrows; ++j ) {
         printf("%.1f ", z[j]);
         b_bar[i] += z[j]*rhs[j];
      }
      printf("\n");
   }

   printf("\nOptimal solution (non basic variables are equal to zero):\n");
   idx = 0;     /// Compute the nonzeros
   n_cuts = 0;  /// Number of fractional variables (cuts to be generated)
   for ( i = 0; i < m-1; ++i ) {
      POST_CMD( CPXbinvarow(env, model, i, z) );
      for ( j = 0; j < n1; ++j ) {
         if ( z[j] >= 0 )
            printf("+");
         printf("%.1f x%d ", z[j], j+1);
         if ( floor(z[j]+0.5) != 0 )
            idx++;
      }
      printf("= %.1f\n", b_bar[i]);
      /// Count the number of cuts to be generated
      if ( floor(b_bar[i]) != b_bar[i] ) 
         n_cuts++;
   }

   /// Allocate memory for the new data structure
   gc_sense = (char*)   malloc ( n_cuts * sizeof(char) ); 
   gc_rhs   = (double*) malloc ( n_cuts * sizeof(double) ); 
   rmatbeg  = (int*)    malloc ( n_cuts * sizeof(int) ); 
   rmatind  = (int*)    malloc (    idx * sizeof(int) ); 
   rmatval  = (double*) malloc (    idx * sizeof(double) ); 

   printf("\nGenerate Gomory cuts:\n");
   idx = 0;
   cut = 0;  /// Index of cut to be added
   for ( i = 0; i < m-1; ++i ) 
      if ( floor(b_bar[i]) != b_bar[i] ) {
         printf("Row %d gives cut ->   ", i+1);
         POST_CMD( CPXbinvarow(env, model, i, z) );
         rmatbeg[cut] = idx;
         for ( j = 0; j < n1; ++j ) {
            z[j] = floor(z[j]); /// DANGER!
            if ( z[j] != 0 ) {
               rmatind[idx] = j;
               rmatval[idx] = z[j];
               idx++;
            }
            /// Print the cut
            if ( z[j] >= 0 )
               printf("+");
            printf("%.1f x%d ", z[j], j+1);
         }
         gc_rhs[cut] = floor(b_bar[i]); /// DANGER!
         gc_sense[cut] = 'L';
         printf("<= %.1f\n", gc_rhs[cut]);
         cut++;
      }

   /// Add the new cuts
   POST_CMD( CPXaddrows (env, model, 0, 
            n_cuts, idx, gc_rhs, gc_sense, 
            rmatbeg, rmatind, rmatval, 
            NULL, NULL) );

   /// Solve the new LP
   POST_CMD( CPXlpopt(env, model) );

   /// Check the results
   cur_numrows = CPXgetnumrows (env, model);
   cur_numcols = CPXgetnumcols (env, model);

   POST_CMD( CPXsolution (env, model, &solstat, &objval, x, NULL, NULL, NULL) );

   if ( solstat != 1 ) {
      printf("The solver did not find an optimal solution\nSolver status code: %d\n",solstat);
      exit(0);
   }
   /// Write the output to the screen 
   printf ("\nSolution status = %d\n", solstat);
   printf ("Solution value = %f\n\n", objval);

   POST_CMD( CPXgetbase(env, model, cstat, NULL) );

   print_solution(cur_numcols, x, cstat);

   free_and_null ((char **) &x);
   free_and_null ((char **) &z);
   free_and_null ((char **) &cstat);
   free_and_null ((char **) &rmatbeg);
   free_and_null ((char **) &rmatind);
   free_and_null ((char **) &rmatval);

QUIT:
   free_and_null ((char **) &x);
   free_and_null ((char **) &z);
   free_and_null ((char **) &cstat);

   if ( error ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      CPXgeterrorstring (env, error, errmsg);
      fprintf (stderr, "%s", errmsg);
   }

   /* Free up the problem as allocated by CPXcreateprob, if necessary */
   if ( model != NULL ) {
      status = CPXfreeprob (env, &model);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status);
      }
   }

   /* Free up the CPLEX environment, if necessary */
   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

      if ( error ) {
         char  errmsg[CPXMESSAGEBUFSIZE];
         fprintf (stderr, "Could not close CPLEX environment.\n");
         CPXgeterrorstring (env, status, errmsg);
         fprintf (stderr, "%s", errmsg);
      }
   }

   return (status);
}
static int
populatebynonzero (CPXENVptr env, CPXLPptr lp)
{
   int      status    = 0;
   double   obj[NUMCOLS];
   double   lb[NUMCOLS];
   double   ub[NUMCOLS];
   char     *colname[NUMCOLS];
   double   rhs[NUMROWS];
   char     sense[NUMROWS];
   char     *rowname[NUMROWS];
   int      rowlist[NUMNZ];
   int      collist[NUMNZ];
   double   vallist[NUMNZ];

   status = CPXchgobjsen (env, lp, CPX_MAX);  /* Problem is maximization */
   if ( status )  goto TERMINATE;

   /* Now create the new rows.  First, populate the arrays. */

   rowname[0] = "c1";
   sense[0]   = 'L';
   rhs[0]     = 20.0;

   rowname[1] = "c2";
   sense[1]   = 'L';
   rhs[1]     = 30.0;

   status = CPXnewrows (env, lp, NUMROWS, rhs, sense, NULL, rowname);
   if ( status )   goto TERMINATE;

   /* Now add the new columns.  First, populate the arrays. */

       obj[0] = 1.0;      obj[1] = 2.0;           obj[2] = 3.0;

        lb[0] = 0.0;       lb[1] = 0.0;           lb[2]  = 0.0;
        ub[0] = 40.0;      ub[1] = CPX_INFBOUND;  ub[2]  = CPX_INFBOUND;

   colname[0] = "x1"; colname[1] = "x2";      colname[2] = "x3";

   status = CPXnewcols (env, lp, NUMCOLS, obj, lb, ub, NULL, colname);
   if ( status )  goto TERMINATE;

   /* Now create the list of coefficients */

   rowlist[0] = 0;   collist[0] = 0;   vallist[0] = -1.0;
   rowlist[1] = 0;   collist[1] = 1;   vallist[1] = 1.0;
   rowlist[2] = 0;   collist[2] = 2;   vallist[2] = 1.0;
   rowlist[3] = 1;   collist[3] = 0;   vallist[3] = 1.0;
   rowlist[4] = 1;   collist[4] = 1;   vallist[4] = -3.0;
   rowlist[5] = 1;   collist[5] = 2;   vallist[5] = 1.0;

   status = CPXchgcoeflist (env, lp, 6, rowlist, collist, vallist);
   
   if ( status )  goto TERMINATE;

TERMINATE:

   return (status);

}  /* END populatebynonzero */
예제 #20
0
파일: foodmanu.c 프로젝트: renvieir/ioc
static int
buildmodel (CPXENVptr env, CPXLPptr lp)
{

   int    colcnt = NUMVARS*NUMMONTHS*NUMPRODUCTS;

   double *obj     = NULL;
   double *lb      = NULL;
   double *ub      = NULL;
   char   *ctype   = NULL;
   int    *rmatind = NULL;
   double *rmatval = NULL;

   int    indicator;
   int    rmatbeg[1];
   double rhs[1];
   char   sense[1];

   int    m, p;
   int    status = 0;

   status = CPXchgobjsen (env, lp, CPX_MAX); /* Maximization problem */
   if ( status ) {
      fprintf (stderr, "Could not change objective sense.\n");
      goto TERMINATE;
   }

   rmatbeg[0] = 0;

   /* Allocate colcnt-sized arrays */

   obj     = (double *) malloc (colcnt * sizeof(double));
   lb      = (double *) malloc (colcnt * sizeof(double));
   ub      = (double *) malloc (colcnt * sizeof(double));
   ctype   = (char *)   malloc (colcnt * sizeof(char));
   rmatind = (int * )   malloc (colcnt * sizeof(int));
   rmatval = (double *) malloc (colcnt * sizeof(double));

   if ( obj     == NULL ||
        lb      == NULL ||
        ub      == NULL ||
        ctype   == NULL ||
        rmatind == NULL ||
        rmatval == NULL   ) {
      fprintf (stderr, "Could not allocate colcnt arrays\n");
      status = CPXERR_NO_MEMORY;
      goto TERMINATE;
   }

   /* Create variables. For each month and each product, we have 3
      variables corresponding to the quantity used (semi-continuous),
      stored (continuous) and bought (continuous) and one binary
      variable indicating whether or not the product is used during
      this month. */

   for (m = 0; m < NUMMONTHS; m++) {
      for (p = 0; p < NUMPRODUCTS; p++) {

         /* The quantity bought is a continuous variable. It has a cost */

         obj[varindex(m, p, BUY)]    = -cost[m*NUMPRODUCTS + p];
         lb[varindex (m, p, BUY)]    = 0.0;
         ub[varindex (m, p, BUY)]    = CPX_INFBOUND;
         ctype[varindex (m, p, BUY)] = 'C';

         /* When an oil is used, the quantity must be at least 20
            tons. This is modeled as a semi-continuous variable. */

         obj[varindex (m, p, USE)]   = 0.0;
         lb[varindex (m, p, USE)]    = 20.0;
         ub[varindex (m, p, USE)]    = CPX_INFBOUND;
         ctype[varindex (m, p, USE)] = 'S';

         /* It is possible to store up to 1000 tons of each
            product. There are storage costs. */

         obj[varindex (m, p, STORE)]   = -5.0;
         lb[varindex (m, p, STORE)]    = 0.0;
         ub[varindex (m, p, STORE)]    = 1000.0;
         ctype[varindex (m, p, STORE)] = 'C';

         /* At the end, we must have exactly 500 tons of each
            product in storage. */

         if ( m == NUMMONTHS - 1 ) {
            lb[varindex (m, p, STORE)] = 500.0;
            ub[varindex (m, p, STORE)] = 500.0;
         }

         /* The variable indicating whether or not a product is
            used during a month is a binary variable. */

         obj[varindex (m, p, IS_USED)]   = 0.0;
         lb[varindex (m, p, IS_USED)]    = 0.0;
         ub[varindex (m, p, IS_USED)]    = 1.0;
         ctype[varindex (m, p, IS_USED)] = 'B';
      }
   }

   status = CPXnewcols (env, lp, colcnt, obj, lb, ub, ctype, NULL);
   if ( status ) {
      fprintf (stderr, "Could not add new columns.\n");
      goto TERMINATE;
   }

   /* Constraints for each month */

   for (m = 0; m < NUMMONTHS; m++) {
      int totalindex;

      /* For each product, create an indicator constraint linking the
         quantity used and the binary variable indicating whether or
         not the product is used */

      for (p = 0; p < NUMPRODUCTS; p++) {
         indicator  = varindex (m, p, IS_USED);
         rmatind[0] = varindex (m, p, USE);
         rmatval[0] = 1.0;
         status = CPXaddindconstr (env, lp, indicator, 1, 1, 0.0, 'L',
                                   rmatind, rmatval, NULL);
         if ( status ) {
            fprintf (stderr, "Could not add new indicator constraint.\n");
            goto TERMINATE;
         }
      }

      /* Not more than 200 tons of vegetable oil can be refined */

      rmatind[0] = varindex (m, VEGOIL1, USE);
      rmatind[1] = varindex (m, VEGOIL2, USE);
      rmatval[0] = 1.0;
      rmatval[1] = 1.0;
      rhs[0]     = 200.0;
      sense[0]   = 'L';
      status = CPXaddrows (env, lp, 0, 1, 2, rhs,
                           sense, rmatbeg, rmatind, rmatval,
                           NULL, NULL);

      /* Not more than 250 tons of non-vegetable oil can be refined */

      rmatind[0] = varindex (m, OIL1, USE);
      rmatind[1] = varindex (m, OIL2, USE);
      rmatind[2] = varindex (m, OIL3, USE);
      rmatval[0] = 1.0;
      rmatval[1] = 1.0;
      rmatval[2] = 1.0;
      rhs[0]     = 250.0;
      sense[0]   = 'L';
      status = CPXaddrows (env, lp, 0, 1, 3, rhs,
                           sense, rmatbeg, rmatind, rmatval,
                           NULL, NULL);
      if ( status ) {
         fprintf (stderr, "Could not add new rows.\n");
         goto TERMINATE;
      }

      /* Constraint on food composition */

      /* Add a variable corresponding to total quantity produced
         in a month */

      obj[0]   = 150.0;
      lb[0]    = 0.0;
      ub[0]    = CPX_INFBOUND;
      ctype[0] = 'C';

      status = CPXnewcols (env, lp, 1, obj, lb, ub, ctype, NULL);
      if ( status ) {
         fprintf (stderr, "Could not add new columns.\n");
         goto TERMINATE;
      }
      totalindex = CPXgetnumcols (env, lp) - 1;

      /* Total quantity = sum (quantities) */

      for (p = 0; p < NUMPRODUCTS; p++) {
         rmatind[p] = varindex (m, p, USE);
         rmatval[p] = 1.0;
      }
      rmatind[NUMPRODUCTS] = totalindex;
      rmatval[NUMPRODUCTS] = -1.0;
      rhs[0]               =  0.0;
      sense[0]             = 'E';
      status = CPXaddrows (env, lp, 0, 1, NUMPRODUCTS + 1, rhs,
                           sense, rmatbeg, rmatind, rmatval,
                           NULL, NULL);
      if ( status ) {
         fprintf (stderr, "Could not add new rows.\n");
         goto TERMINATE;
      }

      /* Hardness constraints
          sum (quantity * hardness) >= 3 * total quantity
          sum (quantity * hardness) <= 6 * total quantity
      */

      for (p = 0; p < NUMPRODUCTS; p++) {
         rmatind[p] = varindex (m, p, USE);
         rmatval[p] = hardness[p];
      }
      rmatind[NUMPRODUCTS] = totalindex;
      rmatval[NUMPRODUCTS] = -3.0;
      rhs[0]               =  0.0;
      sense[0]             = 'G';
      status = CPXaddrows (env, lp, 0, 1, NUMPRODUCTS + 1, rhs,
                           sense, rmatbeg, rmatind, rmatval,
                           NULL, NULL);
      if ( status ) {
         fprintf (stderr, "Could not add new rows.\n");
         goto TERMINATE;
      }

      rmatval[NUMPRODUCTS] = -6.0;
      sense[0]             = 'L';
      status = CPXaddrows (env, lp, 0, 1, NUMPRODUCTS + 1, rhs,
                           sense, rmatbeg, rmatind, rmatval,
                           NULL, NULL);
      if ( status ) {
         fprintf (stderr, "Could not add new rows.\n");
         goto TERMINATE;
      }

      /* The food may never be made up of more than three oils */

      for (p = 0; p < NUMPRODUCTS; p++) {
         rmatind[p] = varindex (m, p, IS_USED);
         rmatval[p] = 1.0;
      }
      rhs[0]   = 3.0;
      sense[0] = 'L';
      status = CPXaddrows (env, lp, 0, 1, NUMPRODUCTS, rhs,
                           sense, rmatbeg, rmatind, rmatval,
                           NULL, NULL);
      if ( status ) {
         fprintf (stderr, "Could not add new rows.\n");
         goto TERMINATE;
      }

      /* If product veg 1 or veg 2 is used then oil 3 must be used */

      indicator  = varindex (m, VEGOIL1, IS_USED);
      rmatind[0] = varindex (m, OIL3, USE);
      rmatval[0] = 1.0;
      status = CPXaddindconstr (env, lp, indicator, 0, 1, 20.0, 'G',
                                rmatind, rmatval, NULL);

      indicator = varindex (m, VEGOIL2, IS_USED);
      status = CPXaddindconstr (env, lp, indicator, 0, 1, 20.0, 'G',
                                rmatind, rmatval, NULL);

      if ( status ) {
         fprintf (stderr, "Could not add new indicator constraint.\n");
         goto TERMINATE;
      }

      /* We can store each product from one month to the next,
         starting with a stock of 500 tons */

      for (p = 0; p < NUMPRODUCTS; p++) {
         int n = 0;
         if ( m != 0 ) {
            rmatind[n]   = varindex (m-1, p, STORE); /* stored last month */
            rmatval[n++] = 1.0;
            rmatind[n]   = varindex (m, p, BUY);     /* bought this month */
            rmatval[n++] = 1.0;
            rmatind[n]   = varindex (m, p, USE);     /* used this month */
            rmatval[n++] = -1.0;
            rmatind[n]   = varindex (m, p, STORE);   /* stored this month */
            rmatval[n++] = -1.0;
            rhs[0]       = 0.0;
            sense[0]     = 'E';
         }
         else {
            rmatind[n]   = varindex (m, p, BUY);   /* bought this month */
            rmatval[n++] = 1.0;
            rmatind[n]   = varindex (m, p, USE);   /* used this month */
            rmatval[n++] = -1.0;
            rmatind[n]   = varindex (m, p, STORE); /* stored this month */
            rmatval[n++] = -1.0;
            rhs[0]       = -500.0;
            sense[0]     = 'E';
         }
         status = CPXaddrows (env, lp, 0, 1, n, rhs,
                              sense, rmatbeg, rmatind, rmatval,
                              NULL, NULL);
         if ( status ) {
            fprintf (stderr, "Could not add new rows.\n");
            goto TERMINATE;
         }
      }
   }

 TERMINATE:

   free_and_null ((char **)&obj);
   free_and_null ((char **)&lb);
   free_and_null ((char **)&ub);
   free_and_null ((char **)&ctype);
   free_and_null ((char **)&rmatind);
   free_and_null ((char **)&rmatval);

   return (status);

}  /* END buildmodel */
예제 #21
0
파일: TP.cpp 프로젝트: peter3110/tp-io
int main(int argc, char **argv) { 

    char ejes[100];
    char labels[100];
    char test[100];

    archivoInput          = argv[1];
    randomness            = argv[2];
    porcentajeParticiones = atof(argv[3]);
    algoritmo             = argv[4];
    epsilonClique         = atof(argv[5]);
    epsilonAgujero        = atof(argv[6]);
    numeroDeModelo        = atoi(argv[7]);
    RECORRIDO_ARBOL       = atoi(argv[8]);
    VARIABLE_CORTE        = atoi(argv[9]);
    semilla               = atoi(argv[10]);

    srand(semilla);

    if(not freopen(archivoInput.c_str(), "r", stdin)){
        cout << "No pude abrir archivo: " << archivoInput << endl;
        return 1;
    }

    sprintf(ejes, "ejes.out");
    sprintf(labels, "labels.out");
    if(randomness == "notrandom") { 
        sprintf(test, "%s%s", argv[1], argv[2]);
    }
    else if (randomness == "random") {
        sprintf(test, "%s%s", argv[1], argv[3]);
    }
    else{
        cout << "Paramtros mal introducidos" << endl;
        return 0;
    }

    read(randomness); // cada elemento de la particion conformado por un unico nodo

    // Le paso por parametro el algoritmo a implementar: bb = branch and bound, cb = cut and branch
    if(algoritmo != "bb" && algoritmo != "cb") {
        cout << "Error introduciendo parametro de algoritmo a ser aplicado " << endl;
        return 0;
    }

    // ==============================================================================================

    // Genero el problema de cplex.
    int status;
    // Creo el entorno.
    CPXENVptr env = CPXopenCPLEX(&status); // Puntero al entorno.
    CPXLPptr lp; // Puntero al LP
     
    if (env == NULL) {
        cerr << "Error creando el entorno" << endl;
        exit(1);
    }

    ///Iniciio el reloj
    CPXgettime(env, &inittime);
        
    // Creo el LP.
    lp = CPXcreateprob(env, &status, "instancia coloreo de grafo particionado");
     
    if (lp == NULL) {
        cerr << "Error creando el LP" << endl;
        exit(1);
    }

    // Definimos las variables. En total, son P + N*P variables ( las W[j] y las X[i][j] )
    int cantVariables = P + N*P;
    double *ub, *lb, *objfun; // Cota superior, cota inferior, coeficiente de la funcion objetivo.
    char *xctype, **colnames; // tipo de la variable , string con el nombre de la variable.
    ub       = new double[cantVariables]; 
    lb       = new double[cantVariables];
    objfun   = new double[cantVariables];
    xctype   = new char[cantVariables];
    colnames = new char*[cantVariables];

    for (int i = 0; i < cantVariables; i++) {
        ub[i] = 1.0; // seteo upper y lower bounds de cada variable
        lb[i] = 0.0;
        if(i < P) {  // agrego el costo en la funcion objetivo de cada variables
            objfun[i] = 1;  // busco minimizar Sum(W_j) para j=0..P (la cantidad de colores utilizados).
        }
        else {
            objfun[i] = 0;  // los X[i][j] no contribuyen a la funcion objetivo
        }
        xctype[i] = 'B';  // 'C' es continua, 'B' binaria, 'I' Entera.
        colnames[i] = new char[10];
    }

    /* Defino el tipo de variable BoolVarMatrix, que sera utilizado en la resolucion
     * recordar: X_v_j = 1 sii el color j es asignado al vertice v
     * recordar: W_j = 1 si X_v_j = 1 para al menos un vertice v
    */
    for(int j=0; j<P; j++) {
        sprintf(colnames[j], "W_%d", j);
        // cout << colnames[j] << endl;
    }
    for(int i=0; i<N; i++) {
        for(int j=0; j<P; j++) {
            sprintf(colnames[xijIndice(i,j)], "X_%d_%d", i, j);
            // cout << colnames[xijIndice(i,j)] << endl;
        }
    }


    // ========================== Agrego las columnas. =========================== //
    if(algoritmo == "cb"){
        // si quiero resolver la relajacion, agregar los cortes y despues resolver el MIP, no agrego xctype
        status = CPXnewcols(env, lp, cantVariables, objfun, lb, ub, NULL, colnames);
    }
    else if (algoritmo == "bb"){
        // si quiero hacer MIP, directamente, con brancha and bound, agrego xctype
        status = CPXnewcols(env, lp, cantVariables, objfun, lb, ub, xctype, colnames);
    }
    else {
        cout << "Error: parametro de algoritmo bb/cb mal introducido" << endl;
        return 0;
    }
    
    if (status) {
        cerr << "Problema agregando las variables CPXnewcols" << endl;
        exit(1);
    }
    
    // Libero las estructuras.
    for (int i = 0; i < cantVariables; i++) {
        delete[] colnames[i];
    }

    delete[] ub;
    delete[] lb;
    delete[] objfun;
    delete[] xctype;
    delete[] colnames;

    // CPLEX por defecto minimiza. Le cambiamos el sentido a la funcion objetivo si se quiere maximizar.
    // CPXchgobjsen(env, lp, CPX_MAX);

    // ================================================================================================ //
    // ===================================== Restricciones ============================================ //

    // i)   Asigno exactamente un color a exactamente un vertice de cada particion ( P restricciones )
    // ii)  Dos vertices adyacentes no pueden tener el mismo color ( E restricciones )
    // iii) Los W_j estan bien armados, en funcion de X_v_j ( 2*P restricciones )

    // ccnt = numero nuevo de columnas en las restricciones.
    // rcnt = cuantas restricciones se estan agregando.
    // nzcnt = # de coeficientes != 0 a ser agregados a la matriz. Solo se pasan los valores que no son cero.
 
    int ccnt = 0;
    int rcnt;
    if(numeroDeModelo == 0){
        rcnt = P + (E*P)/2 + 2*P;  // Cota maxima a la cantidad de restricciones
    }
    else{
        rcnt = P + (E*P)/2 + N*P;
    }
                                    // (E/2 porque en la entrada se supone que en la entrada me pasan 2 veces cada eje)
    int nzcnt = 0;  // al ppio es cero (para cada valor q agrego, lo voy a incrementar en 1)

    char sense[rcnt]; // Sentido de la desigualdad. 'G' es mayor o igual y 'E' para igualdad, 'L' menor o igual

    double *rhs = new double[rcnt]; // Termino independiente de las restricciones.
    int *matbeg = new int[rcnt];    //Posicion en la que comienza cada restriccion en matind y matval.
    int *matind = new int[rcnt*cantVariables];       // Array con los indices de las variables con coeficientes != 0 en la desigualdad.
    double *matval = new double[rcnt*cantVariables]; // Array que en la posicion i tiene coeficiente ( != 0) de la variable matind[i] en la restriccion.

    // CPLEX va a leer hasta la cantidad nzcnt que le pasemos.
    int cantRestricciones = 0;  // r = numero de restriccion

    // i) P restricciones - exactamente un color a cada vertice (una restriccion por cada particion)
    for(int particion = 0; particion < P; particion++) {
        matbeg[cantRestricciones] = nzcnt;
        rhs[cantRestricciones]    = 1;
        sense[cantRestricciones]  = 'E';
		for(int e = 0; e < S[particion].size(); e++) {
			for(int color = 0; color < P; color++) {
				matind[nzcnt] = xijIndice(S[particion][e], color);
				matval[nzcnt] = 1;
				nzcnt++;
			}
		}
        cantRestricciones++;
    }

	// ii) Cota superior de (E*P)/2 restricciones mas
	// Una para cada par de vecinos i j, para cada color pero solo cuando i < j, y estan en distinta particion
	for(int i = 0; i < N; i++) {
		for(int j = i + 1; j < N; j++) { 
			if(M[i][j] == 1 and dameParticion(i) != dameParticion(j)){
				for(int color = 0; color < P; color++) {
					matbeg[cantRestricciones] = nzcnt;
					rhs[cantRestricciones]    = 1;
					sense[cantRestricciones]  = 'L';

					matind[nzcnt] = xijIndice(i,color);
					matval[nzcnt] = 1;
					nzcnt++;
					matind[nzcnt] = xijIndice(j,color);
					matval[nzcnt] = 1;
					nzcnt++;
					cantRestricciones++;
				}
			}
		}
    }

    if(numeroDeModelo == 0){

        // iii) 2*P restricciones mas
		// - P * wj + sigma xij <= 0
        for(int k=0; k<P; k++) {  // para cada color
            matbeg[cantRestricciones] = nzcnt;
            rhs[cantRestricciones] = 0;
            sense[cantRestricciones] = 'L';
            matind[nzcnt] = k;
            matval[nzcnt] = -1 * P;
            nzcnt++;
            for(int i=0; i<N; i++) {
                matind[nzcnt] = xijIndice(i,k);
                matval[nzcnt] = 1;
                nzcnt++;
            }
            cantRestricciones++;
        }

		//  - wj + sigma xij >= 0
        for(int k=0; k<P; k++) {
            matbeg[cantRestricciones] = nzcnt;
            rhs[cantRestricciones] = 0;
            sense[cantRestricciones] = 'G';
            matind[nzcnt] = k;
            matval[nzcnt] = -1;
            nzcnt++;
            for(int i=0; i<N; i++) {
                matind[nzcnt] = xijIndice(i,k);
                matval[nzcnt] = 1;
                nzcnt++;
            }
            cantRestricciones++;
        }

    }
    else{
		// iii) N*P restricciones mas
		// -wj + xij <= 0
        for(int color = 0; color < P; color++) { 
            for(int i = 0; i < N; i++) {
                matbeg[cantRestricciones] = nzcnt;
                rhs[cantRestricciones] = 0;
                sense[cantRestricciones] = 'L';
                matind[nzcnt] = color;
                matval[nzcnt] = -1;
                nzcnt++;
                matind[nzcnt] = xijIndice(i, color);
                matval[nzcnt] = 1;
                nzcnt++;
                cantRestricciones++;
            }
        }
    }

    //Actualizo rcnt.
    rcnt = cantRestricciones;


    // ===================================================================================================
    
    // Agregamos las restricciones al lp.
    status = CPXaddrows(env, lp, ccnt, rcnt, nzcnt, rhs, sense, matbeg, matind, matval, NULL, NULL);

    if (status) {
        cerr << "Problema agregando restricciones." << endl;
        exit(1);
    }
            
    delete[] rhs;
    delete[] matbeg;
    delete[] matind;
    delete[] matval;


    // ============================================================================================== //
    // ================================== Optimizamos el problema. ================================== //
    // Seteo de algunos parametros.

    // Para desactivar la salida poner CPX_OFF.
    status = CPXsetintparam(env, CPX_PARAM_SCRIND, CPX_ON);
        
    if (status) {
        cerr << "Problema seteando SCRIND" << endl;
        exit(1);
    }
        
    // Setea el tiempo limite de ejecucion.
    status = CPXsetdblparam(env, CPX_PARAM_TILIM, TIEMPO_LIMITE);  // setear limite de tiempo en 3600 !!!!!!!
    
    if (status) {
        cerr << "Problema seteando el tiempo limite" << endl;
        exit(1);
    }
 
    // Escribimos el problema a un archivo .lp.
    // status = CPXwriteprob(env, lp, "test.lp", NULL);

    if (status) {
        cerr << "Problema escribiendo modelo" << endl;
        exit(1);
    }
        
    // Seteamos algunos parametros para resolver con branch and bound
    CPXsetintparam(env, CPX_PARAM_MIPSEARCH, CPX_MIPSEARCH_TRADITIONAL);

    // Para facilitar la comparación evitamos paralelismo:
    CPXsetintparam(env, CPX_PARAM_THREADS, 1);

    //Para que no se adicionen planos de corte:
    CPXsetintparam(env,CPX_PARAM_EACHCUTLIM, 0);
    CPXsetintparam(env, CPX_PARAM_FRACCUTS, -1);
    CPXsetintparam(env, CPX_PARAM_LANDPCUTS, -1);

    // Para que no haga preprocesamientos
    CPXsetintparam(env, CPX_PARAM_PRESLVND, -1);
    CPXsetintparam(env, CPX_PARAM_REPEATPRESOLVE, 0);
    CPXsetintparam(env, CPX_PARAM_RELAXPREIND, 0);
    CPXsetintparam(env, CPX_PARAM_REDUCE, 0);

    // Recorrido del arbol
    CPXsetintparam(env, CPX_PARAM_NODESEL, RECORRIDO_ARBOL);

    // Seleccion de variable
    CPXsetintparam(env, CPX_PARAM_VARSEL, VARIABLE_CORTE); 

    CPXgettime(env, &endtime);
    tiempoPreparar = endtime - inittime;
    inittime = endtime;

    // =========================================================================================================
    // resuelvo con cut and branch (con los cortes definidos por nosotros) o con branch and bound (y sin cortes)
    // =========================================================================================================
    if(algoritmo == "cb") {
        
        // while (algo) ... resolver el lp, chequear si la restr inducida por la clique actual es violada. Seguir
        //cout << "antes" << endl;
        
        for(int ciclocb=0; ciclocb<CANT_CICLOS_CB; ciclocb++) {
            status = CPXlpopt(env, lp);
        
            //cout << "despues" << endl;
            double objval;
            status = CPXgetobjval(env, lp, &objval);
            // Aca, deberia agregar los cortes requeridos, en funcion de "cliques" y "objval"

            // mostrameValores(env, lp);

            double *sol = new double[cantVariables];
            CPXgetx(env, lp, sol, 0, cantVariables - 1);

            //CPXwriteprob (env, lp, "antesDeClique.lp", "LP");
            // BUSCAR Y AGREGAR CLIQUE
            vector < vector<int> > agregados;
            for(int color=0; color<P; color++) {
                for(int i=0; i<CANT_RESTR_CLIQUES; i++) {
                    bool iteracionRandom = (i!=0);
                    vector<int> clique = dameClique(sol, color, iteracionRandom);
                    sort(clique.begin(), clique.end());
                    bool incluido = find(agregados.begin(), agregados.end(), clique) != agregados.end();

                    if (not incluido and not clique.empty()) {
                        agregados.push_back(clique);
                        agregarRestriccionClique(env, lp, clique);
                        cantidadCortesClique++;
                        // cout << "AGREGO RESTRICCION DE CLIQUE de random " << iteracionRandom << " y de color #"<< color << ": ";
                        // for(int j=0; j<clique.size(); j++) {
                        //     cout << clique[j] << " ";
                        // }
                        // cout << endl;
                    }
                }
            }

            // BUSCAR Y AGREGAR AGUJERO
            agregados.clear();
            for(int color=0; color<P; color++) {
                for(int i=0; i<CANT_RESTR_AGUJEROS; i++) {
                    vector<int> agujero = dameAgujero(sol, color);

                    bool incluido = find(agregados.begin(), agregados.end(), agujero) != agregados.end();
                    if (not incluido and not agujero.empty()) {
                        agregados.push_back(agujero);
                        agregarRestriccionAgujero(env, lp, agujero);
                        cantidadCortesAgujero++;
                        // cout << "AGREGO RESTRICCION DE AGUJERO de color #"<< color << ": ";
                        // for(int j=0; j<agujero.size(); j++) {
                        //     cout << agujero[j] << " ";
                        // }
                        // cout << endl;
                    }
                }
            }


            delete [] sol;
        }
        
        // CPXwriteprob (env, lp, "lpCB.lp", "LP");

        ///Cuando salimos, pasamos a binaria y corremos un branch and bound
        char *ctype = new char[cantVariables];
        for (int i = 0; i < cantVariables; i++) {
            ctype[i] = 'B';
        }

        // cout << "Antes cambiar tipo" << endl;
        status = CPXcopyctype (env, lp, ctype);
        // cout << "Despues cambiar tipo" << endl;
        delete[] ctype;

        CPXgettime(env, &endtime);
        tiempoCutAndBranch = endtime - inittime;
        inittime = endtime;
    }

    ///Corremos el BB, ya sea porque esto es lo que queriamos originalemente, o porque terminamos con los planos de corte

    // cout << "ANTES" << endl;
    //CPXwriteprob (env, lp, "antesDeMip.lp", "LP");
    CPXmipopt(env,lp);
    // cout << "DESPUES" << endl;

    CPXgettime(env, &endtime);
    tiempoBranchAndBound = endtime - inittime;
    // inittime = endtime;
    
    status = CPXgettime(env, &endtime);

    if (status) {
        cerr << "Problema optimizando CPLEX" << endl;
        exit(1);
    }

    // Chequeamos el estado de la solucion.
    int solstat;
    char statstring[510];
    CPXCHARptr p;
    solstat = CPXgetstat(env, lp);
    p = CPXgetstatstring(env, solstat, statstring);
    string statstr(statstring);
    cout << endl << "Resultado de la optimizacion: " << statstring << endl;
    
    if(solstat!=CPXMIP_OPTIMAL && solstat!=CPXMIP_OPTIMAL_TOL && solstat!=CPXMIP_NODE_LIM_FEAS && solstat!=CPXMIP_TIME_LIM_FEAS){
        cout << "No hay solucion" << endl;
    }
    else{
        double objval;
        status = CPXgetobjval(env, lp, &objval);
            
        if (status) {
            cerr << "Problema obteniendo valor de mejor solucion." << endl;
            exit(1);
        }

        cout << "Datos de la resolucion: " << "\t" << objval << "\t" << tiempoPreparar + tiempoCutAndBranch + tiempoBranchAndBound << endl; 

        cout << "Tiempo en preparar: " << "\t" << tiempoPreparar << endl; 
        cout << "Tiempo en CB: " << "\t" << tiempoCutAndBranch << endl; 
        cout << "Tiempo en BB: " << "\t" << tiempoBranchAndBound << endl; 

        // Tomamos los valores de todas las variables. Estan numeradas de 0 a n-1.
        double *sol = new double[cantVariables];
        status = CPXgetx(env, lp, sol, 0, cantVariables - 1);

        if (status) {
            cerr << "Problema obteniendo la solucion del LP." << endl;
            exit(1);
        }

        impresionModelo(env, lp);

            
        // Solo escribimos las variables distintas de cero (tolerancia, 1E-05).
        //solfile << "Status de la solucion: " << statstr << endl;
        // for(int j=0; j<P; j++) {
        //     if(sol[j] > TOL) {
        //         cout << "W_" << j << " = " << sol[j] << endl;
        //     }
        // }
        // for(int i=0; i<N; i++) {
        //     for(int j=0; j<P; j++) {
        //         if(sol[P + P*i + j] > TOL) {
        //             cout << "X_" << i << "_" << j << " = " << sol[P+P*i+j] << endl;
        //         }
        //     }
        // }
        
        //solfile.close();

        // ==================== Devuelvo el grafo resultante coloreado, para graficar! ====================== //
        // ofstream streamEjes, streamLabels;
        //ofstream streamParticiones;
        // Tomamos los valores de la solucion y los escribimos a un archivo.
        // streamEjes.open(ejes);
        // for(int v1=0; v1<N; v1++) {
        //     for(int v2=v1+1; v2<N; v2++) {
        //         if (M[v1][v2] == 1) { 
        //             streamEjes << v1+1 << " " << v2+1 << endl;
        //         }
        //     }
        // } streamEjes.close();
        // cout << ejes << endl;
        
        // streamLabels.open(labels);
        // bool estaColoreado;
        // for(int v=0; v<N; v++){
        //     estaColoreado = false;
        //     for(int j=0; j<P; j++){
        //         if (sol[P + P*v + j] == 1) {
        //             streamLabels << v+1 << " " << j+1 << endl;
        //             estaColoreado = true;
        //         }
        //     }
        //     if(not estaColoreado) {
        //         streamLabels << v+1 << " " << 0 << endl;
        //     }
        // }
        // streamLabels.close();

        // delete [] sol;
    }

    return 0;
}