Пример #1
0
long GenModelCplex::Solve()
{
    if(!bcreated)
        throw string("Solve() not available : Problem not created yet");
    CplexData* d = static_cast<CplexData*>(solverdata);
    int status = 0;
    if(boolParam.count("qp") > 0 && boolParam["qp"])
        status = CPXqpopt(d->env, d->lp);
    else if(boolParam.count("mip") > 0 && boolParam["mip"])
        status = CPXmipopt(d->env, d->lp);
    else if(strParam.count("algo") > 0 && strParam["algo"] == "interior")
        status = CPXbaropt(d->env, d->lp);
    else if(strParam.count("algo") > 0 && strParam["algo"] == "dual")
        status = CPXdualopt(d->env, d->lp);
    else if(strParam.count("algo") > 0 && strParam["algo"] == "primal")
        status = CPXprimopt(d->env, d->lp);
    else if(strParam.count("algo") > 0 && strParam["algo"] == "concurrent")
    {
        //printf("choosing concurrent algo\n");
        CPXsetintparam (d->env, CPX_PARAM_LPMETHOD, CPX_ALG_CONCURRENT);
        status = CPXlpopt(d->env, d->lp);
    }
    else if(strParam.count("algo") > 0 && strParam["algo"] == "sifting")
    {
        CPXsetintparam (d->env, CPX_PARAM_LPMETHOD, CPX_ALG_SIFTING);
        status = CPXlpopt(d->env, d->lp);
    }
    else
        status = CPXlpopt(d->env, d->lp);

    return 0;
}
Пример #2
0
void CplexSolver::run() {
	CPXchgobjsen(_env, _prob, _is_minimize ? CPX_MIN : CPX_MAX);
	if (_is_mip) {
		CPXsetintparam(_env, CPX_PARAM_SOLUTIONTARGET, CPX_SOLUTIONTARGET_OPTIMALGLOBAL);
		CPXmipopt(_env, _prob);
	} else
		CPXlpopt(_env, _prob);
}
Пример #3
0
int
main (int argc, char *argv[])
{
   CPXENVptr env = NULL;
   CPXLPptr  lp = NULL;
   int       status = 0;
   int       j;
   int       numcols;
   double    totinv; 

   int       solstat;
   double    objval;
   double    *x = NULL;

   double    rrhs[1];
   char      rsense[1];
   int       rmatbeg[1];

   int       *indices = NULL;
   double    *values = NULL;
   char      *namestore = NULL;
   char      **nameptr = NULL;
   int       surplus, storespace;

   const char * datadir = argc <= 1 ? "../../../examples/data" : argv[1];
   char *prod = NULL;

   prod = (char *) malloc (strlen (datadir) + 1 + strlen("prod.lp") + 1);
   sprintf (prod, "%s/prod.lp", datadir);

   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXgeterrorstring will produce the text of
      the error message.  Note that CPXopenCPLEX produces no output,
      so the only way to see the cause of the error is to use
      CPXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON.  */

   if ( env == NULL ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn on output to the screen */

   status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on screen indicator, error %d.\n", status);
      goto TERMINATE;
   }

   /* Create the problem, using the filename as the problem name */

   lp = CPXcreateprob (env, &status, "prod.lp");

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout.  Note that most CPLEX routines return
      an error code to indicate the reason for failure.   */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now read the file, and copy the data into the created lp */

   status = CPXreadcopyprob (env, lp, prod, NULL);
   if ( status ) {
      fprintf (stderr, "Failed to read and copy the problem data.\n");
      goto TERMINATE;
   }

   /* Tell presolve to do only primal reductions,
      turn off simplex logging */

   status = CPXsetintparam (env, CPXPARAM_Preprocessing_Reduce, 1);
   if ( status ) {
      fprintf (stderr, "Failed to set CPXPARAM_Preprocessing_Reduce: %d\n", status);
      goto TERMINATE;
   }
   status = CPXsetintparam (env, CPXPARAM_Simplex_Display, 0);
   if ( status ) {
      fprintf (stderr, "Failed to set CPXPARAM_Simplex_Display: %d\n", status);
      goto TERMINATE;
   } 

   if ( status ) {
      fprintf (stderr, "Failure to set parameters\n");
      goto TERMINATE;
   } 


   /* Optimize the problem and obtain solution. */

   status = CPXlpopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to optimize profit LP.\n");
      goto TERMINATE;
   }

   solstat = CPXgetstat (env, lp);
   status  = CPXgetobjval (env, lp, &objval);

   if ( status || solstat != CPX_STAT_OPTIMAL ) {
      fprintf (stderr, "Solution failed. Status %d, solstat %d.\n",
               status, solstat);
      goto TERMINATE;
   }
   printf ("Profit objective value is %g\n", objval);


   /* Allocate space for column names */

   numcols = CPXgetnumcols (env, lp);
   if ( !numcols ) {
      fprintf (stderr, "No columns in problem\n");
      goto TERMINATE;
   }

   CPXgetcolname (env, lp, NULL, NULL, 0, &surplus, 0, numcols-1);
   storespace = - surplus;

   namestore = (char *) malloc (storespace * sizeof(char));
   nameptr   = (char **) malloc (numcols * sizeof(char *));
   if ( namestore == NULL  ||  nameptr == NULL ) {
      fprintf (stderr, "No memory for column names\n");
      goto TERMINATE;
   }
 
   status = CPXgetcolname (env, lp, nameptr, namestore, storespace,
                           &surplus, 0, numcols-1);
   if ( status ) {
      fprintf (stderr, "Failed to get column names\n");
      goto TERMINATE;
   }

   /* Allocate space for solution */

   x = (double *) malloc (numcols * sizeof(double));

   if ( x == NULL ) {
      fprintf (stderr,"No memory for solution.\n");
      goto TERMINATE;
   }

   status = CPXgetx (env, lp, x, 0, numcols-1);
   if ( status ) {
      fprintf (stderr, "Failed to obtain primal solution.\n");
      goto TERMINATE;
   }

   totinv = 0;
   for (j = 0; j < numcols; j++) {
      if ( !strncmp (nameptr[j], "inv", 3) )  totinv += x[j];
   }
   printf ("Inventory level under profit objective is %g\n", totinv);

   /* Allocate space for a constraint */

   indices = (int *)    malloc (numcols * sizeof (int));
   values  = (double *) malloc (numcols * sizeof (double));

   if ( indices == NULL  ||  values == NULL ) {
      fprintf (stderr, "No memory for constraint\n");
      goto TERMINATE;
   }

   /* Get profit objective and add it as a constraint */

   status = CPXgetobj (env, lp, values, 0, numcols-1);
   if ( status ) {
      fprintf (stderr,
              "Failed to get profit objective.  Status %d\n", status);
      goto TERMINATE;
   }
   for (j = 0; j < numcols; j++) {
      indices[j] = j;
   }

   rrhs[0]    = objval - fabs (objval) * 1e-6;
   rsense[0]  = 'G';
   rmatbeg[0] = 0;

   status = CPXpreaddrows (env, lp, 1, numcols, rrhs, rsense,
                           rmatbeg, indices, values, NULL);

   if ( status ) {
      fprintf (stderr,
              "Failed to add objective as constraint.  Status %d\n",
              status);
      goto TERMINATE;
   }

   /* Set up objective to maximize negative of sum of inventory */

   totinv = 0;
   for (j = 0; j < numcols; j++) {
      if ( strncmp (nameptr[j], "inv", 3) ) {
         values[j] = 0.0;
      }
      else {
         values[j] = - 1.0;
      }
   }

   status = CPXprechgobj (env, lp, numcols, indices, values);

   if ( status ) {
      fprintf (stderr,
              "Failed to change to inventory objective.  Status %d\n",
              status);
      goto TERMINATE;
   }

   status = CPXlpopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Optimization on inventory level failed. Status %d.\n",
              status);
      goto TERMINATE;
   }

   solstat = CPXgetstat (env, lp);
   status  = CPXgetobjval (env, lp, &objval);
   if ( status  ||  solstat != CPX_STAT_OPTIMAL ) {
      fprintf (stderr, "Solution failed. Status %d, solstat %d.\n",
               status, solstat);
      goto TERMINATE;
   }

   printf("Solution status %d.\n", solstat);
   printf ("Inventory level after optimization is %g\n", -objval);


   status = CPXgetx (env, lp, x, 0, numcols-1);
   if ( status ) {
      fprintf (stderr, "Failed to obtain primal solution.\n");
      goto TERMINATE;
   }

   printf("Found solution");

   /* Write out the solution */

   printf ("\n");
   for (j = 0; j < numcols; j++) {
      printf ( "%s:  Value = %17.10g\n", nameptr[j], x[j]);
   }


