Ejemplo n.º 1
0
Archivo: lp.c Proyecto: kleptog/pyglpk
static PyObject* LPX_basis_adv(LPXObject *self) {
#if GLPK_VERSION(4, 31)
  glp_adv_basis(LP, 0);
#else
  lpx_adv_basis(LP);
#endif
  Py_RETURN_NONE;
}
Ejemplo n.º 2
0
int c_glp_solve_simplex(glp_prob *lp, int msg_lev, int tm_lim, int presolve){
	glp_smcp smcp;
	glp_init_smcp (&smcp);
	smcp.msg_lev = msg_lev;
	smcp.tm_lim = tm_lim;
	smcp.presolve = presolve ? GLP_ON : GLP_OFF;
	glp_adv_basis(lp, 0);
	return glp_simplex(lp, &smcp);
}
Ejemplo n.º 3
0
int main(void)
{     glp_prob *P;
      P = glp_create_prob();
      glp_read_mps(P, GLP_MPS_DECK, NULL, "25fv47.mps");
      glp_adv_basis(P, 0);
      glp_simplex(P, NULL);
      glp_print_sol(P, "25fv47.txt");
      glp_delete_prob(P);
      return 0;
}
Ejemplo n.º 4
0
static int preprocess_and_solve_mip(glp_prob *P, const glp_iocp *parm)
{     /* solve MIP using the preprocessor */
      ENV *env = get_env_ptr();
      int term_out = env->term_out;
      NPP *npp;
      glp_prob *mip = NULL;
      glp_bfcp bfcp;
      glp_smcp smcp;
      int ret;
      if (parm->msg_lev >= GLP_MSG_ALL)
         xprintf("Preprocessing...\n");
      /* create preprocessor workspace */
      npp = npp_create_wksp();
      /* load original problem into the preprocessor workspace */
      npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF);
      /* process MIP prior to applying the branch-and-bound method */
      if (!term_out || parm->msg_lev < GLP_MSG_ALL)
         env->term_out = GLP_OFF;
      else
         env->term_out = GLP_ON;
      ret = npp_integer(npp, parm);
      env->term_out = term_out;
      if (ret == 0)
         ;
      else if (ret == GLP_ENOPFS)
      {  if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n");
      }
      else if (ret == GLP_ENODFS)
      {  if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION\n");
      }
      else
         xassert(ret != ret);
      if (ret != 0) goto done;
      /* build transformed MIP */
      mip = glp_create_prob();
      npp_build_prob(npp, mip);
      /* if the transformed MIP is empty, it has empty solution, which
         is optimal */
      if (mip->m == 0 && mip->n == 0)
      {  mip->mip_stat = GLP_OPT;
         mip->mip_obj = mip->c0;
         if (parm->msg_lev >= GLP_MSG_ALL)
         {  xprintf("Objective value = %17.9e\n", mip->mip_obj);
            xprintf("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR"
               "\n");
         }
         goto post;
      }
      /* display some statistics */
      if (parm->msg_lev >= GLP_MSG_ALL)
      {  int ni = glp_get_num_int(mip);
         int nb = glp_get_num_bin(mip);
         char s[50];
         xprintf("%d row%s, %d column%s, %d non-zero%s\n",
            mip->m, mip->m == 1 ? "" : "s", mip->n, mip->n == 1 ? "" :
            "s", mip->nnz, mip->nnz == 1 ? "" : "s");
         if (nb == 0)
            strcpy(s, "none of");
         else if (ni == 1 && nb == 1)
            strcpy(s, "");
         else if (nb == 1)
            strcpy(s, "one of");
         else if (nb == ni)
            strcpy(s, "all of");
         else
            sprintf(s, "%d of", nb);
         xprintf("%d integer variable%s, %s which %s binary\n",
            ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are");
      }
      /* inherit basis factorization control parameters */
      glp_get_bfcp(P, &bfcp);
      glp_set_bfcp(mip, &bfcp);
      /* scale the transformed problem */
      if (!term_out || parm->msg_lev < GLP_MSG_ALL)
         env->term_out = GLP_OFF;
      else
         env->term_out = GLP_ON;
      glp_scale_prob(mip,
         GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP);
      env->term_out = term_out;
      /* build advanced initial basis */
      if (!term_out || parm->msg_lev < GLP_MSG_ALL)
         env->term_out = GLP_OFF;
      else
         env->term_out = GLP_ON;
      glp_adv_basis(mip, 0);
      env->term_out = term_out;
      /* solve initial LP relaxation */
      if (parm->msg_lev >= GLP_MSG_ALL)
         xprintf("Solving LP relaxation...\n");
      glp_init_smcp(&smcp);
      smcp.msg_lev = parm->msg_lev;
      mip->it_cnt = P->it_cnt;
      ret = glp_simplex(mip, &smcp);
      P->it_cnt = mip->it_cnt;
      if (ret != 0)
      {  if (parm->msg_lev >= GLP_MSG_ERR)
            xprintf("glp_intopt: cannot solve LP relaxation\n");
         ret = GLP_EFAIL;
         goto done;
      }
      /* check status of the basic solution */
      ret = glp_get_status(mip);
      if (ret == GLP_OPT)
         ret = 0;
      else if (ret == GLP_NOFEAS)
         ret = GLP_ENOPFS;
      else if (ret == GLP_UNBND)
         ret = GLP_ENODFS;
      else
         xassert(ret != ret);
      if (ret != 0) goto done;
      /* solve the transformed MIP */
      mip->it_cnt = P->it_cnt;
#if 0 /* 11/VII-2013 */
      ret = solve_mip(mip, parm);
#else
      if (parm->use_sol)
      {  mip->mip_stat = P->mip_stat;
         mip->mip_obj = P->mip_obj;
      }
      ret = solve_mip(mip, parm, P, npp);
#endif
      P->it_cnt = mip->it_cnt;
      /* only integer feasible solution can be postprocessed */
      if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS))
      {  P->mip_stat = mip->mip_stat;
         goto done;
      }
      /* postprocess solution from the transformed MIP */
post: npp_postprocess(npp, mip);
      /* the transformed MIP is no longer needed */
      glp_delete_prob(mip), mip = NULL;
      /* store solution to the original problem */
      npp_unload_sol(npp, P);
