Exemple #1
0
void ipp_unload_sol(IPP *ipp, LPX *orig, int i_stat)
{     int i, j, k, len, *ind;
      double temp, *row_mipx, *val;
      xassert(ipp->orig_m == lpx_get_num_rows(orig));
      xassert(ipp->orig_n == lpx_get_num_cols(orig));
      xassert(ipp->orig_dir == lpx_get_obj_dir(orig));
      /* all columns must be computed/recovered */
      xassert(ipp->orig_n <= ipp->ncols);
      for (j = 1; j <= ipp->ncols; j++) xassert(ipp->col_stat[j]);
      /* compute values of auxiliary variables using known values of
         structural variables (columns) */
      row_mipx = xcalloc(1+ipp->orig_m, sizeof(double));
      ind = xcalloc(1+ipp->orig_n, sizeof(int));
      val = xcalloc(1+ipp->orig_n, sizeof(double));
      for (i = 1; i <= ipp->orig_m; i++)
      {  len = lpx_get_mat_row(orig, i, ind, val);
         temp = 0.0;
         for (k = 1; k <= len; k++)
            temp += val[k] * ipp->col_mipx[ind[k]];
         row_mipx[i] = temp;
      }
      xfree(ind);
      xfree(val);
      /* store solution components into the original problem object */
      lpx_put_mip_soln(orig, i_stat, row_mipx, ipp->col_mipx);
      xfree(row_mipx);
      return;
}
Exemple #2
0
void lpp_load_sol(LPP *lpp, LPX *prob)
{     int i, j, ref, stat;
      double prim, dual;
      insist(lpp->m == lpx_get_num_rows(prob));
      insist(lpp->n == lpx_get_num_cols(prob));
      insist(lpp->orig_dir == lpx_get_obj_dir(prob));
      insist(lpx_get_status(prob) != LPX_UNDEF);
      for (i = 1; i <= lpp->m; i++)
      {  lpx_get_row_info(prob, i, &stat, &prim, &dual);
         ref = lpp->row_ref[i];
         insist(1 <= ref && ref <= lpp->nrows);
         insist(lpp->row_stat[ref] == 0);
         lpp->row_stat[ref] = stat;
         lpp->row_prim[ref] = prim;
         lpp->row_dual[ref] =
            (lpp->orig_dir == LPX_MIN ? + dual : - dual);
      }
      for (j = 1; j <= lpp->n; j++)
      {  lpx_get_col_info(prob, j, &stat, &prim, &dual);
         ref = lpp->col_ref[j];
         insist(1 <= ref && ref <= lpp->ncols);
         insist(lpp->col_stat[ref] == 0);
         lpp->col_stat[ref] = stat;
         lpp->col_prim[ref] = prim;
         lpp->col_dual[ref] =
            (lpp->orig_dir == LPX_MIN ? + dual : - dual);
      }
      ufree(lpp->row_ref), lpp->row_ref = NULL;
      ufree(lpp->col_ref), lpp->col_ref = NULL;
      return;
}
Exemple #3
0
int CClp_load_warmstart(CClp *lp, CClp_warmstart *warm)
{     /* RESTORES the warmstart information in warm. */
      int i, j, m, n, tagx, type, *rstat, *cstat;
      m = lpx_get_num_rows(lp->lp);
      n = lpx_get_num_cols(lp->lp);
      cstat = warm->cstat;
      rstat = warm->rstat;
      if (cstat == NULL || rstat == NULL)
      {  print("CClp_load_warmstart: no basis information");
         return 0;
      }
      for (j = 0; j < n; j++)
      {  if (cstat[j] == IS_BASIC)
            tagx = LPX_BS;
         else
         {  lpx_get_col_bnds(lp->lp, j+1, &type, NULL, NULL);
            switch (type)
            {  case LPX_FR:
                  tagx = LPX_NF; break;
               case LPX_LO:
                  tagx = LPX_NL; break;
               case LPX_UP:
                  tagx = LPX_NU; break;
               case LPX_DB:
                  tagx = (cstat[j] == AT_UPPER ? LPX_NU : LPX_NL);
                  break;
               case LPX_FX:
                  tagx = LPX_NS; break;
               default:
                  insist(type != type);
            }
         }
         lpx_set_col_stat(lp->lp, j+1, tagx);
      }
      for (i = 0; i < m; i++)
      {  if (rstat[i] == IS_BASIC)
            tagx = LPX_BS;
         else
         {  lpx_get_row_bnds(lp->lp, i+1, &type, NULL, NULL);
            switch (type)
            {  case LPX_FR:
                  tagx = LPX_NF; break;
               case LPX_LO:
                  tagx = LPX_NL; break;
               case LPX_UP:
                  tagx = LPX_NU; break;
               case LPX_DB:
                  tagx = (rstat[i] == AT_UPPER ? LPX_NU : LPX_NL);
                  break;
               case LPX_FX:
                  tagx = LPX_NS; break;
               default:
                  insist(type != type);
            }
         }
         lpx_set_row_stat(lp->lp, i+1, tagx);
      }
      return 0;
}
Exemple #4
0
void lpx_unscale_prob(LPX *lp)
{     int m = lpx_get_num_rows(lp);
      int n = lpx_get_num_cols(lp);
      int i, j;
      for (i = 1; i <= m; i++) lpx_set_rii(lp, i, 1.0);
      for (j = 1; j <= n; j++) lpx_set_sjj(lp, j, 1.0);
      return;
}
Exemple #5
0
int CClp_pi(CClp *lp, double *pi)
{     /* RETURNS the dual values on the constraints.
         - pi should be an array of length at least nrows. */
      int nrows, i;
      nrows = lpx_get_num_rows(lp->lp);
      insist(nrows > 0);
      for (i = 0; i < nrows; i++)
         lpx_get_row_info(lp->lp, i+1, NULL, NULL, &pi[i]);
      return 0;
}
Exemple #6
0
int CClp_get_warmstart(CClp *lp, CClp_warmstart **warm)
{     /* SAVES information for efficiently resolving the current lp in
         warm, for example, basis or norm information. */
      int i, j, tagx;
      CClp_free_warmstart(warm);
      (*warm) = umalloc(sizeof(CClp_warmstart));
      (*warm)->ncols = 0;
      (*warm)->nrows = 0;
      (*warm)->cstat = NULL;
      (*warm)->rstat = NULL;
      (*warm)->ncols = lpx_get_num_cols(lp->lp);
      if ((*warm)->ncols == 0)
      {  print("CClp_get_warmstart: no columns in LP");
         CClp_free_warmstart(warm);
         return 1;
      }
      (*warm)->nrows = lpx_get_num_rows(lp->lp);
      if ((*warm)->nrows == 0)
      {  print("CClp_get_warmstart: no rows in LP");
         CClp_free_warmstart(warm);
         return 1;
      }
      (*warm)->cstat = ucalloc((*warm)->ncols, sizeof(int));
      (*warm)->rstat = ucalloc((*warm)->nrows, sizeof(int));
      for (i = 1; i <= (*warm)->nrows; i++)
      {  lpx_get_row_info(lp->lp, i, &tagx, NULL, NULL);
         switch (tagx)
         {  case LPX_BS:
               (*warm)->rstat[i-1] = IS_BASIC; break;
            case LPX_NL:
               (*warm)->rstat[i-1] = AT_LOWER; break;
            case LPX_NU:
               (*warm)->rstat[i-1] = AT_UPPER; break;
            case LPX_NS:
               (*warm)->rstat[i-1] = AT_LOWER; break;
            default: insist(tagx != tagx);
         }
      }
      for (j = 1; j <= (*warm)->ncols; j++)
      {  lpx_get_col_info(lp->lp, j, &tagx, NULL, NULL);
         switch (tagx)
         {  case LPX_BS:
               (*warm)->cstat[j-1] = IS_BASIC; break;
            case LPX_NL:
               (*warm)->cstat[j-1] = AT_LOWER; break;
            case LPX_NU:
               (*warm)->cstat[j-1] = AT_UPPER; break;
            case LPX_NS:
               (*warm)->cstat[j-1] = AT_LOWER; break;
            default:
               insist(tagx != tagx);
         }
      }
      return 0;
}
Exemple #7
0
int CClp_opt(CClp *lp, int method)
{     /* CALLS designated LP solution method. */
      int stat, ret;
      if (MSGLEV >= 1)
      {  int m = lpx_get_num_rows(lp->lp);
         int n = lpx_get_num_cols(lp->lp);
         int nz = lpx_get_num_nz(lp->lp);
         print("CClp_opt: %-11s m = %d; n = %d; nz = %d",
            method == CClp_METHOD_DUAL ? "(dual)" : "(primal)",
            m, n, nz);
      }
      lpx_set_int_parm(lp->lp, LPX_K_DUAL, method == CClp_METHOD_DUAL);
      switch (MSGLEV)
      {  case 0:
            lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 0);
            lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 1000000);
            lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 1e6);
            break;
         case 1:
            lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 2);
            lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 200);
            lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 5.0);
            break;
         case 2:
            lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 3);
            lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 200);
            lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 0.0);
            break;
         default:
            insist(MSGLEV != MSGLEV);
      }
      ret = lpx_simplex(lp->lp);
      if (ret == LPX_E_FAULT)
      {  if (MSGLEV >= 1) print("CClp_opt: restarting from advanced bas"
            "is...");
         lpx_adv_basis(lp->lp);
         ret = lpx_simplex(lp->lp);
      }
      if (ret != LPX_E_OK)
      {  print("CClp_opt: lpx_simplex failed; return code = %d", ret);
         ret = 1;
         goto done;
      }
      stat = lpx_get_status(lp->lp);
      if (stat == LPX_OPT)
         ret = 0;
      else if (stat == LPX_NOFEAS)
         ret = 2;
      else
      {  print("CClp_opt: optimization status = %d", stat);
         ret = 1;
      }