TERMINATE:

   /* Free the filename */

   free_and_null ((char **) &prod);

   /* Free up the basis and solution */

   free_and_null ((char **) &indices);
   free_and_null ((char **) &values);
   free_and_null ((char **) &nameptr);
   free_and_null ((char **) &namestore);
   free_and_null ((char **) &x);


   /* Free up the problem, if necessary */

   if ( lp != NULL ) {
      status = CPXfreeprob (env, &lp);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status);
      }
   }

   /* Free up the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

      /* Note that CPXcloseCPLEX produces no output,
         so the only way to see the cause of the error is to use
         CPXgeterrorstring.  For other CPLEX routines, the errors will
         be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */

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

}  /* END main */
Пример #4
0
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;
}
Пример #5
0
int
main (int argc, char *argv[])
{
   /* Declare and allocate space for the variables and arrays where we will
      store the optimization results including the status, objective value,
      maximum bound violation, variable values, and basis. */

   int      solnstat, solnmethod, solntype;
   double   objval, maxviol;
   double   *x     = NULL;
   int      *cstat = NULL;
   int      *rstat = NULL;

   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status = 0;
   int           j;
   int           cur_numrows, cur_numcols;
   char          **cur_colname = NULL;
   char          *cur_colnamestore = NULL;
   int           cur_colnamespace;
   int           surplus;
   int           method;

   char          *basismsg;

   /* Check the command line arguments */

   if (( argc != 3 )                                              ||
       ( strchr ("podhbnsc", argv[2][0]) == NULL )  ) {
      usage (argv[0]);
      goto TERMINATE;
   }

   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXgeterrorstring will produce the text of
      the error message.  Note that CPXopenCPLEX produces no output,
      so the only way to see the cause of the error is to use
      CPXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON.  */

   if ( env == NULL ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn on output to the screen */

   status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on screen indicator, error %d.\n", status);
      goto TERMINATE;
   }

   /* Create the problem, using the filename as the problem name */

   lp = CPXcreateprob (env, &status, argv[1]);

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout.  Note that most CPLEX routines return
      an error code to indicate the reason for failure.   */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now read the file, and copy the data into the created lp */

   status = CPXreadcopyprob (env, lp, argv[1], NULL);
   if ( status ) {
      fprintf (stderr, "Failed to read and copy the problem data.\n");
      goto TERMINATE;
   }

   /* Optimize the problem and obtain solution. */

   switch (argv[2][0]) {
      case 'o':
         method = CPX_ALG_AUTOMATIC;
         break;
      case 'p':
         method = CPX_ALG_PRIMAL;
         break;
      case 'd':
         method = CPX_ALG_DUAL;
         break;
      case 'n':
         method = CPX_ALG_NET;
         break;
      case 'h':
         method = CPX_ALG_BARRIER;
         break;
      case 'b':
         method = CPX_ALG_BARRIER;
         status = CPXsetintparam (env, CPXPARAM_Barrier_Crossover,
                                  CPX_ALG_NONE);
         if ( status ) {
            fprintf (stderr, 
                     "Failed to set the crossover method, error %d.\n", status);
            goto TERMINATE;
         }
         break;
      case 's':
         method = CPX_ALG_SIFTING;
         break;
      case 'c':
         method = CPX_ALG_CONCURRENT;
         break;
      default:
         method = CPX_ALG_NONE;
         break;
   }

   status = CPXsetintparam (env, CPXPARAM_LPMethod, method);
   if ( status ) {
      fprintf (stderr, 
               "Failed to set the optimization method, error %d.\n", status);
      goto TERMINATE;
   }
   

   status = CPXlpopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to optimize LP.\n");
      goto TERMINATE;
   }

   solnstat = CPXgetstat (env, lp);

   if      ( solnstat == CPX_STAT_UNBOUNDED ) {
      printf ("Model is unbounded\n");
      goto TERMINATE;
   }
   else if ( solnstat == CPX_STAT_INFEASIBLE ) {
      printf ("Model is infeasible\n");
      goto TERMINATE;
   }
   else if ( solnstat == CPX_STAT_INForUNBD ) {
      printf ("Model is infeasible or unbounded\n");
      goto TERMINATE;
   }

   status = CPXsolninfo (env, lp, &solnmethod, &solntype, NULL, NULL);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution info.\n");
      goto TERMINATE;
   }
   printf ("Solution status %d, solution method %d\n", solnstat, solnmethod);

   if ( solntype == CPX_NO_SOLN ) {
      fprintf (stderr, "Solution not available.\n");
      goto TERMINATE;
   }
    
   status = CPXgetobjval (env, lp, &objval);
   if ( status ) {
      fprintf (stderr, "Failed to obtain objective value.\n");
      goto TERMINATE;
   }
   printf ("Objective value %.10g.\n", objval);

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is.  cur_numrows and cur_numcols store the 
      current number of rows and columns, respectively.  */

   cur_numcols = CPXgetnumcols (env, lp);
   cur_numrows = CPXgetnumrows (env, lp);

   /* Retrieve basis, if one is available */

   if ( solntype == CPX_BASIC_SOLN ) {
      cstat = (int *) malloc (cur_numcols*sizeof(int));
      rstat = (int *) malloc (cur_numrows*sizeof(int));
      if ( cstat == NULL || rstat == NULL ) {
         fprintf (stderr, "No memory for basis statuses.\n");
         goto TERMINATE;
      }

      status = CPXgetbase (env, lp, cstat, rstat);
      if ( status ) {
         fprintf (stderr, "Failed to get basis; error %d.\n", status);
         goto TERMINATE;
      }
   }
   else {
      printf ("No basis available\n");
   }


   /* Retrieve solution vector */

   x = (double *) malloc (cur_numcols*sizeof(double));
   if ( x == NULL ) {
      fprintf (stderr, "No memory for solution.\n");
      goto TERMINATE;
   }

   status = CPXgetx (env, lp, x, 0, cur_numcols-1);
   if ( status ) {
      fprintf (stderr, "Failed to obtain primal solution.\n");
      goto TERMINATE;
   }


   /* Now get the column names for the problem.  First we determine how
      much space is used to hold the names, and then do the allocation.
      Then we call CPXgetcolname() to get the actual names. */ 

   status = CPXgetcolname (env, lp, NULL, NULL, 0, &surplus, 0,
                           cur_numcols-1);

   if (( status != CPXERR_NEGATIVE_SURPLUS ) &&
       ( status != 0 )                         )  {
      fprintf (stderr, 
               "Could not determine amount of space for column names.\n");
      goto TERMINATE;
   }

   cur_colnamespace = - surplus;
   if ( cur_colnamespace > 0 ) {
      cur_colname      = (char **) malloc (sizeof(char *)*cur_numcols);
      cur_colnamestore = (char *)  malloc (cur_colnamespace);
      if ( cur_colname      == NULL ||
           cur_colnamestore == NULL   ) {
         fprintf (stderr, "Failed to get memory for column names.\n");
         status = -1;
         goto TERMINATE;
      }
      status = CPXgetcolname (env, lp, cur_colname, cur_colnamestore, 
                              cur_colnamespace, &surplus, 0, cur_numcols-1);
      if ( status ) {
         fprintf (stderr, "CPXgetcolname failed.\n");
         goto TERMINATE;
      }
   }
   else {
      printf ("No names associated with problem.  Using Fake names.\n");
   }

   /* Write out the solution */

   for (j = 0; j < cur_numcols; j++) {
      if ( cur_colnamespace > 0 ) {
         printf ("%-16s:  ", cur_colname[j]);
      }
      else {
         printf ("Fake%-6.6d      :  ", j);;
      }
      printf ("%17.10g", x[j]);
      if ( cstat != NULL ) {
         switch (cstat[j]) {
            case CPX_AT_LOWER:
               basismsg = "Nonbasic at lower bound";
               break;
            case CPX_BASIC:
               basismsg = "Basic";
               break;
            case CPX_AT_UPPER:
               basismsg = "Nonbasic at upper bound";
               break;
            case CPX_FREE_SUPER:
               basismsg = "Superbasic, or free variable at zero";
               break;
            default:
               basismsg = "Bad basis status";
               break;
         }
         printf ("  %s",basismsg);
      }
      printf ("\n");
   }

   /* Display the maximum bound violation. */

   status = CPXgetdblquality (env, lp, &maxviol, CPX_MAX_PRIMAL_INFEAS);
   if ( status ) {
      fprintf (stderr, "Failed to obtain bound violation.\n");
      goto TERMINATE;
   }
   printf ("Maximum bound violation = %17.10g\n", maxviol);

   