done: /* delete the transformed MIP, if it exists */
      if (mip != NULL) glp_delete_prob(mip);
      /* delete preprocessor workspace */
      npp_delete_wksp(npp);
      return ret;
}
Ejemplo n.º 5
0
char *call_lp(int next_expr(int))
{int i,constraints; expr_type_t goal_type; 
 char *retval, *retval2;
    /* initially the expression to be checked is in entropy_expr.
       determine first the variables */
    init_var_assignment(); /* start collecting variables */
    add_expr_variables();  /* variables in the expression to be checked */
    constraints=0;
    for(i=0;next_expr(i)==0;i++){ /* go over all constraints */
        constraints++;
         // Markov constraints give several cols
        if(entropy_expr.type==ent_Markov){
            constraints+=entropy_expr.n-3;
        }
        add_expr_variables();
    }
    /* figure out final variables, rows, cols, number of Shannon */
    if(do_variable_assignment()){ // number of variables is less than 2
        return "number of final random variables is less than 2";
    }
    /* get memory for row and column permutation */
    cols += constraints;
    rowperm=malloc((rows+1)*sizeof(int));
    colperm=malloc((cols+1)*sizeof(int));
    if(!rowperm || !colperm){
        if(rowperm){ free(rowperm); rowperm=NULL; }
        if(colperm){ free(colperm); colperm=NULL; }
        return "the problem is too large, not enough memory";
    }
    for(i=0;i<=rows;i++) rowperm[i]=i;    perm_array(rows+1,rowperm);
    for(i=0;i<=cols;i++) colperm[i]= i-1; perm_array(cols+1,colperm);
    /* the expression to be checked, this will be the goal */
    if(constraints) next_expr(-1);
    goal_type=entropy_expr.type; // ent_eq, ent_ge
    create_glp(); // create a new glp instance
    for(i=0;i<entropy_expr.n;i++){
        row_idx[i+1]=varidx(entropy_expr.item[i].var);
        row_val[i+1]=entropy_expr.item[i].coeff;
    }
    add_goal(entropy_expr.n); // right hand side value
    // go over the columns add them to the lp instance
    for(i=1;i<=cols;i++){
        int colct=colperm[i];
        if(add_shannon(i,colct)){ // this is a constraint
            add_constraint(i,colct-(shannon+var_no),next_expr);
        }
    }
    /* call the lp */
    init_glp_parameters();
    if(parm.presolve!=GLP_ON) // generate the first basis
        glp_adv_basis(P,0);

    retval=invoke_lp();
    // call again with -1.0 when checking for ent_eq
    if(goal_type==ent_eq && (retval==EXPR_TRUE || retval==EXPR_FALSE)){
        next_expr(-1); // reload the problem
        for(i=0;i<entropy_expr.n;i++){
            row_idx[i+1]=varidx(entropy_expr.item[i].var);
            row_val[i+1]=-entropy_expr.item[i].coeff;
        }
        add_goal(entropy_expr.n); // right hand side value
        retval2=invoke_lp();
        if(retval2==EXPR_TRUE){
            if(retval==EXPR_FALSE) retval=EQ_LE_ONLY;
        } else if(retval2==EXPR_FALSE){
            if(retval==EXPR_TRUE) retval=EQ_GE_ONLY;
        } else {
            retval=retval2;
        }
    }
    /* release allocated memory */
    release_glp();
    if(rowperm){ free(rowperm); rowperm=NULL; }
    if(colperm){ free(colperm); colperm=NULL; }
    return retval;
}
Ejemplo n.º 6
0
int max_flow_lp(int nn, int ne, const int beg[/*1+ne*/],
      const int end[/*1+ne*/], const int cap[/*1+ne*/], int s, int t,
      int x[/*1+ne*/])
{     glp_prob *lp;
      glp_smcp smcp;
      int i, k, nz, flow, *rn, *cn;
      double temp, *aa;
      /* create LP problem instance */
      lp = glp_create_prob();
      /* create LP rows; i-th row is the conservation condition of the
       * flow at i-th node, i = 1, ..., nn */
      glp_add_rows(lp, nn);
      for (i = 1; i <= nn; i++)
         glp_set_row_bnds(lp, i, GLP_FX, 0.0, 0.0);
      /* create LP columns; k-th column is the elementary flow thru
       * k-th edge, k = 1, ..., ne; the last column with the number
       * ne+1 is the total flow through the network, which goes along
       * a dummy feedback edge from the sink to the source */
      glp_add_cols(lp, ne+1);
      for (k = 1; k <= ne; k++)
      {  xassert(cap[k] > 0);
         glp_set_col_bnds(lp, k, GLP_DB, -cap[k], +cap[k]);
      }
      glp_set_col_bnds(lp, ne+1, GLP_FR, 0.0, 0.0);
      /* build the constraint matrix; structurally this matrix is the
       * incidence matrix of the network, so each its column (including
       * the last column for the dummy edge) has exactly two non-zero
       * entries */
      rn = xalloc(1+2*(ne+1), sizeof(int));
      cn = xalloc(1+2*(ne+1), sizeof(int));
      aa = xalloc(1+2*(ne+1), sizeof(double));
      nz = 0;
      for (k = 1; k <= ne; k++)
      {  /* x[k] > 0 means the elementary flow thru k-th edge goes from
          * node beg[k] to node end[k] */
         nz++, rn[nz] = beg[k], cn[nz] = k, aa[nz] = -1.0;
         nz++, rn[nz] = end[k], cn[nz] = k, aa[nz] = +1.0;
      }
      /* total flow thru the network goes from the sink to the source
       * along the dummy feedback edge */
      nz++, rn[nz] = t, cn[nz] = ne+1, aa[nz] = -1.0;
      nz++, rn[nz] = s, cn[nz] = ne+1, aa[nz] = +1.0;
      /* check the number of non-zero entries */
      xassert(nz == 2*(ne+1));
      /* load the constraint matrix into the LP problem object */
      glp_load_matrix(lp, nz, rn, cn, aa);
      xfree(rn);
      xfree(cn);
      xfree(aa);
      /* objective function is the total flow through the network to
       * be maximized */
      glp_set_obj_dir(lp, GLP_MAX);
      glp_set_obj_coef(lp, ne + 1, 1.0);
      /* solve LP instance with the (primal) simplex method */
      glp_term_out(0);
      glp_adv_basis(lp, 0);
      glp_term_out(1);
      glp_init_smcp(&smcp);
      smcp.msg_lev = GLP_MSG_ON;
      smcp.out_dly = 5000;
      xassert(glp_simplex(lp, &smcp) == 0);
      xassert(glp_get_status(lp) == GLP_OPT);
      /* obtain optimal elementary flows thru edges of the network */
      /* (note that the constraint matrix is unimodular and the data
       * are integral, so all elementary flows in basic solution should
       * also be integral) */
      for (k = 1; k <= ne; k++)
      {  temp = glp_get_col_prim(lp, k);
         x[k] = (int)floor(temp + .5);
         xassert(fabs(x[k] - temp) <= 1e-6);
      }
      /* obtain the maximum flow thru the original network which is the
       * flow thru the dummy feedback edge */
      temp = glp_get_col_prim(lp, ne+1);
      flow = (int)floor(temp + .5);
      xassert(fabs(flow - temp) <= 1e-6);
      /* delete LP problem instance */
      glp_delete_prob(lp);
      /* return to the calling program */
      return flow;
}
Ejemplo n.º 7
0
OptSolutionData* GLPKRunSolver(int ProbType) {
	OptSolutionData* NewSolution = NULL;

	int NumVariables = glp_get_num_cols(GLPKModel);

	int Status = 0;
	if (ProbType == MILP) {
		Status = glp_simplex(GLPKModel, NULL); // Use default settings
		if (Status != 0) {
			FErrorFile() << "Failed to optimize problem." << endl;
			FlushErrorFile();
			return NULL;
		}
		Status = glp_intopt(GLPKModel, NULL); // Use default settings
		if (Status != 0) {
			FErrorFile() << "Failed to optimize problem." << endl;
			FlushErrorFile();
			return NULL;
		}
		NewSolution = new OptSolutionData;

		Status = glp_mip_status(GLPKModel);
		if (Status == GLP_UNDEF || Status == GLP_NOFEAS) {
			NewSolution->Status = INFEASIBLE;
			return NewSolution;
		} else if (Status == GLP_FEAS) {
			NewSolution->Status = UNBOUNDED;
			return NewSolution;
		} else if (Status == GLP_OPT) {
			NewSolution->Status = SUCCESS;
		} else {
			delete NewSolution;
			FErrorFile() << "Problem status unrecognized." << endl;
			FlushErrorFile();
			return NULL;
		}

		NewSolution->Objective = glp_mip_obj_val(GLPKModel);
	
		NewSolution->SolutionData.resize(NumVariables);
		for (int i=0; i < NumVariables; i++) {
			NewSolution->SolutionData[i] = glp_mip_col_val(GLPKModel, i+1);
		}
	} else if (ProbType == LP) {
		//First we check the basis matrix to ensure it is not singular
		if (glp_warm_up(GLPKModel) != 0) {
			glp_adv_basis(GLPKModel, 0);
		}
		Status = glp_simplex(GLPKModel, NULL); // Use default settings
		if (Status == GLP_EBADB) {  /* the basis is invalid; build some valid basis */
			glp_adv_basis(GLPKModel, 0);
			Status = glp_simplex(GLPKModel, NULL); // Use default settings
		}
		if (Status != 0) {
			FErrorFile() << "Failed to optimize problem." << endl;
			FlushErrorFile();
			return NULL;
		}
		NewSolution = new OptSolutionData;

		Status = glp_get_status(GLPKModel);
		if (Status == GLP_INFEAS || Status == GLP_NOFEAS || Status == GLP_UNDEF) {
			cout << "Model is infeasible" << endl;
			FErrorFile() << "Model is infeasible" << endl;
			FlushErrorFile();
			NewSolution->Status = INFEASIBLE;
			return NewSolution;
		} else if (Status == GLP_FEAS || Status == GLP_UNBND) {
			cout << "Model is unbounded" << endl;
			FErrorFile() << "Model is unbounded" << endl;
			FlushErrorFile();
			NewSolution->Status = UNBOUNDED;
			return NewSolution;
		} else if (Status == GLP_OPT) {
			NewSolution->Status = SUCCESS;
		} else {
			delete NewSolution;
			FErrorFile() << "Problem status unrecognized." << endl;
			FlushErrorFile();
			return NULL;
		}

		NewSolution->Objective = glp_get_obj_val(GLPKModel);
	
		NewSolution->SolutionData.resize(NumVariables);
		for (int i=0; i < NumVariables; i++) {
			NewSolution->SolutionData[i] = glp_get_col_prim(GLPKModel, i+1);
		}
	} else {
		FErrorFile() << "Optimization problem type cannot be handled by GLPK solver." << endl;
		FlushErrorFile();
		return NULL;
	}

	return NewSolution;
}
Ejemplo n.º 8
0
void lpx_adv_basis(LPX *lp)
{     /* construct advanced initial LP basis */
      glp_adv_basis(lp, 0);
      return;
}
Ejemplo n.º 9
0
static int preprocess_and_solve_lp(glp_prob *P, const glp_smcp *parm)
{     /* solve LP using the preprocessor */
      NPP *npp;
      glp_prob *lp = NULL;
      glp_bfcp bfcp;
      int ret;
      if (parm->msg_lev >= GLP_MSG_ALL)
         xprintf("Preprocessing...\n");
      /* create preprocessor workspace */
      npp = npp_create_wksp();
      /* load original problem into the preprocessor workspace */
      npp_load_prob(npp, P, GLP_OFF, GLP_SOL, GLP_OFF);
      /* process LP prior to applying primal/dual simplex method */
      ret = npp_simplex(npp, parm);
      if (ret == 0)
         ;
      else if (ret == GLP_ENOPFS)
      {  if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n");
      }
      else if (ret == GLP_ENODFS)
      {  if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n");
      }
      else
         xassert(ret != ret);
      if (ret != 0) goto done;
      /* build transformed LP */
      lp = glp_create_prob();
      npp_build_prob(npp, lp);
      /* if the transformed LP is empty, it has empty solution, which
         is optimal */
      if (lp->m == 0 && lp->n == 0)
      {  lp->pbs_stat = lp->dbs_stat = GLP_FEAS;
         lp->obj_val = lp->c0;
         if (parm->msg_lev >= GLP_MSG_ON && parm->out_dly == 0)
         {  xprintf("~%6d: obj = %17.9e  infeas = %10.3e\n", P->it_cnt,
               lp->obj_val, 0.0);
         }
         if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("OPTIMAL SOLUTION FOUND BY LP PREPROCESSOR\n");
         goto post;
      }
      if (parm->msg_lev >= GLP_MSG_ALL)
      {  xprintf("%d row%s, %d column%s, %d non-zero%s\n",
            lp->m, lp->m == 1 ? "" : "s", lp->n, lp->n == 1 ? "" : "s",
            lp->nnz, lp->nnz == 1 ? "" : "s");
      }
      /* inherit basis factorization control parameters */
      glp_get_bfcp(P, &bfcp);
      glp_set_bfcp(lp, &bfcp);
      /* scale the transformed problem */
      {  ENV *env = get_env_ptr();
         int term_out = env->term_out;
         if (!term_out || parm->msg_lev < GLP_MSG_ALL)
            env->term_out = GLP_OFF;
         else
            env->term_out = GLP_ON;
         glp_scale_prob(lp, GLP_SF_AUTO);
         env->term_out = term_out;
      }
      /* build advanced initial basis */
      {  ENV *env = get_env_ptr();
         int term_out = env->term_out;
         if (!term_out || parm->msg_lev < GLP_MSG_ALL)
            env->term_out = GLP_OFF;
         else
            env->term_out = GLP_ON;
         glp_adv_basis(lp, 0);
         env->term_out = term_out;
      }
      /* solve the transformed LP */
      lp->it_cnt = P->it_cnt;
      ret = solve_lp(lp, parm);
      P->it_cnt = lp->it_cnt;
      /* only optimal solution can be postprocessed */
      if (!(ret == 0 && lp->pbs_stat == GLP_FEAS && lp->dbs_stat ==
            GLP_FEAS))
      {  if (parm->msg_lev >= GLP_MSG_ERR)
            xprintf("glp_simplex: unable to recover undefined or non-op"
               "timal solution\n");
         if (ret == 0)
         {  if (lp->pbs_stat == GLP_NOFEAS)
               ret = GLP_ENOPFS;
            else if (lp->dbs_stat == GLP_NOFEAS)
               ret = GLP_ENODFS;
            else
               xassert(lp != lp);
         }
         goto done;
      }
post: /* postprocess solution from the transformed LP */
      npp_postprocess(npp, lp);
      /* the transformed LP is no longer needed */
      glp_delete_prob(lp), lp = NULL;
      /* store solution to the original problem */
      npp_unload_sol(npp, P);
      /* the original LP has been successfully solved */
      ret = 0;
done: /* delete the transformed LP, if it exists */
      if (lp != NULL) glp_delete_prob(lp);
      /* delete preprocessor workspace */
      npp_delete_wksp(npp);
      return ret;
}
Ejemplo n.º 10
0
int glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn,
      	 double *a, double *b, char *ctype, int *freeLB, double *lb,
      	 int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver,
      	 int save_pb, char *save_filename, char *filetype,
         double *xmin, double *fmin, double *status,
      	 double *lambda, double *redcosts, double *time, double *mem)
{
  int typx = 0;
  int method;

  clock_t t_start = clock();

  //Redirect standard output
  if (glpIntParam[0] > 1) glp_term_hook (glpk_print_hook, NULL);
  else glp_term_hook (NULL, NULL);

  //-- Create an empty LP/MILP object
  LPX *lp = lpx_create_prob ();

  //-- Set the sense of optimization
  if (sense == 1)
    glp_set_obj_dir (lp, GLP_MIN);
  else
    glp_set_obj_dir (lp, GLP_MAX);

  //-- Define the number of unknowns and their domains.
  glp_add_cols (lp, n);
  for (int i = 0; i < n; i++)
  {
    //-- Define type of the structural variables
    if (! freeLB[i] && ! freeUB[i]) {
      if ( lb[i] == ub[i] )
        glp_set_col_bnds (lp, i+1, GLP_FX, lb[i], ub[i]);
      else
        glp_set_col_bnds (lp, i+1, GLP_DB, lb[i], ub[i]);
    }
    else
	  {
      if (! freeLB[i] && freeUB[i])
        glp_set_col_bnds (lp, i+1, GLP_LO, lb[i], ub[i]);
      else
      {
        if (freeLB[i] && ! freeUB[i])
		      glp_set_col_bnds (lp, i+1, GLP_UP, lb[i], ub[i]);
	      else
		      glp_set_col_bnds (lp, i+1, GLP_FR, lb[i], ub[i]);
	    }
	  }

  // -- Set the objective coefficient of the corresponding
  // -- structural variable. No constant term is assumed.
  glp_set_obj_coef(lp,i+1,c[i]);

  if (isMIP)
    glp_set_col_kind (lp, i+1, vartype[i]);
  }

  glp_add_rows (lp, m);

  for (int i = 0; i < m; i++)
  {
    /*  If the i-th row has no lower bound (types F,U), the
        corrispondent parameter will be ignored.
        If the i-th row has no upper bound (types F,L), the corrispondent
        parameter will be ignored.
        If the i-th row is of S type, the i-th LB is used, but
        the i-th UB is ignored.
    */

    switch (ctype[i])
    {
      case 'F': typx = GLP_FR; break;
      // upper bound
	  case 'U': typx = GLP_UP; break;
      // lower bound
	  case 'L': typx = GLP_LO; break;
      // fixed constraint
	  case 'S': typx = GLP_FX; break;
      // double-bounded variable
      case 'D': typx = GLP_DB; break;
	}

    if ( typx == GLP_DB && -b[i] < b[i]) {
        glp_set_row_bnds (lp, i+1, typx, -b[i], b[i]);
    }
    else if(typx == GLP_DB && -b[i] == b[i]) {
        glp_set_row_bnds (lp, i+1, GLP_FX, b[i], b[i]);
    }
    else {
    // this should be glp_set_row_bnds (lp, i+1, typx, -b[i], b[i]);
        glp_set_row_bnds (lp, i+1, typx, b[i], b[i]);
    }

  }
  // Load constraint matrix A
  glp_load_matrix (lp, nz, rn, cn, a);

  // Save problem
  if (save_pb) {
    if (!strcmp(filetype,"cplex")){
      if (glp_write_lp (lp, NULL, save_filename) != 0) {
	        mexErrMsgTxt("glpk: unable to write the problem");
	        longjmp (mark, -1);
      }
    }else{
      if (!strcmp(filetype,"fixedmps")){
        if (glp_write_mps (lp, GLP_MPS_DECK, NULL, save_filename) != 0) {
            mexErrMsgTxt("glpk: unable to write the problem");
	        longjmp (mark, -1);
        }
      }else{
        if (!strcmp(filetype,"freemps")){
          if (glp_write_mps (lp, GLP_MPS_FILE, NULL, save_filename) != 0) {
              mexErrMsgTxt("glpk: unable to write the problem");
	          longjmp (mark, -1);
          }
        }else{// plain text
          if (lpx_print_prob (lp, save_filename) != 0) {
              mexErrMsgTxt("glpk: unable to write the problem");
	          longjmp (mark, -1);
          }
        }
      }
    }
  }
  //-- scale the problem data (if required)
  if (! glpIntParam[16] || lpsolver != 1) {
    switch ( glpIntParam[1] ) {
        case ( 0 ): glp_scale_prob( lp, GLP_SF_SKIP ); break;
        case ( 1 ): glp_scale_prob( lp, GLP_SF_GM ); break;
        case ( 2 ): glp_scale_prob( lp, GLP_SF_EQ ); break;
        case ( 3 ): glp_scale_prob( lp, GLP_SF_AUTO  ); break;
        case ( 4 ): glp_scale_prob( lp, GLP_SF_2N ); break;
        default :
            mexErrMsgTxt("glpk: unrecognized scaling option");
            longjmp (mark, -1);
    }
  }
  else {
    /* do nothing? or unscale?
        glp_unscale_prob( lp );
    */
  }

  //-- build advanced initial basis (if required)
  if (lpsolver == 1 && ! glpIntParam[16])
    glp_adv_basis (lp, 0);

  glp_smcp sParam;
  glp_init_smcp(&sParam);

  //-- set control parameters for simplex/exact method
  if (lpsolver == 1 || lpsolver == 3){
    //remap of control parameters for simplex method
    sParam.msg_lev=glpIntParam[0];	// message level

    // simplex method: primal/dual
    switch ( glpIntParam[2] ) {
        case 0: sParam.meth=GLP_PRIMAL; break;
        case 1: sParam.meth=GLP_DUAL;   break;
        case 2: sParam.meth=GLP_DUALP;  break;
        default:
            mexErrMsgTxt("glpk: unrecognized primal/dual method");
            longjmp (mark, -1);
    }

    // pricing technique
    if (glpIntParam[3]==0) sParam.pricing=GLP_PT_STD;
    else sParam.pricing=GLP_PT_PSE;

    // ratio test
    if (glpIntParam[20]==0) sParam.r_test = GLP_RT_STD;
    else sParam.r_test=GLP_RT_HAR;

    //tollerances
    sParam.tol_bnd=glpRealParam[1];	// primal feasible tollerance
    sParam.tol_dj=glpRealParam[2];	// dual feasible tollerance
    sParam.tol_piv=glpRealParam[3];	// pivot tollerance
    sParam.obj_ll=glpRealParam[4];	// lower limit
    sParam.obj_ul=glpRealParam[5];	// upper limit

    // iteration limit
    if (glpIntParam[5]==-1) sParam.it_lim=INT_MAX;
    else sParam.it_lim=glpIntParam[5];

    // time limit
    if (glpRealParam[6]==-1) sParam.tm_lim=INT_MAX;
    else sParam.tm_lim=(int) glpRealParam[6];
    sParam.out_frq=glpIntParam[7];	// output frequency
    sParam.out_dly=(int) glpRealParam[7];	// output delay
    // presolver
    if (glpIntParam[16]) sParam.presolve=GLP_ON;
    else sParam.presolve=GLP_OFF;
  }else{
	for(int i = 0; i < NIntP; i++) {
        // skip assinging ratio test or
        if ( i == 18 || i == 20) continue;
		lpx_set_int_parm (lp, IParam[i], glpIntParam[i]);
    }

	for (int i = 0; i < NRealP; i++) {
		lpx_set_real_parm (lp, RParam[i], glpRealParam[i]);
    }
  }

  //set MIP params if MIP....
  glp_iocp iParam;
  glp_init_iocp(&iParam);

  if ( isMIP ){
    method = 'I';

    switch (glpIntParam[0]) { //message level
         case 0:  iParam.msg_lev = GLP_MSG_OFF;   break;
         case 1:  iParam.msg_lev = GLP_MSG_ERR;   break;
         case 2:  iParam.msg_lev = GLP_MSG_ON;    break;
         case 3:  iParam.msg_lev = GLP_MSG_ALL;   break;
         default:  mexErrMsgTxt("glpk: msg_lev bad param");
    }
    switch (glpIntParam[14]) { //branching param
         case 0:  iParam.br_tech = GLP_BR_FFV;    break;
         case 1:  iParam.br_tech = GLP_BR_LFV;    break;
         case 2:  iParam.br_tech = GLP_BR_MFV;    break;
         case 3:  iParam.br_tech = GLP_BR_DTH;    break;
         default: mexErrMsgTxt("glpk: branch bad param");
    }
    switch (glpIntParam[15]) { //backtracking heuristic
        case 0:  iParam.bt_tech = GLP_BT_DFS;    break;
        case 1:  iParam.bt_tech = GLP_BT_BFS;    break;
        case 2:  iParam.bt_tech = GLP_BT_BLB;    break;
        case 3:  iParam.bt_tech = GLP_BT_BPH;    break;
        default: mexErrMsgTxt("glpk: backtrack bad param");
    }

    if (  glpRealParam[8] > 0.0 && glpRealParam[8] < 1.0 )
        iParam.tol_int = glpRealParam[8];  // absolute tolorence
    else
        mexErrMsgTxt("glpk: tolint must be between 0 and 1");

    iParam.tol_obj = glpRealParam[9];  // relative tolarence
    iParam.mip_gap = glpRealParam[10]; // realative gap tolerance

    // set time limit for mip
    if ( glpRealParam[6] < 0.0 || glpRealParam[6] > 1e6 )
       iParam.tm_lim = INT_MAX;
    else
       iParam.tm_lim = (int)(1000.0 * glpRealParam[6] );

    // Choose Cutsets for mip
    // shut all cuts off, then start over....
    iParam.gmi_cuts = GLP_OFF;
    iParam.mir_cuts = GLP_OFF;
    iParam.cov_cuts = GLP_OFF;
    iParam.clq_cuts = GLP_OFF;

    switch( glpIntParam[17] ) {
        case 0: break;
        case 1: iParam.gmi_cuts = GLP_ON; break;
        case 2: iParam.mir_cuts = GLP_ON; break;
        case 3: iParam.cov_cuts = GLP_ON; break;
        case 4: iParam.clq_cuts = GLP_ON; break;
        case 5: iParam.clq_cuts = GLP_ON;
                iParam.gmi_cuts = GLP_ON;
                iParam.mir_cuts = GLP_ON;
                iParam.cov_cuts = GLP_ON;
                iParam.clq_cuts = GLP_ON; break;
        default: mexErrMsgTxt("glpk: cutset bad param");
    }

    switch( glpIntParam[18] ) { // pre-processing for mip
        case 0: iParam.pp_tech = GLP_PP_NONE; break;
        case 1: iParam.pp_tech = GLP_PP_ROOT; break;
        case 2: iParam.pp_tech = GLP_PP_ALL;  break;
        default:  mexErrMsgTxt("glpk: pprocess bad param");
    }

    if (glpIntParam[16])  iParam.presolve=GLP_ON;
    else                  iParam.presolve=GLP_OFF;

    if (glpIntParam[19])  iParam.binarize = GLP_ON;
    else                  iParam.binarize = GLP_OFF;

  }
  else {
     /* Choose simplex method ('S')
     or interior point method ('T')
     or Exact method          ('E')
     to solve the problem  */
    switch (lpsolver) {
      case 1: method = 'S'; break;
      case 2: method = 'T'; break;
      case 3: method = 'E'; break;
      default:
            mexErrMsgTxt("glpk:  lpsolver != lpsolver");
            longjmp (mark, -1);
    }
  }

	// now run the problem...
	int errnum = 0;

	switch (method) {
	case 'I':
		errnum = glp_intopt( lp, &iParam );
		errnum += 200; //this is to avoid ambiguity in the return codes.
		break;

	case 'S':
		errnum = glp_simplex(lp, &sParam);
		errnum += 100; //this is to avoid ambiguity in the return codes.
		break;

	case 'T':
		errnum = glp_interior(lp, NULL );
		errnum += 300; //this is to avoid ambiguity in the return codes.
		break;

	case 'E':
		errnum = glp_exact(lp, &sParam);
		errnum += 100; //this is to avoid ambiguity in the return codes.
		break;

	default:  /*xassert (method != method); */
		mexErrMsgTxt("glpk: method != method");
		longjmp (mark, -1);
	}

    if (errnum==100 || errnum==200 || errnum==300 || errnum==106 || errnum==107 || errnum==108 || errnum==109 || errnum==209 || errnum==214 || errnum==308) {

    // Get status and object value
    if (isMIP) {
      *status = glp_mip_status (lp);
      *fmin = glp_mip_obj_val (lp);
    }
    else {

      if (lpsolver == 1 || lpsolver == 3) {
        *status = glp_get_status (lp);
        *fmin = glp_get_obj_val (lp);
	  }
      else {
        *status = glp_ipt_status (lp);
        *fmin = glp_ipt_obj_val (lp);
	  }
    }

    // Get optimal solution (if exists)
    if (isMIP) {

      for (int i = 0; i < n; i++)
        xmin[i] = glp_mip_col_val (lp, i+1);
    }
    else {

      /* Primal values */
      for (int i = 0; i < n; i++) {

        if (lpsolver == 1 || lpsolver == 3)
              xmin[i] = glp_get_col_prim (lp, i+1);
        else
		      xmin[i] = glp_ipt_col_prim (lp, i+1);
      }

      /* Dual values */
      for (int i = 0; i < m; i++) {

        if (lpsolver == 1 || lpsolver == 3)
            lambda[i] = glp_get_row_dual (lp, i+1);
	    else
            lambda[i] = glp_ipt_row_dual (lp, i+1);
      }

      /* Reduced costs */
      for (int i = 0; i < glp_get_num_cols (lp); i++) {

        if (lpsolver == 1 || lpsolver == 3)
            redcosts[i] = glp_get_col_dual (lp, i+1);
        else
            redcosts[i] = glp_ipt_col_dual (lp, i+1);
      }

    }

    *time = (clock () - t_start) / CLOCKS_PER_SEC;

    size_t tpeak;
    glp_mem_usage(NULL, NULL, NULL, &tpeak);
    *mem=((double) tpeak) / (1024);

	lpx_delete_prob(lp);

    return 0;
  }
  else {
   // printf("errnum is %d\n", errnum);
  }

  lpx_delete_prob(lp);

  /* this shouldn't be nessiary with glp_deleted_prob, but try it
  if we have weird behavior again... */
  glp_free_env();


  *status = errnum;

  return errnum;
}
Ejemplo n.º 11
0
int glp_main(int argc, const char *argv[])
{     /* stand-alone LP/MIP solver */
      struct csa _csa, *csa = &_csa;
      int ret;
      xlong_t start;
      /* perform initialization */
      csa->prob = glp_create_prob();
      glp_get_bfcp(csa->prob, &csa->bfcp);
      glp_init_smcp(&csa->smcp);
      csa->smcp.presolve = GLP_ON;
      glp_init_iocp(&csa->iocp);
      csa->iocp.presolve = GLP_ON;
      csa->tran = NULL;
      csa->graph = NULL;
      csa->format = FMT_MPS_FILE;
      csa->in_file = NULL;
      csa->ndf = 0;
      csa->out_dpy = NULL;
      csa->solution = SOL_BASIC;
      csa->in_res = NULL;
      csa->dir = 0;
      csa->scale = 1;
      csa->out_sol = NULL;
      csa->out_res = NULL;
      csa->out_bnds = NULL;
      csa->check = 0;
      csa->new_name = NULL;
      csa->out_mps = NULL;
      csa->out_freemps = NULL;
      csa->out_cpxlp = NULL;
      csa->out_pb = NULL;
      csa->out_npb = NULL;
      csa->log_file = NULL;
      csa->crash = USE_ADV_BASIS;
      csa->exact = 0;
      csa->xcheck = 0;
      csa->nomip = 0;
      /* parse command-line parameters */
      ret = parse_cmdline(csa, argc, argv);
      if (ret < 0)
      {  ret = EXIT_SUCCESS;
         goto done;
      }
      if (ret > 0)
      {  ret = EXIT_FAILURE;
         goto done;
      }
      /*--------------------------------------------------------------*/
      /* remove all output files specified in the command line */
      if (csa->out_dpy != NULL) remove(csa->out_dpy);
      if (csa->out_sol != NULL) remove(csa->out_sol);
      if (csa->out_res != NULL) remove(csa->out_res);
      if (csa->out_bnds != NULL) remove(csa->out_bnds);
      if (csa->out_mps != NULL) remove(csa->out_mps);
      if (csa->out_freemps != NULL) remove(csa->out_freemps);
      if (csa->out_cpxlp != NULL) remove(csa->out_cpxlp);
      if (csa->out_pb != NULL) remove(csa->out_pb);
      if (csa->out_npb != NULL) remove(csa->out_npb);
      if (csa->log_file != NULL) remove(csa->log_file);
      /*--------------------------------------------------------------*/
      /* open log file, if required */
      if (csa->log_file != NULL)
      {  if (lib_open_log(csa->log_file))
         {  xprintf("Unable to create log file\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      /*--------------------------------------------------------------*/
      /* read problem data from the input file */
      if (csa->in_file == NULL)
      {  xprintf("No input problem file specified; try %s --help\n",
            argv[0]);
         ret = EXIT_FAILURE;
         goto done;
      }
      if (csa->format == FMT_MPS_DECK)
      {  ret = glp_read_mps(csa->prob, GLP_MPS_DECK, NULL,
            csa->in_file);
         if (ret != 0)
err1:    {  xprintf("MPS file processing error\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      else if (csa->format == FMT_MPS_FILE)
      {  ret = glp_read_mps(csa->prob, GLP_MPS_FILE, NULL,
            csa->in_file);
         if (ret != 0) goto err1;
      }
      else if (csa->format == FMT_CPLEX_LP)
      {  ret = glp_read_lp(csa->prob, NULL, csa->in_file);
         if (ret != 0)
         {  xprintf("CPLEX LP file processing error\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      else if (csa->format == FMT_MATHPROG)
      {  int k;
         /* allocate the translator workspace */
         csa->tran = glp_mpl_alloc_wksp();
         /* read model section and optional data section */
         if (glp_mpl_read_model(csa->tran, csa->in_file, csa->ndf > 0))
err2:    {  xprintf("MathProg model processing error\n");
            ret = EXIT_FAILURE;
            goto done;
         }
         /* read optional data section(s), if necessary */
         for (k = 1; k <= csa->ndf; k++)
         {  if (glp_mpl_read_data(csa->tran, csa->in_data[k]))
               goto err2;
         }
         /* generate the model */
         if (glp_mpl_generate(csa->tran, csa->out_dpy)) goto err2;
         /* build the problem instance from the model */
         glp_mpl_build_prob(csa->tran, csa->prob);
      }
      else if (csa->format == FMT_MIN_COST)
      {  csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data));
         ret = glp_read_mincost(csa->graph, offsetof(v_data, rhs),
            offsetof(a_data, low), offsetof(a_data, cap),
            offsetof(a_data, cost), csa->in_file);
         if (ret != 0)
         {  xprintf("DIMACS file processing error\n");
            ret = EXIT_FAILURE;
            goto done;
         }
         glp_mincost_lp(csa->prob, csa->graph, GLP_ON,
            offsetof(v_data, rhs), offsetof(a_data, low),
            offsetof(a_data, cap), offsetof(a_data, cost));
         glp_set_prob_name(csa->prob, csa->in_file);
      }
      else if (csa->format == FMT_MAX_FLOW)
      {  int s, t;
         csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data));
         ret = glp_read_maxflow(csa->graph, &s, &t,
            offsetof(a_data, cap), csa->in_file);
         if (ret != 0)
         {  xprintf("DIMACS file processing error\n");
            ret = EXIT_FAILURE;
            goto done;
         }
         glp_maxflow_lp(csa->prob, csa->graph, GLP_ON, s, t,
            offsetof(a_data, cap));
         glp_set_prob_name(csa->prob, csa->in_file);
      }
      else
         xassert(csa != csa);
      /*--------------------------------------------------------------*/
      /* change problem name, if required */
      if (csa->new_name != NULL)
         glp_set_prob_name(csa->prob, csa->new_name);
      /* change optimization direction, if required */
      if (csa->dir != 0)
         glp_set_obj_dir(csa->prob, csa->dir);
      /* order rows and columns of the constraint matrix */
      lpx_order_matrix(csa->prob);
      /*--------------------------------------------------------------*/
      /* write problem data in fixed MPS format, if required */
      if (csa->out_mps != NULL)
      {  ret = glp_write_mps(csa->prob, GLP_MPS_DECK, NULL,
            csa->out_mps);
         if (ret != 0)
         {  xprintf("Unable to write problem in fixed MPS format\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      /* write problem data in free MPS format, if required */
      if (csa->out_freemps != NULL)
      {  ret = glp_write_mps(csa->prob, GLP_MPS_FILE, NULL,
            csa->out_freemps);
         if (ret != 0)
         {  xprintf("Unable to write problem in free MPS format\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      /* write problem data in CPLEX LP format, if required */
      if (csa->out_cpxlp != NULL)
      {  ret = glp_write_lp(csa->prob, NULL, csa->out_cpxlp);
         if (ret != 0)
         {  xprintf("Unable to write problem in CPLEX LP format\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      /* write problem data in OPB format, if required */
      if (csa->out_pb != NULL)
      {  ret = lpx_write_pb(csa->prob, csa->out_pb, 0, 0);
         if (ret != 0)
         {  xprintf("Unable to write problem in OPB format\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      /* write problem data in normalized OPB format, if required */
      if (csa->out_npb != NULL)
      {  ret = lpx_write_pb(csa->prob, csa->out_npb, 1, 1);
         if (ret != 0)
         {  xprintf(
               "Unable to write problem in normalized OPB format\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      /*--------------------------------------------------------------*/
      /* if only problem data check is required, skip computations */
      if (csa->check)
      {  ret = EXIT_SUCCESS;
         goto done;
      }
      /*--------------------------------------------------------------*/
      /* determine the solution type */
      if (!csa->nomip &&
          glp_get_num_int(csa->prob) + glp_get_num_bin(csa->prob) > 0)
      {  if (csa->solution == SOL_INTERIOR)
         {  xprintf("Interior-point method is not able to solve MIP pro"
               "blem; use --simplex\n");
            ret = EXIT_FAILURE;
            goto done;
         }
         csa->solution = SOL_INTEGER;
      }
      /*--------------------------------------------------------------*/
      /* if solution is provided, read it and skip computations */
      if (csa->in_res != NULL)
      {  if (csa->solution == SOL_BASIC)
            ret = glp_read_sol(csa->prob, csa->in_res);
         else if (csa->solution == SOL_INTERIOR)
            ret = glp_read_ipt(csa->prob, csa->in_res);
         else if (csa->solution == SOL_INTEGER)
            ret = glp_read_mip(csa->prob, csa->in_res);
         else
            xassert(csa != csa);
         if (ret != 0)
         {  xprintf("Unable to read problem solution\n");
            ret = EXIT_FAILURE;
            goto done;
         }
         goto skip;
      }
      /*--------------------------------------------------------------*/
      /* scale the problem data, if required */
      if (csa->scale)
      {  if (csa->solution == SOL_BASIC && !csa->smcp.presolve ||
             csa->solution == SOL_INTERIOR ||
             csa->solution == SOL_INTEGER && !csa->iocp.presolve)
            glp_scale_prob(csa->prob, GLP_SF_AUTO);
      }
      /* construct starting LP basis */
      if (csa->solution == SOL_BASIC && !csa->smcp.presolve ||
          csa->solution == SOL_INTEGER && !csa->iocp.presolve)
      {  if (csa->crash == USE_STD_BASIS)
            glp_std_basis(csa->prob);
         else if (csa->crash == USE_ADV_BASIS)
            glp_adv_basis(csa->prob, 0);
         else if (csa->crash == USE_CPX_BASIS)
            glp_cpx_basis(csa->prob);
         else
            xassert(csa != csa);
      }
      /*--------------------------------------------------------------*/
      /* solve the problem */
      start = xtime();
      if (csa->solution == SOL_BASIC)
      {  if (!csa->exact)
         {  glp_set_bfcp(csa->prob, &csa->bfcp);
            glp_simplex(csa->prob, &csa->smcp);
            if (csa->xcheck)
            {  if (csa->smcp.presolve &&
                   glp_get_status(csa->prob) != GLP_OPT)
                  xprintf("If you need to check final basis for non-opt"
                     "imal solution, use --nopresol\n");
               else
                  glp_exact(csa->prob, &csa->smcp);
            }
            if (csa->out_sol != NULL || csa->out_res != NULL)
            {  if (csa->smcp.presolve &&
                   glp_get_status(csa->prob) != GLP_OPT)
               xprintf("If you need actual output for non-optimal solut"
                  "ion, use --nopresol\n");
            }
         }
         else
            glp_exact(csa->prob, &csa->smcp);
      }
      else if (csa->solution == SOL_INTERIOR)
         glp_interior(csa->prob, NULL);
      else if (csa->solution == SOL_INTEGER)
      {  if (!csa->iocp.presolve)
         {  glp_set_bfcp(csa->prob, &csa->bfcp);
            glp_simplex(csa->prob, &csa->smcp);
         }
         glp_intopt(csa->prob, &csa->iocp);
      }
      else
         xassert(csa != csa);
      /*--------------------------------------------------------------*/
      /* display statistics */
      xprintf("Time used:   %.1f secs\n", xdifftime(xtime(), start));
      {  xlong_t tpeak;
         char buf[50];
         lib_mem_usage(NULL, NULL, NULL, &tpeak);
         xprintf("Memory used: %.1f Mb (%s bytes)\n",
            xltod(tpeak) / 1048576.0, xltoa(tpeak, buf));
      }
      /*--------------------------------------------------------------*/
skip: /* postsolve the model, if necessary */
      if (csa->tran != NULL)
      {  if (csa->solution == SOL_BASIC)
            ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_SOL);
         else if (csa->solution == SOL_INTERIOR)
            ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_IPT);
         else if (csa->solution == SOL_INTEGER)
            ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_MIP);
         else
            xassert(csa != csa);
         if (ret != 0)
         {  xprintf("Model postsolving error\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      /*--------------------------------------------------------------*/
      /* write problem solution in printable format, if required */
      if (csa->out_sol != NULL)
      {  if (csa->solution == SOL_BASIC)
            ret = lpx_print_sol(csa->prob, csa->out_sol);
         else if (csa->solution == SOL_INTERIOR)
            ret = lpx_print_ips(csa->prob, csa->out_sol);
         else if (csa->solution == SOL_INTEGER)
            ret = lpx_print_mip(csa->prob, csa->out_sol);
         else
            xassert(csa != csa);
         if (ret != 0)
         {  xprintf("Unable to write problem solution\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      /* write problem solution in printable format, if required */
      if (csa->out_res != NULL)
      {  if (csa->solution == SOL_BASIC)
            ret = glp_write_sol(csa->prob, csa->out_res);
         else if (csa->solution == SOL_INTERIOR)
            ret = glp_write_ipt(csa->prob, csa->out_res);
         else if (csa->solution == SOL_INTEGER)
            ret = glp_write_mip(csa->prob, csa->out_res);
         else
            xassert(csa != csa);
         if (ret != 0)
         {  xprintf("Unable to write problem solution\n");
            ret = EXIT_FAILURE;
            goto done;
         }
      }
      /* write sensitivity bounds information, if required */
      if (csa->out_bnds != NULL)
      {  if (csa->solution == SOL_BASIC)
         {  ret = lpx_print_sens_bnds(csa->prob, csa->out_bnds);
            if (ret != 0)
            {  xprintf("Unable to write sensitivity bounds information "
                  "\n");
               ret = EXIT_FAILURE;
               goto done;
            }
         }
         else
            xprintf("Cannot write sensitivity bounds information for in"
               "terior-point or MIP solution\n");
      }
      /*--------------------------------------------------------------*/
      /* all seems to be ok */
      ret = EXIT_SUCCESS;
      /*--------------------------------------------------------------*/
done: /* delete the LP/MIP problem object */
      if (csa->prob != NULL)
         glp_delete_prob(csa->prob);
      /* free the translator workspace, if necessary */
      if (csa->tran != NULL)
         glp_mpl_free_wksp(csa->tran);
      /* delete the network problem object, if necessary */
      if (csa->graph != NULL)
         glp_delete_graph(csa->graph);
      xassert(gmp_pool_count() == 0);
      gmp_free_mem();
      /* close log file, if necessary */
      if (csa->log_file != NULL) lib_close_log();
      /* check that no memory blocks are still allocated */
      {  int count;
         xlong_t total;
         lib_mem_usage(&count, NULL, &total, NULL);
         if (count != 0)
            xerror("Error: %d memory block(s) were lost\n", count);
         xassert(count == 0);
         xassert(total.lo == 0 && total.hi == 0);
      }
      /* free the library environment */
      lib_free_env();
      /* return to the control program */
      return ret;
}