Example #1
0
static void fill_smcp(LPX *lp, glp_smcp *parm)
{     glp_init_smcp(parm);
      switch (lpx_get_int_parm(lp, LPX_K_MSGLEV))
      {  case 0:  parm->msg_lev = GLP_MSG_OFF;   break;
         case 1:  parm->msg_lev = GLP_MSG_ERR;   break;
         case 2:  parm->msg_lev = GLP_MSG_ON;    break;
         case 3:  parm->msg_lev = GLP_MSG_ALL;   break;
         default: xassert(lp != lp);
      }
      switch (lpx_get_int_parm(lp, LPX_K_DUAL))
      {  case 0:  parm->meth = GLP_PRIMAL;       break;
         case 1:  parm->meth = GLP_DUAL;         break;
         default: xassert(lp != lp);
      }
      switch (lpx_get_int_parm(lp, LPX_K_PRICE))
      {  case 0:  parm->pricing = GLP_PT_STD;    break;
         case 1:  parm->pricing = GLP_PT_PSE;    break;
         default: xassert(lp != lp);
      }
      if (lpx_get_real_parm(lp, LPX_K_RELAX) == 0.0)
         parm->r_test = GLP_RT_STD;
      else
         parm->r_test = GLP_RT_HAR;
      parm->tol_bnd = lpx_get_real_parm(lp, LPX_K_TOLBND);
      parm->tol_dj  = lpx_get_real_parm(lp, LPX_K_TOLDJ);
      parm->tol_piv = lpx_get_real_parm(lp, LPX_K_TOLPIV);
      parm->obj_ll  = lpx_get_real_parm(lp, LPX_K_OBJLL);
      parm->obj_ul  = lpx_get_real_parm(lp, LPX_K_OBJUL);
      if (lpx_get_int_parm(lp, LPX_K_ITLIM) < 0)
         parm->it_lim = INT_MAX;
      else
         parm->it_lim = lpx_get_int_parm(lp, LPX_K_ITLIM);
      if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0)
         parm->tm_lim = INT_MAX;
      else
         parm->tm_lim =
            (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM));
      parm->out_frq = lpx_get_int_parm(lp, LPX_K_OUTFRQ);
      parm->out_dly =
            (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_OUTDLY));
      switch (lpx_get_int_parm(lp, LPX_K_PRESOL))
      {  case 0:  parm->presolve = GLP_OFF;      break;
         case 1:  parm->presolve = GLP_ON;       break;
         default: xassert(lp != lp);
      }
      return;
}
Example #2
0
static PyObject* Params_parameter_get(ParamsObject *self,
                                      struct param_getsets *pgs) {
    switch (pgs->type) {
    case 0: // Boolean.
        return PyBool_FromLong(lpx_get_int_parm(LP, pgs->code));
    case 1: // Integer.
        return PyInt_FromLong(lpx_get_int_parm(LP, pgs->code));
    case 2: // Float.
        return PyFloat_FromDouble(lpx_get_real_parm(LP, pgs->code));
    default: // Um, apparently I made a mistake in the PGS definition array.
        PyErr_Format(PyExc_RuntimeError, "parameter type code %d unrecognized",
                     pgs->type);
        return NULL;
    }
}
Example #3
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;
}
Example #4
0
static int solve_mip(LPX *lp, int presolve)
{     glp_iocp parm;
      int ret;
      glp_init_iocp(&parm);
      switch (lpx_get_int_parm(lp, LPX_K_MSGLEV))
      {  case 0:  parm.msg_lev = GLP_MSG_OFF;   break;
         case 1:  parm.msg_lev = GLP_MSG_ERR;   break;
         case 2:  parm.msg_lev = GLP_MSG_ON;    break;
         case 3:  parm.msg_lev = GLP_MSG_ALL;   break;
         default: xassert(lp != lp);
      }
      switch (lpx_get_int_parm(lp, LPX_K_BRANCH))
      {  case 0:  parm.br_tech = GLP_BR_FFV;    break;
         case 1:  parm.br_tech = GLP_BR_LFV;    break;
         case 2:  parm.br_tech = GLP_BR_DTH;    break;
         case 3:  parm.br_tech = GLP_BR_MFV;    break;
         default: xassert(lp != lp);
      }
      switch (lpx_get_int_parm(lp, LPX_K_BTRACK))
      {  case 0:  parm.bt_tech = GLP_BT_DFS;    break;
         case 1:  parm.bt_tech = GLP_BT_BFS;    break;
         case 2:  parm.bt_tech = GLP_BT_BPH;    break;
         case 3:  parm.bt_tech = GLP_BT_BLB;    break;
         default: xassert(lp != lp);
      }
      parm.tol_int = lpx_get_real_parm(lp, LPX_K_TOLINT);
      parm.tol_obj = lpx_get_real_parm(lp, LPX_K_TOLOBJ);
      if (lpx_get_real_parm(lp, LPX_K_TMLIM) < 0.0 ||
          lpx_get_real_parm(lp, LPX_K_TMLIM) > 1e6)
         parm.tm_lim = INT_MAX;
      else
         parm.tm_lim =
            (int)(1000.0 * lpx_get_real_parm(lp, LPX_K_TMLIM));
      parm.mip_gap = lpx_get_real_parm(lp, LPX_K_MIPGAP);
      if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_GOMORY)
         parm.gmi_cuts = GLP_ON;
      else
         parm.gmi_cuts = GLP_OFF;
      if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_MIR)
         parm.mir_cuts = GLP_ON;
      else
         parm.mir_cuts = GLP_OFF;
      if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_COVER)
         parm.cov_cuts = GLP_ON;
      else
         parm.cov_cuts = GLP_OFF;
      if (lpx_get_int_parm(lp, LPX_K_USECUTS) & LPX_C_CLIQUE)
         parm.clq_cuts = GLP_ON;
      else
         parm.clq_cuts = GLP_OFF;
      parm.presolve = presolve;
      if (lpx_get_int_parm(lp, LPX_K_BINARIZE))
         parm.binarize = GLP_ON;
      ret = glp_intopt(lp, &parm);
      switch (ret)
      {  case 0:           ret = LPX_E_OK;      break;
         case GLP_ENOPFS:  ret = LPX_E_NOPFS;   break;
         case GLP_ENODFS:  ret = LPX_E_NODFS;   break;
         case GLP_EBOUND:
         case GLP_EROOT:   ret = LPX_E_FAULT;   break;
         case GLP_EFAIL:   ret = LPX_E_SING;    break;
         case GLP_EMIPGAP: ret = LPX_E_MIPGAP;  break;
         case GLP_ETMLIM:  ret = LPX_E_TMLIM;   break;
         default:          xassert(ret != ret);
      }
      return ret;
}
Example #5
0
int lpx_integer(LPX *mip)
{     int m = lpx_get_num_rows(mip);
      int n = lpx_get_num_cols(mip);
      MIPTREE *tree;
      LPX *lp;
      int ret, i, j, stat, type, len, *ind;
      double lb, ub, coef, *val;
#if 0
      /* the problem must be of MIP class */
      if (lpx_get_class(mip) != LPX_MIP)
      {  print("lpx_integer: problem is not of MIP class");
         ret = LPX_E_FAULT;
         goto done;
      }
#endif
      /* an optimal solution of LP relaxation must be known */
      if (lpx_get_status(mip) != LPX_OPT)
      {  print("lpx_integer: optimal solution of LP relaxation required"
            );
         ret = LPX_E_FAULT;
         goto done;
      }
      /* bounds of all integer variables must be integral */
      for (j = 1; j <= n; j++)
      {  if (lpx_get_col_kind(mip, j) != LPX_IV) continue;
         type = lpx_get_col_type(mip, j);
         if (type == LPX_LO || type == LPX_DB || type == LPX_FX)
         {  lb = lpx_get_col_lb(mip, j);
            if (lb != floor(lb))
            {  print("lpx_integer: integer column %d has non-integer lo"
                  "wer bound or fixed value %g", j, lb);
               ret = LPX_E_FAULT;
               goto done;
            }
         }
         if (type == LPX_UP || type == LPX_DB)
         {  ub = lpx_get_col_ub(mip, j);
            if (ub != floor(ub))
            {  print("lpx_integer: integer column %d has non-integer up"
                  "per bound %g", j, ub);
               ret = LPX_E_FAULT;
               goto done;
            }
         }
      }
      /* it seems all is ok */
      if (lpx_get_int_parm(mip, LPX_K_MSGLEV) >= 2)
         print("Integer optimization begins...");
      /* create the branch-and-bound tree */
      tree = mip_create_tree(m, n, lpx_get_obj_dir(mip));
      /* set up column kinds */
      for (j = 1; j <= n; j++)
         tree->int_col[j] = (lpx_get_col_kind(mip, j) == LPX_IV);
      /* access the LP relaxation template */
      lp = tree->lp;
      /* set up the objective function */
      tree->int_obj = 1;
      for (j = 0; j <= tree->n; j++)
      {  coef = lpx_get_obj_coef(mip, j);
         lpx_set_obj_coef(lp, j, coef);
         if (coef != 0.0 && !(tree->int_col[j] && coef == floor(coef)))
            tree->int_obj = 0;
      }
      if (lpx_get_int_parm(mip, LPX_K_MSGLEV) >= 2 && tree->int_obj)
         print("Objective function is integral");
      /* set up the constraint matrix */
      ind = xcalloc(1+n, sizeof(int));
      val = xcalloc(1+n, sizeof(double));
      for (i = 1; i <= m; i++)
      {  len = lpx_get_mat_row(mip, i, ind, val);
         lpx_set_mat_row(lp, i, len, ind, val);
      }
      xfree(ind);
      xfree(val);
      /* set up scaling matrices */
      for (i = 1; i <= m; i++)
         lpx_set_rii(lp, i, lpx_get_rii(mip, i));
      for (j = 1; j <= n; j++)
         lpx_set_sjj(lp, j, lpx_get_sjj(mip, j));
      /* revive the root subproblem */
      mip_revive_node(tree, 1);
      /* set up row attributes for the root subproblem */
      for (i = 1; i <= m; i++)
      {  type = lpx_get_row_type(mip, i);
         lb = lpx_get_row_lb(mip, i);
         ub = lpx_get_row_ub(mip, i);
         stat = lpx_get_row_stat(mip, i);
         lpx_set_row_bnds(lp, i, type, lb, ub);
         lpx_set_row_stat(lp, i, stat);
      }
      /* set up column attributes for the root subproblem */
      for (j = 1; j <= n; j++)
      {  type = lpx_get_col_type(mip, j);
         lb = lpx_get_col_lb(mip, j);
         ub = lpx_get_col_ub(mip, j);
         stat = lpx_get_col_stat(mip, j);
         lpx_set_col_bnds(lp, j, type, lb, ub);
         lpx_set_col_stat(lp, j, stat);
      }
      /* freeze the root subproblem */
      mip_freeze_node(tree);
      /* inherit some control parameters and statistics */
      tree->msg_lev = lpx_get_int_parm(mip, LPX_K_MSGLEV);
      if (tree->msg_lev > 2) tree->msg_lev = 2;
      tree->branch = lpx_get_int_parm(mip, LPX_K_BRANCH);
      tree->btrack = lpx_get_int_parm(mip, LPX_K_BTRACK);
      tree->tol_int = lpx_get_real_parm(mip, LPX_K_TOLINT);
      tree->tol_obj = lpx_get_real_parm(mip, LPX_K_TOLOBJ);
      tree->tm_lim = lpx_get_real_parm(mip, LPX_K_TMLIM);
      lpx_set_int_parm(lp, LPX_K_BFTYPE, lpx_get_int_parm(mip,
         LPX_K_BFTYPE));
      lpx_set_int_parm(lp, LPX_K_PRICE, lpx_get_int_parm(mip,
         LPX_K_PRICE));
      lpx_set_real_parm(lp, LPX_K_RELAX, lpx_get_real_parm(mip,
         LPX_K_RELAX));
      lpx_set_real_parm(lp, LPX_K_TOLBND, lpx_get_real_parm(mip,
         LPX_K_TOLBND));
      lpx_set_real_parm(lp, LPX_K_TOLDJ, lpx_get_real_parm(mip,
         LPX_K_TOLDJ));
      lpx_set_real_parm(lp, LPX_K_TOLPIV, lpx_get_real_parm(mip,
         LPX_K_TOLPIV));
      lpx_set_int_parm(lp, LPX_K_ITLIM, lpx_get_int_parm(mip,
         LPX_K_ITLIM));
      lpx_set_int_parm(lp, LPX_K_ITCNT, lpx_get_int_parm(mip,
         LPX_K_ITCNT));
      /* reset the status of MIP solution */
      lpx_put_mip_soln(mip, LPX_I_UNDEF, NULL, NULL);
      /* try solving the problem */
      ret = mip_driver(tree);
      /* if an integer feasible solution has been found, copy it to the
         MIP problem object */
      if (tree->found)
         lpx_put_mip_soln(mip, LPX_I_FEAS, &tree->mipx[0],
            &tree->mipx[m]);
      /* copy back statistics about spent resources */
      lpx_set_real_parm(mip, LPX_K_TMLIM, tree->tm_lim);
      lpx_set_int_parm(mip, LPX_K_ITLIM, lpx_get_int_parm(lp,
         LPX_K_ITLIM));
      lpx_set_int_parm(mip, LPX_K_ITCNT, lpx_get_int_parm(lp,
         LPX_K_ITCNT));
      /* analyze exit code reported by the mip driver */
      switch (ret)
      {  case MIP_E_OK:
            if (tree->found)
            {  if (lpx_get_int_parm(mip, LPX_K_MSGLEV) >= 3)
                  print("INTEGER OPTIMAL SOLUTION FOUND");
               lpx_put_mip_soln(mip, LPX_I_OPT, NULL, NULL);
            }
            else
            {  if (lpx_get_int_parm(mip, LPX_K_MSGLEV) >= 3)
                  print("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION");
               lpx_put_mip_soln(mip, LPX_I_NOFEAS, NULL, NULL);
            }
            ret = LPX_E_OK;
            break;
         case MIP_E_ITLIM:
            if (lpx_get_int_parm(mip, LPX_K_MSGLEV) >= 3)
               print("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED");
            ret = LPX_E_ITLIM;
            break;
         case MIP_E_TMLIM:
            if (lpx_get_int_parm(mip, LPX_K_MSGLEV) >= 3)
               print("TIME LIMIT EXCEEDED; SEARCH TERMINATED");
            ret = LPX_E_TMLIM;
            break;
         case MIP_E_ERROR:
            if (lpx_get_int_parm(mip, LPX_K_MSGLEV) >= 1)
               print("lpx_integer: cannot solve current LP relaxation");
            ret = LPX_E_SING;
            break;
         default:
            xassert(ret != ret);
      }
      /* delete the branch-and-bound tree */
      mip_delete_tree(tree);
done: /* return to the application program */
      return ret;
}
Example #6
0
int lpx_warm_up(LPX *lp)
{     int m, n, j, k, ret, type, stat, p_stat, d_stat;
      double lb, ub, prim, dual, tol_bnd, tol_dj, dir;
      double *row_prim, *row_dual, *col_prim, *col_dual, sum;
      m = lpx_get_num_rows(lp);
      n = lpx_get_num_cols(lp);
      /* reinvert the basis matrix, if necessary */
      if (lpx_is_b_avail(lp))
         ret = LPX_E_OK;
      else
      {  if (m == 0 || n == 0)
         {  ret = LPX_E_EMPTY;
            goto done;
         }
#if 0
         ret = lpx_invert(lp);
         switch (ret)
         {  case 0:
               ret = LPX_E_OK;
               break;
            case 1:
            case 2:
               ret = LPX_E_SING;
               goto done;
            case 3:
               ret = LPX_E_BADB;
               goto done;
            default:
               xassert(ret != ret);
         }
#else
         switch (glp_factorize(lp))
         {  case 0:
               ret = LPX_E_OK;
               break;
            case GLP_EBADB:
               ret = LPX_E_BADB;
               goto done;
            case GLP_ESING:
            case GLP_ECOND:
               ret = LPX_E_SING;
               goto done;
            default:
               xassert(lp != lp);
         }
#endif
      }
      /* allocate working arrays */
      row_prim = xcalloc(1+m, sizeof(double));
      row_dual = xcalloc(1+m, sizeof(double));
      col_prim = xcalloc(1+n, sizeof(double));
      col_dual = xcalloc(1+n, sizeof(double));
      /* compute primal basic solution components */
      lpx_eval_b_prim(lp, row_prim, col_prim);
      /* determine primal status of basic solution */
      tol_bnd = 3.0 * lpx_get_real_parm(lp, LPX_K_TOLBND);
      p_stat = LPX_P_FEAS;
      for (k = 1; k <= m+n; k++)
      {  if (k <= m)
         {  type = lpx_get_row_type(lp, k);
            lb = lpx_get_row_lb(lp, k);
            ub = lpx_get_row_ub(lp, k);
            prim = row_prim[k];
         }
         else
         {  type = lpx_get_col_type(lp, k-m);
            lb = lpx_get_col_lb(lp, k-m);
            ub = lpx_get_col_ub(lp, k-m);
            prim = col_prim[k-m];
         }
         if (type == LPX_LO || type == LPX_DB || type == LPX_FX)
         {  /* variable x[k] has lower bound */
            if (prim < lb - tol_bnd * (1.0 + fabs(lb)))
            {  p_stat = LPX_P_INFEAS;
               break;
            }
         }
         if (type == LPX_UP || type == LPX_DB || type == LPX_FX)
         {  /* variable x[k] has upper bound */
            if (prim > ub + tol_bnd * (1.0 + fabs(ub)))
            {  p_stat = LPX_P_INFEAS;
               break;
            }
         }
      }
      /* compute dual basic solution components */
      lpx_eval_b_dual(lp, row_dual, col_dual);
      /* determine dual status of basic solution */
      tol_dj = 3.0 * lpx_get_real_parm(lp, LPX_K_TOLDJ);
      dir = (lpx_get_obj_dir(lp) == LPX_MIN ? +1.0 : -1.0);
      d_stat = LPX_D_FEAS;
      for (k = 1; k <= m+n; k++)
      {  if (k <= m)
         {  stat = lpx_get_row_stat(lp, k);
            dual = row_dual[k];
         }
         else
         {  stat = lpx_get_col_stat(lp, k-m);
            dual = col_dual[k-m];
         }
         if (stat == LPX_BS || stat == LPX_NL || stat == LPX_NF)
         {  /* reduced cost of x[k] must be non-negative (minimization)
               or non-positive (maximization) */
            if (dir * dual < - tol_dj)
            {  d_stat = LPX_D_INFEAS;
               break;
            }
         }
         if (stat == LPX_BS || stat == LPX_NU || stat == LPX_NF)
         {  /* reduced cost of x[k] must be non-positive (minimization)
               or non-negative (maximization) */
            if (dir * dual > + tol_dj)
            {  d_stat = LPX_D_INFEAS;
               break;
            }
         }
      }
      /* store basic solution components */
      p_stat = p_stat - LPX_P_UNDEF + GLP_UNDEF;
      d_stat = d_stat - LPX_D_UNDEF + GLP_UNDEF;
      sum = lpx_get_obj_coef(lp, 0);
      for (j = 1; j <= n; j++)
         sum += lpx_get_obj_coef(lp, j) * col_prim[j];
      glp_put_solution(lp, 0, &p_stat, &d_stat, &sum,
         NULL, row_prim, row_dual, NULL, col_prim, col_dual);
      xassert(lpx_is_b_avail(lp));
      /* free working arrays */
      xfree(row_prim);
      xfree(row_dual);
      xfree(col_prim);
      xfree(col_dual);
done: /* return to the calling program */
      return ret;
}
Example #7
0
int lpx_intopt(LPX *_mip)
{     IPP *ipp = NULL;
      LPX *orig = _mip, *prob = NULL;
      int orig_m, orig_n, i, j, ret, i_stat;
      /* the problem must be of MIP class */
      if (lpx_get_class(orig) != LPX_MIP)
      {  print("lpx_intopt: problem is not of MIP class");
         ret = LPX_E_FAULT;
         goto done;
      }
      /* the problem must have at least one row and one column */
      orig_m = lpx_get_num_rows(orig);
      orig_n = lpx_get_num_cols(orig);
      if (!(orig_m > 0 && orig_n > 0))
      {  print("lpx_intopt: problem has no rows/columns");
         ret = LPX_E_FAULT;
         goto done;
      }
      /* check that each double-bounded row and column has bounds */
      for (i = 1; i <= orig_m; i++)
      {  if (lpx_get_row_type(orig, i) == LPX_DB)
         {  if (lpx_get_row_lb(orig, i) >= lpx_get_row_ub(orig, i))
            {  print("lpx_intopt: row %d has incorrect bounds", i);
               ret = LPX_E_FAULT;
               goto done;
            }
         }
      }
      for (j = 1; j <= orig_n; j++)
      {  if (lpx_get_col_type(orig, j) == LPX_DB)
         {  if (lpx_get_col_lb(orig, j) >= lpx_get_col_ub(orig, j))
            {  print("lpx_intopt: column %d has incorrect bounds", j);
               ret = LPX_E_FAULT;
               goto done;
            }
         }
      }
      /* bounds of all integer variables must be integral */
      for (j = 1; j <= orig_n; j++)
      {  int type;
         double lb, ub;
         if (lpx_get_col_kind(orig, j) != LPX_IV) continue;
         type = lpx_get_col_type(orig, j);
         if (type == LPX_LO || type == LPX_DB || type == LPX_FX)
         {  lb = lpx_get_col_lb(orig, j);
            if (lb != floor(lb))
            {  print("lpx_intopt: integer column %d has non-integer low"
                  "er bound or fixed value %g", j, lb);
               ret = LPX_E_FAULT;
               goto done;
            }
         }
         if (type == LPX_UP || type == LPX_DB)
         {  ub = lpx_get_col_ub(orig, j);
            if (ub != floor(ub))
            {  print("lpx_intopt: integer column %d has non-integer upp"
                  "er bound %g", j, ub);
               ret = LPX_E_FAULT;
               goto done;
            }
         }
      }
      /* reset the status of MIP solution */
      lpx_put_mip_soln(orig, LPX_I_UNDEF, NULL, NULL);
      /* create MIP presolver workspace */
      ipp = ipp_create_wksp();
      /* load the original problem into the presolver workspace */
      ipp_load_orig(ipp, orig);
      /* perform basic MIP presolve analysis */
      switch (ipp_basic_tech(ipp))
      {  case 0:
            /* no infeasibility is detected */
            break;
         case 1:
nopfs:      /* primal infeasibility is detected */
            print("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION");
            ret = LPX_E_NOPFS;
            goto done;
         case 2:
            /* dual infeasibility is detected */
nodfs:      print("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION");
            ret = LPX_E_NODFS;
            goto done;
         default:
            insist(ipp != ipp);
      }
      /* reduce column bounds */
      switch (ipp_reduce_bnds(ipp))
      {  case 0:  break;
         case 1:  goto nopfs;
         default: insist(ipp != ipp);
      }
      /* perform basic MIP presolve analysis */
      switch (ipp_basic_tech(ipp))
      {  case 0:  break;
         case 1:  goto nopfs;
         case 2:  goto nodfs;
         default: insist(ipp != ipp);
      }
      /* replace general integer variables by sum of binary variables,
         if required */
      if (lpx_get_int_parm(orig, LPX_K_BINARIZE))
         ipp_binarize(ipp);
      /* perform coefficient reduction */
      ipp_reduction(ipp);
      /* if the resultant problem is empty, it has an empty solution,
         which is optimal */
      if (ipp->row_ptr == NULL || ipp->col_ptr == NULL)
      {  insist(ipp->row_ptr == NULL);
         insist(ipp->col_ptr == NULL);
         print("Objective value = %.10g",
            ipp->orig_dir == LPX_MIN ? +ipp->c0 : -ipp->c0);
         print("INTEGER OPTIMAL SOLUTION FOUND BY MIP PRESOLVER");
         /* allocate recovered solution segment */
         ipp->col_stat = ucalloc(1+ipp->ncols, sizeof(int));
         ipp->col_mipx = ucalloc(1+ipp->ncols, sizeof(double));
         for (j = 1; j <= ipp->ncols; j++) ipp->col_stat[j] = 0;
         /* perform MIP postsolve processing */
         ipp_postsolve(ipp);
         /* unload recovered MIP solution and store it in the original
            problem object */
         ipp_unload_sol(ipp, orig, LPX_I_OPT);
         ret = LPX_E_OK;
         goto done;
      }
      /* build resultant MIP problem object */
      prob = ipp_build_prob(ipp);
      /* display some statistics */
      {  int m = lpx_get_num_rows(prob);
         int n = lpx_get_num_cols(prob);
         int nnz = lpx_get_num_nz(prob);
         int ni = lpx_get_num_int(prob);
         int nb = lpx_get_num_bin(prob);
         char s[50];
         print("lpx_intopt: presolved MIP has %d row%s, %d column%s, %d"
            " non-zero%s", m, m == 1 ? "" : "s", n, n == 1 ? "" : "s",
            nnz, nnz == 1 ? "" : "s");
         if (nb == 0)
            strcpy(s, "none of");
         else if (ni == 1 && nb == 1)
            strcpy(s, "");
         else if (nb == 1)
            strcpy(s, "one of");
         else if (nb == ni)
            strcpy(s, "all of");
         else
            sprintf(s, "%d of", nb);
         print("lpx_intopt: %d integer column%s, %s which %s binary",
            ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are");
      }
      /* inherit some control parameters and statistics */
      lpx_set_int_parm(prob, LPX_K_PRICE, lpx_get_int_parm(orig,
         LPX_K_PRICE));
      lpx_set_real_parm(prob, LPX_K_RELAX, lpx_get_real_parm(orig,
         LPX_K_RELAX));
      lpx_set_real_parm(prob, LPX_K_TOLBND, lpx_get_real_parm(orig,
         LPX_K_TOLBND));
      lpx_set_real_parm(prob, LPX_K_TOLDJ, lpx_get_real_parm(orig,
         LPX_K_TOLDJ));
      lpx_set_real_parm(prob, LPX_K_TOLPIV, lpx_get_real_parm(orig,
         LPX_K_TOLPIV));
      lpx_set_int_parm(prob, LPX_K_ITLIM, lpx_get_int_parm(orig,
         LPX_K_ITLIM));
      lpx_set_int_parm(prob, LPX_K_ITCNT, lpx_get_int_parm(orig,
         LPX_K_ITCNT));
      lpx_set_real_parm(prob, LPX_K_TMLIM, lpx_get_real_parm(orig,
         LPX_K_TMLIM));
      lpx_set_int_parm(prob, LPX_K_BRANCH, lpx_get_int_parm(orig,
         LPX_K_BRANCH));
      lpx_set_int_parm(prob, LPX_K_BTRACK, lpx_get_int_parm(orig,
         LPX_K_BTRACK));
      lpx_set_real_parm(prob, LPX_K_TOLINT, lpx_get_real_parm(orig,
         LPX_K_TOLINT));
      lpx_set_real_parm(prob, LPX_K_TOLOBJ, lpx_get_real_parm(orig,
         LPX_K_TOLOBJ));
      /* build an advanced initial basis */
      lpx_adv_basis(prob);
      /* solve LP relaxation */
      print("Solving LP relaxation...");
      switch (lpx_simplex(prob))
      {  case LPX_E_OK:
            break;
         case LPX_E_ITLIM:
            ret = LPX_E_ITLIM;
            goto done;
         case LPX_E_TMLIM:
            ret = LPX_E_TMLIM;
            goto done;
         default:
            print("lpx_intopt: cannot solve LP relaxation");
            ret = LPX_E_SING;
            goto done;
      }
      /* analyze status of the basic solution */
      switch (lpx_get_status(prob))
      {  case LPX_OPT:
            break;
         case LPX_NOFEAS:
            ret = LPX_E_NOPFS;
            goto done;
         case LPX_UNBND:
            ret = LPX_E_NODFS;
            goto done;
         default:
            insist(prob != prob);
      }
      /* generate cutting planes, if necessary */
      if (lpx_get_int_parm(orig, LPX_K_USECUTS))
      {  ret =  generate_cuts(prob);
         if (ret != LPX_E_OK) goto done;
      }
      /* call the branch-and-bound solver */
      ret = lpx_integer(prob);
      /* determine status of MIP solution */
      i_stat = lpx_mip_status(prob);
      if (i_stat == LPX_I_OPT || i_stat == LPX_I_FEAS)
      {  /* load MIP solution of the resultant problem into presolver
            workspace */
         ipp_load_sol(ipp, prob);
         /* perform MIP postsolve processing */
         ipp_postsolve(ipp);
         /* unload recovered MIP solution and store it in the original
            problem object */
         ipp_unload_sol(ipp, orig, i_stat);
      }
      else
      {  /* just set the status of MIP solution */
         lpx_put_mip_soln(orig, i_stat, NULL, NULL);
      }
done: /* copy back statistics about spent resources */
      if (prob != NULL)
      {  lpx_set_int_parm(orig, LPX_K_ITLIM, lpx_get_int_parm(prob,
            LPX_K_ITLIM));
         lpx_set_int_parm(orig, LPX_K_ITCNT, lpx_get_int_parm(prob,
            LPX_K_ITCNT));
         lpx_set_real_parm(orig, LPX_K_TMLIM, lpx_get_real_parm(prob,
            LPX_K_TMLIM));
      }
      /* delete the resultant problem object */
      if (prob != NULL) lpx_delete_prob(prob);
      /* delete MIP presolver workspace */
      if (ipp != NULL) ipp_delete_wksp(ipp);
      return ret;
}
Example #8
0
static int generate_cuts(LPX *prob)
{     int prob_m, prob_n, prob_nz, msg_lev, dual, nrows, it_cnt, ret;
      double out_dly, tm_lim, tm_lag = 0.0, tm_beg = utime();
      print("Generating cutting planes...");
      /* determine the number of rows, columns, and non-zeros on entry
         to the routine */
      prob_m = lpx_get_num_rows(prob);
      prob_n = lpx_get_num_cols(prob);
      prob_nz = lpx_get_num_nz(prob);
      /* save some control parameters */
      msg_lev = lpx_get_int_parm(prob, LPX_K_MSGLEV);
      dual = lpx_get_int_parm(prob, LPX_K_DUAL);
      out_dly = lpx_get_real_parm(prob, LPX_K_OUTDLY);
      tm_lim = lpx_get_real_parm(prob, LPX_K_TMLIM);
      /* and set their new values needed for re-optimization */
      lpx_set_int_parm(prob, LPX_K_MSGLEV, 1);
      lpx_set_int_parm(prob, LPX_K_DUAL, 1);
      lpx_set_real_parm(prob, LPX_K_OUTDLY, 10.0);
      lpx_set_real_parm(prob, LPX_K_TMLIM, -1.0);
loop: /* main loop starts here */
      /* display current status of the problem */
      if (utime() - tm_lag >= 5.0 - 0.001)
         show_status(prob, prob_m, prob_nz), tm_lag = utime();
      /* check if the patience has been exhausted */
      if (tm_lim >= 0.0 && tm_lim <= utime() - tm_beg)
      {  ret = LPX_E_TMLIM;
         goto done;
      }
      /* not more than 500 cut inequalities are allowed */
      if (lpx_get_num_rows(prob) - prob_m >= 500)
      {  ret = LPX_E_OK;
         goto done;
      }
      /* not more than 50,000 cut coefficients are allowed */
      if (lpx_get_num_nz(prob) - prob_nz >= 50000)
      {  ret = LPX_E_OK;
         goto done;
      }
      /* try to generate Gomory's mixed integer cut */
      nrows = lpx_get_num_rows(prob);
      gen_gomory_cut(prob, prob_n);
      if (nrows == lpx_get_num_rows(prob))
      {  /* nothing has been generated */
         ret = LPX_E_OK;
         goto done;
      }
      /* re-optimize current LP relaxation using dual simplex */
      it_cnt = lpx_get_int_parm(prob, LPX_K_ITCNT);
      switch (lpx_simplex(prob))
      {  case LPX_E_OK:
            break;
         case LPX_E_ITLIM:
            ret = LPX_E_ITLIM;
            goto done;
         default:
            ret = LPX_E_SING;
            goto done;
      }
      if (it_cnt == lpx_get_int_parm(prob, LPX_K_ITCNT))
      {  ret = LPX_E_OK;
         goto done;
      }
      /* analyze status of the basic solution */
      switch (lpx_get_status(prob))
      {  case LPX_OPT:
            break;
         case LPX_NOFEAS:
            ret = LPX_E_NOPFS;
            goto done;
         default:
            insist(prob != prob);
      }
      /* continue generating cutting planes */
      goto loop;
done: /* display final status of the problem */
      show_status(prob, prob_m, prob_nz);
      switch (ret)
      {  case LPX_E_OK:
            break;
         case LPX_E_NOPFS:
            print("PROBLEM HAS NO INTEGER FEASIBLE SOLUTION");
            break;
         case LPX_E_ITLIM:
            print("ITERATIONS LIMIT EXCEEDED; SEARCH TERMINATED");
            break;
         case LPX_E_TMLIM:
            print("TIME LIMIT EXCEEDED; SEARCH TERMINATED");
            break;
         case LPX_E_SING:
            print("lpx_intopt: cannot re-optimize LP relaxation");
            break;
         default:
            insist(ret != ret);
      }
      /* decrease the time limit by spent amount of the time */
      if (tm_lim >= 0.0)
      {  tm_lim -= (utime() - tm_beg);
         if (tm_lim < 0.0) tm_lim = 0.0;
      }
      /* restore some control parameters and update statistics */
      lpx_set_int_parm(prob, LPX_K_MSGLEV, msg_lev);
      lpx_set_int_parm(prob, LPX_K_DUAL, dual);
      lpx_set_real_parm(prob, LPX_K_OUTDLY, out_dly);
      lpx_set_real_parm(prob, LPX_K_TMLIM, tm_lim);
      return ret;
}