TERMINATE:

   /* Free up the basis and solution */

   free_and_null ((char **) &cstat);
   free_and_null ((char **) &rstat);
   free_and_null ((char **) &x);
   free_and_null ((char **) &cur_colname);
   free_and_null ((char **) &cur_colnamestore);

   /* Free up the problem, if necessary */

   if ( lp != NULL ) {
      status = CPXfreeprob (env, &lp);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status);
      }
   }

   /* Free up the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

      /* Note that CPXcloseCPLEX produces no output,
         so the only way to see the cause of the error is to use
         CPXgeterrorstring.  For other CPLEX routines, the errors will
         be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */

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

}  /* END main */
Пример #6
0
OptSolutionData* CPLEXRunSolver(int ProbType) {
	OptSolutionData* NewSolution = NULL;
	int Status = 0;
	if (ProbType == LP) {
		Status = CPXsetintparam (CPLEXenv, CPX_PARAM_LPMETHOD, CPX_ALG_AUTOMATIC);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		Status = CPXsetintparam (CPLEXenv, CPX_PARAM_SIMDISPLAY, 0);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		Status = CPXchgprobtype(CPLEXenv, CPLEXModel, CPXPROB_LP);
		Status = CPXlpopt(CPLEXenv, CPLEXModel);
	} else if(ProbType == MILP || ProbType == MIQP) {
		//Setting the bound tightening on high
		Status = CPXsetintparam (CPLEXenv, CPX_PARAM_BNDSTRENIND, 1);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		//Setting tolerance to 1e-9 instead of 1e-6
		double tolerance = atof(GetParameter("Solver tolerance").data());
		Status = CPXsetdblparam(CPLEXenv,CPX_PARAM_EPRHS, tolerance);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		Status = CPXsetdblparam(CPLEXenv,CPX_PARAM_EPINT, tolerance);
		if (Status) {
			FErrorFile() << "Failed to set the optimization method." << endl;
			FlushErrorFile();
			return NULL;
		}
		//Deactivates all messages from MIP solver
		Status = CPXchgprobtype(CPLEXenv, CPLEXModel, CPXPROB_MILP);
		Status = CPXmipopt (CPLEXenv, CPLEXModel);
	} else if(ProbType == QP) {
		Status = CPXqpopt (CPLEXenv, CPLEXModel);
	}
	if (Status ) {
		cout << "Failed to optimize LP." << endl;
		return NULL;
	}
	int Temp = CPXgetstat (CPLEXenv, CPLEXModel);
	NewSolution = new OptSolutionData;
	if (Temp == CPX_STAT_UNBOUNDED) {
		cout << "Model is unbounded" << endl;
		FErrorFile() << "Model is unbounded" << endl;
		FlushErrorFile();
		NewSolution->Status = UNBOUNDED;
		return NewSolution;
	} else if (Temp == CPX_STAT_INFEASIBLE) {
		cout << "Model is infeasible" << endl;
		FErrorFile() << "Model is infeasible" << endl;
		FlushErrorFile();
		NewSolution->Status = INFEASIBLE;
		return NewSolution;
	} else if (Temp == CPX_STAT_INForUNBD ) {
		cout << "Model is infeasible or unbounded" << endl;
		FErrorFile() << "Model is infeasible or unbounded" << endl;
		FlushErrorFile();
		NewSolution->Status = INFEASIBLE;
		return NewSolution;
	} else {
		NewSolution->Status = SUCCESS;
	}

	int NumberColumns = CPXgetnumcols (CPLEXenv, CPLEXModel);
	int NumberRows = CPXgetnumrows (CPLEXenv, CPLEXModel);
	NewSolution->NumVariables = NumberColumns;
	NewSolution->SolutionData.resize(NumberColumns);

	double* x = new double[NumberColumns];
	
	if (ProbType == MILP || ProbType == MIQP) {
		Status = CPXgetmipobjval (CPLEXenv, CPLEXModel, &(NewSolution->Objective));
		Status = CPXgetmipx (CPLEXenv, CPLEXModel, x, 0, NumberColumns-1);
	} else {
		Status = CPXsolution(CPLEXenv,CPLEXModel,NULL,&(NewSolution->Objective),x,NULL,NULL,NULL);
	}
	
	if ( Status ) {
		cout << "Failed to obtain objective value." << endl;
		delete [] x;
		NewSolution->Status = INFEASIBLE;
		return NewSolution;
	}

	cout << "Objective value: " << NewSolution->Objective << endl;
	/*
	string* StrNames = new string[NumberColumns];
	char** Names = new char*[NumberColumns];
	char* NameStore = new char[7*NumberColumns];
	int Surplus = 0;

	Status = CPXgetcolname(CPLEXenv, CPLEXModel, Names, NameStore, 7*NumberColumns, &Surplus, 0, NumberColumns-1);
	if (Status) {
		FErrorFile() << "Failed to get column names." << endl;
		FlushErrorFile();
		delete [] StrNames;
		delete [] Names;
		delete [] NameStore;
		delete [] x;
		delete NewSolution;
		return NULL;
	}
	*/
	for (int i=0; i < NumberColumns; i++) {
		//StrNames[i].assign(Names[i]);
		//StrNames[i] = StrNames[i].substr(1, StrNames[i].length()-1);
		//NewSolution->SolutionData[atoi(StrNames[i].data())-1] = x[i];
		NewSolution->SolutionData[i] = x[i];
	}
	/*
	delete [] StrNames;
	delete [] Names;
	delete [] NameStore;
	*/
	delete [] x;

	return NewSolution;
}
extern int solve_allocation(int nodeSize, int windowSize, int timeout, 
			sched_nodeinfo_t *node_array, 
			solver_job_list_t *job_array)
{
	solver_job_list_t *solver_job_ptr;
	int solstat;
	int n = windowSize, m = nodeSize;
	double objval;
	double *x = NULL;
	double *pi = NULL;
	double *slack = NULL;
	double *dj = NULL;
	double *obj = NULL;
	int NUMCOLS = n * (2 * m + 2);

	CPXENVptr env = NULL;
	CPXLPptr lp = NULL;
	int status = 0;
	int i, j, k;
	int cur_numrows, cur_numcols;
	char envstr[256] = "ILOG_LICENSE_FILE=/home/seren/ILOG/CPLEX_Studio_AcademicResearch122/licenses/access.ilm";

	if ( envstr != NULL ) {
		CPXputenv (envstr);
	}

	env = CPXopenCPLEX (&status);
	if ( env == NULL ) {
		char  errmsg[1024];
		CPXgeterrorstring (env, status, errmsg);
		fprintf (stderr, "%s", errmsg);
		goto TERMINATE;
	}

	status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON);
	if ( status ) {
		goto TERMINATE;
	}

	status = CPXsetintparam (env, CPX_PARAM_DATACHECK, CPX_ON);
	if ( status ) {
		goto TERMINATE;
	}

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

	if ( lp == NULL ) {
		goto TERMINATE;
	}

	obj = (double*)malloc(NUMCOLS * sizeof(double));
	status = CPXsetdblparam(env,CPX_PARAM_TILIM,5);
	status = populatebynonzero (env, lp, nodeSize, windowSize, timeout, node_array, job_array);

	if ( status ) {
		fprintf (stderr, "Failed to populate problem.");
		goto TERMINATE;
	}

	status = CPXlpopt (env, lp);
	if ( status ) {
		fprintf (stderr, "Failed to optimize LP.");
		goto TERMINATE;
	}

	cur_numrows = CPXgetnumrows (env, lp);
	cur_numcols = CPXgetnumcols (env, lp);
	x = (double *) malloc (cur_numcols * sizeof(double));
	slack = (double *) malloc (cur_numrows * sizeof(double));
	dj = (double *) malloc (cur_numcols * sizeof(double));
	pi = (double *) malloc (cur_numrows * sizeof(double));

	if ( x == NULL ||
		slack == NULL ||
		dj    == NULL ||
		pi    == NULL   ) {
		status = CPXERR_NO_MEMORY;
		goto TERMINATE;
	}

	status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
	if ( status ) {
		goto TERMINATE;
	}

	/*debug3("\nSolution status = %d\n", solstat);*/
	printf("Solution value  = %f\n\n", objval);

	/*
	for (i = 0; i < cur_numrows; i++) {
		printf ("Row %d:  Slack = %10f  Pi = %10f\n", i, slack[i], pi[i]);
	}
	
	for (j = 0; j < cur_numcols; j++) {
		printf ("Column %d:  Value = %10f  Reduced cost = %10f\n",
		  j, x[j], dj[j]);
	}
	*/
	/*debug3("sending solution results to slurm");*/