done: return ret;
}
Exemple #8
0
int CClp_delete_set_of_rows(CClp *lp, int *delstat)
{     /* DELETES the rows corresponding to 1 entries in delstat.
         - delstat is a 0/1 array having an entry for each row. */
      int m = lpx_get_num_rows(lp->lp);
      int nrs = 0, i;
      int *num = ucalloc(1+m, sizeof(int));
      for (i = 0; i < m; i++)
         if (delstat[i]) num[++nrs] = i+1;
      if (nrs > 0) lpx_del_rows(lp->lp, nrs, num);
      ufree(num);
      return 0;
}
int GLPKAddConstraint(LinEquation* InEquation) {
	if (InEquation->QuadCoeff.size() > 0) {
		FErrorFile() << "GLPK solver cannot accept quadratic constraints." << endl;
		FlushErrorFile();
		return FAIL;
	}

	if (GLPKModel == NULL) {
		FErrorFile() << "Could not add constraint because GLPK object does not exist." << endl;
		FlushErrorFile();
		return FAIL;
	}

	int NumRows = lpx_get_num_rows(GLPKModel);

	if (InEquation->Index >= NumRows) {
		lpx_add_rows(GLPKModel, 1);
	}

	if (InEquation->EqualityType == EQUAL) {
		lpx_set_row_bnds(GLPKModel, InEquation->Index+1, LPX_FX, InEquation->RightHandSide, InEquation->RightHandSide);
	} else if (InEquation->EqualityType == GREATER) {
		lpx_set_row_bnds(GLPKModel, InEquation->Index+1, LPX_LO, InEquation->RightHandSide, InEquation->RightHandSide);
	} else if (InEquation->EqualityType == LESS) {
		lpx_set_row_bnds(GLPKModel, InEquation->Index+1, LPX_UP, InEquation->RightHandSide, InEquation->RightHandSide);
	} else {
		FErrorFile() << "Could not add constraint because the constraint type was not recognized." << endl;
		FlushErrorFile();
		return FAIL;
	}

	int NumColumns = lpx_get_num_cols(GLPKModel);

	int* Indecies = new int[int(InEquation->Variables.size())+1];
	double* Coeff = new double[int(InEquation->Variables.size())+1];
	for (int i=0; i < int(InEquation->Variables.size()); i++) {
		if (InEquation->Variables[i]->Index < NumColumns) {
			Coeff[i+1] = InEquation->Coefficient[i];
			Indecies[i+1] = InEquation->Variables[i]->Index+1;
		} else {
			FErrorFile() << "Variable index found in constraint is out of the range found in GLPK problem" << endl;
			FlushErrorFile();
			return FAIL;
		}
	}

	lpx_set_mat_row(GLPKModel, InEquation->Index+1, int(InEquation->Variables.size()), Indecies, Coeff);

	delete [] Indecies;
	delete [] Coeff;

	return SUCCESS;
}
Exemple #10
0
void lpp_unload_sol(LPP *lpp, LPX *orig)
{     int i, j, k, m, n, typx, tagx;
      m = lpp->orig_m;
      n = lpp->orig_n;
      insist(m == lpx_get_num_rows(orig));
      insist(n == lpx_get_num_cols(orig));
      insist(lpp->orig_dir == lpx_get_obj_dir(orig));
      /* check row and column statuses */
      insist(m <= lpp->nrows);
      insist(n <= lpp->ncols);
      for (k = 1; k <= m+n; k++)
      {  tagx = (k <= m ? lpp->row_stat[k] : lpp->col_stat[k-m]);
         if (tagx != LPX_BS)
         {  if (k <= m)
               lpx_get_row_bnds(orig, k, &typx, NULL, NULL);
            else
               lpx_get_col_bnds(orig, k-m, &typx, NULL, NULL);
            switch (typx)
            {  case LPX_FR:
                  insist(tagx == LPX_NF);
                  break;
               case LPX_LO:
                  insist(tagx == LPX_NL);
                  break;
               case LPX_UP:
                  insist(tagx == LPX_NU);
                  break;
               case LPX_DB:
                  insist(tagx == LPX_NL || tagx == LPX_NU);
                  break;
               case LPX_FX:
                  insist(tagx == LPX_NS);
                  break;
               default:
                  insist(orig != orig);
            }
         }
      }
      /* if the original problem is maximization, change signs of dual
         values */
      if (lpp->orig_dir == LPX_MAX)
      {  for (i = 1; i <= m; i++) lpp->row_dual[i] = -lpp->row_dual[i];
         for (j = 1; j <= n; j++) lpp->col_dual[j] = -lpp->col_dual[j];
      }
      /* store solution components into the original problem object (it
         is assumed that the recovered solution is optimal) */
      lpx_put_solution(orig, LPX_P_FEAS, LPX_D_FEAS,
         lpp->row_stat, lpp->row_prim, lpp->row_dual,
         lpp->col_stat, lpp->col_prim, lpp->col_dual);
      return;
}
void lpx_eval_b_dual(LPX *lp, double row_dual[], double col_dual[])
{     int i, j, k, m, n, len, *ind;
      double dj, *cB, *pi, *val;
      if (!lpx_is_b_avail(lp))
         xfault("lpx_eval_b_dual: LP basis is not available\n");
      m = lpx_get_num_rows(lp);
      n = lpx_get_num_cols(lp);
      /* store zero reduced costs of basic auxiliary and structural
         variables and build the vector cB of objective coefficients at
         basic variables */
      cB = xcalloc(1+m, sizeof(double));
      for (i = 1; i <= m; i++)
      {  k = lpx_get_b_info(lp, i);
         /* xB[i] is k-th original variable */
         xassert(1 <= k && k <= m+n);
         if (k <= m)
         {  row_dual[k] = 0.0;
            cB[i] = 0.0;
         }
         else
         {  col_dual[k-m] = 0.0;
            cB[i] = lpx_get_obj_coef(lp, k-m);
         }
      }
      /* solve the system B'*pi = cB to compute the vector pi */
      pi = cB, lpx_btran(lp, pi);
      /* compute reduced costs of non-basic auxiliary variables */
      for (i = 1; i <= m; i++)
      {  if (lpx_get_row_stat(lp, i) != LPX_BS)
            row_dual[i] = - pi[i];
      }
      /* compute reduced costs of non-basic structural variables */
      ind = xcalloc(1+m, sizeof(int));
      val = xcalloc(1+m, sizeof(double));
      for (j = 1; j <= n; j++)
      {  if (lpx_get_col_stat(lp, j) != LPX_BS)
         {  dj = lpx_get_obj_coef(lp, j);
            len = lpx_get_mat_col(lp, j, ind, val);
            for (k = 1; k <= len; k++) dj += val[k] * pi[ind[k]];
            col_dual[j] = dj;
         }
      }
      xfree(ind);
      xfree(val);
      xfree(cB);
      return;
}
Exemple #12
0
void lpx_scale_prob(LPX *lp)
{     /* scale LP/MIP problem data */
      int m = lpx_get_num_rows(lp);
      int n = lpx_get_num_cols(lp);
      int sc_ord = 0, sc_max = 20;
      double sc_eps = 0.01;
      int i, j;
      double *R, *S;
      /* initialize R := I and S := I */
      R = xcalloc(1+m, sizeof(double));
      S = xcalloc(1+n, sizeof(double));
      for (i = 1; i <= m; i++) R[i] = 1.0;
      for (j = 1; j <= n; j++) S[j] = 1.0;
      /* if the problem has no rows/columns, skip computations */
      if (m == 0 || n == 0) goto skip;
      /* compute the scaling matrices R and S */
      switch (lpx_get_int_parm(lp, LPX_K_SCALE))
      {  case 0:
            /* no scaling */
            break;
         case 1:
            /* equilibration scaling */
            eq_scal(m, n, lp, mat, R, S, sc_ord);
            break;
         case 2:
            /* geometric mean scaling */
            gm_scal(m, n, lp, mat, R, S, sc_ord, sc_max, sc_eps);
            break;
         case 3:
            /* geometric mean scaling, then equilibration scaling */
            gm_scal(m, n, lp, mat, R, S, sc_ord, sc_max, sc_eps);
            eq_scal(m, n, lp, mat, R, S, sc_ord);
            break;
         default:
            xassert(lp != lp);
      }
skip: /* enter the scaling matrices R and S into the problem object and
         thereby perform implicit scaling */
      for (i = 1; i <= m; i++) lpx_set_rii(lp, i, R[i]);
      for (j = 1; j <= n; j++) lpx_set_sjj(lp, j, S[j]);
      xfree(R);
      xfree(S);
      return;
}
Exemple #13
0
int CClp_addrows(CClp *lp, int newrows, int newnz, double *rhs,
      char *sense, int *rmatbeg, int *rmatind, double *rmatval)
{     /* ADDS the rows to the LP.
         - newrows is the number of rows to be added;
         - newnz is the number of nonzero coefficients in the new rows;
         - rhs is an array of the rhs values for the new rows;
         - sense is 'L', 'E', or 'G' for each of the new rows;
         - rmatbeg, rmatind, and rmatval give the coefficients of the
           new rows in sparse format. The arrays can be freed after the
           call. */
      int i;
      lpx_add_rows(lp->lp, newrows);
      for (i = 0; i < newrows; i++)
      {  int seqn, type, k, t;
         double lo, up;
         seqn = lpx_get_num_rows(lp->lp) - newrows + i + 1;
         switch (sense[i])
         {  case 'L':
               type = LPX_UP, lo = 0.0, up = rhs[i];
               break;
            case 'E':
               type = LPX_FX, lo = up = rhs[i];
               break;
            case 'G':
               type = LPX_LO, lo = rhs[i], up = 0.0;
               break;
            default:
               insist(sense[i] != sense[i]);
         }
         lpx_set_row_bnds(lp->lp, seqn, type, lo, up);
         insist(rmatbeg != NULL);
         insist(rmatind != NULL);
         insist(rmatval != NULL);
         insist(rmatbeg[0] == 0);
         t = (i < newrows-1 ? rmatbeg[i+1] : newnz);
         for (k = rmatbeg[i]; k < t; k++) rmatind[k]++;
         lpx_set_mat_row(lp->lp, seqn, t - rmatbeg[i],
            &rmatind[rmatbeg[i]] - 1, &rmatval[rmatbeg[i]] - 1);
         for (k = rmatbeg[i]; k < t; k++) rmatind[k]--;
      }
      return 0;
}
Exemple #14
0
void lpx_std_basis(LPX *lp)
{     int i, j, m, n, type;
      double lb, ub;
      /* all auxiliary variables are basic */
      m = lpx_get_num_rows(lp);
      for (i = 1; i <= m; i++)
         lpx_set_row_stat(lp, i, LPX_BS);
      /* all structural variables are non-basic */
      n = lpx_get_num_cols(lp);
      for (j = 1; j <= n; j++)
      {  type = lpx_get_col_type(lp, j);
         lb = lpx_get_col_lb(lp, j);
         ub = lpx_get_col_ub(lp, j);
         if (type != LPX_DB || fabs(lb) <= fabs(ub))
            lpx_set_col_stat(lp, j, LPX_NL);
         else
            lpx_set_col_stat(lp, j, LPX_NU);
      }
      return;
}
Exemple #15
0
static int mat(void *info, int k, int ndx[], double val[])
{     /* this auxiliary routine obtains a required row or column of the
         original constraint matrix */
      LPX *lp = info;
      int m = lpx_get_num_rows(lp);
      int n = lpx_get_num_cols(lp);
      int i, j, len;
      if (k > 0)
      {  /* i-th row required */
         i = +k;
         xassert(1 <= i && i <= m);
         len = lpx_get_mat_row(lp, i, ndx, val);
      }
      else
      {  /* j-th column required */
         j = -k;
         xassert(1 <= j && j <= n);
         len = lpx_get_mat_col(lp, j, ndx, val);
      }
      return len;
}
Exemple #16
0
static void show_status(LPX *prob, int prob_m, int prob_nz)
{     int n, j, count;
      double x, tol_int;
      /* determine the number of structural variables of integer kind
         whose current values are still fractional */
      n = lpx_get_num_cols(prob);
      tol_int = lpx_get_real_parm(prob, LPX_K_TOLINT);
      count = 0;
      for (j = 1; j <= n; j++)
      {  if (lpx_get_col_kind(prob, j) != LPX_IV) continue;
         x = lpx_get_col_prim(prob, j);
         if (fabs(x - floor(x + 0.5)) <= tol_int) continue;
         count++;
      }
      print("&%6d: obj = %17.9e   frac = %5d   cuts = %5d (%d)",
         lpx_get_int_parm(prob, LPX_K_ITCNT),
         lpx_get_obj_val(prob), count,
         lpx_get_num_rows(prob) - prob_m,
         lpx_get_num_nz(prob) - prob_nz);
      return;
}
Exemple #17
0
int lpx_reduce_form(LPX *lp, int len, int ind[], double val[],
      double _work[])
{     int m = lpx_get_num_rows(lp);
      int n = lpx_get_num_cols(lp);
      int i, j, k, t;
      double *work = _work;
      /* allocate working array */
      if (_work == NULL) work = ucalloc(1+m+n, sizeof(double));
      /* convert the original linear form to dense format */
      for (k = 1; k <= m+n; k++)
         work[k] = 0.0;
      for (t = 1; t <= len; t++)
      {  k = ind[t];
         if (!(1 <= k && k <= m+n))
            fault("lpx_reduce_form: ind[%d] = %d; ordinal number out of"
               " range", t, k);
         work[k] += val[t];
      }
      /* perform substitution */
      for (i = 1; i <= m; i++)
      {  /* substitute x[i] = a[i,1]*x[m+1] + ... + a[i,n]*x[m+n] */
         if (work[i] == 0.0) continue;
         len = lpx_get_mat_row(lp, i, ind, val);
         for (t = 1; t <= len; t++)
         {  j = ind[t];
            work[m+j] += work[i] * val[t];
         }
      }
      /* convert the resultant linear form to sparse format */
      len = 0;
      for (j = 1; j <= n; j++)
      {  if (work[m+j] == 0.0) continue;
         len++;
         ind[len] = j;
         val[len] = work[m+j];
      }
      /* free working array */
      if (_work == NULL) ufree(work);
      return len;
}
int lpx_transform_col(LPX *lp, int len, int ind[], double val[])
{     int i, m, t;
      double *a, *alfa;
      if (!lpx_is_b_avail(lp))
         xfault("lpx_transform_col: LP basis is not available\n");
      m = lpx_get_num_rows(lp);
      /* unpack the column to be transformed to the array a */
      a = xcalloc(1+m, sizeof(double));
      for (i = 1; i <= m; i++) a[i] = 0.0;
      if (!(0 <= len && len <= m))
         xfault("lpx_transform_col: len = %d; invalid column length\n",
            len);
      for (t = 1; t <= len; t++)
      {  i = ind[t];
         if (!(1 <= i && i <= m))
            xfault("lpx_transform_col: ind[%d] = %d; row index out of r"
               "ange\n", t, i);
         if (val[t] == 0.0)
            xfault("lpx_transform_col: val[%d] = 0; zero coefficient no"
               "t allowed\n", t);
         if (a[i] != 0.0)
            xfault("lpx_transform_col: ind[%d] = %d; duplicate row indi"
               "ces not allowed\n", t, i);
         a[i] = val[t];
      }
      /* solve the system B*a = alfa to compute the vector alfa */
      alfa = a, lpx_ftran(lp, alfa);
      /* store resultant coefficients */
      len = 0;
      for (i = 1; i <= m; i++)
      {  if (alfa[i] != 0.0)
         {  len++;
            ind[len] = lpx_get_b_info(lp, i);
            val[len] = alfa[i];
         }
      }
      xfree(a);
      return len;
}
Exemple #19
0
int CClp_new_row(CClp *lp, char sense, double rhs)
{     /* ADDS a new empty row to the lp.
         - sense is 'L', 'E', or 'G' for a <=, =, or >= constraint;
         - rhs is the right-hand side of the row. */
      int seqn;
      lpx_add_rows(lp->lp, 1);
      seqn = lpx_get_num_rows(lp->lp);
      switch (sense)
      {  case 'L':
            lpx_set_row_bnds(lp->lp, seqn, LPX_UP, 0.0, rhs);
            break;
         case 'E':
            lpx_set_row_bnds(lp->lp, seqn, LPX_FX, rhs, rhs);
            break;
         case 'G':
            lpx_set_row_bnds(lp->lp, seqn, LPX_LO, rhs, 0.0);
            break;
         default:
            insist(sense != sense);
      }
      return 0;
}
Exemple #20
0
int CClp_get_info(CClp *lp, CClp_info **info)
{     /* BUILDS information useful for efficiently answering questions
         about the status of rows and columns. */
      int i, j, tagx;
      CClp_free_info(info);
      (*info) = umalloc(sizeof(CClp_info));
      (*info)->ncols = 0;
      (*info)->nrows = 0;
      (*info)->cstat = NULL;
      (*info)->rstat = NULL;
      (*info)->ncols = lpx_get_num_cols(lp->lp);
      insist((*info)->ncols > 0);
      (*info)->nrows = lpx_get_num_rows(lp->lp);
      insist((*info)->nrows > 0);
      (*info)->cstat = ucalloc((*info)->ncols, sizeof(int));
      (*info)->rstat = ucalloc((*info)->nrows, sizeof(int));
      for (i = 1; i <= (*info)->nrows; i++)
      {  lpx_get_row_info(lp->lp, i, &tagx, NULL, NULL);
         (*info)->rstat[i-1] = tagx == LPX_BS ? 1 : 0;
      }
      for (j = 1; j <= (*info)->ncols; j++)
      {  lpx_get_col_info(lp->lp, j, &tagx, NULL, NULL);
         switch (tagx)
         {  case LPX_BS:
               (*info)->cstat[j-1] = 0; break;
            case LPX_NL:
               (*info)->cstat[j-1] = 1; break;
            case LPX_NU:
               (*info)->cstat[j-1] = 2; break;
            case LPX_NS:
               (*info)->cstat[j-1] = 1; break;
            default:
               insist(tagx != tagx);
         }
      }
      return 0;
}
Exemple #21
0
int main(int argc, char *argv[])
{     LPX *lp;
      MPL *mpl = NULL;
      int ret;
      double start;
      /* parse command line parameters */
      parse_cmdline(argc, argv);
      /* remove all output files specified in the command line */
      if (display != NULL) remove(display);
      if (out_sol != NULL) remove(out_sol);
      if (out_bnds != NULL) remove(out_bnds);
      if (out_mps != NULL) remove(out_mps);
      if (out_lpt != NULL) remove(out_lpt);
      if (out_txt != NULL) remove(out_txt);
      if (out_glp != NULL) remove(out_glp);
      /* read problem from the input file */
      if (in_file == NULL)
      {  print("No input file specified; try %s --help", argv[0]);
         exit(EXIT_FAILURE);
      }
      switch (format)
      {  case 0:
            lp = lpx_read_mps(in_file);
            if (lp == NULL)
            {  print("MPS file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         case 1:
            lp = lpx_read_lpt(in_file);
            if (lp == NULL)
            {  print("CPLEX LP file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         case 2:
#if 0 /* 01/VIII-2004 */
            lp = lpx_read_model(in_file, in_data, display);
            if (lp == NULL)
            {  print("Model processing error");
               exit(EXIT_FAILURE);
            }
#else
            /* initialize the translator database */
            mpl = mpl_initialize();
            /* read model section and optional data section */
            ret = mpl_read_model(mpl, in_file, in_data != NULL);
            if (ret == 4)
err:        {  print("Model processing error");
               exit(EXIT_FAILURE);
            }
            insist(ret == 1 || ret == 2);
            /* read data section, if necessary */
            if (in_data != NULL)
            {  insist(ret == 1);
               ret = mpl_read_data(mpl, in_data);
               if (ret == 4) goto err;
               insist(ret == 2);
            }
            /* generate model */
            ret = mpl_generate(mpl, display);
            if (ret == 4) goto err;
            /* extract problem instance */
            lp = lpx_extract_prob(mpl);
            insist(lp != NULL);
#endif
            if (lpx_get_num_rows(lp) == 0)
            {  print("Problem has no rows");
               exit(EXIT_FAILURE);
            }
            if (lpx_get_num_cols(lp) == 0)
            {  print("Problem has no columns");
               exit(EXIT_FAILURE);
            }
            break;
         case 3:
            lp = lpx_read_prob(in_file);
            if (lp == NULL)
            {  print("GNU LP file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         default:
            insist(format != format);
      }
      /* change problem name (if required) */
      if (newname != NULL) lpx_set_prob_name(lp, newname);
      /* change optimization direction (if required) */
      if (dir != 0) lpx_set_obj_dir(lp, dir);
      /* write problem in MPS format (if required) */
      if (out_mps != NULL)
      {  lpx_set_int_parm(lp, LPX_K_MPSORIG, orig);
         ret = lpx_write_mps(lp, out_mps);
         if (ret != 0)
         {  print("Unable to write problem in MPS format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in CPLEX LP format (if required) */
      if (out_lpt != NULL)
      {  lpx_set_int_parm(lp, LPX_K_LPTORIG, orig);
         ret = lpx_write_lpt(lp, out_lpt);
         if (ret != 0)
         {  print("Unable to write problem in CPLEX LP format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in plain text format (if required) */
      if (out_txt != NULL)
      {  lpx_set_int_parm(lp, LPX_K_LPTORIG, orig);
         ret = lpx_print_prob(lp, out_txt);
         if (ret != 0)
         {  print("Unable to write problem in plain text format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in GNU LP format (if required) */
      if (out_glp != NULL)
      {  ret = lpx_write_prob(lp, out_glp);
         if (ret != 0)
         {  print("Unable to write problem in GNU LP format");
            exit(EXIT_FAILURE);
         }
      }
      /* if only data check is required, skip computations */
      if (check) goto skip;
      /* scale the problem data (if required) */
      if (scale && (!presol || method == 1)) lpx_scale_prob(lp);
      /* build advanced initial basis (if required) */
      if (method == 0 && basis && !presol) lpx_adv_basis(lp);
      /* set some control parameters, which might be changed in the
         command line */
      lpx_set_int_parm(lp, LPX_K_PRICE, price);
      if (!relax) lpx_set_real_parm(lp, LPX_K_RELAX, 0.0);
      lpx_set_int_parm(lp, LPX_K_PRESOL, presol);
      lpx_set_int_parm(lp, LPX_K_BRANCH, branch);
      lpx_set_int_parm(lp, LPX_K_BTRACK, btrack);
      lpx_set_real_parm(lp, LPX_K_TMLIM, (double)tmlim);
      /* solve the problem */
      start = utime();
      switch (method)
      {  case 0:
            if (nomip || lpx_get_class(lp) == LPX_LP)
            {  ret = lpx_simplex(lp);
               if (presol && ret != LPX_E_OK && out_sol != NULL)
                  print("If you need actual output for non-optimal solu"
                     "tion, use --nopresol");
            }
            else
            {  method = 2;
               lpx_simplex(lp);
               if (!intopt)
                  lpx_integer(lp);
               else
                  lpx_intopt(lp);
            }
            break;
         case 1:
            if (nomip || lpx_get_class(lp) == LPX_LP)
               lpx_interior(lp);
            else
            {  print("Interior point method is not able to solve MIP pr"
                  "oblem; use --simplex");
               exit(EXIT_FAILURE);
            }
            break;
         default:
            insist(method != method);
      }
      /* display statistics */
      print("Time used:   %.1f secs", utime() - start);
      print("Memory used: %.1fM (%d bytes)",
         (double)lib_env_ptr()->mem_tpeak / (double)(1024 * 1024),
         lib_env_ptr()->mem_tpeak);
#if 1 /* 01/VIII-2004 */
      if (mpl != NULL && mpl_has_solve_stmt(mpl))
      {  int n, j, round;
         /* store the solution to the translator database */
         n = lpx_get_num_cols(lp);
         round = lpx_get_int_parm(lp, LPX_K_ROUND);
         lpx_set_int_parm(lp, LPX_K_ROUND, 1);
         switch (method)
         {  case 0:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_get_col_prim(lp, j));
               break;
            case 1:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_ipt_col_prim(lp, j));
               break;
            case 2:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_mip_col_val(lp, j));
               break;
            default:
               insist(method != method);
         }
         lpx_set_int_parm(lp, LPX_K_ROUND, round);
         /* perform postsolving */
         ret = mpl_postsolve(mpl, display);
         if (ret == 4)
         {  print("Model postsolving error");
            exit(EXIT_FAILURE);
         }
         insist(ret == 3);
      }
#endif
      /* write problem solution found by the solver (if required) */
      if (out_sol != NULL)
      {  switch (method)
         {  case 0:
               ret = lpx_print_sol(lp, out_sol);
               break;
            case 1:
               ret = lpx_print_ips(lp, out_sol);
               break;
            case 2:
               ret = lpx_print_mip(lp, out_sol);
               break;
            default:
               insist(method != method);
         }
         if (ret != 0)
         {  print("Unable to write problem solution");
            exit(EXIT_FAILURE);
         }
      }
      /* write sensitivity bounds information (if required) */
      if (out_bnds != NULL)
      {  if (method != 0)
         {  print("Cannot write sensitivity bounds information for inte"
               "rior-point or MIP solution");
            exit(EXIT_FAILURE);
         }
         ret = lpx_print_sens_bnds(lp, out_bnds);
         if (ret != 0)
         {  print("Unable to write sensitivity bounds information");
            exit(EXIT_FAILURE);
         }
      }
skip: /* delete the problem object */
      lpx_delete_prob(lp);
#if 1 /* 01/VIII-2004 */
      /* if the translator database exists, destroy it */
      if (mpl != NULL) mpl_terminate(mpl);
#endif
      /* check that no memory blocks are still allocated */
      insist(lib_env_ptr()->mem_total == 0);
      insist(lib_env_ptr()->mem_count == 0);
      /* return to the control program */
      return 0;
}
Exemple #22
0
void lpp_load_orig(LPP *lpp, LPX *orig)
{     LPPROW *row;
      LPPCOL *col, **map;
      int i, j, t, len, typx, *ndx;
      double lb, ub, temp, *c, *val;
      /* save some information about the original problem */
      lpp->orig_m = lpx_get_num_rows(orig);
      lpp->orig_n = lpx_get_num_cols(orig);
      lpp->orig_nnz = lpx_get_num_nz(orig);
      lpp->orig_dir = lpx_get_obj_dir(orig);
      /* allocate working arrays */
      c = ucalloc(1+lpp->orig_n, sizeof(double));
      ndx = ucalloc(1+lpp->orig_n, sizeof(int));
      val = ucalloc(1+lpp->orig_n, sizeof(double));
      /* auxiliary variables (i.e. rows) in the original problem may
         have non-zero objective coefficients; so, we substitute these
         auxiliary variables into the objective function in order that
         it depends only on structural variables (i.e. columns); the
         resultant vector of objective coefficients is accumulated in
         the working array c */
      for (j = 1; j <= lpp->orig_n; j++)
         c[j] = lpx_get_col_coef(orig, j);
      for (i = 1; i <= lpp->orig_m; i++)
      {  /* obtain an objective coefficient at i-th row */
         temp = lpx_get_row_coef(orig, i);
         /* substitute i-th row into the objective function */
         if (temp != 0.0)
         {  len = lpx_get_mat_row(orig, i, ndx, val);
            for (t = 1; t <= len; t++) c[ndx[t]] += val[t] * temp;
         }
      }
      /* copy rows of the original problem into the workspace; each
         row created in the workspace is assigned a reference number,
         which is its ordinal number in the original problem */
      for (i = 1; i <= lpp->orig_m; i++)
      {  lpx_get_row_bnds(orig, i, &typx, &lb, &ub);
         if (typx == LPX_FR || typx == LPX_UP) lb = -DBL_MAX;
         if (typx == LPX_FR || typx == LPX_LO) ub = +DBL_MAX;
         if (typx == LPX_FX) ub = lb;
         lpp_add_row(lpp, lb, ub);
      }
      /* copy columns of the original problem into the workspace; each
         column created in the workspace is assigned a reference number,
         which its ordinal number in the original problem */
      for (j = 1; j <= lpp->orig_n; j++)
      {  lpx_get_col_bnds(orig, j, &typx, &lb, &ub);
         if (typx == LPX_FR || typx == LPX_UP) lb = -DBL_MAX;
         if (typx == LPX_FR || typx == LPX_LO) ub = +DBL_MAX;
         if (typx == LPX_FX) ub = lb;
         lpp_add_col(lpp, lb, ub, c[j]);
      }
      /* copy the constant term of the original objective function */
      lpp->c0 = lpx_get_obj_c0(orig);
      /* if the original problem is maximization, change the sign of
         the objective function, because the transformed problem to be
         processed by the presolver must be minimization */
      if (lpp->orig_dir == LPX_MAX)
      {  for (col = lpp->col_ptr; col != NULL; col = col->next)
            col->c = - col->c;
         lpp->c0 = - lpp->c0;
      }
      /* build an auxiliary array to map column ordinal numbers to the
         corresponding pointers */
      insist(sizeof(LPPCOL *) <= sizeof(double));
      map = (LPPCOL **)c;
      for (col = lpp->col_ptr; col != NULL; col = col->next)
         map[col->j] = col;
      /* copy the original constraint matrix into the workspace */
      for (row = lpp->row_ptr; row != NULL; row = row->next)
#if 1
      {  len = lpx_get_mat_row(orig, row->i, ndx, val);
         for (t = 1; t <= len; t++)
            lpp_add_aij(lpp, row, map[ndx[t]], val[t]);
      }
#else /* 27/XI-2003 (the problem persists) */
      {  double big, eps;
         len = lpx_get_mat_row(orig, row->i, ndx, val);
         big = 0.0;
         for (t = 1; t <= len; t++)
            if (big < fabs(val[t])) big = fabs(val[t]);
         eps = 1e-10 * big;
         for (t = 1; t <= len; t++)
         {  if (fabs(val[t]) < eps) continue;
            lpp_add_aij(lpp, row, map[ndx[t]], val[t]);
         }
      }
#endif
      /* free working arrays */
      ufree(c);
      ufree(ndx);
      ufree(val);
      return;
}
Exemple #23
0
int lpx_write_cpxlp(LPX *lp, const char *fname)
{     /* write problem data in CPLEX LP format */
      FILE *fp;
      int nrows, ncols, i, j, t, len, typx, flag, kind, *ind;
      double lb, ub, temp, *val;
      char line[1023+1], term[1023+1], rname[255+1], cname[255+1];
      print("lpx_write_cpxlp: writing problem data to `%s'...", fname);
      /* open the output text file */
      fp = xfopen(fname, "w");
      if (fp == NULL)
      {  print("lpx_write_cpxlp: unable to create `%s' - %s", fname,
            strerror(errno));
         goto fail;
      }
      /* determine the number of rows and columns */
      nrows = lpx_get_num_rows(lp);
      ncols = lpx_get_num_cols(lp);
      /* the problem should contain at least one row and one column */
      if (!(nrows > 0 && ncols > 0))
         fault("lpx_write_cpxlp: problem has no rows/columns");
      /* write problem name */
      {  const char *name = lpx_get_prob_name(lp);
         if (name == NULL) name = "Unknown";
         fprintf(fp, "\\* Problem: %s *\\\n", name);
         fprintf(fp, "\n");
      }
      /* allocate working arrays */
      ind = xcalloc(1+ncols, sizeof(int));
      val = xcalloc(1+ncols, sizeof(double));
      /* write the objective function definition and the constraints
         section */
      for (i = 0; i <= nrows; i++)
      {  if (i == 0)
         {  switch (lpx_get_obj_dir(lp))
            {  case LPX_MIN:
                  fprintf(fp, "Minimize\n");
                  break;
               case LPX_MAX:
                  fprintf(fp, "Maximize\n");
                  break;
               default:
                  xassert(lp != lp);
            }
         }
         else if (i == 1)
         {  temp = lpx_get_obj_coef(lp, 0);
            if (temp != 0.0)
               fprintf(fp, "\\* constant term = %.*g *\\\n", DBL_DIG,
                  temp);
            fprintf(fp, "\n");
            fprintf(fp, "Subject To\n");
         }
         row_name(lp, i, rname);
         if (i == 0)
         {  len = 0;
            for (j = 1; j <= ncols; j++)
            {  temp = lpx_get_obj_coef(lp, j);
               if (temp != 0.0)
                  len++, ind[len] = j, val[len] = temp;
            }
         }
         else
         {  lpx_get_row_bnds(lp, i, &typx, &lb, &ub);
            if (typx == LPX_FR) continue;
            len = lpx_get_mat_row(lp, i, ind, val);
         }
         flag = 0;
more:    if (!flag)
            sprintf(line, " %s:", rname);
         else
            sprintf(line, " %*s ", strlen(rname), "");
         for (t = 1; t <= len; t++)
         {  col_name(lp, ind[t], cname);
            if (val[t] == +1.0)
               sprintf(term, " + %s", cname);
            else if (val[t] == -1.0)
               sprintf(term, " - %s", cname);
            else if (val[t] > 0.0)
               sprintf(term, " + %.*g %s", DBL_DIG, +val[t], cname);
            else if (val[t] < 0.0)
               sprintf(term, " - %.*g %s", DBL_DIG, -val[t], cname);
            else
               xassert(lp != lp);
            if (strlen(line) + strlen(term) > 72)
               fprintf(fp, "%s\n", line), line[0] = '\0';
            strcat(line, term);
         }
         if (len == 0)
         {  /* empty row */
            sprintf(term, " 0 %s", col_name(lp, 1, cname));
            strcat(line, term);
         }
         if (i > 0)
         {  switch (typx)
            {  case LPX_LO:
               case LPX_DB:
                  sprintf(term, " >= %.*g", DBL_DIG, lb);
                  break;
               case LPX_UP:
                  sprintf(term, " <= %.*g", DBL_DIG, ub);
                  break;
               case LPX_FX:
                  sprintf(term, " = %.*g", DBL_DIG, lb);
                  break;
               default:
                  xassert(typx != typx);
            }
            if (strlen(line) + strlen(term) > 72)
               fprintf(fp, "%s\n", line), line[0] = '\0';
            strcat(line, term);
         }
         fprintf(fp, "%s\n", line);
         if (i > 0 && typx == LPX_DB)
         {  /* double-bounded row needs a copy for its upper bound */
            flag = 1;
            typx = LPX_UP;
            goto more;
         }
      }
      /* free working arrays */
      xfree(ind);
      xfree(val);
      /* write the bounds section */
      flag = 0;
      for (j = 1; j <= ncols; j++)
      {  col_name(lp, j, cname);
         lpx_get_col_bnds(lp, j, &typx, &lb, &ub);
         if (typx == LPX_LO && lb == 0.0) continue;
         if (!flag)
         {  fprintf(fp, "\n");
            fprintf(fp, "Bounds\n");
            flag = 1;
         }
         switch (typx)
         {  case LPX_FR:
               fprintf(fp, " %s free\n", cname);
               break;
            case LPX_LO:
               fprintf(fp, " %s >= %.*g\n", cname, DBL_DIG, lb);
               break;
            case LPX_UP:
               fprintf(fp, " %s <= %.*g\n", cname, DBL_DIG, ub);
               break;
            case LPX_DB:
               fprintf(fp, " %.*g <= %s <= %.*g\n", DBL_DIG, lb, cname,
                  DBL_DIG, ub);
               break;
            case LPX_FX:
               fprintf(fp, " %s = %.*g\n", cname, DBL_DIG, lb);
               break;
            default:
               xassert(typx != typx);
         }
      }
      /* write the general section */
      if (lpx_get_class(lp) == LPX_MIP)
      {  flag = 0;
         for (j = 1; j <= ncols; j++)
         {  kind = lpx_get_col_kind(lp, j);
            if (kind == LPX_CV) continue;
            xassert(kind == LPX_IV);
            if (!flag)
            {  fprintf(fp, "\n");
               fprintf(fp, "Generals\n");
               flag = 1;
            }
            fprintf(fp, " %s\n", col_name(lp, j, cname));
         }
      }
      /* write the end keyword */
      fprintf(fp, "\n");
      fprintf(fp, "End\n");
      /* close the output text file */
      fflush(fp);
      if (ferror(fp))
      {  print("lpx_write_cpxlp: write error on `%s' - %s", fname,
            strerror(errno));
         goto fail;
      }
      xfclose(fp);
      /* return to the calling program */
      return 0;
fail: /* the operation failed */
      if (fp != NULL) xfclose(fp);
      return 1;
}
Exemple #24
0
LPX *lpx_read_cpxlp(const char *fname)
{     /* read problem data in CPLEX LP format */
      struct dsa _dsa, *dsa = &_dsa;
      if (setjmp(dsa->jump)) goto fail;
      dsa->lp = NULL;
      dsa->fname = fname;
      dsa->fp = NULL;
      dsa->count = 0;
      dsa->c = '\n';
      dsa->token = T_EOF;
      dsa->image[0] = '\0';
      dsa->imlen = 0;
      dsa->value = 0.0;
      dsa->n_max = 100;
      dsa->map = xcalloc(1+dsa->n_max, sizeof(int));
      memset(&dsa->map[1], 0, dsa->n_max * sizeof(int));
      dsa->ind = xcalloc(1+dsa->n_max, sizeof(int));
      dsa->val = xcalloc(1+dsa->n_max, sizeof(double));
      dsa->lb = xcalloc(1+dsa->n_max, sizeof(double));
      dsa->ub = xcalloc(1+dsa->n_max, sizeof(double));
      print("lpx_read_cpxlp: reading problem data from `%s'...",
         dsa->fname);
      dsa->fp = xfopen(dsa->fname, "r");
      if (dsa->fp == NULL)
      {  print("lpx_read_cpxlp: unable to open `%s' - %s", dsa->fname,
            strerror(errno));
         goto fail;
      }
      dsa->lp = lpx_create_prob();
      lpx_create_index(dsa->lp);
#if 0
      /* read very first character */
      read_char(dsa);
#endif
      /* scan very first token */
      scan_token(dsa);
      /* parse definition of the objective function */
      if (!(dsa->token == T_MINIMIZE || dsa->token == T_MAXIMIZE))
         fatal(dsa, "`minimize' or `maximize' keyword missing");
      parse_objective(dsa);
      /* parse constraints section */
      if (dsa->token != T_SUBJECT_TO)
         fatal(dsa, "constraints section missing");
      parse_constraints(dsa);
      /* parse optional bounds section */
      if (dsa->token == T_BOUNDS) parse_bounds(dsa);
      /* parse optional general, integer, and binary sections */
      while (dsa->token == T_GENERAL ||
             dsa->token == T_INTEGER ||
             dsa->token == T_BINARY) parse_integer(dsa);
      /* check for the keyword 'end' */
      if (dsa->token == T_END)
         scan_token(dsa);
      else if (dsa->token == T_EOF)
         print("%s:%d: warning: keyword `end' missing", dsa->fname,
            dsa->count);
      else
         fatal(dsa, "symbol `%s' in wrong position", dsa->image);
      /* nothing must follow the keyword 'end' (except comments) */
      if (dsa->token != T_EOF)
         fatal(dsa, "extra symbol(s) detected beyond `end'");
      /* set bounds of variables */
      {  int j, type;
         double lb, ub;
         for (j = lpx_get_num_cols(dsa->lp); j >= 1; j--)
         {  lb = dsa->lb[j];
            ub = dsa->ub[j];
            if (lb == +DBL_MAX) lb = 0.0;      /* default lb */
            if (ub == -DBL_MAX) ub = +DBL_MAX; /* default ub */
            if (lb == -DBL_MAX && ub == +DBL_MAX)
               type = LPX_FR;
            else if (ub == +DBL_MAX)
               type = LPX_LO;
            else if (lb == -DBL_MAX)
               type = LPX_UP;
            else if (lb != ub)
               type = LPX_DB;
            else
               type = LPX_FX;
            lpx_set_col_bnds(dsa->lp, j, type, lb, ub);
         }
      }
      /* print some statistics */
      {  int m = lpx_get_num_rows(dsa->lp);
         int n = lpx_get_num_cols(dsa->lp);
         int nnz = lpx_get_num_nz(dsa->lp);
         print("lpx_read_cpxlp: %d row%s, %d column%s, %d non-zero%s",
            m, m == 1 ? "" : "s", n, n == 1 ? "" : "s", nnz, nnz == 1 ?
            "" : "s");
      }
      if (lpx_get_class(dsa->lp) == LPX_MIP)
      {  int ni = lpx_get_num_int(dsa->lp);
         int nb = lpx_get_num_bin(dsa->lp);
         char s[50];
         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);
         print("lpx_read_cpxlp: %d integer column%s, %s which %s binary"
            , ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are");
      }
      print("lpx_read_cpxlp: %d lines were read", dsa->count);
      xfclose(dsa->fp);
      xfree(dsa->map);
      xfree(dsa->ind);
      xfree(dsa->val);
      xfree(dsa->lb);
      xfree(dsa->ub);
      lpx_delete_index(dsa->lp);
      lpx_order_matrix(dsa->lp);
      return dsa->lp;
fail: if (dsa->lp != NULL) lpx_delete_prob(dsa->lp);
      if (dsa->fp != NULL) xfclose(dsa->fp);
      if (dsa->map != NULL) xfree(dsa->map);
      if (dsa->ind != NULL) xfree(dsa->ind);
      if (dsa->val != NULL) xfree(dsa->val);
      if (dsa->lb != NULL) xfree(dsa->lb);
      if (dsa->ub != NULL) xfree(dsa->ub);
      return NULL;
}
int lpx_print_prob(LPX *lp, const char *fname)
{     XFILE *fp;
      int m, n, mip, i, j, len, t, type, *ndx;
      double coef, lb, ub, *val;
      char *str, name[255+1];
      xprintf("lpx_write_prob: writing problem data to `%s'...\n",
         fname);
      fp = xfopen(fname, "w");
      if (fp == NULL)
      {  xprintf("lpx_write_prob: unable to create `%s' - %s\n",
            fname, strerror(errno));
         goto fail;
      }
      m = lpx_get_num_rows(lp);
      n = lpx_get_num_cols(lp);
      mip = (lpx_get_class(lp) == LPX_MIP);
      str = (void *)lpx_get_prob_name(lp);
      xfprintf(fp, "Problem:    %s\n", str == NULL ? "(unnamed)" : str);
      xfprintf(fp, "Class:      %s\n", !mip ? "LP" : "MIP");
      xfprintf(fp, "Rows:       %d\n", m);
      if (!mip)
         xfprintf(fp, "Columns:    %d\n", n);
      else
         xfprintf(fp, "Columns:    %d (%d integer, %d binary)\n",
            n, lpx_get_num_int(lp), lpx_get_num_bin(lp));
      xfprintf(fp, "Non-zeros:  %d\n", lpx_get_num_nz(lp));
      xfprintf(fp, "\n");
      xfprintf(fp, "*** OBJECTIVE FUNCTION ***\n");
      xfprintf(fp, "\n");
      switch (lpx_get_obj_dir(lp))
      {  case LPX_MIN:
            xfprintf(fp, "Minimize:");
            break;
         case LPX_MAX:
            xfprintf(fp, "Maximize:");
            break;
         default:
            xassert(lp != lp);
      }
      str = (void *)lpx_get_obj_name(lp);
      xfprintf(fp, " %s\n", str == NULL ? "(unnamed)" : str);
      coef = lpx_get_obj_coef(lp, 0);
      if (coef != 0.0)
         xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef,
            "(constant term)");
      for (i = 1; i <= m; i++)
#if 0
      {  coef = lpx_get_row_coef(lp, i);
#else
      {  coef = 0.0;
#endif
         if (coef != 0.0)
            xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef,
               row_name(lp, i, name));
      }
      for (j = 1; j <= n; j++)
      {  coef = lpx_get_obj_coef(lp, j);
         if (coef != 0.0)
            xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef,
               col_name(lp, j, name));
      }
      xfprintf(fp, "\n");
      xfprintf(fp, "*** ROWS (CONSTRAINTS) ***\n");
      ndx = xcalloc(1+n, sizeof(int));
      val = xcalloc(1+n, sizeof(double));
      for (i = 1; i <= m; i++)
      {  xfprintf(fp, "\n");
         xfprintf(fp, "Row %d: %s", i, row_name(lp, i, name));
         lpx_get_row_bnds(lp, i, &type, &lb, &ub);
         switch (type)
         {  case LPX_FR:
               xfprintf(fp, " free");
               break;
            case LPX_LO:
               xfprintf(fp, " >= %.*g", DBL_DIG, lb);
               break;
            case LPX_UP:
               xfprintf(fp, " <= %.*g", DBL_DIG, ub);
               break;
            case LPX_DB:
               xfprintf(fp, " >= %.*g <= %.*g", DBL_DIG, lb, DBL_DIG,
                  ub);
               break;
            case LPX_FX:
               xfprintf(fp, " = %.*g", DBL_DIG, lb);
               break;
            default:
               xassert(type != type);
         }
         xfprintf(fp, "\n");
#if 0
         coef = lpx_get_row_coef(lp, i);
#else
         coef = 0.0;
#endif
         if (coef != 0.0)
            xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef,
               "(objective)");
         len = lpx_get_mat_row(lp, i, ndx, val);
         for (t = 1; t <= len; t++)
            xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, val[t],
               col_name(lp, ndx[t], name));
      }
      xfree(ndx);
      xfree(val);
      xfprintf(fp, "\n");
      xfprintf(fp, "*** COLUMNS (VARIABLES) ***\n");
      ndx = xcalloc(1+m, sizeof(int));
      val = xcalloc(1+m, sizeof(double));
      for (j = 1; j <= n; j++)
      {  xfprintf(fp, "\n");
         xfprintf(fp, "Col %d: %s", j, col_name(lp, j, name));
         if (mip)
         {  switch (lpx_get_col_kind(lp, j))
            {  case LPX_CV:
                  break;
               case LPX_IV:
                  xfprintf(fp, " integer");
                  break;
               default:
                  xassert(lp != lp);
            }
         }
         lpx_get_col_bnds(lp, j, &type, &lb, &ub);
         switch (type)
         {  case LPX_FR:
               xfprintf(fp, " free");
               break;
            case LPX_LO:
               xfprintf(fp, " >= %.*g", DBL_DIG, lb);
               break;
            case LPX_UP:
               xfprintf(fp, " <= %.*g", DBL_DIG, ub);
               break;
            case LPX_DB:
               xfprintf(fp, " >= %.*g <= %.*g", DBL_DIG, lb, DBL_DIG,
                  ub);
               break;
            case LPX_FX:
               xfprintf(fp, " = %.*g", DBL_DIG, lb);
               break;
            default:
               xassert(type != type);
         }
         xfprintf(fp, "\n");
         coef = lpx_get_obj_coef(lp, j);
         if (coef != 0.0)
            xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, coef,
               "(objective)");
         len = lpx_get_mat_col(lp, j, ndx, val);
         for (t = 1; t <= len; t++)
            xfprintf(fp, "%*.*g %s\n", DBL_DIG+7, DBL_DIG, val[t],
               row_name(lp, ndx[t], name));
      }
      xfree(ndx);
      xfree(val);
      xfprintf(fp, "\n");
      xfprintf(fp, "End of output\n");
      xfflush(fp);
      if (xferror(fp))
      {  xprintf("lpx_write_prob: write error on `%s' - %s\n", fname,
            strerror(errno));
         goto fail;
      }
      xfclose(fp);
      return 0;
fail: if (fp != NULL) xfclose(fp);
      return 1;
}

#undef row_name
#undef col_name

/*----------------------------------------------------------------------
-- lpx_print_sol - write LP problem solution in printable format.
--
-- *Synopsis*
--
-- #include "glplpx.h"
-- int lpx_print_sol(LPX *lp, char *fname);
--
-- *Description*
--
-- The routine lpx_print_sol writes the current basic solution of an LP
-- problem, which is specified by the pointer lp, to a text file, whose
-- name is the character string fname, in printable format.
--
-- Information reported by the routine lpx_print_sol is intended mainly
-- for visual analysis.
--
-- *Returns*
--
-- If the operation was successful, the routine returns zero. Otherwise
-- the routine prints an error message and returns non-zero. */

int lpx_print_sol(LPX *lp, const char *fname)
{     XFILE *fp;
      int what, round;
      xprintf(
         "lpx_print_sol: writing LP problem solution to `%s'...\n",
         fname);
      fp = xfopen(fname, "w");
      if (fp == NULL)
      {  xprintf("lpx_print_sol: can't create `%s' - %s\n", fname,
            strerror(errno));
         goto fail;
      }
      /* problem name */
      {  const char *name;
         name = lpx_get_prob_name(lp);
         if (name == NULL) name = "";
         xfprintf(fp, "%-12s%s\n", "Problem:", name);
      }
      /* number of rows (auxiliary variables) */
      {  int nr;
         nr = lpx_get_num_rows(lp);
         xfprintf(fp, "%-12s%d\n", "Rows:", nr);
      }
      /* number of columns (structural variables) */
      {  int nc;
         nc = lpx_get_num_cols(lp);
         xfprintf(fp, "%-12s%d\n", "Columns:", nc);
      }
      /* number of non-zeros (constraint coefficients) */
      {  int nz;
         nz = lpx_get_num_nz(lp);
         xfprintf(fp, "%-12s%d\n", "Non-zeros:", nz);
      }
      /* solution status */
      {  int status;
         status = lpx_get_status(lp);
         xfprintf(fp, "%-12s%s\n", "Status:",
            status == LPX_OPT    ? "OPTIMAL" :
            status == LPX_FEAS   ? "FEASIBLE" :
            status == LPX_INFEAS ? "INFEASIBLE (INTERMEDIATE)" :
            status == LPX_NOFEAS ? "INFEASIBLE (FINAL)" :
            status == LPX_UNBND  ? "UNBOUNDED" :
            status == LPX_UNDEF  ? "UNDEFINED" : "???");
      }
      /* objective function */
      {  char *name;
         int dir;
         double obj;
         name = (void *)lpx_get_obj_name(lp);
         dir = lpx_get_obj_dir(lp);
         obj = lpx_get_obj_val(lp);
         xfprintf(fp, "%-12s%s%s%.10g %s\n", "Objective:",
            name == NULL ? "" : name,
            name == NULL ? "" : " = ", obj,
            dir == LPX_MIN ? "(MINimum)" :
            dir == LPX_MAX ? "(MAXimum)" : "(" "???" ")");
      }
      /* main sheet */
      for (what = 1; what <= 2; what++)
      {  int mn, ij;
         xfprintf(fp, "\n");
         xfprintf(fp, "   No. %-12s St   Activity     Lower bound   Upp"
            "er bound    Marginal\n",
            what == 1 ? "  Row name" : "Column name");
         xfprintf(fp, "------ ------------ -- ------------- -----------"
            "-- ------------- -------------\n");
         mn = (what == 1 ? lpx_get_num_rows(lp) : lpx_get_num_cols(lp));
         for (ij = 1; ij <= mn; ij++)
         {  const char *name;
            int typx, tagx;
            double lb, ub, vx, dx;
            if (what == 1)
            {  name = lpx_get_row_name(lp, ij);
               if (name == NULL) name = "";
               lpx_get_row_bnds(lp, ij, &typx, &lb, &ub);
               round = lpx_get_int_parm(lp, LPX_K_ROUND);
               lpx_set_int_parm(lp, LPX_K_ROUND, 1);
               lpx_get_row_info(lp, ij, &tagx, &vx, &dx);
               lpx_set_int_parm(lp, LPX_K_ROUND, round);
            }
            else
            {  name = lpx_get_col_name(lp, ij);
               if (name == NULL) name = "";
               lpx_get_col_bnds(lp, ij, &typx, &lb, &ub);
               round = lpx_get_int_parm(lp, LPX_K_ROUND);
               lpx_set_int_parm(lp, LPX_K_ROUND, 1);
               lpx_get_col_info(lp, ij, &tagx, &vx, &dx);
               lpx_set_int_parm(lp, LPX_K_ROUND, round);
            }
            /* row/column ordinal number */
            xfprintf(fp, "%6d ", ij);
            /* row column/name */
            if (strlen(name) <= 12)
               xfprintf(fp, "%-12s ", name);
            else
               xfprintf(fp, "%s\n%20s", name, "");
            /* row/column status */
            xfprintf(fp, "%s ",
               tagx == LPX_BS ? "B " :
               tagx == LPX_NL ? "NL" :
               tagx == LPX_NU ? "NU" :
               tagx == LPX_NF ? "NF" :
               tagx == LPX_NS ? "NS" : "??");
            /* row/column primal activity */
            xfprintf(fp, "%13.6g ", vx);
            /* row/column lower bound */
            if (typx == LPX_LO || typx == LPX_DB || typx == LPX_FX)
               xfprintf(fp, "%13.6g ", lb);
            else
               xfprintf(fp, "%13s ", "");
            /* row/column upper bound */
            if (typx == LPX_UP || typx == LPX_DB)
               xfprintf(fp, "%13.6g ", ub);
            else if (typx == LPX_FX)
               xfprintf(fp, "%13s ", "=");
            else
               xfprintf(fp, "%13s ", "");
            /* row/column dual activity */
            if (tagx != LPX_BS)
            {  if (dx == 0.0)
                  xfprintf(fp, "%13s", "< eps");
               else
                  xfprintf(fp, "%13.6g", dx);
            }
            /* end of line */
            xfprintf(fp, "\n");
         }
      }
      xfprintf(fp, "\n");
#if 1
      if (lpx_get_prim_stat(lp) != LPX_P_UNDEF &&
          lpx_get_dual_stat(lp) != LPX_D_UNDEF)
      {  int m = lpx_get_num_rows(lp);
         LPXKKT kkt;
         xfprintf(fp, "Karush-Kuhn-Tucker optimality conditions:\n\n");
         lpx_check_kkt(lp, 1, &kkt);
         xfprintf(fp, "KKT.PE: max.abs.err. = %.2e on row %d\n",
            kkt.pe_ae_max, kkt.pe_ae_row);
         xfprintf(fp, "        max.rel.err. = %.2e on row %d\n",
            kkt.pe_re_max, kkt.pe_re_row);
         switch (kkt.pe_quality)
         {  case 'H':
               xfprintf(fp, "        High quality\n");
               break;
            case 'M':
               xfprintf(fp, "        Medium quality\n");
               break;
            case 'L':
               xfprintf(fp, "        Low quality\n");
               break;
            default:
               xfprintf(fp, "        PRIMAL SOLUTION IS WRONG\n");
               break;
         }
         xfprintf(fp, "\n");
         xfprintf(fp, "KKT.PB: max.abs.err. = %.2e on %s %d\n",
            kkt.pb_ae_max, kkt.pb_ae_ind <= m ? "row" : "column",
            kkt.pb_ae_ind <= m ? kkt.pb_ae_ind : kkt.pb_ae_ind - m);
         xfprintf(fp, "        max.rel.err. = %.2e on %s %d\n",
            kkt.pb_re_max, kkt.pb_re_ind <= m ? "row" : "column",
            kkt.pb_re_ind <= m ? kkt.pb_re_ind : kkt.pb_re_ind - m);
         switch (kkt.pb_quality)
         {  case 'H':
               xfprintf(fp, "        High quality\n");
               break;
            case 'M':
               xfprintf(fp, "        Medium quality\n");
               break;
            case 'L':
               xfprintf(fp, "        Low quality\n");
               break;
            default:
               xfprintf(fp, "        PRIMAL SOLUTION IS INFEASIBLE\n");
               break;
         }
         xfprintf(fp, "\n");
         xfprintf(fp, "KKT.DE: max.abs.err. = %.2e on column %d\n",
            kkt.de_ae_max, kkt.de_ae_col);
         xfprintf(fp, "        max.rel.err. = %.2e on column %d\n",
            kkt.de_re_max, kkt.de_re_col);
         switch (kkt.de_quality)
         {  case 'H':
               xfprintf(fp, "        High quality\n");
               break;
            case 'M':
               xfprintf(fp, "        Medium quality\n");
               break;
            case 'L':
               xfprintf(fp, "        Low quality\n");
               break;
            default:
               xfprintf(fp, "        DUAL SOLUTION IS WRONG\n");
               break;
         }
         xfprintf(fp, "\n");
         xfprintf(fp, "KKT.DB: max.abs.err. = %.2e on %s %d\n",
            kkt.db_ae_max, kkt.db_ae_ind <= m ? "row" : "column",
            kkt.db_ae_ind <= m ? kkt.db_ae_ind : kkt.db_ae_ind - m);
         xfprintf(fp, "        max.rel.err. = %.2e on %s %d\n",
            kkt.db_re_max, kkt.db_re_ind <= m ? "row" : "column",
            kkt.db_re_ind <= m ? kkt.db_re_ind : kkt.db_re_ind - m);
         switch (kkt.db_quality)
         {  case 'H':
               xfprintf(fp, "        High quality\n");
               break;
            case 'M':
               xfprintf(fp, "        Medium quality\n");
               break;
            case 'L':
               xfprintf(fp, "        Low quality\n");
               break;
            default:
               xfprintf(fp, "        DUAL SOLUTION IS INFEASIBLE\n");
               break;
         }
         xfprintf(fp, "\n");
      }
#endif
#if 1
      if (lpx_get_status(lp) == LPX_UNBND)
      {  int m = lpx_get_num_rows(lp);
         int k = lpx_get_ray_info(lp);
         xfprintf(fp, "Unbounded ray: %s %d\n",
            k <= m ? "row" : "column", k <= m ? k : k - m);
         xfprintf(fp, "\n");
      }
#endif
      xfprintf(fp, "End of output\n");
      xfflush(fp);
      if (xferror(fp))
      {  xprintf("lpx_print_sol: can't write to `%s' - %s\n", fname,
            strerror(errno));
         goto fail;
      }
      xfclose(fp);
      return 0;
fail: if (fp != NULL) xfclose(fp);
      return 1;
}
int lpx_print_mip(LPX *lp, const char *fname)
{     XFILE *fp;
      int what, round;
#if 0
      if (lpx_get_class(lp) != LPX_MIP)
         fault("lpx_print_mip: error -- not a MIP problem");
#endif
      xprintf(
         "lpx_print_mip: writing MIP problem solution to `%s'...\n",
         fname);
      fp = xfopen(fname, "w");
      if (fp == NULL)
      {  xprintf("lpx_print_mip: can't create `%s' - %s\n", fname,
            strerror(errno));
         goto fail;
      }
      /* problem name */
      {  const char *name;
         name = lpx_get_prob_name(lp);
         if (name == NULL) name = "";
         xfprintf(fp, "%-12s%s\n", "Problem:", name);
      }
      /* number of rows (auxiliary variables) */
      {  int nr;
         nr = lpx_get_num_rows(lp);
         xfprintf(fp, "%-12s%d\n", "Rows:", nr);
      }
      /* number of columns (structural variables) */
      {  int nc, nc_int, nc_bin;
         nc = lpx_get_num_cols(lp);
         nc_int = lpx_get_num_int(lp);
         nc_bin = lpx_get_num_bin(lp);
         xfprintf(fp, "%-12s%d (%d integer, %d binary)\n", "Columns:",
            nc, nc_int, nc_bin);
      }
      /* number of non-zeros (constraint coefficients) */
      {  int nz;
         nz = lpx_get_num_nz(lp);
         xfprintf(fp, "%-12s%d\n", "Non-zeros:", nz);
      }
      /* solution status */
      {  int status;
         status = lpx_mip_status(lp);
         xfprintf(fp, "%-12s%s\n", "Status:",
            status == LPX_I_UNDEF  ? "INTEGER UNDEFINED" :
            status == LPX_I_OPT    ? "INTEGER OPTIMAL" :
            status == LPX_I_FEAS   ? "INTEGER NON-OPTIMAL" :
            status == LPX_I_NOFEAS ? "INTEGER EMPTY" : "???");
      }
      /* objective function */
      {  char *name;
         int dir;
         double mip_obj;
         name = (void *)lpx_get_obj_name(lp);
         dir = lpx_get_obj_dir(lp);
         mip_obj = lpx_mip_obj_val(lp);
         xfprintf(fp, "%-12s%s%s%.10g %s\n", "Objective:",
            name == NULL ? "" : name,
            name == NULL ? "" : " = ", mip_obj,
            dir == LPX_MIN ? "(MINimum)" :
            dir == LPX_MAX ? "(MAXimum)" : "(" "???" ")");
      }
      /* main sheet */
      for (what = 1; what <= 2; what++)
      {  int mn, ij;
         xfprintf(fp, "\n");
         xfprintf(fp, "   No. %-12s      Activity     Lower bound   Upp"
            "er bound\n",
            what == 1 ? "  Row name" : "Column name");
         xfprintf(fp, "------ ------------    ------------- -----------"
            "-- -------------\n");
         mn = (what == 1 ? lpx_get_num_rows(lp) : lpx_get_num_cols(lp));
         for (ij = 1; ij <= mn; ij++)
         {  const char *name;
            int kind, typx;
            double lb, ub, vx;
            if (what == 1)
            {  name = lpx_get_row_name(lp, ij);
               if (name == NULL) name = "";
               kind = LPX_CV;
               lpx_get_row_bnds(lp, ij, &typx, &lb, &ub);
               round = lpx_get_int_parm(lp, LPX_K_ROUND);
               lpx_set_int_parm(lp, LPX_K_ROUND, 1);
               vx = lpx_mip_row_val(lp, ij);
               lpx_set_int_parm(lp, LPX_K_ROUND, round);
            }
            else
            {  name = lpx_get_col_name(lp, ij);
               if (name == NULL) name = "";
               kind = lpx_get_col_kind(lp, ij);
               lpx_get_col_bnds(lp, ij, &typx, &lb, &ub);
               round = lpx_get_int_parm(lp, LPX_K_ROUND);
               lpx_set_int_parm(lp, LPX_K_ROUND, 1);
               vx = lpx_mip_col_val(lp, ij);
               lpx_set_int_parm(lp, LPX_K_ROUND, round);
            }
            /* row/column ordinal number */
            xfprintf(fp, "%6d ", ij);
            /* row column/name */
            if (strlen(name) <= 12)
               xfprintf(fp, "%-12s ", name);
            else
               xfprintf(fp, "%s\n%20s", name, "");
            /* row/column kind */
            xfprintf(fp, "%s  ",
               kind == LPX_CV ? " " : kind == LPX_IV ? "*" : "?");
            /* row/column primal activity */
            xfprintf(fp, "%13.6g", vx);
            /* row/column lower and upper bounds */
            switch (typx)
            {  case LPX_FR:
                  break;
               case LPX_LO:
                  xfprintf(fp, " %13.6g", lb);
                  break;
               case LPX_UP:
                  xfprintf(fp, " %13s %13.6g", "", ub);
                  break;
               case LPX_DB:
                  xfprintf(fp, " %13.6g %13.6g", lb, ub);
                  break;
               case LPX_FX:
                  xfprintf(fp, " %13.6g %13s", lb, "=");
                  break;
               default:
                  xassert(typx != typx);
            }
            /* end of line */
            xfprintf(fp, "\n");
         }
      }
      xfprintf(fp, "\n");
#if 1
      if (lpx_mip_status(lp) != LPX_I_UNDEF)
      {  int m = lpx_get_num_rows(lp);
         LPXKKT kkt;
         xfprintf(fp, "Integer feasibility conditions:\n\n");
         lpx_check_int(lp, &kkt);
         xfprintf(fp, "INT.PE: max.abs.err. = %.2e on row %d\n",
            kkt.pe_ae_max, kkt.pe_ae_row);
         xfprintf(fp, "        max.rel.err. = %.2e on row %d\n",
            kkt.pe_re_max, kkt.pe_re_row);
         switch (kkt.pe_quality)
         {  case 'H':
               xfprintf(fp, "        High quality\n");
               break;
            case 'M':
               xfprintf(fp, "        Medium quality\n");
               break;
            case 'L':
               xfprintf(fp, "        Low quality\n");
               break;
            default:
               xfprintf(fp, "        SOLUTION IS WRONG\n");
               break;
         }
         xfprintf(fp, "\n");
         xfprintf(fp, "INT.PB: max.abs.err. = %.2e on %s %d\n",
            kkt.pb_ae_max, kkt.pb_ae_ind <= m ? "row" : "column",
            kkt.pb_ae_ind <= m ? kkt.pb_ae_ind : kkt.pb_ae_ind - m);
         xfprintf(fp, "        max.rel.err. = %.2e on %s %d\n",
            kkt.pb_re_max, kkt.pb_re_ind <= m ? "row" : "column",
            kkt.pb_re_ind <= m ? kkt.pb_re_ind : kkt.pb_re_ind - m);
         switch (kkt.pb_quality)
         {  case 'H':
               xfprintf(fp, "        High quality\n");
               break;
            case 'M':
               xfprintf(fp, "        Medium quality\n");
               break;
            case 'L':
               xfprintf(fp, "        Low quality\n");
               break;
            default:
               xfprintf(fp, "        SOLUTION IS INFEASIBLE\n");
               break;
         }
         xfprintf(fp, "\n");
      }
#endif
      xfprintf(fp, "End of output\n");
      xfflush(fp);
      if (xferror(fp))
      {  xprintf("lpx_print_mip: can't write to `%s' - %s\n", fname,
            strerror(errno));
         goto fail;
      }
      xfclose(fp);
      return 0;
fail: if (fp != NULL) xfclose(fp);
      return 1;
}
int lpx_print_ips(LPX *lp, const char *fname)
{     XFILE *fp;
      int what, round;
      xprintf("lpx_print_ips: writing LP problem solution to `%s'...\n",
         fname);
      fp = xfopen(fname, "w");
      if (fp == NULL)
      {  xprintf("lpx_print_ips: can't create `%s' - %s\n", fname,
            strerror(errno));
         goto fail;
      }
      /* problem name */
      {  const char *name;
         name = lpx_get_prob_name(lp);
         if (name == NULL) name = "";
         xfprintf(fp, "%-12s%s\n", "Problem:", name);
      }
      /* number of rows (auxiliary variables) */
      {  int nr;
         nr = lpx_get_num_rows(lp);
         xfprintf(fp, "%-12s%d\n", "Rows:", nr);
      }
      /* number of columns (structural variables) */
      {  int nc;
         nc = lpx_get_num_cols(lp);
         xfprintf(fp, "%-12s%d\n", "Columns:", nc);
      }
      /* number of non-zeros (constraint coefficients) */
      {  int nz;
         nz = lpx_get_num_nz(lp);
         xfprintf(fp, "%-12s%d\n", "Non-zeros:", nz);
      }
      /* solution status */
      {  int status;
         status = lpx_ipt_status(lp);
         xfprintf(fp, "%-12s%s\n", "Status:",
            status == LPX_T_UNDEF  ? "INTERIOR UNDEFINED" :
            status == LPX_T_OPT    ? "INTERIOR OPTIMAL" : "???");
      }
      /* objective function */
      {  char *name;
         int dir;
         double obj;
         name = (void *)lpx_get_obj_name(lp);
         dir = lpx_get_obj_dir(lp);
         obj = lpx_ipt_obj_val(lp);
         xfprintf(fp, "%-12s%s%s%.10g %s\n", "Objective:",
            name == NULL ? "" : name,
            name == NULL ? "" : " = ", obj,
            dir == LPX_MIN ? "(MINimum)" :
            dir == LPX_MAX ? "(MAXimum)" : "(" "???" ")");
      }
      /* main sheet */
      for (what = 1; what <= 2; what++)
      {  int mn, ij;
         xfprintf(fp, "\n");
         xfprintf(fp, "   No. %-12s      Activity     Lower bound   Upp"
            "er bound    Marginal\n",
            what == 1 ? "  Row name" : "Column name");
         xfprintf(fp, "------ ------------    ------------- -----------"
            "-- ------------- -------------\n");
         mn = (what == 1 ? lpx_get_num_rows(lp) : lpx_get_num_cols(lp));
         for (ij = 1; ij <= mn; ij++)
         {  const char *name;
            int typx /*, tagx */;
            double lb, ub, vx, dx;
            if (what == 1)
            {  name = lpx_get_row_name(lp, ij);
               if (name == NULL) name = "";
               lpx_get_row_bnds(lp, ij, &typx, &lb, &ub);
               round = lpx_get_int_parm(lp, LPX_K_ROUND);
               lpx_set_int_parm(lp, LPX_K_ROUND, 1);
               vx = lpx_ipt_row_prim(lp, ij);
               dx = lpx_ipt_row_dual(lp, ij);
               lpx_set_int_parm(lp, LPX_K_ROUND, round);
            }
            else
            {  name = lpx_get_col_name(lp, ij);
               if (name == NULL) name = "";
               lpx_get_col_bnds(lp, ij, &typx, &lb, &ub);
               round = lpx_get_int_parm(lp, LPX_K_ROUND);
               lpx_set_int_parm(lp, LPX_K_ROUND, 1);
               vx = lpx_ipt_col_prim(lp, ij);
               dx = lpx_ipt_col_dual(lp, ij);
               lpx_set_int_parm(lp, LPX_K_ROUND, round);
            }
            /* row/column ordinal number */
            xfprintf(fp, "%6d ", ij);
            /* row column/name */
            if (strlen(name) <= 12)
               xfprintf(fp, "%-12s ", name);
            else
               xfprintf(fp, "%s\n%20s", name, "");
            /* two positions are currently not used */
            xfprintf(fp, "   ");
            /* row/column primal activity */
            xfprintf(fp, "%13.6g ", vx);
            /* row/column lower bound */
            if (typx == LPX_LO || typx == LPX_DB || typx == LPX_FX)
               xfprintf(fp, "%13.6g ", lb);
            else
               xfprintf(fp, "%13s ", "");
            /* row/column upper bound */
            if (typx == LPX_UP || typx == LPX_DB)
               xfprintf(fp, "%13.6g ", ub);
            else if (typx == LPX_FX)
               xfprintf(fp, "%13s ", "=");
            else
               xfprintf(fp, "%13s ", "");
            /* row/column dual activity */
            xfprintf(fp, "%13.6g", dx);
            /* end of line */
            xfprintf(fp, "\n");
         }
      }
      xfprintf(fp, "\n");
      xfprintf(fp, "End of output\n");
      xfflush(fp);
      if (xferror(fp))
      {  xprintf("lpx_print_ips: can't write to `%s' - %s\n", fname,
            strerror(errno));
         goto fail;
      }
      xfclose(fp);
      return 0;
fail: if (fp != NULL) xfclose(fp);
      return 1;
}
Exemple #28
0
int main(int argc, char *argv[])
{     LPX *lp;
      MPL *mpl = NULL;
      int ret;
      ulong_t start;
      /* parse command line parameters */
      parse_cmdline(argc, argv);
      /* set available memory limit */
      if (memlim >= 0)
         lib_mem_limit(ulmul(ulset(0, 1048576), ulset(0, memlim)));
      /* remove all output files specified in the command line */
      if (display != NULL) remove(display);
      if (out_bas != NULL) remove(out_bas);
      if (out_sol != NULL) remove(out_sol);
      if (out_bnds != NULL) remove(out_bnds);
      if (out_mps != NULL) remove(out_mps);
      if (out_freemps != NULL) remove(out_freemps);
      if (out_cpxlp != NULL) remove(out_cpxlp);
      if (out_txt != NULL) remove(out_txt);
      if (out_glp != NULL) remove(out_glp);
      if (log_file != NULL) remove(log_file);
      /* open hardcopy file, if necessary */
      if (log_file != NULL)
      {  if (lib_open_log(log_file))
         {  print("Unable to create log file");
            exit(EXIT_FAILURE);
         }
      }
      /* read problem data from the input file */
      if (in_file == NULL)
      {  print("No input file specified; try %s --help", argv[0]);
         exit(EXIT_FAILURE);
      }
      switch (format)
      {  case 0:
            lp = lpx_read_mps(in_file);
            if (lp == NULL)
            {  print("MPS file processing error");
               exit(EXIT_FAILURE);
            }
            orig = 1;
            break;
         case 1:
            lp = lpx_read_cpxlp(in_file);
            if (lp == NULL)
            {  print("CPLEX LP file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         case 2:
            /* initialize the translator database */
            mpl = mpl_initialize();
            /* read model section and optional data section */
            ret = mpl_read_model(mpl, in_file, in_data != NULL);
            if (ret == 4)
err:        {  print("Model processing error");
               exit(EXIT_FAILURE);
            }
            xassert(ret == 1 || ret == 2);
            /* read data section, if necessary */
            if (in_data != NULL)
            {  xassert(ret == 1);
               ret = mpl_read_data(mpl, in_data);
               if (ret == 4) goto err;
               xassert(ret == 2);
            }
            /* generate model */
            ret = mpl_generate(mpl, display);
            if (ret == 4) goto err;
            /* extract problem instance */
            lp = lpx_extract_prob(mpl);
            xassert(lp != NULL);
            break;
         case 3:
            lp = lpx_read_prob(in_file);
            if (lp == NULL)
            {  print("GNU LP file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         case 4:
            lp = lpx_read_freemps(in_file);
            if (lp == NULL)
            {  print("MPS file processing error");
               exit(EXIT_FAILURE);
            }
            break;
         default:
            xassert(format != format);
      }
      /* order rows and columns of the constraint matrix */
      lpx_order_matrix(lp);
      /* change problem name (if required) */
      if (newname != NULL) lpx_set_prob_name(lp, newname);
      /* change optimization direction (if required) */
      if (dir != 0) lpx_set_obj_dir(lp, dir);
      /* write problem in fixed MPS format (if required) */
      if (out_mps != NULL)
      {  lpx_set_int_parm(lp, LPX_K_MPSORIG, orig);
         ret = lpx_write_mps(lp, out_mps);
         if (ret != 0)
         {  print("Unable to write problem in fixed MPS format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in free MPS format (if required) */
      if (out_freemps != NULL)
      {  ret = lpx_write_freemps(lp, out_freemps);
         if (ret != 0)
         {  print("Unable to write problem in free MPS format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in CPLEX LP format (if required) */
      if (out_cpxlp != NULL)
      {  ret = lpx_write_cpxlp(lp, out_cpxlp);
         if (ret != 0)
         {  print("Unable to write problem in CPLEX LP format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in plain text format (if required) */
      if (out_txt != NULL)
      {  lpx_set_int_parm(lp, LPX_K_LPTORIG, orig);
         ret = lpx_print_prob(lp, out_txt);
         if (ret != 0)
         {  print("Unable to write problem in plain text format");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem in GNU LP format (if required) */
      if (out_glp != NULL)
      {  ret = lpx_write_prob(lp, out_glp);
         if (ret != 0)
         {  print("Unable to write problem in GNU LP format");
            exit(EXIT_FAILURE);
         }
      }
      /* if only data check is required, skip computations */
      if (check) goto skip;
      /* scale the problem data (if required) */
      if (scale && (!presol || method == 1)) lpx_scale_prob(lp);
      /* build initial LP basis */
      if (method == 0 && !presol && in_bas == NULL)
      {  switch (basis)
         {  case 0:
               lpx_std_basis(lp);
               break;
            case 1:
               if (lpx_get_num_rows(lp) > 0 && lpx_get_num_cols(lp) > 0)
                  lpx_adv_basis(lp);
               break;
            case 2:
               if (lpx_get_num_rows(lp) > 0 && lpx_get_num_cols(lp) > 0)
                  lpx_cpx_basis(lp);
               break;
            default:
               xassert(basis != basis);
         }
      }
      /* or read initial basis from input text file in MPS format */
      if (in_bas != NULL)
      {  if (method != 0)
         {  print("Initial LP basis is useless for interior-point solve"
               "r and therefore ignored");
            goto nobs;
         }
         lpx_set_int_parm(lp, LPX_K_MPSORIG, orig);
         ret = lpx_read_bas(lp, in_bas);
         if (ret != 0)
         {  print("Unable to read initial LP basis");
            exit(EXIT_FAILURE);
         }
         if (presol)
         {  presol = 0;
            print("LP presolver disabled because initial LP basis has b"
               "een provided");
         }
nobs:    ;
      }
      /* set some control parameters, which might be changed in the
         command line */
      lpx_set_int_parm(lp, LPX_K_BFTYPE, bf_type);
      lpx_set_int_parm(lp, LPX_K_PRICE, price);
      if (!relax) lpx_set_real_parm(lp, LPX_K_RELAX, 0.0);
      lpx_set_int_parm(lp, LPX_K_PRESOL, presol);
      lpx_set_int_parm(lp, LPX_K_BRANCH, branch);
      lpx_set_int_parm(lp, LPX_K_BTRACK, btrack);
      lpx_set_real_parm(lp, LPX_K_TMLIM, (double)tmlim);
      lpx_set_int_parm(lp, LPX_K_BINARIZE, binarize);
      lpx_set_int_parm(lp, LPX_K_USECUTS, use_cuts);
      /* solve the problem */
      start = xtime();
      switch (method)
      {  case 0:
            if (nomip || lpx_get_class(lp) == LPX_LP)
            {  ret = (!exact ? lpx_simplex(lp) : lpx_exact(lp));
               if (xcheck)
               {  if (!presol || ret == LPX_E_OK)
                     lpx_exact(lp);
                  else
                     print("If you need checking final basis for non-op"
                        "timal solution, use --nopresol");
               }
               if (presol && ret != LPX_E_OK && (out_bas != NULL ||
                  out_sol != NULL))
                  print("If you need actual output for non-optimal solu"
                     "tion, use --nopresol");
            }
            else
            {  method = 2;
               if (!intopt)
               {  ret = (!exact ? lpx_simplex(lp) : lpx_exact(lp));
                  if (xcheck && (!presol || ret == LPX_E_OK))
                     lpx_exact(lp);
                  lpx_integer(lp);
               }
               else
                  lpx_intopt(lp);
            }
            break;
         case 1:
            if (nomip || lpx_get_class(lp) == LPX_LP)
               lpx_interior(lp);
            else
            {  print("Interior-point method is not able to solve MIP pr"
                  "oblem; use --simplex");
               exit(EXIT_FAILURE);
            }
            break;
         default:
            xassert(method != method);
      }
      /* display statistics */
      print("Time used:   %.1f secs", xdifftime(xtime(), start));
      {  ulong_t tpeak;
         char buf[50];
         lib_mem_usage(NULL, NULL, NULL, &tpeak);
         print("Memory used: %.1f Mb (%s bytes)",
            (4294967296.0 * tpeak.hi + tpeak.lo) / 1048576.0,
            ultoa(tpeak, buf, 10));
      }
      if (mpl != NULL && mpl_has_solve_stmt(mpl))
      {  int n, j, round;
         /* store the solution to the translator database */
         n = lpx_get_num_cols(lp);
         round = lpx_get_int_parm(lp, LPX_K_ROUND);
         lpx_set_int_parm(lp, LPX_K_ROUND, 1);
         switch (method)
         {  case 0:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_get_col_prim(lp, j));
               break;
            case 1:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_ipt_col_prim(lp, j));
               break;
            case 2:
               for (j = 1; j <= n; j++)
                  mpl_put_col_value(mpl, j, lpx_mip_col_val(lp, j));
               break;
            default:
               xassert(method != method);
         }
         lpx_set_int_parm(lp, LPX_K_ROUND, round);
         /* perform postsolving */
         ret = mpl_postsolve(mpl);
         if (ret == 4)
         {  print("Model postsolving error");
            exit(EXIT_FAILURE);
         }
         xassert(ret == 3);
      }
      /* write final LP basis (if required) */
      if (out_bas != NULL)
      {  lpx_set_int_parm(lp, LPX_K_MPSORIG, orig);
         ret = lpx_write_bas(lp, out_bas);
         if (ret != 0)
         {  print("Unable to write final LP basis");
            exit(EXIT_FAILURE);
         }
      }
      /* write problem solution found by the solver (if required) */
      if (out_sol != NULL)
      {  switch (method)
         {  case 0:
               ret = lpx_print_sol(lp, out_sol);
               break;
            case 1:
               ret = lpx_print_ips(lp, out_sol);
               break;
            case 2:
               ret = lpx_print_mip(lp, out_sol);
               break;
            default:
               xassert(method != method);
         }
         if (ret != 0)
         {  print("Unable to write problem solution");
            exit(EXIT_FAILURE);
         }
      }
      /* write sensitivity bounds information (if required) */
      if (out_bnds != NULL)
      {  if (method != 0)
         {  print("Cannot write sensitivity bounds information for inte"
               "rior-point or MIP solution");
            exit(EXIT_FAILURE);
         }
         ret = lpx_print_sens_bnds(lp, out_bnds);
         if (ret != 0)
         {  print("Unable to write sensitivity bounds information");
            exit(EXIT_FAILURE);
         }
      }
skip: /* delete the problem object */
      lpx_delete_prob(lp);
      /* if the translator database exists, destroy it */
      if (mpl != NULL) mpl_terminate(mpl);
      xassert(gmp_pool_count() == 0);
      gmp_free_mem();
      /* close the hardcopy file */
      if (log_file != NULL) lib_close_log();
      /* check that no memory blocks are still allocated */
      {  int count;
         ulong_t total;
         lib_mem_usage(&count, NULL, &total, NULL);
         xassert(count == 0);
         xassert(total.lo == 0 && total.hi == 0);
      }
      /* free the library environment */
      lib_free_env();
      /* return to the control program */
      return 0;
}
Exemple #29
0
int CClp_nrows(CClp *lp)
{     /* RETURNS the number of rows in the LP. */
      return lpx_get_num_rows(lp->lp);
}
Exemple #30
0
int CClp_limited_dualopt(CClp *lp, int iterationlim, int *status,
      double *objupperlim)
{     /* CALLS the dual simplex method with a limit on the number of
         pivots.
         - upperbound it is used to cutoff the dual simplex method (when
           the objective value reaches upperbound); it can be NULL;
         - status returns the status of the optimization (it can be
           NULL). */
      int stat, ret;
      insist(iterationlim == iterationlim);
      insist(objupperlim == objupperlim);
      if (MSGLEV >= 1)
      {  int m = lpx_get_num_rows(lp->lp);
         int n = lpx_get_num_cols(lp->lp);
         int nz = lpx_get_num_nz(lp->lp);
         print("CClp_limited_dualopt: m = %d; n = %d; nz = %d", m, n,
            nz);
      }
      lpx_set_int_parm(lp->lp, LPX_K_DUAL, 1);
      switch (MSGLEV)
      {  case 0:
            lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 0);
            lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 1000000);
            lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 1e6);
            break;
         case 1:
            lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 2);
            lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 200);
            lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 5.0);
            break;
         case 2:
            lpx_set_int_parm(lp->lp, LPX_K_MSGLEV, 3);
            lpx_set_int_parm(lp->lp, LPX_K_OUTFRQ, 200);
            lpx_set_real_parm(lp->lp, LPX_K_OUTDLY, 0.0);
            break;
         default:
            insist(MSGLEV != MSGLEV);
      }
      ret = lpx_simplex(lp->lp);
      if (ret == LPX_E_FAULT)
      {  if (MSGLEV >= 1) print("CClp_limited_dualopt: restarting from "
            "advanced basis...");
         lpx_adv_basis(lp->lp);
         ret = lpx_simplex(lp->lp);
      }
      if (ret != LPX_E_OK)
      {  print("CClp_limited_dualopt: lpx_simplex failed; return code ="
            " %d", ret);
         if (status) *status = CClp_FAILURE;
         ret = 1;
         goto done;
      }
      stat = lpx_get_status(lp->lp);
      if (stat == LPX_OPT)
      {  if (status) *status = CClp_SUCCESS;
         ret = 0;
      }
      else if (stat == LPX_NOFEAS)
      {  if (status) *status = CClp_INFEASIBLE;
         ret = 0;
      }
      else
      {  print("CClp_limited_dualopt: optimization status = %d", stat);
         if (status) *status = CClp_FAILURE;
         ret = 1;
      }
done: return ret;
}