Beispiel #1
0
int ipm_solve(glp_prob *P, const glp_iptcp *parm)
{     struct csa _dsa, *csa = &_dsa;
      int m = P->m;
      int n = P->n;
      int nnz = P->nnz;
      GLPROW *row;
      GLPCOL *col;
      GLPAIJ *aij;
      int i, j, loc, ret, *A_ind, *A_ptr;
      double dir, *A_val, *b, *c, *x, *y, *z;
      xassert(m > 0);
      xassert(n > 0);
      /* allocate working arrays */
      A_ptr = xcalloc(1+m+1, sizeof(int));
      A_ind = xcalloc(1+nnz, sizeof(int));
      A_val = xcalloc(1+nnz, sizeof(double));
      b = xcalloc(1+m, sizeof(double));
      c = xcalloc(1+n, sizeof(double));
      x = xcalloc(1+n, sizeof(double));
      y = xcalloc(1+m, sizeof(double));
      z = xcalloc(1+n, sizeof(double));
      /* prepare rows and constraint coefficients */
      loc = 1;
      for (i = 1; i <= m; i++)
      {  row = P->row[i];
         xassert(row->type == GLP_FX);
         b[i] = row->lb * row->rii;
         A_ptr[i] = loc;
         for (aij = row->ptr; aij != NULL; aij = aij->r_next)
         {  A_ind[loc] = aij->col->j;
            A_val[loc] = row->rii * aij->val * aij->col->sjj;
            loc++;
         }
      }
      A_ptr[m+1] = loc;
      xassert(loc-1 == nnz);
      /* prepare columns and objective coefficients */
      if (P->dir == GLP_MIN)
         dir = +1.0;
      else if (P->dir == GLP_MAX)
         dir = -1.0;
      else
         xassert(P != P);
      c[0] = dir * P->c0;
      for (j = 1; j <= n; j++)
      {  col = P->col[j];
         xassert(col->type == GLP_LO && col->lb == 0.0);
         c[j] = dir * col->coef * col->sjj;
      }
      /* allocate and initialize the common storage area */
      csa->m = m;
      csa->n = n;
      csa->A_ptr = A_ptr;
      csa->A_ind = A_ind;
      csa->A_val = A_val;
      csa->b = b;
      csa->c = c;
      csa->x = x;
      csa->y = y;
      csa->z = z;
      csa->parm = parm;
      initialize(csa);
      /* solve LP with the interior-point method */
      ret = ipm_main(csa);
      /* deallocate the common storage area */
      terminate(csa);
      /* determine solution status */
      if (ret == 0)
      {  /* optimal solution found */
         P->ipt_stat = GLP_OPT;
         ret = 0;
      }
      else if (ret == 1)
      {  /* problem has no feasible (primal or dual) solution */
         P->ipt_stat = GLP_NOFEAS;
         ret = 0;
      }
      else if (ret == 2)
      {  /* no convergence */
         P->ipt_stat = GLP_INFEAS;
         ret = GLP_ENOCVG;
      }
      else if (ret == 3)
      {  /* iteration limit exceeded */
         P->ipt_stat = GLP_INFEAS;
         ret = GLP_EITLIM;
      }
      else if (ret == 4)
      {  /* numeric instability on solving Newtonian system */
         P->ipt_stat = GLP_INFEAS;
         ret = GLP_EINSTAB;
      }
      else
         xassert(ret != ret);
      /* store row solution components */
      for (i = 1; i <= m; i++)
      {  row = P->row[i];
         row->pval = row->lb;
         row->dval = dir * y[i] * row->rii;
      }
      /* store column solution components */
      P->ipt_obj = P->c0;
      for (j = 1; j <= n; j++)
      {  col = P->col[j];
         col->pval = x[j] * col->sjj;
         col->dval = dir * z[j] / col->sjj;
         P->ipt_obj += col->coef * col->pval;
      }
      /* free working arrays */
      xfree(A_ptr);
      xfree(A_ind);
      xfree(A_val);
      xfree(b);
      xfree(c);
      xfree(x);
      xfree(y);
      xfree(z);
      return ret;
}
Beispiel #2
0
int lpx_interior(LPX *_lp)
{   /* easy-to-use driver to the interior-point method */
    struct dsa _dsa, *dsa = &_dsa;
    int ret, status;
    double *row_pval, *row_dval, *col_pval, *col_dval;
    /* initialize working area */
    dsa->lp = _lp;
    dsa->orig_m = lpx_get_num_rows(dsa->lp);
    dsa->orig_n = lpx_get_num_cols(dsa->lp);
    dsa->ref = NULL;
    dsa->m = 0;
    dsa->n = 0;
    dsa->size = 0;
    dsa->ne = 0;
    dsa->ia = NULL;
    dsa->ja = NULL;
    dsa->ar = NULL;
    dsa->b = NULL;
    dsa->c = NULL;
    dsa->x = NULL;
    dsa->y = NULL;
    dsa->z = NULL;
    /* check if the problem is empty */
    if (!(dsa->orig_m > 0 && dsa->orig_n > 0))
    {   print("lpx_interior: problem has no rows and/or columns");
        ret = LPX_E_FAULT;
        goto done;
    }
    /* issue warning about dense columns */
    if (dsa->orig_m >= 200)
    {   int j, len, ndc = 0;
        for (j = 1; j <= dsa->orig_n; j++)
        {   len = lpx_get_mat_col(dsa->lp, j, NULL, NULL);
            if ((double)len > 0.30 * (double)dsa->orig_m) ndc++;
        }
        if (ndc == 1)
            print("lpx_interior: WARNING: PROBLEM HAS ONE DENSE COLUMN")
            ;
        else if (ndc > 0)
            print("lpx_interior: WARNING: PROBLEM HAS %d DENSE COLUMNS",
                  ndc);
    }
    /* determine dimension of transformed LP */
    print("lpx_interior: original LP problem has %d rows and %d colum"
          "ns", dsa->orig_m, dsa->orig_n);
    calc_mn(dsa);
    print("lpx_interior: transformed LP problem has %d rows and %d co"
          "lumns", dsa->m, dsa->n);
    /* transform original LP to standard formulation */
    dsa->ref = ucalloc(1+dsa->orig_m+dsa->orig_n, sizeof(int));
    dsa->size = lpx_get_num_nz(dsa->lp);
    if (dsa->size < dsa->m) dsa->size = dsa->m;
    if (dsa->size < dsa->n) dsa->size = dsa->n;
    dsa->ne = 0;
    dsa->ia = ucalloc(1+dsa->size, sizeof(int));
    dsa->ja = ucalloc(1+dsa->size, sizeof(int));
    dsa->ar = ucalloc(1+dsa->size, sizeof(double));
    dsa->b = ucalloc(1+dsa->m, sizeof(double));
    dsa->c = ucalloc(1+dsa->n, sizeof(double));
    transform(dsa);
    /* solve the transformed LP problem */
    {   int *A_ptr = ucalloc(1+dsa->m+1, sizeof(int));
        int *A_ind = ucalloc(1+dsa->ne, sizeof(int));
        double *A_val = ucalloc(1+dsa->ne, sizeof(double));
        int i, k, pos, len;
        /* determine row lengths */
        for (i = 1; i <= dsa->m; i++)
            A_ptr[i] = 0;
        for (k = 1; k <= dsa->ne; k++)
            A_ptr[dsa->ia[k]]++;
        /* set up row pointers */
        pos = 1;
        for (i = 1; i <= dsa->m; i++)
            len = A_ptr[i], pos += len, A_ptr[i] = pos;
        A_ptr[dsa->m+1] = pos;
        insist(pos - 1 == dsa->ne);
        /* build the matrix */
        for (k = 1; k <= dsa->ne; k++)
        {   pos = --A_ptr[dsa->ia[k]];
            A_ind[pos] = dsa->ja[k];
            A_val[pos] = dsa->ar[k];
        }
        ufree(dsa->ia), dsa->ia = NULL;
        ufree(dsa->ja), dsa->ja = NULL;
        ufree(dsa->ar), dsa->ar = NULL;
        dsa->x = ucalloc(1+dsa->n, sizeof(double));
        dsa->y = ucalloc(1+dsa->m, sizeof(double));
        dsa->z = ucalloc(1+dsa->n, sizeof(double));
        ret = ipm_main(dsa->m, dsa->n, A_ptr, A_ind, A_val, dsa->b,
                       dsa->c, dsa->x, dsa->y, dsa->z);
        ufree(A_ptr);
        ufree(A_ind);
        ufree(A_val);
        ufree(dsa->b), dsa->b = NULL;
        ufree(dsa->c), dsa->c = NULL;
    }
    /* analyze return code reported by the solver */
    switch (ret)
    {
    case 0:
        /* optimal solution found */
        ret = LPX_E_OK;
        break;
    case 1:
        /* problem has no feasible (primal or dual) solution */
        ret = LPX_E_NOFEAS;
        break;
    case 2:
        /* no convergence */
        ret = LPX_E_NOCONV;
        break;
    case 3:
        /* iterations limit exceeded */
        ret = LPX_E_ITLIM;
        break;
    case 4:
        /* numerical instability on solving Newtonian system */
        ret = LPX_E_INSTAB;
        break;
    default:
        insist(ret != ret);
    }
    /* recover solution of original LP */
    row_pval = ucalloc(1+dsa->orig_m, sizeof(double));
    row_dval = ucalloc(1+dsa->orig_m, sizeof(double));
    col_pval = ucalloc(1+dsa->orig_n, sizeof(double));
    col_dval = ucalloc(1+dsa->orig_n, sizeof(double));
    restore(dsa, row_pval, row_dval, col_pval, col_dval);
    ufree(dsa->ref), dsa->ref = NULL;
    ufree(dsa->x), dsa->x = NULL;
    ufree(dsa->y), dsa->y = NULL;
    ufree(dsa->z), dsa->z = NULL;
    /* store solution components into the problem object */
    status = (ret == LPX_E_OK ? LPX_T_OPT : LPX_T_UNDEF);
    lpx_put_ipt_soln(dsa->lp, status, row_pval, row_dval, col_pval,
                     col_dval);
    ufree(row_pval);
    ufree(row_dval);
    ufree(col_pval);
    ufree(col_dval);
done: /* return to the calling program */
    return ret;
}