Example #1
0
int glp_mpl_postsolve(glp_tran *tran, glp_prob *prob, int sol)
{     /* postsolve the model */
      int i, j, m, n, stat, ret;
      double prim, dual;
      if (!(tran->phase == 3 && !tran->flag_p))
         xerror("glp_mpl_postsolve: invalid call sequence\n");
      if (!(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP))
         xerror("glp_mpl_postsolve: sol = %d; invalid parameter\n",
            sol);
      m = mpl_get_num_rows(tran);
      n = mpl_get_num_cols(tran);
      if (!(m == glp_get_num_rows(prob) &&
            n == glp_get_num_cols(prob)))
         xerror("glp_mpl_postsolve: wrong problem object\n");
      if (!mpl_has_solve_stmt(tran))
      {  ret = 0;
         goto done;
      }
      for (i = 1; i <= m; i++)
      {  if (sol == GLP_SOL)
         {  stat = glp_get_row_stat(prob, i);
            prim = glp_get_row_prim(prob, i);
            dual = glp_get_row_dual(prob, i);
         }
         else if (sol == GLP_IPT)
         {  stat = 0;
            prim = glp_ipt_row_prim(prob, i);
            dual = glp_ipt_row_dual(prob, i);
         }
         else if (sol == GLP_MIP)
         {  stat = 0;
            prim = glp_mip_row_val(prob, i);
            dual = 0.0;
         }
         else
            xassert(sol != sol);
         if (fabs(prim) < 1e-9) prim = 0.0;
         if (fabs(dual) < 1e-9) dual = 0.0;
         mpl_put_row_soln(tran, i, stat, prim, dual);
      }
      for (j = 1; j <= n; j++)
      {  if (sol == GLP_SOL)
         {  stat = glp_get_col_stat(prob, j);
            prim = glp_get_col_prim(prob, j);
            dual = glp_get_col_dual(prob, j);
         }
         else if (sol == GLP_IPT)
         {  stat = 0;
            prim = glp_ipt_col_prim(prob, j);
            dual = glp_ipt_col_dual(prob, j);
         }
         else if (sol == GLP_MIP)
         {  stat = 0;
            prim = glp_mip_col_val(prob, j);
            dual = 0.0;
         }
         else
            xassert(sol != sol);
         if (fabs(prim) < 1e-9) prim = 0.0;
         if (fabs(dual) < 1e-9) dual = 0.0;
         mpl_put_col_soln(tran, j, stat, prim, dual);
      }
      ret = mpl_postsolve(tran);
      if (ret == 3)
         ret = 0;
      else if (ret == 4)
         ret = 1;
done: return ret;
}
Example #2
0
double lpx_get_row_dual(LPX *lp, int i)
{     /* retrieve row dual value (basic solution) */
      return glp_get_row_dual(lp, i);
}
Example #3
0
static int branch_drtom(glp_tree *T, int *_next)
{     glp_prob *mip = T->mip;
      int m = mip->m;
      int n = mip->n;
      char *non_int = T->non_int;
      int j, jj, k, t, next, kase, len, stat, *ind;
      double x, dk, alfa, delta_j, delta_k, delta_z, dz_dn, dz_up,
         dd_dn, dd_up, degrad, *val;
      /* basic solution of LP relaxation must be optimal */
      xassert(glp_get_status(mip) == GLP_OPT);
      /* allocate working arrays */
      ind = xcalloc(1+n, sizeof(int));
      val = xcalloc(1+n, sizeof(double));
      /* nothing has been chosen so far */
      jj = 0, degrad = -1.0;
      /* walk through the list of columns (structural variables) */
      for (j = 1; j <= n; j++)
      {  /* if j-th column is not marked as fractional, skip it */
         if (!non_int[j]) continue;
         /* obtain (fractional) value of j-th column in basic solution
            of LP relaxation */
         x = glp_get_col_prim(mip, j);
         /* since the value of j-th column is fractional, the column is
            basic; compute corresponding row of the simplex table */
         len = glp_eval_tab_row(mip, m+j, ind, val);
         /* the following fragment computes a change in the objective
            function: delta Z = new Z - old Z, where old Z is the
            objective value in the current optimal basis, and new Z is
            the objective value in the adjacent basis, for two cases:
            1) if new upper bound ub' = floor(x[j]) is introduced for
               j-th column (down branch);
            2) if new lower bound lb' = ceil(x[j]) is introduced for
               j-th column (up branch);
            since in both cases the solution remaining dual feasible
            becomes primal infeasible, one implicit simplex iteration
            is performed to determine the change delta Z;
            it is obvious that new Z, which is never better than old Z,
            is a lower (minimization) or upper (maximization) bound of
            the objective function for down- and up-branches. */
         for (kase = -1; kase <= +1; kase += 2)
         {  /* if kase < 0, the new upper bound of x[j] is introduced;
               in this case x[j] should decrease in order to leave the
               basis and go to its new upper bound */
            /* if kase > 0, the new lower bound of x[j] is introduced;
               in this case x[j] should increase in order to leave the
               basis and go to its new lower bound */
            /* apply the dual ratio test in order to determine which
               auxiliary or structural variable should enter the basis
               to keep dual feasibility */
            k = glp_dual_rtest(mip, len, ind, val, kase, 1e-9);
            if (k != 0) k = ind[k];
            /* if no non-basic variable has been chosen, LP relaxation
               of corresponding branch being primal infeasible and dual
               unbounded has no primal feasible solution; in this case
               the change delta Z is formally set to infinity */
            if (k == 0)
            {  delta_z =
                  (T->mip->dir == GLP_MIN ? +DBL_MAX : -DBL_MAX);
               goto skip;
            }
            /* row of the simplex table that corresponds to non-basic
               variable x[k] choosen by the dual ratio test is:
                  x[j] = ... + alfa * x[k] + ...
               where alfa is the influence coefficient (an element of
               the simplex table row) */
            /* determine the coefficient alfa */
            for (t = 1; t <= len; t++) if (ind[t] == k) break;
            xassert(1 <= t && t <= len);
            alfa = val[t];
            /* since in the adjacent basis the variable x[j] becomes
               non-basic, knowing its value in the current basis we can
               determine its change delta x[j] = new x[j] - old x[j] */
            delta_j = (kase < 0 ? floor(x) : ceil(x)) - x;
            /* and knowing the coefficient alfa we can determine the
               corresponding change delta x[k] = new x[k] - old x[k],
               where old x[k] is a value of x[k] in the current basis,
               and new x[k] is a value of x[k] in the adjacent basis */
            delta_k = delta_j / alfa;
            /* Tomlin noticed that if the variable x[k] is of integer
               kind, its change cannot be less (eventually) than one in
               the magnitude */
            if (k > m && glp_get_col_kind(mip, k-m) != GLP_CV)
            {  /* x[k] is structural integer variable */
               if (fabs(delta_k - floor(delta_k + 0.5)) > 1e-3)
               {  if (delta_k > 0.0)
                     delta_k = ceil(delta_k);  /* +3.14 -> +4 */
                  else
                     delta_k = floor(delta_k); /* -3.14 -> -4 */
               }
            }
            /* now determine the status and reduced cost of x[k] in the
               current basis */
            if (k <= m)
            {  stat = glp_get_row_stat(mip, k);
               dk = glp_get_row_dual(mip, k);
            }
            else
            {  stat = glp_get_col_stat(mip, k-m);
               dk = glp_get_col_dual(mip, k-m);
            }
            /* if the current basis is dual degenerate, some reduced
               costs which are close to zero may have wrong sign due to
               round-off errors, so correct the sign of d[k] */
            switch (T->mip->dir)
            {  case GLP_MIN:
                  if (stat == GLP_NL && dk < 0.0 ||
                      stat == GLP_NU && dk > 0.0 ||
                      stat == GLP_NF) dk = 0.0;
                  break;
               case GLP_MAX:
                  if (stat == GLP_NL && dk > 0.0 ||
                      stat == GLP_NU && dk < 0.0 ||
                      stat == GLP_NF) dk = 0.0;
                  break;
               default:
                  xassert(T != T);
            }
            /* now knowing the change of x[k] and its reduced cost d[k]
               we can compute the corresponding change in the objective
               function delta Z = new Z - old Z = d[k] * delta x[k];
               note that due to Tomlin's modification new Z can be even
               worse than in the adjacent basis */
            delta_z = dk * delta_k;
skip:       /* new Z is never better than old Z, therefore the change
               delta Z is always non-negative (in case of minimization)
               or non-positive (in case of maximization) */
            switch (T->mip->dir)
            {  case GLP_MIN: xassert(delta_z >= 0.0); break;
               case GLP_MAX: xassert(delta_z <= 0.0); break;
               default: xassert(T != T);
            }
            /* save the change in the objective fnction for down- and
               up-branches, respectively */
            if (kase < 0) dz_dn = delta_z; else dz_up = delta_z;
         }
         /* thus, in down-branch no integer feasible solution can be
            better than Z + dz_dn, and in up-branch no integer feasible
            solution can be better than Z + dz_up, where Z is value of
            the objective function in the current basis */
         /* following the heuristic by Driebeck and Tomlin we choose a
            column (i.e. structural variable) which provides largest
            degradation of the objective function in some of branches;
            besides, we select the branch with smaller degradation to
            be solved next and keep other branch with larger degradation
            in the active list hoping to minimize the number of further
            backtrackings */
         if (degrad < fabs(dz_dn) || degrad < fabs(dz_up))
         {  jj = j;
            if (fabs(dz_dn) < fabs(dz_up))
            {  /* select down branch to be solved next */
               next = GLP_DN_BRNCH;
               degrad = fabs(dz_up);
            }
            else
            {  /* select up branch to be solved next */
               next = GLP_UP_BRNCH;
               degrad = fabs(dz_dn);
            }
            /* save the objective changes for printing */
            dd_dn = dz_dn, dd_up = dz_up;
            /* if down- or up-branch has no feasible solution, we does
               not need to consider other candidates (in principle, the
               corresponding branch could be pruned right now) */
            if (degrad == DBL_MAX) break;
         }
      }
      /* free working arrays */
      xfree(ind);
      xfree(val);
      /* something must be chosen */
      xassert(1 <= jj && jj <= n);
#if 1 /* 02/XI-2009 */
      if (degrad < 1e-6 * (1.0 + 0.001 * fabs(mip->obj_val)))
      {  jj = branch_mostf(T, &next);
         goto done;
      }
#endif
      if (T->parm->msg_lev >= GLP_MSG_DBG)
      {  xprintf("branch_drtom: column %d chosen to branch on\n", jj);
         if (fabs(dd_dn) == DBL_MAX)
            xprintf("branch_drtom: down-branch is infeasible\n");
         else
            xprintf("branch_drtom: down-branch bound is %.9e\n",
               lpx_get_obj_val(mip) + dd_dn);
         if (fabs(dd_up) == DBL_MAX)
            xprintf("branch_drtom: up-branch   is infeasible\n");
         else
            xprintf("branch_drtom: up-branch   bound is %.9e\n",
               lpx_get_obj_val(mip) + dd_up);
      }
done: *_next = next;
      return jj;
}
Example #4
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();

  // Obsolete
  //lib_set_fault_hook (NULL, glpk_fault_hook);

  //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
  glp_prob *lp = glp_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])
      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;
	  }
      
    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 (lpx_write_cpxlp (lp, save_filename) != 0) {
	        mexErrMsgTxt("glpkcc: unable to write the problem");
	        longjmp (mark, -1);
      }
    }else{
      if (!strcmp(filetype,"fixedmps")){
        if (lpx_write_mps (lp, save_filename) != 0) {
          mexErrMsgTxt("glpkcc: unable to write the problem");
	        longjmp (mark, -1);  
        }
      }else{
        if (!strcmp(filetype,"freemps")){
          if (lpx_write_freemps (lp, save_filename) != 0) {
            mexErrMsgTxt("glpkcc: unable to write the problem");
	          longjmp (mark, -1);
          }
        }else{// plain text
          if (lpx_print_prob (lp, save_filename) != 0) {
            mexErrMsgTxt("glpkcc: unable to write the problem");
	          longjmp (mark, -1);
          } 
        } 
      }    
    } 
  }
  //-- scale the problem data (if required)
  if (glpIntParam[1] && (! glpIntParam[16] || lpsolver != 1))
    lpx_scale_prob (lp);

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

  glp_smcp sParam;
  glp_init_smcp(&sParam);
  
  //-- set control parameters
  if (lpsolver==1){
    //remap of control parameters for simplex method
    sParam.msg_lev=glpIntParam[0];	// message level
    // simplex method: primal/dual
    if (glpIntParam[2]==0) sParam.meth=GLP_PRIMAL;		
    else sParam.meth=GLP_DUALP;
    // pricing technique
    if (glpIntParam[3]==0) sParam.pricing=GLP_PT_STD;
    else sParam.pricing=GLP_PT_PSE;
    //sParam.r_test not available
    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++)
		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]);
  }
  

  // Choose simplex method ('S') or interior point method ('T') to solve the problem
  if (lpsolver == 1)
    method = 'S';
  else
    method = 'T';
	
  int errnum;

  switch (method){
    case 'S': {
      if (isMIP){
	    method = 'I';
	    errnum = lpx_intopt (lp);
      }
      else{
		errnum = glp_simplex(lp, &sParam);
		errnum += 100; //this is to avoid ambiguity in the return codes.
	  }
    }
    break;

    case 'T': errnum = lpx_interior(lp); break;

    default:  xassert (method != method);
  }

  /*  errnum assumes the following results:
      errnum = 0 <=> No errors
      errnum = 1 <=> Iteration limit exceeded.
      errnum = 2 <=> Numerical problems with basis matrix.
  */
  if (errnum == LPX_E_OK || errnum==100){
    // Get status and object value
    if (isMIP)
    {
      *status = glp_mip_status (lp);
      *fmin = glp_mip_obj_val (lp);
    }
    else
    {
      if (lpsolver == 1)
      {
        *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)
          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) 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) 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;
    
   	glp_ulong tpeak;
    lib_mem_usage(NULL, NULL, NULL, &tpeak);
    *mem=(double)(4294967296.0 * tpeak.hi + tpeak.lo) / (1024);
       
	  glp_delete_prob (lp);
    return 0;
  }

  glp_delete_prob (lp);

  *status = errnum;

  return errnum;
}
Example #5
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;
}
Example #6
0
File: glpk.c Project: ugonj/cvxopt
static PyObject *simplex(PyObject *self, PyObject *args,
    PyObject *kwrds)
{
    matrix *c, *h, *b=NULL, *x=NULL, *z=NULL, *y=NULL;
    PyObject *G, *A=NULL, *t=NULL;
    glp_prob *lp;
    glp_smcp *options = NULL;
    pysmcp *smcpParm = NULL;
    int m, n, p, i, j, k, nnz, nnzmax, *rn=NULL, *cn=NULL;
    double *a=NULL, val;
    char *kwlist[] = {"c", "G", "h", "A", "b","options", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "OOO|OOO!", kwlist, &c,
        &G, &h, &A, &b,&smcp_t,&smcpParm)) return NULL;

    if ((Matrix_Check(G) && MAT_ID(G) != DOUBLE) ||
        (SpMatrix_Check(G) && SP_ID(G) != DOUBLE) ||
        (!Matrix_Check(G) && !SpMatrix_Check(G))){
        PyErr_SetString(PyExc_TypeError, "G must be a 'd' matrix");
        return NULL;
    }
    if ((m = Matrix_Check(G) ? MAT_NROWS(G) : SP_NROWS(G)) <= 0)
        err_p_int("m");
    if ((n = Matrix_Check(G) ? MAT_NCOLS(G) : SP_NCOLS(G)) <= 0)
        err_p_int("n");

    if (!Matrix_Check(h) || h->id != DOUBLE) err_dbl_mtrx("h");
    if (h->nrows != m || h->ncols != 1){
        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
        return NULL;
    }

    if (A){
        if ((Matrix_Check(A) && MAT_ID(A) != DOUBLE) ||
            (SpMatrix_Check(A) && SP_ID(A) != DOUBLE) ||
            (!Matrix_Check(A) && !SpMatrix_Check(A))){
                PyErr_SetString(PyExc_ValueError, "A must be a dense "
                    "'d' matrix or a general sparse matrix");
                return NULL;
	}
        if ((p = Matrix_Check(A) ? MAT_NROWS(A) : SP_NROWS(A)) < 0)
            err_p_int("p");
        if ((Matrix_Check(A) ? MAT_NCOLS(A) : SP_NCOLS(A)) != n){
            PyErr_SetString(PyExc_ValueError, "incompatible "
                "dimensions");
            return NULL;
	}
    }
    else p = 0;

    if (b && (!Matrix_Check(b) || b->id != DOUBLE)) err_dbl_mtrx("b");
    if ((b && (b->nrows != p || b->ncols != 1)) || (!b && p !=0 )){
        PyErr_SetString(PyExc_ValueError, "incompatible dimensions");
        return NULL;
    }
    if(!smcpParm) 
    {
      smcpParm = (pysmcp*)malloc(sizeof(*smcpParm));
      glp_init_smcp(&(smcpParm->obj));
    }
    if(smcpParm) 
    {
      Py_INCREF(smcpParm);
      options = &smcpParm->obj;
      options->presolve = 1;
    }

    lp = glp_create_prob();
    glp_add_rows(lp, m+p);
    glp_add_cols(lp, n);

    for (i=0; i<n; i++){
        glp_set_obj_coef(lp, i+1, MAT_BUFD(c)[i]);
        glp_set_col_bnds(lp, i+1, GLP_FR, 0.0, 0.0);
    }
    for (i=0; i<m; i++)
        glp_set_row_bnds(lp, i+1, GLP_UP, 0.0, MAT_BUFD(h)[i]);
    for (i=0; i<p; i++)
        glp_set_row_bnds(lp, i+m+1, GLP_FX, MAT_BUFD(b)[i],
            MAT_BUFD(b)[i]);

    nnzmax = (SpMatrix_Check(G) ? SP_NNZ(G) : m*n ) +
        ((A && SpMatrix_Check(A)) ? SP_NNZ(A) : p*n);
    a = (double *) calloc(nnzmax+1, sizeof(double));
    rn = (int *) calloc(nnzmax+1, sizeof(int));
    cn = (int *) calloc(nnzmax+1, sizeof(int));
    if (!a || !rn || !cn){
        free(a);  free(rn);  free(cn);  glp_delete_prob(lp);
        return PyErr_NoMemory();
    }

    nnz = 0;
    if (SpMatrix_Check(G)) {
        for (j=0; j<n; j++) for (k=SP_COL(G)[j]; k<SP_COL(G)[j+1]; k++)
            if ((val = SP_VALD(G)[k]) != 0.0){
                a[1+nnz] = val;
                rn[1+nnz] = SP_ROW(G)[k]+1;
                cn[1+nnz] = j+1;
                nnz++;
            }
    }
    else for (j=0; j<n; j++) for (i=0; i<m; i++)
        if ((val = MAT_BUFD(G)[i+j*m]) != 0.0){
            a[1+nnz] = val;
            rn[1+nnz] = i+1;
            cn[1+nnz] = j+1;
            nnz++;
        }

    if (A && SpMatrix_Check(A)){
        for (j=0; j<n; j++) for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1]; k++)
            if ((val = SP_VALD(A)[k]) != 0.0){
                a[1+nnz] = val;
                rn[1+nnz] = m+SP_ROW(A)[k]+1;
                cn[1+nnz] = j+1;
                nnz++;
            }
    }
    else for (j=0; j<n; j++) for (i=0; i<p; i++)
        if ((val = MAT_BUFD(A)[i+j*p]) != 0.0){
            a[1+nnz] = val;
            rn[1+nnz] = m+i+1;
            cn[1+nnz] = j+1;
            nnz++;
        }

    glp_load_matrix(lp, nnz, rn, cn, a);
    free(rn);  free(cn);  free(a);

    if (!(t = PyTuple_New(A ? 4 : 3))){
        glp_delete_prob(lp);
        return PyErr_NoMemory();
    }


    switch (glp_simplex(lp,options)){

        case 0:

            x = (matrix *) Matrix_New(n,1,DOUBLE);
            z = (matrix *) Matrix_New(m,1,DOUBLE);
            if (A) y = (matrix *) Matrix_New(p,1,DOUBLE);
            if (!x || !z || (A && !y)){
                Py_XDECREF(x);
                Py_XDECREF(z);
                Py_XDECREF(y);
                Py_XDECREF(t);
                Py_XDECREF(smcpParm);
                glp_delete_prob(lp);
                return PyErr_NoMemory();
            }

            set_output_string(t,"optimal");

            for (i=0; i<n; i++)
                MAT_BUFD(x)[i] = glp_get_col_prim(lp, i+1);
            PyTuple_SET_ITEM(t, 1, (PyObject *) x);

            for (i=0; i<m; i++)
                MAT_BUFD(z)[i] = -glp_get_row_dual(lp, i+1);
            PyTuple_SET_ITEM(t, 2, (PyObject *) z);

            if (A){
                for (i=0; i<p; i++)
                    MAT_BUFD(y)[i] = -glp_get_row_dual(lp, m+i+1);
                PyTuple_SET_ITEM(t, 3, (PyObject *) y);
            }

            Py_XDECREF(smcpParm);
            glp_delete_prob(lp);
            return (PyObject *) t;
        case GLP_EBADB:
            set_output_string(t,"incorrect initial basis");
            break;
        case GLP_ESING:
            set_output_string(t,"singular initial basis matrix");
            break;
        case GLP_ECOND:
            set_output_string(t,"ill-conditioned initial basis matrix");
            break;
        case GLP_EBOUND:
            set_output_string(t,"incorrect bounds");
            break;
        case GLP_EFAIL:
            set_output_string(t,"solver failure");
            break;
        case GLP_EOBJLL:
            set_output_string(t,"objective function reached lower limit");
            break;
        case GLP_EOBJUL:
            set_output_string(t,"objective function reached upper limit");
            break;
        case GLP_EITLIM:
            set_output_string(t,"iteration limit exceeded");
            break;
        case GLP_ETMLIM:
            set_output_string(t,"time limit exceeded");
            break;
        case GLP_ENOPFS:
            set_output_string(t,"primal infeasible");
            break;
        case GLP_ENODFS:
            set_output_string(t,"dual infeasible");
            break;
        default:
            set_output_string(t,"unknown");
            break;
    }

    Py_XDECREF(smcpParm);
    glp_delete_prob(lp);

    PyTuple_SET_ITEM(t, 1, Py_BuildValue(""));
    PyTuple_SET_ITEM(t, 2, Py_BuildValue(""));
    if (A) PyTuple_SET_ITEM(t, 3, Py_BuildValue(""));

    return (PyObject *) t;
}