/*
	for (j = 0; j < windowSize; j++) {
		if (x[j] > 0) {
			solver_job_ptr = &job_array[j];
			solver_job_ptr->node_bitmap = (bitstr_t *) bit_alloc (node_record_count);
			solver_job_ptr->job_ptr->details->req_node_bitmap = (bitstr_t *) bit_alloc (node_record_count);
			solver_job_ptr->onnodes = (int *) xmalloc (sizeof(int)*node_record_count);
			solver_job_ptr->job_ptr->details->req_node_layout = (int *)xmalloc(sizeof(int) * node_record_count);
			solver_job_ptr->job_ptr->details->req_node_bitmap = (bitstr_t *) bit_alloc (node_record_count);
			for (i = 0; i < nodeSize; i++) {
				k = (1 + i) * windowSize + j;
				if (x[k] > 0) {
					bit_set (solver_job_ptr->node_bitmap, (bitoff_t) (i));
					bit_set (solver_job_ptr->job_ptr->details->req_node_bitmap, (bitoff_t) (i));		
					node_array[i].rem_cpus -= x[k];
					node_array[i].rem_gpus -= solver_job_ptr->gpu;
					solver_job_ptr->onnodes[i] = x[k]; 
					solver_job_ptr->job_ptr->details->req_node_layout[i] = solver_job_ptr->onnodes[i]; 
					solver_job_ptr->alloc_total += x[k];
				}
			}
		} else
			job_array[j].alloc_total = 0;
	} 
*/
/*	status = CPXwriteprob (env, lp, "lpex1.lp", NULL);
	if ( status ) {
		fprintf (stderr, "Failed to write LP to disk.");
		goto TERMINATE;
	}
*/
TERMINATE:

	free_and_null ((char **) &x);
	free_and_null ((char **) &slack);
	free_and_null ((char **) &dj);
	free_and_null ((char **) &pi);

	if ( lp != NULL ) {
		status = CPXfreeprob (env, &lp);
		if ( status ) {
			fprintf (stderr, "CPXfreeprob failed, error code %d.", status);
		}
	}

	if ( env != NULL ) {
		status = CPXcloseCPLEX (&env);
		if ( status ) {
			char  errmsg[1024];
			fprintf (stderr, "Could not close CPLEX environment.");
			CPXgeterrorstring (env, status, errmsg);
			fprintf (stderr, "%s", errmsg);
		}
	}     
	
	return (status);
}
Пример #8
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);
}
Пример #9
0
int
main (int  argc,
      char *argv[])
{
   int status = 0;

   /* Declare and allocate space for the variables and arrays where
      we will store the optimization results, including the status, 
      objective value, and variable values */
   
   int    solstat;
   double objval, relobj;
   double *x = NULL;
	 
   MYCB info;

   CPXENVptr env = NULL;
   CPXLPptr  lp  = NULL;
   CPXLPptr  lpclone = NULL;

   int j;
   int cur_numcols;

   /* Check the command line arguments */

   if ( argc != 2 ) {
      usage (argv[0]);
      goto TERMINATE;
   }

   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXgeterrorstring will produce the text of
      the error message.  Note that CPXopenCPLEX produces no
      output, so the only way to see the cause of the error is to use
      CPXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput parameter is set to CPX_ON */

   if ( env == NULL ) {
      char errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn on output to the screen */

   status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on screen indicator, error %d.\n",
               status);
      goto TERMINATE;
   }


   /* Turn on traditional search for use with control callbacks */

   status = CPXsetintparam (env, CPXPARAM_MIP_Strategy_Search,
                            CPX_MIPSEARCH_TRADITIONAL);
   if ( status )  goto TERMINATE;

   /* Create the problem, using the filename as the problem name */

   lp = CPXcreateprob (env, &status, argv[1]);

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout.  Note that most CPLEX routines return
      an error code to indicate the reason for failure */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now read the file, and copy the data into the created lp */

   status = CPXreadcopyprob (env, lp, argv[1], NULL);
   if ( status ) {
      fprintf (stderr,
               "Failed to read and copy the problem data.\n");
      goto TERMINATE;
   }

   /* We transfer a problem with semi-continuous or semi-integer
      variables to a MIP problem by adding variables and  
      constraints. So in MIP callbacks, the size of the problem
      is changed and this example won't work for such problems */

   if ( CPXgetnumsemicont (env, lp) + CPXgetnumsemiint (env, lp) ) {
      fprintf (stderr, 
         "Not for problems with semi-continuous or semi-integer variables.\n");
      goto TERMINATE;
   }

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is. cur_numcols store the current number 
      of columns */

   cur_numcols = CPXgetnumcols (env, lp);

   x = (double *) malloc (cur_numcols * sizeof (double));
   if ( x == NULL ) {
      fprintf (stderr, "Memory allocation failed.\n");
      goto TERMINATE;
   }

   /* Solve relaxation of MIP */

   /* Clone original model */

   lpclone = CPXcloneprob (env, lp, &status);
   if ( status ) {
      fprintf (stderr, "Failed to clone problem.\n");
      goto TERMINATE;
   }

   /* Relax */

   status = CPXchgprobtype (env, lpclone, CPXPROB_LP);
   if ( status ) {
      fprintf (stderr, "Failed to relax problem.\n");
      goto TERMINATE;
   }

   /* Solve LP relaxation of original model using "default"
      LP solver */

   status = CPXlpopt (env, lpclone);
   if ( status ) {
      fprintf (stderr, "Failed to solve relaxation.\n");
      goto TERMINATE;
   }

   status = CPXsolution (env, lpclone, NULL, &relobj, x, NULL,
                         NULL, NULL);
   if ( status ) {
      fprintf (stderr, "Failed to extract solution.\n");
      goto TERMINATE;
   }

   printf ("Solution status = %d", CPXgetstat(env,lpclone));
   printf ("\nLP relaxation objective: %.4e\n\n", relobj);

   /* Set up solve callback */
   
   info.count = 0;
   info.mip   = lp;
   info.relx  = x;

   status = CPXsetsolvecallbackfunc (env, &solvecallback,
                                     (void *) &info);
   if ( status ) {
      fprintf (stderr, "Failed to set solve callback.\n");
      goto TERMINATE;
   }

   /* Optimize the problem and obtain solution */

   status = CPXmipopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to optimize MIP.\n");
      goto TERMINATE;
   }

   solstat = CPXgetstat (env, lp);

   status = CPXgetobjval (env, lp, &objval);
   if ( status ) {
      fprintf (stderr,"Failed to obtain objective value.\n");
      goto TERMINATE;
   }

   printf ("Solution status %d.\n", solstat); 
   printf ("Objective value %.10g\n", objval);

   status = CPXgetx (env, lp, x, 0, cur_numcols-1);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution.\n");
      goto TERMINATE;
   }

   /* Write out the solution */

   for (j = 0; j < cur_numcols; j++) {
      if ( fabs (x[j]) > 1e-10 ) {
         printf ( "Column %d:  Value = %17.10g\n", j, x[j]);
      }
   }
   

