示例#1
0
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;
}
示例#2
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;
}
示例#3
0
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;
}
示例#4
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;
}
示例#5
0
static void restore(struct dsa *dsa, double row_pval[],
                    double row_dval[], double col_pval[], double col_dval[])
{   /* restore solution of original LP */
    LPX *lp = dsa->lp;
    int orig_m = dsa->orig_m;
    int orig_n = dsa->orig_n;
    int *ref = dsa->ref;
    int m = dsa->m;
    double *x = dsa->x;
    double *y = dsa->y;
    int dir = lpx_get_obj_dir(lp);
    int i, j, k, type, t, len, *ind;
    double lb, ub, rii, sjj, temp, *val;
    /* compute primal values of structural variables */
    for (k = 1; k <= orig_n; k++)
    {   j = ref[orig_m+k];
        type = lpx_get_col_type(lp, k);
        sjj = lpx_get_sjj(lp, k);
        lb = lpx_get_col_lb(lp, k) / sjj;
        ub = lpx_get_col_ub(lp, k) / sjj;
        switch (type)
        {
        case LPX_FR:
            /* source: -inf < x < +inf */
            /* result: x = x' - x'', x' >= 0, x'' >= 0 */
            col_pval[k] = x[j] - x[j+1];
            break;
        case LPX_LO:
            /* source: lb <= x < +inf */
            /* result: x = lb + x', x' >= 0 */
            col_pval[k] = lb + x[j];
            break;
        case LPX_UP:
            /* source: -inf < x <= ub */
            /* result: x = ub - x', x' >= 0 */
            col_pval[k] = ub - x[j];
            break;
        case LPX_DB:
            /* source: lb <= x <= ub */
            /* result: x = lb + x', x' + x'' = ub - lb */
            col_pval[k] = lb + x[j];
            break;
        case LPX_FX:
            /* source: x = lb */
            /* result: just substitute */
            col_pval[k] = lb;
            break;
        default:
            insist(type != type);
        }
    }
    /* compute primal values of auxiliary variables */
    /* xR = A * xS */
    ind = ucalloc(1+orig_n, sizeof(int));
    val = ucalloc(1+orig_n, sizeof(double));
    for (k = 1; k <= orig_m; k++)
    {   rii = lpx_get_rii(lp, k);
        temp = 0.0;
        len = lpx_get_mat_row(lp, k, ind, val);
        for (t = 1; t <= len; t++)
        {   sjj = lpx_get_sjj(lp, ind[t]);
            temp += (rii * val[t] * sjj) * col_pval[ind[t]];
        }
        row_pval[k] = temp;
    }
    ufree(ind);
    ufree(val);
    /* compute dual values of auxiliary variables */
    for (k = 1; k <= orig_m; k++)
    {   type = lpx_get_row_type(lp, k);
        i = ref[k];
        switch (type)
        {
        case LPX_FR:
            insist(i == 0);
            row_dval[k] = 0.0;
            break;
        case LPX_LO:
        case LPX_UP:
        case LPX_DB:
        case LPX_FX:
            insist(1 <= i && i <= m);
            row_dval[k] = (dir == LPX_MIN ? +1.0 : -1.0) * y[i];
            break;
        default:
            insist(type != type);
        }
    }
    /* compute dual values of structural variables */
    /* dS = cS - A' * (dR - cR) */
    ind = ucalloc(1+orig_m, sizeof(int));
    val = ucalloc(1+orig_m, sizeof(double));
    for (k = 1; k <= orig_n; k++)
    {   sjj = lpx_get_sjj(lp, k);
        temp = lpx_get_obj_coef(lp, k) / sjj;
        len = lpx_get_mat_col(lp, k, ind, val);
        for (t = 1; t <= len; t++)
        {   rii = lpx_get_rii(lp, ind[t]);
            temp -= (rii * val[t] * sjj) * row_dval[ind[t]];
        }
        col_dval[k] = temp;
    }
    ufree(ind);
    ufree(val);
    /* unscale solution of original LP */
    for (i = 1; i <= orig_m; i++)
    {   rii = lpx_get_rii(lp, i);
        row_pval[i] /= rii;
        row_dval[i] *= rii;
    }
    for (j = 1; j <= orig_n; j++)
    {   sjj = lpx_get_sjj(lp, j);
        col_pval[j] *= sjj;
        col_dval[j] /= sjj;
    }
    return;
}
示例#6
0
static void transform(struct dsa *dsa)
{   /* transform original LP to standard formulation */
    LPX *lp = dsa->lp;
    int orig_m = dsa->orig_m;
    int orig_n = dsa->orig_n;
    int *ref = dsa->ref;
    int m = dsa->m;
    int n = dsa->n;
    double *b = dsa->b;
    double *c = dsa->c;
    int i, j, k, type, t, ii, len, *ind;
    double lb, ub, coef, rii, sjj, *val;
    /* initialize components of transformed LP */
    dsa->ne = 0;
    for (i = 1; i <= m; i++) b[i] = 0.0;
    c[0] = lpx_get_obj_coef(lp, 0);
    for (j = 1; j <= n; j++) c[j] = 0.0;
    /* i and j are, respectively, ordinal number of current row and
       ordinal number of current column in transformed LP */
    i = j = 0;
    /* transform rows (auxiliary variables) */
    for (k = 1; k <= orig_m; k++)
    {   type = lpx_get_row_type(lp, k);
        rii = lpx_get_rii(lp, k);
        lb = lpx_get_row_lb(lp, k) * rii;
        ub = lpx_get_row_ub(lp, k) * rii;
        switch (type)
        {
        case LPX_FR:
            /* source: -inf < (L.F.) < +inf */
            /* result: ignore free row */
            ref[k] = 0;
            break;
        case LPX_LO:
            /* source: lb <= (L.F.) < +inf */
            /* result: (L.F.) - x' = lb, x' >= 0 */
            i++;
            j++;
            ref[k] = i;
            new_coef(dsa, i, j, -1.0);
            b[i] = lb;
            break;
        case LPX_UP:
            /* source: -inf < (L.F.) <= ub */
            /* result: (L.F.) + x' = ub, x' >= 0 */
            i++;
            j++;
            ref[k] = i;
            new_coef(dsa, i, j, +1.0);
            b[i] = ub;
            break;
        case LPX_DB:
            /* source: lb <= (L.F.) <= ub */
            /* result: (L.F.) - x' = lb, x' + x'' = ub - lb */
            i++;
            j++;
            ref[k] = i;
            new_coef(dsa, i, j, -1.0);
            b[i] = lb;
            i++;
            new_coef(dsa, i, j, +1.0);
            j++;
            new_coef(dsa, i, j, +1.0);
            b[i] = ub - lb;
            break;
        case LPX_FX:
            /* source: (L.F.) = lb */
            /* result: (L.F.) = lb */
            i++;
            ref[k] = i;
            b[i] = lb;
            break;
        default:
            insist(type != type);
        }
    }
    /* transform columns (structural variables) */
    ind = ucalloc(1+orig_m, sizeof(int));
    val = ucalloc(1+orig_m, sizeof(double));
    for (k = 1; k <= orig_n; k++)
    {   type = lpx_get_col_type(lp, k);
        sjj = lpx_get_sjj(lp, k);
        lb = lpx_get_col_lb(lp, k) / sjj;
        ub = lpx_get_col_ub(lp, k) / sjj;
        coef = lpx_get_obj_coef(lp, k) * sjj;
        len = lpx_get_mat_col(lp, k, ind, val);
        for (t = 1; t <= len; t++)
            val[t] *= (lpx_get_rii(lp, ind[t]) * sjj);
        switch (type)
        {
        case LPX_FR:
            /* source: -inf < x < +inf */
            /* result: x = x' - x'', x' >= 0, x'' >= 0 */
            j++;
            ref[orig_m+k] = j;
            for (t = 1; t <= len; t++)
            {   ii = ref[ind[t]];
                if (ii != 0) new_coef(dsa, ii, j, +val[t]);
            }
            c[j] = +coef;
            j++;
            for (t = 1; t <= len; t++)
            {   ii = ref[ind[t]];
                if (ii != 0) new_coef(dsa, ii, j, -val[t]);
            }
            c[j] = -coef;
            break;
        case LPX_LO:
            /* source: lb <= x < +inf */
            /* result: x = lb + x', x' >= 0 */
            j++;
            ref[orig_m+k] = j;
            for (t = 1; t <= len; t++)
            {   ii = ref[ind[t]];
                if (ii != 0)
                {   new_coef(dsa, ii, j, val[t]);
                    b[ii] -= val[t] * lb;
                }
            }
            c[j] = +coef;
            c[0] += c[j] * lb;
            break;
        case LPX_UP:
            /* source: -inf < x <= ub */
            /* result: x = ub - x', x' >= 0 */
            j++;
            ref[orig_m+k] = j;
            for (t = 1; t <= len; t++)
            {   ii = ref[ind[t]];
                if (ii != 0)
                {   new_coef(dsa, ii, j, -val[t]);
                    b[ii] -= val[t] * ub;
                }
            }
            c[j] = -coef;
            c[0] -= c[j] * ub;
            break;
        case LPX_DB:
            /* source: lb <= x <= ub */
            /* result: x = lb + x', x' + x'' = ub - lb */
            j++;
            ref[orig_m+k] = j;
            for (t = 1; t <= len; t++)
            {   ii = ref[ind[t]];
                if (ii != 0)
                {   new_coef(dsa, ii, j, val[t]);
                    b[ii] -= val[t] * lb;
                }
            }
            c[j] = +coef;
            c[0] += c[j] * lb;
            i++;
            new_coef(dsa, i, j, +1.0);
            j++;
            new_coef(dsa, i, j, +1.0);
            b[i] = ub - lb;
            break;
        case LPX_FX:
            /* source: x = lb */
            /* result: just substitute */
            ref[orig_m+k] = 0;
            for (t = 1; t <= len; t++)
            {   ii = ref[ind[t]];
                if (ii != 0) b[ii] -= val[t] * lb;
            }
            c[0] += coef * lb;
            break;
        default:
            insist(type != type);
        }
    }
    ufree(ind);
    ufree(val);
    /* end of transformation */
    insist(i == m && j == n);
    /* change the objective sign in case of maximization */
    if (lpx_get_obj_dir(lp) == LPX_MAX)
        for (j = 0; j <= n; j++) c[j] = -c[j];
    return;
}
示例#7
0
void lpx_check_kkt(LPX *lp, int scaled, LPXKKT *kkt)
{     int m = lpx_get_num_rows(lp);
      int n = lpx_get_num_cols(lp);
#if 0 /* 21/XII-2003 */
      int *typx = lp->typx;
      double *lb = lp->lb;
      double *ub = lp->ub;
      double *rs = lp->rs;
#else
      int typx, tagx;
      double lb, ub;
#endif
      int dir = lpx_get_obj_dir(lp);
#if 0 /* 21/XII-2003 */
      double *coef = lp->coef;
#endif
#if 0 /* 22/XII-2003 */
      int *A_ptr = lp->A->ptr;
      int *A_len = lp->A->len;
      int *A_ndx = lp->A->ndx;
      double *A_val = lp->A->val;
#endif
      int *A_ndx;
      double *A_val;
#if 0 /* 21/XII-2003 */
      int *tagx = lp->tagx;
      int *posx = lp->posx;
      int *indx = lp->indx;
      double *bbar = lp->bbar;
      double *cbar = lp->cbar;
#endif
      int beg, end, i, j, k, t;
      double cR_i, cS_j, c_k, xR_i, xS_j, x_k, dR_i, dS_j, d_k;
      double g_i, h_k, u_j, v_k, temp, rii, sjj;
      if (lpx_get_prim_stat(lp) == LPX_P_UNDEF)
         xfault("lpx_check_kkt: primal basic solution is undefined\n");
      if (lpx_get_dual_stat(lp) == LPX_D_UNDEF)
         xfault("lpx_check_kkt: dual basic solution is undefined\n");
      /*--------------------------------------------------------------*/
      /* compute largest absolute and relative errors and corresponding
         row indices for the condition (KKT.PE) */
      kkt->pe_ae_max = 0.0, kkt->pe_ae_row = 0;
      kkt->pe_re_max = 0.0, kkt->pe_re_row = 0;
      A_ndx = xcalloc(1+n, sizeof(int));
      A_val = xcalloc(1+n, sizeof(double));
      for (i = 1; i <= m; i++)
      {  /* determine xR[i] */
#if 0 /* 21/XII-2003 */
         if (tagx[i] == LPX_BS)
            xR_i = bbar[posx[i]];
         else
            xR_i = spx_eval_xn_j(lp, posx[i] - m);
#else
         lpx_get_row_info(lp, i, NULL, &xR_i, NULL);
         xR_i *= lpx_get_rii(lp, i);
#endif
         /* g[i] := xR[i] */
         g_i = xR_i;
         /* g[i] := g[i] - (i-th row of A) * xS */
         beg = 1;
         end = lpx_get_mat_row(lp, i, A_ndx, A_val);
         for (t = beg; t <= end; t++)
         {  j = m + A_ndx[t]; /* a[i,j] != 0 */
            /* determine xS[j] */
#if 0 /* 21/XII-2003 */
            if (tagx[j] == LPX_BS)
               xS_j = bbar[posx[j]];
            else
               xS_j = spx_eval_xn_j(lp, posx[j] - m);
#else
            lpx_get_col_info(lp, j-m, NULL, &xS_j, NULL);
            xS_j /= lpx_get_sjj(lp, j-m);
#endif
            /* g[i] := g[i] - a[i,j] * xS[j] */
            rii = lpx_get_rii(lp, i);
            sjj = lpx_get_sjj(lp, j-m);
            g_i -= (rii * A_val[t] * sjj) * xS_j;
         }
         /* unscale xR[i] and g[i] (if required) */
         if (!scaled)
         {  rii = lpx_get_rii(lp, i);
            xR_i /= rii, g_i /= rii;
         }
         /* determine absolute error */
         temp = fabs(g_i);
         if (kkt->pe_ae_max < temp)
            kkt->pe_ae_max = temp, kkt->pe_ae_row = i;
         /* determine relative error */
         temp /= (1.0 + fabs(xR_i));
         if (kkt->pe_re_max < temp)
            kkt->pe_re_max = temp, kkt->pe_re_row = i;
      }
      xfree(A_ndx);
      xfree(A_val);
      /* estimate the solution quality */
      if (kkt->pe_re_max <= 1e-9)
         kkt->pe_quality = 'H';
      else if (kkt->pe_re_max <= 1e-6)
         kkt->pe_quality = 'M';
      else if (kkt->pe_re_max <= 1e-3)
         kkt->pe_quality = 'L';
      else
         kkt->pe_quality = '?';
      /*--------------------------------------------------------------*/
      /* compute largest absolute and relative errors and corresponding
         variable indices for the condition (KKT.PB) */
      kkt->pb_ae_max = 0.0, kkt->pb_ae_ind = 0;
      kkt->pb_re_max = 0.0, kkt->pb_re_ind = 0;
      for (k = 1; k <= m+n; k++)
      {  /* determine x[k] */
         if (k <= m)
         {  lpx_get_row_bnds(lp, k, &typx, &lb, &ub);
            rii = lpx_get_rii(lp, k);
            lb *= rii;
            ub *= rii;
            lpx_get_row_info(lp, k, &tagx, &x_k, NULL);
            x_k *= rii;
         }
         else
         {  lpx_get_col_bnds(lp, k-m, &typx, &lb, &ub);
            sjj = lpx_get_sjj(lp, k-m);
            lb /= sjj;
            ub /= sjj;
            lpx_get_col_info(lp, k-m, &tagx, &x_k, NULL);
            x_k /= sjj;
         }
         /* skip non-basic variable */
         if (tagx != LPX_BS) continue;
         /* compute h[k] */
         h_k = 0.0;
         switch (typx)
         {  case LPX_FR:
               break;
            case LPX_LO:
               if (x_k < lb) h_k = x_k - lb;
               break;
            case LPX_UP:
               if (x_k > ub) h_k = x_k - ub;
               break;
            case LPX_DB:
            case LPX_FX:
               if (x_k < lb) h_k = x_k - lb;
               if (x_k > ub) h_k = x_k - ub;
               break;
            default:
               xassert(typx != typx);
         }
         /* unscale x[k] and h[k] (if required) */
         if (!scaled)
         {  if (k <= m)
            {  rii = lpx_get_rii(lp, k);
               x_k /= rii, h_k /= rii;
            }
            else
            {  sjj = lpx_get_sjj(lp, k-m);
               x_k *= sjj, h_k *= sjj;
            }
         }
         /* determine absolute error */
         temp = fabs(h_k);
         if (kkt->pb_ae_max < temp)
            kkt->pb_ae_max = temp, kkt->pb_ae_ind = k;
         /* determine relative error */
         temp /= (1.0 + fabs(x_k));
         if (kkt->pb_re_max < temp)
            kkt->pb_re_max = temp, kkt->pb_re_ind = k;
      }
      /* estimate the solution quality */
      if (kkt->pb_re_max <= 1e-9)
         kkt->pb_quality = 'H';
      else if (kkt->pb_re_max <= 1e-6)
         kkt->pb_quality = 'M';
      else if (kkt->pb_re_max <= 1e-3)
         kkt->pb_quality = 'L';
      else
         kkt->pb_quality = '?';
      /*--------------------------------------------------------------*/
      /* compute largest absolute and relative errors and corresponding
         column indices for the condition (KKT.DE) */
      kkt->de_ae_max = 0.0, kkt->de_ae_col = 0;
      kkt->de_re_max = 0.0, kkt->de_re_col = 0;
      A_ndx = xcalloc(1+m, sizeof(int));
      A_val = xcalloc(1+m, sizeof(double));
      for (j = m+1; j <= m+n; j++)
      {  /* determine cS[j] */
#if 0 /* 21/XII-2003 */
         cS_j = coef[j];
#else
         sjj = lpx_get_sjj(lp, j-m);
         cS_j = lpx_get_obj_coef(lp, j-m) * sjj;
#endif
         /* determine dS[j] */
#if 0 /* 21/XII-2003 */
         if (tagx[j] == LPX_BS)
            dS_j = 0.0;
         else
            dS_j = cbar[posx[j] - m];
#else
         lpx_get_col_info(lp, j-m, NULL, NULL, &dS_j);
         dS_j *= sjj;
#endif
         /* u[j] := dS[j] - cS[j] */
         u_j = dS_j - cS_j;
         /* u[j] := u[j] + (j-th column of A) * (dR - cR) */
         beg = 1;
         end = lpx_get_mat_col(lp, j-m, A_ndx, A_val);
         for (t = beg; t <= end; t++)
         {  i = A_ndx[t]; /* a[i,j] != 0 */
            /* determine cR[i] */
#if 0 /* 21/XII-2003 */
            cR_i = coef[i];
#else
            cR_i = 0.0;
#endif
            /* determine dR[i] */
#if 0 /* 21/XII-2003 */
            if (tagx[i] == LPX_BS)
               dR_i = 0.0;
            else
               dR_i = cbar[posx[i] - m];
#else
            lpx_get_row_info(lp, i, NULL, NULL, &dR_i);
            rii = lpx_get_rii(lp, i);
            dR_i /= rii;
#endif
            /* u[j] := u[j] + a[i,j] * (dR[i] - cR[i]) */
            rii = lpx_get_rii(lp, i);
            sjj = lpx_get_sjj(lp, j-m);
            u_j += (rii * A_val[t] * sjj) * (dR_i - cR_i);
         }
         /* unscale cS[j], dS[j], and u[j] (if required) */
         if (!scaled)
         {  sjj = lpx_get_sjj(lp, j-m);
            cS_j /= sjj, dS_j /= sjj, u_j /= sjj;
         }
         /* determine absolute error */
         temp = fabs(u_j);
         if (kkt->de_ae_max < temp)
            kkt->de_ae_max = temp, kkt->de_ae_col = j - m;
         /* determine relative error */
         temp /= (1.0 + fabs(dS_j - cS_j));
         if (kkt->de_re_max < temp)
            kkt->de_re_max = temp, kkt->de_re_col = j - m;
      }
      xfree(A_ndx);
      xfree(A_val);
      /* estimate the solution quality */
      if (kkt->de_re_max <= 1e-9)
         kkt->de_quality = 'H';
      else if (kkt->de_re_max <= 1e-6)
         kkt->de_quality = 'M';
      else if (kkt->de_re_max <= 1e-3)
         kkt->de_quality = 'L';
      else
         kkt->de_quality = '?';
      /*--------------------------------------------------------------*/
      /* compute largest absolute and relative errors and corresponding
         variable indices for the condition (KKT.DB) */
      kkt->db_ae_max = 0.0, kkt->db_ae_ind = 0;
      kkt->db_re_max = 0.0, kkt->db_re_ind = 0;
      for (k = 1; k <= m+n; k++)
      {  /* determine c[k] */
#if 0 /* 21/XII-2003 */
         c_k = coef[k];
#else
         if (k <= m)
            c_k = 0.0;
         else
         {  sjj = lpx_get_sjj(lp, k-m);
            c_k = lpx_get_obj_coef(lp, k-m) / sjj;
         }
#endif
         /* determine d[k] */
#if 0 /* 21/XII-2003 */
         d_k = cbar[j-m];
#else
         if (k <= m)
         {  lpx_get_row_info(lp, k, &tagx, NULL, &d_k);
            rii = lpx_get_rii(lp, k);
            d_k /= rii;
         }
         else
         {  lpx_get_col_info(lp, k-m, &tagx, NULL, &d_k);
            sjj = lpx_get_sjj(lp, k-m);
            d_k *= sjj;
         }
#endif
         /* skip basic variable */
         if (tagx == LPX_BS) continue;
         /* compute v[k] */
         v_k = 0.0;
         switch (tagx)
         {  case LPX_NL:
               switch (dir)
               {  case LPX_MIN:
                     if (d_k < 0.0) v_k = d_k;
                     break;
                  case LPX_MAX:
                     if (d_k > 0.0) v_k = d_k;
                     break;
                  default:
                     xassert(dir != dir);
               }
               break;
            case LPX_NU:
               switch (dir)
               {  case LPX_MIN:
                     if (d_k > 0.0) v_k = d_k;
                     break;
                  case LPX_MAX:
                     if (d_k < 0.0) v_k = d_k;
                     break;
                  default:
                     xassert(dir != dir);
               }
               break;
            case LPX_NF:
               v_k = d_k;
               break;
            case LPX_NS:
               break;
            default:
               xassert(tagx != tagx);
         }
         /* unscale c[k], d[k], and v[k] (if required) */
         if (!scaled)
         {  if (k <= m)
            {  rii = lpx_get_rii(lp, k);
               c_k *= rii, d_k *= rii, v_k *= rii;
            }
            else
            {  sjj = lpx_get_sjj(lp, k-m);
               c_k /= sjj, d_k /= sjj, v_k /= sjj;
            }
         }
         /* determine absolute error */
         temp = fabs(v_k);
         if (kkt->db_ae_max < temp)
            kkt->db_ae_max = temp, kkt->db_ae_ind = k;
         /* determine relative error */
         temp /= (1.0 + fabs(d_k - c_k));
         if (kkt->db_re_max < temp)
            kkt->db_re_max = temp, kkt->db_re_ind = k;
      }
      /* estimate the solution quality */
      if (kkt->db_re_max <= 1e-9)
         kkt->db_quality = 'H';
      else if (kkt->db_re_max <= 1e-6)
         kkt->db_quality = 'M';
      else if (kkt->db_re_max <= 1e-3)
         kkt->db_quality = 'L';
      else
         kkt->db_quality = '?';
      /* complementary slackness is always satisfied by definition for
         any basic solution, so not checked */
      kkt->cs_ae_max = 0.0, kkt->cs_ae_ind = 0;
      kkt->cs_re_max = 0.0, kkt->cs_re_ind = 0;
      kkt->cs_quality = 'H';
      return;
}
示例#8
0
static int mat(void *info, int k, int ndx[])
{     /* this auxiliary routine returns the pattern of a given row or
         a given column of the augmented constraint matrix A~ = (I|-A),
         in which columns of fixed variables are implicitly cleared */
      LPX *lp = info;
      int m = lpx_get_num_rows(lp);
      int n = lpx_get_num_cols(lp);
      int typx, i, j, lll, len = 0;
      if (k > 0)
      {  /* the pattern of the i-th row is required */
         i = +k;
         xassert(1 <= i && i <= m);
#if 0 /* 22/XII-2003 */
         /* if the auxiliary variable x[i] is non-fixed, include its
            element (placed in the i-th column) in the pattern */
         lpx_get_row_bnds(lp, i, &typx, NULL, NULL);
         if (typx != LPX_FX) ndx[++len] = i;
         /* include in the pattern elements placed in columns, which
            correspond to non-fixed structural varables */
         i_beg = aa_ptr[i];
         i_end = i_beg + aa_len[i] - 1;
         for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++)
         {  j = m + sv_ndx[i_ptr];
            lpx_get_col_bnds(lp, j-m, &typx, NULL, NULL);
            if (typx != LPX_FX) ndx[++len] = j;
         }
#else
         lll = lpx_get_mat_row(lp, i, ndx, NULL);
         for (k = 1; k <= lll; k++)
         {  lpx_get_col_bnds(lp, ndx[k], &typx, NULL, NULL);
            if (typx != LPX_FX) ndx[++len] = m + ndx[k];
         }
         lpx_get_row_bnds(lp, i, &typx, NULL, NULL);
         if (typx != LPX_FX) ndx[++len] = i;
#endif
      }
      else
      {  /* the pattern of the j-th column is required */
         j = -k;
         xassert(1 <= j && j <= m+n);
         /* if the (auxiliary or structural) variable x[j] is fixed,
            the pattern of its column is empty */
         if (j <= m)
            lpx_get_row_bnds(lp, j, &typx, NULL, NULL);
         else
            lpx_get_col_bnds(lp, j-m, &typx, NULL, NULL);
         if (typx != LPX_FX)
         {  if (j <= m)
            {  /* x[j] is non-fixed auxiliary variable */
               ndx[++len] = j;
            }
            else
            {  /* x[j] is non-fixed structural variables */
#if 0 /* 22/XII-2003 */
               j_beg = aa_ptr[j];
               j_end = j_beg + aa_len[j] - 1;
               for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++)
                  ndx[++len] = sv_ndx[j_ptr];
#else
               len = lpx_get_mat_col(lp, j-m, ndx, NULL);
#endif
            }
         }
      }
      /* return the length of the row/column pattern */
      return len;
}
示例#9
0
void ipp_load_orig(IPP *ipp, LPX *orig)
{     IPPROW **row;
      IPPCOL *col;
      int i, j, k, type, len, *ind;
      double lb, ub, *val;
      /* save some information about the original problem */
      ipp->orig_m = lpx_get_num_rows(orig);
      ipp->orig_n = lpx_get_num_cols(orig);
      ipp->orig_nnz = lpx_get_num_nz(orig);
      ipp->orig_dir = lpx_get_obj_dir(orig);
      /* allocate working arrays */
      row = xcalloc(1+ipp->orig_m, sizeof(IPPROW *));
      ind = xcalloc(1+ipp->orig_m, sizeof(int));
      val = xcalloc(1+ipp->orig_m, sizeof(double));
      /* copy rows of the original problem into the workspace */
      for (i = 1; i <= ipp->orig_m; i++)
      {  type = lpx_get_row_type(orig, i);
         if (type == LPX_FR || type == LPX_UP)
            lb = -DBL_MAX;
         else
            lb = lpx_get_row_lb(orig, i);
         if (type == LPX_FR || type == LPX_LO)
            ub = +DBL_MAX;
         else
            ub = lpx_get_row_ub(orig, i);
         row[i] = ipp_add_row(ipp, lb, ub);
      }
      /* copy columns of the original problem into the workspace; each
         column created in the workspace is assigned a reference number
         which is its ordinal number in the original problem */
      for (j = 1; j <= ipp->orig_n; j++)
      {  type = lpx_get_col_type(orig, j);
         if (type == LPX_FR || type == LPX_UP)
            lb = -DBL_MAX;
         else
            lb = lpx_get_col_lb(orig, j);
         if (type == LPX_FR || type == LPX_LO)
            ub = +DBL_MAX;
         else
            ub = lpx_get_col_ub(orig, j);
         col = ipp_add_col(ipp, lpx_get_col_kind(orig, j) == LPX_IV,
            lb, ub, lpx_get_obj_coef(orig, j));
         len = lpx_get_mat_col(orig, j, ind, val);
         for (k = 1; k <= len; k++)
            ipp_add_aij(ipp, row[ind[k]], col, val[k]);
      }
      /* copy the constant term of the original objective function */
      ipp->c0 = lpx_get_obj_coef(orig, 0);
      /* 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 (ipp->orig_dir == LPX_MAX)
      {  for (col = ipp->col_ptr; col != NULL; col = col->next)
            col->c = - col->c;
         ipp->c0 = - ipp->c0;
      }
      /* free working arrays */
      xfree(row);
      xfree(ind);
      xfree(val);
      return;
}
示例#10
0
void lpx_eval_b_prim(LPX *lp, double row_prim[], double col_prim[])
{     int i, j, k, m, n, stat, len, *ind;
      double xN, *NxN, *xB, *val;
      if (!lpx_is_b_avail(lp))
         xfault("lpx_eval_b_prim: LP basis is not available\n");
      m = lpx_get_num_rows(lp);
      n = lpx_get_num_cols(lp);
      /* store values of non-basic auxiliary and structural variables
         and compute the right-hand side vector (-N*xN) */
      NxN = xcalloc(1+m, sizeof(double));
      for (i = 1; i <= m; i++) NxN[i] = 0.0;
      /* walk through auxiliary variables */
      for (i = 1; i <= m; i++)
      {  /* obtain status of i-th auxiliary variable */
         stat = lpx_get_row_stat(lp, i);
         /* if it is basic, skip it */
         if (stat == LPX_BS) continue;
         /* i-th auxiliary variable is non-basic; get its value */
         switch (stat)
         {  case LPX_NL: xN = lpx_get_row_lb(lp, i); break;
            case LPX_NU: xN = lpx_get_row_ub(lp, i); break;
            case LPX_NF: xN = 0.0; break;
            case LPX_NS: xN = lpx_get_row_lb(lp, i); break;
            default: xassert(lp != lp);
         }
         /* store the value of non-basic auxiliary variable */
         row_prim[i] = xN;
         /* and add corresponding term to the right-hand side vector */
         NxN[i] -= xN;
      }
      /* walk through structural variables */
      ind = xcalloc(1+m, sizeof(int));
      val = xcalloc(1+m, sizeof(double));
      for (j = 1; j <= n; j++)
      {  /* obtain status of j-th structural variable */
         stat = lpx_get_col_stat(lp, j);
         /* if it basic, skip it */
         if (stat == LPX_BS) continue;
         /* j-th structural variable is non-basic; get its value */
         switch (stat)
         {  case LPX_NL: xN = lpx_get_col_lb(lp, j); break;
            case LPX_NU: xN = lpx_get_col_ub(lp, j); break;
            case LPX_NF: xN = 0.0; break;
            case LPX_NS: xN = lpx_get_col_lb(lp, j); break;
            default: xassert(lp != lp);
         }
         /* store the value of non-basic structural variable */
         col_prim[j] = xN;
         /* and add corresponding term to the right-hand side vector */
         if (xN != 0.0)
         {  len = lpx_get_mat_col(lp, j, ind, val);
            for (k = 1; k <= len; k++) NxN[ind[k]] += val[k] * xN;
         }
      }
      xfree(ind);
      xfree(val);
      /* solve the system B*xB = (-N*xN) to compute the vector xB */
      xB = NxN, lpx_ftran(lp, xB);
      /* store values of basic auxiliary and structural variables */
      for (i = 1; i <= m; i++)
      {  k = lpx_get_b_info(lp, i);
         xassert(1 <= k && k <= m+n);
         if (k <= m)
            row_prim[k] = xB[i];
         else
            col_prim[k-m] = xB[i];
      }
      xfree(NxN);
      return;
}
示例#11
0
int lpx_transform_row(LPX *lp, int len, int ind[], double val[])
{     int i, j, k, m, n, t, lll, *iii;
      double alfa, *a, *aB, *rho, *vvv;
      if (!lpx_is_b_avail(lp))
         xfault("lpx_transform_row: LP basis is not available\n");
      m = lpx_get_num_rows(lp);
      n = lpx_get_num_cols(lp);
      /* unpack the row to be transformed to the array a */
      a = xcalloc(1+n, sizeof(double));
      for (j = 1; j <= n; j++) a[j] = 0.0;
      if (!(0 <= len && len <= n))
         xfault("lpx_transform_row: len = %d; invalid row length\n",
            len);
      for (t = 1; t <= len; t++)
      {  j = ind[t];
         if (!(1 <= j && j <= n))
            xfault("lpx_transform_row: ind[%d] = %d; column index out o"
               "f range\n", t, j);
         if (val[t] == 0.0)
            xfault("lpx_transform_row: val[%d] = 0; zero coefficient no"
               "t allowed\n", t);
         if (a[j] != 0.0)
            xfault("lpx_transform_row: ind[%d] = %d; duplicate column i"
               "ndices not allowed\n", t, j);
         a[j] = val[t];
      }
      /* construct the vector aB */
      aB = 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);
         aB[i] = (k <= m ? 0.0 : a[k-m]);
      }
      /* solve the system B'*rho = aB to compute the vector rho */
      rho = aB, lpx_btran(lp, rho);
      /* compute coefficients at non-basic auxiliary variables */
      len = 0;
      for (i = 1; i <= m; i++)
      {  if (lpx_get_row_stat(lp, i) != LPX_BS)
         {  alfa = - rho[i];
            if (alfa != 0.0)
            {  len++;
               ind[len] = i;
               val[len] = alfa;
            }
         }
      }
      /* compute coefficients at non-basic structural variables */
      iii = xcalloc(1+m, sizeof(int));
      vvv = xcalloc(1+m, sizeof(double));
      for (j = 1; j <= n; j++)
      {  if (lpx_get_col_stat(lp, j) != LPX_BS)
         {  alfa = a[j];
            lll = lpx_get_mat_col(lp, j, iii, vvv);
            for (t = 1; t <= lll; t++) alfa += vvv[t] * rho[iii[t]];
            if (alfa != 0.0)
            {  len++;
               ind[len] = m+j;
               val[len] = alfa;
            }
         }
      }
      xassert(len <= n);
      xfree(iii);
      xfree(vvv);
      xfree(aB);
      xfree(a);
      return len;
}