TERMINATE:

   /* Free the solution vector */

   free_and_null ((char **) &x);

   /* Free the problem as allocated by CPXcreateprob and
      CPXreadcopyprob, if necessary */

   if ( lp != NULL ) {
      status = CPXfreeprob (env, &lp);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n",
                  status);
      }
   }

   /* Free the cloned lp as allocated by CPXcloneprob,
      if necessary */

   if ( lpclone != NULL ) {
      status = CPXfreeprob (env, &lpclone);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n",
                  status);
      }
   }

   /* Free the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

      /* Note that CPXcloseCPLEX produces no output, so the only 
         way to see the cause of the error is to use
         CPXgeterrorstring.  For other CPLEX routines, the errors 
         will be seen if the CPXPARAM_ScreenOutput parameter is set to 
         CPX_ON */

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

} /* END main */
Пример #10
0
int
main (void)
{
   char     probname[16];  /* Problem name is max 16 characters */

   /* Declare and allocate space for the variables and arrays where we
      will store the optimization results including the status, objective
      value, variable values, dual values, row slacks and variable
      reduced costs. */

   int      solstat;
   double   objval;
   double   x[NUMCOLS];
   double   pi[NUMROWS];
   double   slack[NUMROWS];
   double   dj[NUMCOLS];


   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status;
   int           i, j;
   int           cur_numrows, cur_numcols;

   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  The error message will be printed at the end of the
      program. */

   if ( env == NULL ) {
      fprintf (stderr, "Could not open CPLEX environment.\n");
      goto TERMINATE;
   }

   /* Turn *off* output to the screen since we'll be producing it
      via the callback function.  This also means we won't see any
      CPLEX generated errors, but we'll handle that at the end of
      the program. */

   status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_OFF);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn off screen indicator, error %d.\n", status);
      goto TERMINATE;
   }

   /* Create the problem. */

   strcpy (probname, "example");
   lp = CPXcreateprob (env, &status, probname);

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, we wouldn't see
      an error message from CPXcreateprob since we turned off the 
      CPXPARAM_ScreenOutput parameter above.  The only way to see this message
      would be to use the CPLEX message handler, but that clutters up
      the simplicity of this example, which has a point of illustrating
      the CPLEX callback functionality.   */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now populate the problem with the data. */

   status = populatebycolumn (env, lp);

   if ( status ) {
      fprintf (stderr, "Failed to populate problem data.\n");
      goto TERMINATE;
   }

   status = CPXsetlpcallbackfunc (env, mycallback, NULL);
   if ( status ) {
      fprintf (stderr, "Failed to set callback function.\n");
      goto TERMINATE;
   }

   /* Optimize the problem and obtain solution. */

   status = CPXsetintparam (env, CPXPARAM_LPMethod, CPX_ALG_PRIMAL);
   if ( status ) {
      fprintf (stderr, 
               "Failed to set the optimization method, error %d.\n", status);
      goto TERMINATE;
   }


   status = CPXlpopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to optimize LP.\n");
      goto TERMINATE;
   }

   /* Turn off the callback function.  This isn't strictly necessary,
      but is good practice.  Note that the cast in front of NULL
      is only necessary for some compilers.   */

   status = CPXsetlpcallbackfunc (env,
              (int (CPXPUBLIC *)(CPXCENVptr, void *, int, void *)) NULL, NULL);

   if ( status ) {
      fprintf (stderr, "Failed to turn off callback function.\n");
      goto TERMINATE;
   }

   status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution.\n");
      goto TERMINATE;
   }


   /* Write the output to the screen. */

   printf ("\nSolution status = %d\n", solstat);
   printf ("Solution value  = %f\n\n", objval);

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is, rather than using sizes from when the problem
      was built.  cur_numrows and cur_numcols store the current number 
      of rows and columns, respectively.  */

   cur_numrows = CPXgetnumrows (env, lp);
   cur_numcols = CPXgetnumcols (env, lp);
   for (i = 0; i < cur_numrows; i++) {
      printf ("Row %d:  Slack = %10f  Pi = %10f\n", i, slack[i], pi[i]);
   }

   for (j = 0; j < cur_numcols; j++) {
      printf ("Column %d:  Value = %10f  Reduced cost = %10f\n",
              j, x[j], dj[j]);
   }

   /* Finally, write a copy of the problem to a file. */

   status = CPXwriteprob (env, lp, "lpex4.lp", NULL);
   if ( status ) {
      fprintf (stderr, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }
   
   
TERMINATE:

   /* Free up the problem as allocated by CPXcreateprob, if necessary */

   if ( lp != NULL ) {
      int  frstatus;
      frstatus = CPXfreeprob (env, &lp);
      if ( frstatus ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n", frstatus);
         if (( !status ) && frstatus )  status = frstatus;
      }
   }

   /* Free up the CPLEX environment, if necessary */

   if ( env != NULL ) {
      int  clstatus;
      clstatus = CPXcloseCPLEX (&env);

      if ( clstatus ) {
         fprintf (stderr, "CPXcloseCPLEX failed, error code %d.\n", clstatus);
         if (( !status ) && clstatus )  status = clstatus;
      }
   }

   if ( status ) {
      char  errmsg[CPXMESSAGEBUFSIZE];

      /* Note that since we have turned off the CPLEX screen indicator,
         we'll need to print the error message ourselves. */

      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
   }
     
   return (status);

}  /* END main */
int
main (int argc, char **argv)
{
   /* Declare and allocate space for the variables and arrays where we
      will store the optimization results including the status, objective
      value, variable values, dual values, row slacks and variable
      reduced costs. */

   int      solstat;
   double   objval;
   double   *x = NULL;
   double   *pi = NULL;
   double   *slack = NULL;
   double   *dj = NULL;


   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status = 0;
   int           i, j;
   int           cur_numrows, cur_numcols;

   /* Check the command line arguments */

   if (( argc != 2 )                                         ||
       ( argv[1][0] != '-' )                                 ||
       ( strchr ("rcn", argv[1][1]) == NULL )  ) {
      usage (argv[0]);
      goto TERMINATE;
   }

   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXgeterrorstring will produce the text of
      the error message.  Note that CPXopenCPLEX produces no output,
      so the only way to see the cause of the error is to use
      CPXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON.  */

   if ( env == NULL ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn on output to the screen */

   status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on screen indicator, error %d.\n", status);
      goto TERMINATE;
   }

   /* Turn on data checking */

   status = CPXsetintparam (env, CPXPARAM_Read_DataCheck, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on data checking, error %d.\n", status);
      goto TERMINATE;
   }


   /* Create the problem. */

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

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout.  */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now populate the problem with the data.  For building large
      problems, consider setting the row, column and nonzero growth
      parameters before performing this task. */

   switch (argv[1][1]) {
      case 'r':
         status = populatebyrow (env, lp);
         break;
      case 'c':
         status = populatebycolumn (env, lp);
         break;
      case 'n':
         status = populatebynonzero (env, lp);
         break;
   }

   if ( status ) {
      fprintf (stderr, "Failed to populate problem.\n");
      goto TERMINATE;
   }

   /* Optimize the problem and obtain solution. */

   status = CPXlpopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to optimize LP.\n");
      goto TERMINATE;
   }

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is, rather than using sizes from when the problem
      was built.  cur_numrows and cur_numcols store the current number 
      of rows and columns, respectively.  */

   cur_numrows = CPXgetnumrows (env, lp);
   cur_numcols = CPXgetnumcols (env, lp);

   x = (double *) malloc (cur_numcols * sizeof(double));
   slack = (double *) malloc (cur_numrows * sizeof(double));
   dj = (double *) malloc (cur_numcols * sizeof(double));
   pi = (double *) malloc (cur_numrows * sizeof(double));

   if ( x     == NULL ||
        slack == NULL ||
        dj    == NULL ||
        pi    == NULL   ) {
      status = CPXERR_NO_MEMORY;
      fprintf (stderr, "Could not allocate memory for solution.\n");
      goto TERMINATE;
   }

   status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution.\n");
      goto TERMINATE;
   }

   /* Write the output to the screen. */

   printf ("\nSolution status = %d\n", solstat);
   printf ("Solution value  = %f\n\n", objval);

   for (i = 0; i < cur_numrows; i++) {
      printf ("Row %d:  Slack = %10f  Pi = %10f\n", i, slack[i], pi[i]);
   }

   for (j = 0; j < cur_numcols; j++) {
      printf ("Column %d:  Value = %10f  Reduced cost = %10f\n",
              j, x[j], dj[j]);
   }

   /* Finally, write a copy of the problem to a file. */

   status = CPXwriteprob (env, lp, "lpex1.lp", NULL);
   if ( status ) {
      fprintf (stderr, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }

   
TERMINATE:

   /* Free up the solution */

   free_and_null ((char **) &x);
   free_and_null ((char **) &slack);
   free_and_null ((char **) &dj);
   free_and_null ((char **) &pi);

   /* Free up the problem as allocated by CPXcreateprob, if necessary */

   if ( lp != NULL ) {
      status = CPXfreeprob (env, &lp);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status);
      }
   }

   /* Free up the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

      /* Note that CPXcloseCPLEX produces no output,
         so the only way to see the cause of the error is to use
         CPXgeterrorstring.  For other CPLEX routines, the errors will
         be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */

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

}  /* END main */
Пример #12
0
extern int solve_allocation(int nodeSize, int windowSize, int timeout, 
			sched_nodeinfo_t *node_array, 
			solver_job_list_t *job_array)
{
	solver_job_list_t *sjob_ptr;
	struct job_details *job_det_ptr;
	int solstat;
	int n = windowSize, m = nodeSize;
	double objval;
	double *x = NULL;
	double *pi = NULL;
	double *slack = NULL;
	double *dj = NULL;

	CPXENVptr env = NULL;
	CPXLPptr lp = NULL;
	int status = 0;
	int i, j, k;
	int cur_numrows, cur_numcols;

	char envstr[256];
	sprintf(envstr,"ILOG_LICENSE_FILE=%s",get_cplex_license_address());
	if ( envstr != NULL ) {
		CPXputenv (envstr);
	}

	env = CPXopenCPLEX (&status);
	if ( env == NULL ) {
		char  errmsg[1024];
		fatal ("Could not open CPLEX environment.\n");
		CPXgeterrorstring (env, status, errmsg);
		fprintf (stderr, "%s", errmsg);
		goto TERMINATE;
	}

	status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON);
	if (status) {
		fatal("Failure to turn on screen indicator, error %d.",status);
		goto TERMINATE;
	}

	status = CPXsetintparam (env, CPX_PARAM_DATACHECK, CPX_ON);
	if (status) {
		fatal("Failure to turn on data checking, error %d.", status);
		goto TERMINATE;
	}

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

	if (lp == NULL) {
		fatal("Failed to create LP.");
		goto TERMINATE;
	}

	status = CPXsetdblparam(env,CPX_PARAM_TILIM,timeout);
	status = populatebynonzero (env, lp, m, n, timeout, 
					node_array, job_array);

	if ( status ) {
		fprintf (stderr, "Failed to populate problem.");
		goto TERMINATE;
	}

	status = CPXlpopt (env, lp);
	if ( status ) {
		fprintf (stderr, "Failed to optimize LP.");
		goto TERMINATE;
	}

	cur_numrows = CPXgetnumrows (env, lp);
	cur_numcols = CPXgetnumcols (env, lp);
	x = (double *) malloc (cur_numcols * sizeof(double));
	slack = (double *) malloc (cur_numrows * sizeof(double));
	dj = (double *) malloc (cur_numcols * sizeof(double));
	pi = (double *) malloc (cur_numrows * sizeof(double));

	if ( x == NULL ||
		slack == NULL ||
		dj    == NULL ||
		pi    == NULL   ) {
		status = CPXERR_NO_MEMORY;
		fatal ("Could not allocate memory for solution.");
		goto TERMINATE;
	}

	status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
	if ( status ) {
		fatal ("Failed to obtain solution.");
		goto TERMINATE;
	}

	for (j = 0; j < windowSize; j++) {
		if (x[j] > 0) {
			sjob_ptr = &job_array[j];
			job_det_ptr = sjob_ptr->job_ptr->details;
			sjob_ptr->node_bitmap = (bitstr_t *) 
				bit_alloc (node_record_count);
			job_det_ptr->req_node_bitmap = (bitstr_t *) 
				bit_alloc (node_record_count);
			sjob_ptr->onnodes = (uint32_t *) xmalloc 
				(sizeof(uint32_t) * node_record_count);
			job_det_ptr->req_node_layout = (uint16_t *) xmalloc 
				(sizeof(uint16_t) * node_record_count);
			job_det_ptr->req_node_bitmap = (bitstr_t *) bit_alloc
				(node_record_count);
			for (i = 0; i < nodeSize; i++) {
				k = (1 + i) * windowSize + j;
				if (x[k] > 0) {
					bit_set (sjob_ptr->node_bitmap, 
						(bitoff_t) (i));
					bit_set (job_det_ptr->req_node_bitmap, 
						(bitoff_t) (i));		
					node_array[i].rem_cpus -= x[k];
					node_array[i].rem_gpus -= sjob_ptr->gpu;
					sjob_ptr->onnodes[i] = x[k]; 
					job_det_ptr->req_node_layout[i] = 
						sjob_ptr->onnodes[i]; 
					sjob_ptr->alloc_total += x[k];
				}
			}
		} else
			job_array[j].alloc_total = 0;
	} 

TERMINATE:

	free_and_null ((char **) &x);
	free_and_null ((char **) &slack);
	free_and_null ((char **) &dj);
	free_and_null ((char **) &pi);

	if (lp != NULL) {
		status = CPXfreeprob (env, &lp);
		if (status) {
			fatal("CPXfreeprob failed, error code %d.", status);
		}
	}

	if (env != NULL) {
		status = CPXcloseCPLEX (&env);
		if (status) {
			char errmsg[1024];
			fatal("Could not close CPLEX environment.");
			CPXgeterrorstring (env, status, errmsg);
			fatal("%s", errmsg);
		}
	}     
	
	return (status);
}
Пример #13
0
reducemex(double M[], double costs[], double stats[], double ikeep[],
          double m[],
		  int matbeg[], int matcnt[], int matind[], double matval[],
          char sense[], int objsen, double lb[], double ub[],
          int numrows, int numcols, double tol)

{
CPXENVptr     env = NULL;
CPXLPptr      lp = NULL;
int           status;
char          probname[16];
double        *pi;
double        *slack;
double        *dj;


double        *obj;
int           solstat;
double        objval;
double        *x;

double        newval;
int           *indices;

int kc, i;

obj = mxCalloc(numcols,sizeof(double));
x   = mxCalloc(numcols,sizeof(double));

indices = mxCalloc(numcols,sizeof(int));

pi = mxCalloc(numrows,sizeof(double));
slack = mxCalloc(numrows,sizeof(double));
dj = mxCalloc(numcols,sizeof(double));

   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   if ( env == NULL ) {
   char  errmsg[1024];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn off output to the screen */

   status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_OFF);
   if ( status ) {
      fprintf (stderr,
               "Failure to turn on screen indicator, error %d.\n", status);
      goto TERMINATE;
   }

   /* Turn off pre-processor

   status = CPXsetintparam (env, CPX_PARAM_PREIND, CPX_OFF);
   if ( status ) {
      fprintf (stderr,
               "Failure to turn off pre-processor, error %d.\n", status);
      goto TERMINATE;
   }

   /* Turn off aggregator

   status = CPXsetintparam (env, CPX_PARAM_AGGIND, CPX_OFF);
   if ( status ) {
      fprintf (stderr,
               "Failure to turn of aggregator, error %d.\n", status);
      goto TERMINATE;
   }*/

   /* Create the problem. */

   strcpy(probname,"LPnoname");
   lp = CPXcreateprob (env, &status, probname);

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Initialize data */
   for (kc = 0; kc <= numcols-1; kc++)
     {
       indices[kc] = kc;
     }

   /* Now copy the problem data into the lp */

   status = CPXcopylp (env, lp, numcols, numrows, objsen, obj, m,
                       sense, matbeg, matcnt, matind, matval,
                       lb, ub, NULL);

   if ( status ) {
      fprintf (stderr, "Failed to copy problem data.\n");
      goto TERMINATE;
   }

/**********MAIN LOOP************/

   for(i = 0; i <= numrows-1; i++)
   {
   for (kc = 0; kc <= numcols-1; kc++)
     {
       obj[kc] = M[i+kc*numrows];
     }

   CPXchgobj(env, lp, numcols, indices, obj);

 
   newval = m[i] + 10;
   CPXchgrhs(env, lp, 1, &i, &newval);
 
   /* Optimize the problem and obtain solution. */

   status = CPXlpopt (env, lp);   /*status = CPX[prim/dual]opt (env, lp);*/
   if ( status ) {
      fprintf (stderr, "Failed to optimize LP.\n");
      goto TERMINATE;
   }

   status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution.\n");
      goto TERMINATE;
   }

   ikeep[i] = 0;
   if (objval > m[i] + tol)  /* keep row */
     {
       ikeep[i] = 1;
       newval = m[i];
       CPXchgrhs(env, lp, 1, &i, &newval);
     }


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

   costs[i] = objval;
   stats[i] = solstat;

}

TERMINATE:

   /* Free up the problem as allocated by CPXcreateprob, if necessary */

   if ( lp != NULL ) {
      status = CPXfreeprob (env, &lp);
      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 ( status ) {
      char  errmsg[1024];
         fprintf (stderr, "Could not close CPLEX environment.\n");
         CPXgeterrorstring (env, status, errmsg);
         fprintf (stderr, "%s", errmsg);
      }
   }

}
Пример #14
0
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;
}
Пример #15
0
int
main (int argc, char **argv)
{
   int status = 0;

   int    nfoods;
   int    nnutr;
   double *cost     = NULL;
   double *lb       = NULL;
   double *ub       = NULL;
   double *nutrmin  = NULL;
   double *nutrmax  = NULL;
   double **nutrper = NULL;

   double *x = NULL;
   double objval;
   int    solstat;

   /* Declare and allocate space for the variables and arrays where we
      will store the optimization results including the status, objective
      value, variable values, dual values, row slacks and variable
      reduced costs. */

   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           i, j;

   /* Check the command line arguments */

   if (( argc != 3 )                                        ||
       ( argv[1][0] != '-' )                                ||
       ( strchr ("rc", argv[1][1]) == NULL )  ) {
      usage (argv[0]);
      goto TERMINATE;
   }

   status = readdata(argv[2], &nfoods, &cost, &lb, &ub,
                     &nnutr, &nutrmin, &nutrmax, &nutrper);
   if ( status ) goto TERMINATE;


   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXgeterrorstring will produce the text of
      the error message.  Note that CPXopenCPLEX produces no output,
      so the only way to see the cause of the error is to use
      CPXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON.  */

   if ( env == NULL ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn on output to the screen */

   status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on screen indicator, error %d.\n", status);
      goto TERMINATE;
   }

   /* Turn on data checking */

   status = CPXsetintparam (env, CPXPARAM_Read_DataCheck, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on data checking, error %d.\n", status);
      goto TERMINATE;
   }

   /* Create the problem. */

   lp = CPXcreateprob (env, &status, "diet");

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout.  */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now populate the problem with the data.  For building large
      problems, consider setting the row, column and nonzero growth
      parameters before performing this task. */

   switch (argv[1][1]) {
      case 'r':
         status = populatebyrow (env, lp, nfoods, cost, lb, ub, 
                                 nnutr, nutrmin, nutrmax, nutrper);
         break;
      case 'c':
         status = populatebycolumn (env, lp, nfoods, cost, lb, ub, 
                                    nnutr, nutrmin, nutrmax, nutrper);
         break;
   }

   if ( status ) {
      fprintf (stderr, "Failed to populate problem.\n");
      goto TERMINATE;
   }


   /* Optimize the problem and obtain solution. */

   status = CPXlpopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to optimize LP.\n");
      goto TERMINATE;
   }

   x = (double *) malloc (nfoods * sizeof(double));
   if ( x == NULL ) {
      status = CPXERR_NO_MEMORY;
      fprintf (stderr, "Could not allocate memory for solution.\n");
      goto TERMINATE;
   }

   status = CPXsolution (env, lp, &solstat, &objval, x, NULL, NULL, NULL);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution.\n");
      goto TERMINATE;
   }

   /* Write the output to the screen. */

   printf ("\nSolution status = %d\n", solstat);
   printf ("Solution value  = %f\n\n", objval);

   for (j = 0; j < nfoods; j++) {
      printf ("Food %d:  Buy = %10f\n", j, x[j]);
   }

   /* Finally, write a copy of the problem to a file. */

   status = CPXwriteprob (env, lp, "diet.lp", NULL);
   if ( status ) {
      fprintf (stderr, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }

   
TERMINATE:

   /* Free up the problem as allocated by CPXcreateprob, if necessary */

   if ( lp != NULL ) {
      status = CPXfreeprob (env, &lp);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status);
      }
   }

   /* Free up the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

      /* Note that CPXcloseCPLEX produces no output,
         so the only way to see the cause of the error is to use
         CPXgeterrorstring.  For other CPLEX routines, the errors will
         be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */

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

   if ( nutrper != NULL ) {
      for (i = 0; i < nnutr; ++i) {
         free_and_null ((char **) &(nutrper[i]));
      }
   }
   free_and_null ((char **) &nutrper);
   free_and_null ((char **) &cost);
   free_and_null ((char **) &cost);
   free_and_null ((char **) &lb);
   free_and_null ((char **) &ub);
   free_and_null ((char **) &nutrmin);
   free_and_null ((char **) &nutrmax);
   free_and_null ((char **) &x);

   return (status);

}  /* END main */
Пример #16
0
int
main (void)
{
   char     probname[16];  /* Problem name is max 16 characters */
   int      cstat[NUMCOLS];
   int      rstat[NUMROWS];

   /* Declare and allocate space for the variables and arrays where we
      will store the optimization results including the status, objective
      value, variable values, dual values, row slacks and variable
      reduced costs. */

   int      solstat;
   double   objval;
   double   x[NUMCOLS];
   double   pi[NUMROWS];
   double   slack[NUMROWS];
   double   dj[NUMCOLS];


   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status;
   int           i, j;
   int           cur_numrows, cur_numcols;

   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXgeterrorstring will produce the text of
      the error message.  Note that CPXopenCPLEX produces no output,
      so the only way to see the cause of the error is to use
      CPXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON.  */

   if ( env == NULL ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn on output to the screen */

   status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on screen indicator, error %d.\n", status);
      goto TERMINATE;
   }

   /* Create the problem. */

   strcpy (probname, "example");
   lp = CPXcreateprob (env, &status, probname);

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout. */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now populate the problem with the data. */

   status = populatebycolumn (env, lp);

   if ( status ) {
      fprintf (stderr, "Failed to populate problem data.\n");
      goto TERMINATE;
   }

   /* We assume we know the optimal basis.  Variables 1 and 2 are basic,
      while variable 0 is at its upper bound */

   cstat[0] = CPX_AT_UPPER; 
   cstat[1] = CPX_BASIC;     
   cstat[2] = CPX_BASIC;

   /* The row statuses are all nonbasic for this problem */

   rstat[0] = CPX_AT_LOWER;
   rstat[1] = CPX_AT_LOWER;

   /* Now copy the basis */

   status = CPXcopybase (env, lp, cstat, rstat);
   if ( status ) {
      fprintf (stderr, "Failed to copy the basis.\n");
      goto TERMINATE;
   }


   /* Optimize the problem and obtain solution. */

   status = CPXlpopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to optimize LP.\n");
      goto TERMINATE;
   }

   status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution.\n");
      goto TERMINATE;
   }


   /* Write the output to the screen. */

   printf ("\nSolution status = %d\n", solstat);
   printf ("Solution value  = %f\n", objval);
   printf ("Iteration count = %d\n\n", CPXgetitcnt (env, lp));

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is, rather than using sizes from when the problem 
      was built.  cur_numrows and cur_numcols store the current number 
      of rows and columns, respectively.  */

   cur_numrows = CPXgetnumrows (env, lp);
   cur_numcols = CPXgetnumcols (env, lp);
   for (i = 0; i < cur_numrows; i++) {
      printf ("Row %d:  Slack = %10f  Pi = %10f\n", i, slack[i], pi[i]);
   }

   for (j = 0; j < cur_numcols; j++) {
      printf ("Column %d:  Value = %10f  Reduced cost = %10f\n",
              j, x[j], dj[j]);
   }

   /* Finally, write a copy of the problem to a file. */

   status = CPXwriteprob (env, lp, "lpex6.sav", NULL);
   if ( status ) {
      fprintf (stderr, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }
   
   
TERMINATE:

   /* Free up the problem as allocated by CPXcreateprob, if necessary */

   if ( lp != NULL ) {
      status = CPXfreeprob (env, &lp);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status);
      }
   }

   /* Free up the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

      /* Note that CPXcloseCPLEX produces no output,
         so the only way to see the cause of the error is to use
         CPXgeterrorstring.  For other CPLEX routines, the errors will
         be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */

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

}  /* END main */
Пример #17
0
int
main (void)
{
   /* Declare pointers for the variables and arrays that will contain
      the data which define the LP problem.  The setproblemdata() routine
      allocates space for the problem data.  */

   char     *probname = NULL;  
   int      numcols;
   int      numrows;
   int      objsen;
   double   *obj = NULL;
   double   *rhs = NULL;
   char     *sense = NULL;
   int      *matbeg = NULL;
   int      *matcnt = NULL;
   int      *matind = NULL;
   double   *matval = NULL;
   double   *lb = NULL;
   double   *ub = NULL;

   /* Declare and allocate space for the variables and arrays where we
      will store the optimization results including the status, objective
      value, variable values, dual values, row slacks and variable
      reduced costs. */

   int      solstat;
   double   objval;
   double   x[NUMCOLS];
   double   pi[NUMROWS];
   double   slack[NUMROWS];
   double   dj[NUMCOLS];


   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status;
   int           i, j;
   int           cur_numrows, cur_numcols;

   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXgeterrorstring will produce the text of
      the error message.  Note that CPXopenCPLEX produces no output,
      so the only way to see the cause of the error is to use
      CPXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON.  */

   if ( env == NULL ) {
      char  errmsg[CPXMESSAGEBUFSIZE];
      fprintf (stderr, "Could not open CPLEX environment.\n");
      CPXgeterrorstring (env, status, errmsg);
      fprintf (stderr, "%s", errmsg);
      goto TERMINATE;
   }

   /* Turn on output to the screen */

   status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON);
   if ( status ) {
      fprintf (stderr, 
               "Failure to turn on screen indicator, error %d.\n", status);
      goto TERMINATE;
   }

   /* Allocate memory and fill in the data for the problem.  */

   status = setproblemdata (&probname, &numcols, &numrows, &objsen, 
                            &obj, &rhs, &sense, &matbeg, &matcnt, 
                            &matind, &matval, &lb, &ub);
   if ( status ) {
      fprintf (stderr, "Failed to build problem data arrays.\n");
      goto TERMINATE;
   }

   /* Create the problem. */

   lp = CPXcreateprob (env, &status, probname);

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout.  */

   if ( lp == NULL ) {
      fprintf (stderr, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now copy the problem data into the lp */

   status = CPXcopylp (env, lp, numcols, numrows, objsen, obj, rhs, 
                       sense, matbeg, matcnt, matind, matval,
                       lb, ub, NULL);

   if ( status ) {
      fprintf (stderr, "Failed to copy problem data.\n");
      goto TERMINATE;
   }


   /* Optimize the problem and obtain solution. */

   status = CPXlpopt (env, lp);
   if ( status ) {
      fprintf (stderr, "Failed to optimize LP.\n");
      goto TERMINATE;
   }

   status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
   if ( status ) {
      fprintf (stderr, "Failed to obtain solution.\n");
      goto TERMINATE;
   }


   /* Write the output to the screen. */

   printf ("\nSolution status = %d\n", solstat);
   printf ("Solution value  = %f\n\n", objval);

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is, rather than using what was passed to CPXcopylp.
      cur_numrows and cur_numcols store the current number of rows and
      columns, respectively.  */

   cur_numrows = CPXgetnumrows (env, lp);
   cur_numcols = CPXgetnumcols (env, lp);
   for (i = 0; i < cur_numrows; i++) {
      printf ("Row %d:  Slack = %10f  Pi = %10f\n", i, slack[i], pi[i]);
   }

   for (j = 0; j < cur_numcols; j++) {
      printf ("Column %d:  Value = %10f  Reduced cost = %10f\n",
              j, x[j], dj[j]);
   }

   /* Finally, write a copy of the problem to a file. */

   status = CPXwriteprob (env, lp, "lpex1.lp", NULL);
   if ( status ) {
      fprintf (stderr, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }
   
   
TERMINATE:

   /* Free up the problem as allocated by CPXcreateprob, if necessary */

   if ( lp != NULL ) {
      status = CPXfreeprob (env, &lp);
      if ( status ) {
         fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status);
      }
   }

   /* Free up the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

      /* Note that CPXcloseCPLEX produces no output,
         so the only way to see the cause of the error is to use
         CPXgeterrorstring.  For other CPLEX routines, the errors will
         be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */

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

   /* Free up the problem data arrays, if necessary. */

   free_and_null ((char **) &probname);
   free_and_null ((char **) &obj);
   free_and_null ((char **) &rhs);
   free_and_null ((char **) &sense);
   free_and_null ((char **) &matbeg);
   free_and_null ((char **) &matcnt);
   free_and_null ((char **) &matind);
   free_and_null ((char **) &matval);
   free_and_null ((char **) &lb);
   free_and_null ((char **) &ub);
        
   return (status);

}  /* END main */
Пример #18
0
int
main (void)
{
   char     probname[16];  /* Problem name is max 16 characters */

   /* Declare and allocate space for the variables and arrays where we
      will store the optimization results including the status, objective
      value, variable values, dual values, row slacks and variable
      reduced costs. */

   int      solstat;
   double   objval;
   double   x[NUMCOLS];
   double   pi[NUMROWS];
   double   slack[NUMROWS];
   double   dj[NUMCOLS];


   CPXENVptr     env = NULL;
   CPXLPptr      lp = NULL;
   int           status;
   int           i, j;
   int           cur_numrows, cur_numcols;
   char          errmsg[CPXMESSAGEBUFSIZE];

   CPXCHANNELptr  cpxerror   = NULL;
   CPXCHANNELptr  cpxwarning = NULL;
   CPXCHANNELptr  cpxresults = NULL;
   CPXCHANNELptr  ourchannel = NULL;

   char errorlabel[] = "cpxerror";
   char warnlabel[]  = "cpxwarning";
   char reslabel[]   = "cpxresults";
   char ourlabel[]   = "Our Channel";
   char ourmessage[] = "Our Message";

   CPXFILEptr fpout  = NULL;


   /* Initialize the CPLEX environment */

   env = CPXopenCPLEX (&status);

   /* If an error occurs, the status value indicates the reason for
      failure.  A call to CPXgeterrorstring will produce the text of
      the error message.  Note that CPXopenCPLEX produces no output,
      so the only way to see the cause of the error is to use
      CPXgeterrorstring.  For other CPLEX routines, the errors will
      be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON.  */

   /* Since the message handler is yet to be set up, we'll call our
      messaging function directly to print out any errors  */

   if ( env == NULL ) {
      ourmsgfunc (ourmessage, "Could not open CPLEX environment.\n");
      goto TERMINATE;
   }

   /* Now get the standard channels.  If an error, just call our
      message function directly. */

   status = CPXgetchannels (env, &cpxresults, &cpxwarning, &cpxerror, NULL);
   if ( status ) {
      ourmsgfunc (ourmessage, "Could not get standard channels.\n");
      CPXgeterrorstring (env, status, errmsg);
      ourmsgfunc (ourmessage, errmsg);
      goto TERMINATE;
   }

   /* Now set up the error channel first.  The label will be "cpxerror" */

   status = CPXaddfuncdest (env, cpxerror, errorlabel, ourmsgfunc);
   if ( status ) {
      ourmsgfunc (ourmessage, "Could not set up error message handler.\n");
      CPXgeterrorstring (env, status, errmsg);
      ourmsgfunc (ourmessage, errmsg);
   }

   /* Now that we have the error message handler set up, all CPLEX
      generated errors will go through ourmsgfunc.  So we don't have
      to use CPXgeterrorstring to determine the text of the message.
      We can also use CPXmsg to do any other printing.  */

   status = CPXaddfuncdest (env, cpxwarning, warnlabel, ourmsgfunc);
   if ( status ) {
      CPXmsg (cpxerror, "Failed to set up handler for cpxwarning.\n");
      goto TERMINATE;
   }

   status = CPXaddfuncdest (env, cpxresults, reslabel, ourmsgfunc);
   if ( status ) {
      CPXmsg (cpxerror, "Failed to set up handler for cpxresults.\n");
      goto TERMINATE;
   }
   
   /* Now turn on the iteration display. */

   status = CPXsetintparam (env, CPXPARAM_Simplex_Display, 2);
   if ( status ) {
      CPXmsg (cpxerror, "Failed to turn on simplex display level.\n");
      goto TERMINATE;
   }

   /* Create the problem. */

   strcpy (probname, "example");
   lp = CPXcreateprob (env, &status, probname);

   /* A returned pointer of NULL may mean that not enough memory
      was available or there was some other problem.  In the case of 
      failure, an error message will have been written to the error 
      channel from inside CPLEX.  In this example, the setting of
      the parameter CPXPARAM_ScreenOutput causes the error message to
      appear on stdout.  */

   if ( lp == NULL ) {
      CPXmsg (cpxerror, "Failed to create LP.\n");
      goto TERMINATE;
   }

   /* Now populate the problem with the data. */

   status = populatebycolumn (env, lp);

   if ( status ) {
      CPXmsg (cpxerror, "Failed to populate problem data.\n");
      goto TERMINATE;
   }


   /* Optimize the problem and obtain solution. */

   status = CPXlpopt (env, lp);
   if ( status ) {
      CPXmsg (cpxerror, "Failed to optimize LP.\n");
      goto TERMINATE;
   }

   status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
   if ( status ) {
      CPXmsg (cpxerror, "Failed to obtain solution.\n");
      goto TERMINATE;
   }


   /* Write the output to the screen.  We will also write it to a
      file as well by setting up a file destination and a function
      destination. */

   ourchannel = CPXaddchannel (env);
   if ( ourchannel == NULL ) {
      CPXmsg (cpxerror, "Failed to set up our private channel.\n");
      goto TERMINATE;
   }

   fpout = CPXfopen ("lpex5.msg", "w");
   if ( fpout == NULL ) {
      CPXmsg (cpxerror, "Failed to open lpex5.msg file for output.\n");
      goto TERMINATE;
   }
   status = CPXaddfpdest (env, ourchannel, fpout);
   if ( status ) {
      CPXmsg (cpxerror, "Failed to set up output file destination.\n");
      goto TERMINATE;
   }

   status = CPXaddfuncdest (env, ourchannel, ourlabel, ourmsgfunc);
   if ( status ) {
      CPXmsg (cpxerror, "Failed to set up our output function.\n");
      goto TERMINATE;
   }

   /* Now any message to channel ourchannel will go into the file 
      and into the file opened above. */

   CPXmsg (ourchannel, "\nSolution status = %d\n", solstat);
   CPXmsg (ourchannel, "Solution value  = %f\n\n", objval);

   /* The size of the problem should be obtained by asking CPLEX what
      the actual size is, rather than using sizes from when the problem
      was built.  cur_numrows and cur_numcols store the current number 
      of rows and columns, respectively.  */

   cur_numrows = CPXgetnumrows (env, lp);
   cur_numcols = CPXgetnumcols (env, lp);
   for (i = 0; i < cur_numrows; i++) {
      CPXmsg (ourchannel, "Row %d:  Slack = %10f  Pi = %10f\n", 
              i, slack[i], pi[i]);
   }

   for (j = 0; j < cur_numcols; j++) {
      CPXmsg (ourchannel, "Column %d:  Value = %10f  Reduced cost = %10f\n",
              j, x[j], dj[j]);
   }

   /* Finally, write a copy of the problem to a file. */

   status = CPXwriteprob (env, lp, "lpex5.lp", NULL);
   if ( status ) {
      CPXmsg (cpxerror, "Failed to write LP to disk.\n");
      goto TERMINATE;
   }
   
   
TERMINATE:

   /* First check if ourchannel is open */

   if ( ourchannel != NULL ) {
      int  chanstat;
      chanstat = CPXdelfuncdest (env, ourchannel, ourlabel, ourmsgfunc);
      if ( chanstat ) {
         strcpy (errmsg, "CPXdelfuncdest failed.\n");
         ourmsgfunc (ourmessage, errmsg); 
         if (!status)  status = chanstat;
      }
      if ( fpout != NULL ) {
         chanstat = CPXdelfpdest (env, ourchannel, fpout);
         if ( chanstat ) {
            strcpy (errmsg, "CPXdelfpdest failed.\n");
            ourmsgfunc (ourmessage, errmsg);
            if (!status)  status = chanstat;
         }
         CPXfclose (fpout);
      }

      chanstat = CPXdelchannel (env, &ourchannel);
      if ( chanstat ) {
         strcpy (errmsg, "CPXdelchannel failed.\n");
         ourmsgfunc (ourmessage, errmsg); 
         if (!status)  status = chanstat;
      }
   }

   /* Free up the problem as allocated by CPXcreateprob, if necessary */

   if ( lp != NULL ) {
      status = CPXfreeprob (env, &lp);
      if ( status ) {
         strcpy (errmsg, "CPXfreeprob failed.\n");
         ourmsgfunc (ourmessage, errmsg);
      }
   }

   /* Now delete our function destinations from the 3 CPLEX channels. */
   if ( cpxresults != NULL ) {
      int  chanstat;
      chanstat = CPXdelfuncdest (env, cpxresults, reslabel, ourmsgfunc);
      if ( chanstat && !status ) {
         status = chanstat;
         strcpy (errmsg, "Failed to delete cpxresults function.\n");
         ourmsgfunc (ourmessage, errmsg);
      }
   }

   if ( cpxwarning != NULL ) {
      int  chanstat;
      chanstat = CPXdelfuncdest (env, cpxwarning, warnlabel, ourmsgfunc);
      if ( chanstat && !status ) {
         status = chanstat;
         strcpy (errmsg, "Failed to delete cpxwarning function.\n");
         ourmsgfunc (ourmessage, errmsg);
      }
   }

   if ( cpxerror != NULL ) {
      int  chanstat;
      chanstat = CPXdelfuncdest (env, cpxerror, errorlabel, ourmsgfunc);
      if ( chanstat && !status ) {
         status = chanstat;
         strcpy (errmsg, "Failed to delete cpxerror function.\n");
         ourmsgfunc (ourmessage, errmsg);
      }
   }

   /* Free up the CPLEX environment, if necessary */

   if ( env != NULL ) {
      status = CPXcloseCPLEX (&env);

      /* Note that CPXcloseCPLEX produces no output,
         so the only way to see the cause of the error is to use
         CPXgeterrorstring.  For other CPLEX routines, the errors will
         be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */

      if ( status ) {
         strcpy (errmsg, "Could not close CPLEX environment.\n");
         ourmsgfunc (ourmessage, errmsg);
         CPXgeterrorstring (env, status, errmsg);
         ourmsgfunc (ourmessage, errmsg);
      }
   }
     
   return (status);

}  /* END main */