Example #1
0
void npp_dbnd_col(NPP *npp, NPPCOL *q)
{     /* process non-negative column with upper bound */
      struct dbnd_col *info;
      NPPROW *p;
      NPPCOL *s;
      /* the column must be non-negative with upper bound */
      xassert(q->lb == 0.0);
      xassert(q->ub > 0.0);
      xassert(q->ub != +DBL_MAX);
      /* create variable s */
      s = npp_add_col(npp);
      s->is_int = q->is_int;
      s->lb = 0.0, s->ub = +DBL_MAX;
      /* create equality constraint (2) */
      p = npp_add_row(npp);
      p->lb = p->ub = q->ub;
      npp_add_aij(npp, p, q, +1.0);
      npp_add_aij(npp, p, s, +1.0);
      /* create transformation stack entry */
      info = npp_push_tse(npp,
         rcv_dbnd_col, sizeof(struct dbnd_col));
      info->q = q->j;
      info->s = s->j;
      /* remove upper bound of x[q] */
      q->ub = +DBL_MAX;
      return;
}
Example #2
0
void npp_load_prob(NPP *npp, glp_prob *orig, int names, int sol,
      int scaling)
{     /* load original problem into the preprocessor workspace */
      int m = orig->m;
      int n = orig->n;
      NPPROW **link;
      int i, j;
      double dir;
      xassert(names == GLP_OFF || names == GLP_ON);
      xassert(sol == GLP_SOL || sol == GLP_IPT || sol == GLP_MIP);
      xassert(scaling == GLP_OFF || scaling == GLP_ON);
      if (sol == GLP_MIP) xassert(!scaling);
      npp->orig_dir = orig->dir;
      if (npp->orig_dir == GLP_MIN)
         dir = +1.0;
      else if (npp->orig_dir == GLP_MAX)
         dir = -1.0;
      else
         xassert(npp != npp);
      npp->orig_m = m;
      npp->orig_n = n;
      npp->orig_nnz = orig->nnz;
      if (names && orig->name != NULL)
      {  npp->name = dmp_get_atom(npp->pool, strlen(orig->name)+1);
         strcpy(npp->name, orig->name);
      }
      if (names && orig->obj != NULL)
      {  npp->obj = dmp_get_atom(npp->pool, strlen(orig->obj)+1);
         strcpy(npp->obj, orig->obj);
      }
      npp->c0 = dir * orig->c0;
      /* load rows */
      link = xcalloc(1+m, sizeof(NPPROW *));
      for (i = 1; i <= m; i++)
      {  GLPROW *rrr = orig->row[i];
         NPPROW *row;
         link[i] = row = npp_add_row(npp);
         xassert(row->i == i);
         if (names && rrr->name != NULL)
         {  row->name = dmp_get_atom(npp->pool, strlen(rrr->name)+1);
            strcpy(row->name, rrr->name);
         }
         if (!scaling)
         {  if (rrr->type == GLP_FR)
               row->lb = -DBL_MAX, row->ub = +DBL_MAX;
            else if (rrr->type == GLP_LO)
               row->lb = rrr->lb, row->ub = +DBL_MAX;
            else if (rrr->type == GLP_UP)
               row->lb = -DBL_MAX, row->ub = rrr->ub;
            else if (rrr->type == GLP_DB)
               row->lb = rrr->lb, row->ub = rrr->ub;
            else if (rrr->type == GLP_FX)
               row->lb = row->ub = rrr->lb;
            else
               xassert(rrr != rrr);
         }
         else
         {  double rii = rrr->rii;
            if (rrr->type == GLP_FR)
               row->lb = -DBL_MAX, row->ub = +DBL_MAX;
            else if (rrr->type == GLP_LO)
               row->lb = rrr->lb * rii, row->ub = +DBL_MAX;
            else if (rrr->type == GLP_UP)
               row->lb = -DBL_MAX, row->ub = rrr->ub * rii;
            else if (rrr->type == GLP_DB)
               row->lb = rrr->lb * rii, row->ub = rrr->ub * rii;
            else if (rrr->type == GLP_FX)
               row->lb = row->ub = rrr->lb * rii;
            else
               xassert(rrr != rrr);
         }
      }
      /* load columns and constraint coefficients */
      for (j = 1; j <= n; j++)
      {  GLPCOL *ccc = orig->col[j];
         GLPAIJ *aaa;
         NPPCOL *col;
         col = npp_add_col(npp);
         xassert(col->j == j);
         if (names && ccc->name != NULL)
         {  col->name = dmp_get_atom(npp->pool, strlen(ccc->name)+1);
            strcpy(col->name, ccc->name);
         }
         if (sol == GLP_MIP)
#if 0
            col->kind = ccc->kind;
#else
            col->is_int = (char)(ccc->kind == GLP_IV);
#endif
         if (!scaling)
         {  if (ccc->type == GLP_FR)
               col->lb = -DBL_MAX, col->ub = +DBL_MAX;
            else if (ccc->type == GLP_LO)
               col->lb = ccc->lb, col->ub = +DBL_MAX;
            else if (ccc->type == GLP_UP)
               col->lb = -DBL_MAX, col->ub = ccc->ub;
            else if (ccc->type == GLP_DB)
               col->lb = ccc->lb, col->ub = ccc->ub;
            else if (ccc->type == GLP_FX)
               col->lb = col->ub = ccc->lb;
            else
               xassert(ccc != ccc);
            col->coef = dir * ccc->coef;
            for (aaa = ccc->ptr; aaa != NULL; aaa = aaa->c_next)
               npp_add_aij(npp, link[aaa->row->i], col, aaa->val);
         }
         else
         {  double sjj = ccc->sjj;
            if (ccc->type == GLP_FR)
               col->lb = -DBL_MAX, col->ub = +DBL_MAX;
            else if (ccc->type == GLP_LO)
               col->lb = ccc->lb / sjj, col->ub = +DBL_MAX;
            else if (ccc->type == GLP_UP)
               col->lb = -DBL_MAX, col->ub = ccc->ub / sjj;
            else if (ccc->type == GLP_DB)
               col->lb = ccc->lb / sjj, col->ub = ccc->ub / sjj;
            else if (ccc->type == GLP_FX)
               col->lb = col->ub = ccc->lb / sjj;
            else
               xassert(ccc != ccc);
            col->coef = dir * ccc->coef * sjj;
            for (aaa = ccc->ptr; aaa != NULL; aaa = aaa->c_next)
               npp_add_aij(npp, link[aaa->row->i], col,
                  aaa->row->rii * aaa->val * sjj);
         }
      }
      xfree(link);
      /* keep solution indicator and scaling option */
      npp->sol = sol;
      npp->scaling = scaling;
      return;
}
Example #3
0
int npp_hidden_covering(NPP *npp, NPPROW *row)
{     /* identify hidden covering inequality */
      NPPROW *copy;
      NPPAIJ *aij;
      struct elem *ptr, *e;
      int kase, ret, count = 0;
      double b;
      /* the row must be inequality constraint */
      xassert(row->lb < row->ub);
      for (kase = 0; kase <= 1; kase++)
      {  if (kase == 0)
         {  /* process row lower bound */
            if (row->lb == -DBL_MAX) continue;
            ptr = copy_form(npp, row, +1.0);
            b = + row->lb;
         }
         else
         {  /* process row upper bound */
            if (row->ub == +DBL_MAX) continue;
            ptr = copy_form(npp, row, -1.0);
            b = - row->ub;
         }
         /* now the inequality has the form "sum a[j] x[j] >= b" */
         ret = hidden_covering(npp, ptr, &b);
         xassert(0 <= ret && ret <= 2);
         if (kase == 1 && ret == 1 || ret == 2)
         {  /* the original inequality has been identified as hidden
               covering inequality */
            count++;
#ifdef GLP_DEBUG
            xprintf("Original constraint:\n");
            for (aij = row->ptr; aij != NULL; aij = aij->r_next)
               xprintf(" %+g x%d", aij->val, aij->col->j);
            if (row->lb != -DBL_MAX) xprintf(", >= %g", row->lb);
            if (row->ub != +DBL_MAX) xprintf(", <= %g", row->ub);
            xprintf("\n");
            xprintf("Equivalent covering inequality:\n");
            for (e = ptr; e != NULL; e = e->next)
               xprintf(" %sx%d", e->aj > 0.0 ? "+" : "-", e->xj->j);
            xprintf(", >= %g\n", b);
#endif
            if (row->lb == -DBL_MAX || row->ub == +DBL_MAX)
            {  /* the original row is single-sided inequality; no copy
                  is needed */
               copy = NULL;
            }
            else
            {  /* the original row is double-sided inequality; we need
                  to create its copy for other bound before replacing it
                  with the equivalent inequality */
               copy = npp_add_row(npp);
               if (kase == 0)
               {  /* the copy is for upper bound */
                  copy->lb = -DBL_MAX, copy->ub = row->ub;
               }
               else
               {  /* the copy is for lower bound */
                  copy->lb = row->lb, copy->ub = +DBL_MAX;
               }
               /* copy original row coefficients */
               for (aij = row->ptr; aij != NULL; aij = aij->r_next)
                  npp_add_aij(npp, copy, aij->col, aij->val);
            }
            /* replace the original inequality by equivalent one */
            npp_erase_row(npp, row);
            row->lb = b, row->ub = +DBL_MAX;
            for (e = ptr; e != NULL; e = e->next)
               npp_add_aij(npp, row, e->xj, e->aj);
            /* continue processing upper bound for the copy */
            if (copy != NULL) row = copy;
         }
         drop_form(npp, ptr);
      }
      return count;
}
Example #4
0
int npp_reduce_ineq_coef(NPP *npp, NPPROW *row)
{     /* reduce inequality constraint coefficients */
      NPPROW *copy;
      NPPAIJ *aij;
      struct elem *ptr, *e;
      int kase, count[2];
      double b;
      /* the row must be inequality constraint */
      xassert(row->lb < row->ub);
      count[0] = count[1] = 0;
      for (kase = 0; kase <= 1; kase++)
      {  if (kase == 0)
         {  /* process row lower bound */
            if (row->lb == -DBL_MAX) continue;
#ifdef GLP_DEBUG
            xprintf("L");
#endif
            ptr = copy_form(npp, row, +1.0);
            b = + row->lb;
         }
         else
         {  /* process row upper bound */
            if (row->ub == +DBL_MAX) continue;
#ifdef GLP_DEBUG
            xprintf("U");
#endif
            ptr = copy_form(npp, row, -1.0);
            b = - row->ub;
         }
         /* now the inequality has the form "sum a[j] x[j] >= b" */
         count[kase] = reduce_ineq_coef(npp, ptr, &b);
         if (count[kase] > 0)
         {  /* the original inequality has been replaced by equivalent
               one with coefficients reduced */
            if (row->lb == -DBL_MAX || row->ub == +DBL_MAX)
            {  /* the original row is single-sided inequality; no copy
                  is needed */
               copy = NULL;
            }
            else
            {  /* the original row is double-sided inequality; we need
                  to create its copy for other bound before replacing it
                  with the equivalent inequality */
#ifdef GLP_DEBUG
               xprintf("*");
#endif
               copy = npp_add_row(npp);
               if (kase == 0)
               {  /* the copy is for upper bound */
                  copy->lb = -DBL_MAX, copy->ub = row->ub;
               }
               else
               {  /* the copy is for lower bound */
                  copy->lb = row->lb, copy->ub = +DBL_MAX;
               }
               /* copy original row coefficients */
               for (aij = row->ptr; aij != NULL; aij = aij->r_next)
                  npp_add_aij(npp, copy, aij->col, aij->val);
            }
            /* replace the original inequality by equivalent one */
            npp_erase_row(npp, row);
            row->lb = b, row->ub = +DBL_MAX;
            for (e = ptr; e != NULL; e = e->next)
               npp_add_aij(npp, row, e->xj, e->aj);
            /* continue processing upper bound for the copy */
            if (copy != NULL) row = copy;
         }
         drop_form(npp, ptr);
      }
      return count[0] + count[1];
}
Example #5
0
int npp_binarize_prob(NPP *npp)
{     /* binarize MIP problem */
      struct binarize *info;
      NPPROW *row;
      NPPCOL *col, *bin;
      NPPAIJ *aij;
      int u, n, k, temp, nfails, nvars, nbins, nrows;
      /* new variables will be added to the end of the column list, so
         we go from the end to beginning of the column list */
      nfails = nvars = nbins = nrows = 0;
      for (col = npp->c_tail; col != NULL; col = col->prev)
      {  /* skip continuous variable */
         if (!col->is_int) continue;
         /* skip fixed variable */
         if (col->lb == col->ub) continue;
         /* skip binary variable */
         if (col->lb == 0.0 && col->ub == 1.0) continue;
         /* check if the transformation is applicable */
         if (col->lb < -1e6 || col->ub > +1e6 ||
             col->ub - col->lb > 4095.0)
         {  /* unfortunately, not */
            nfails++;
            continue;
         }
         /* process integer non-binary variable x[q] */
         nvars++;
         /* make x[q] non-negative, if its lower bound is non-zero */
         if (col->lb != 0.0)
            npp_lbnd_col(npp, col);
         /* now 0 <= x[q] <= u[q] */
         xassert(col->lb == 0.0);
         u = (int)col->ub;
         xassert(col->ub == (double)u);
         /* if x[q] is binary, further processing is not needed */
         if (u == 1) continue;
         /* determine smallest n such that u <= 2^n - 1 (thus, n is the
            number of binary variables needed) */
         n = 2, temp = 4;
         while (u >= temp)
            n++, temp += temp;
         nbins += n;
         /* create transformation stack entry */
         info = npp_push_tse(npp,
            rcv_binarize_prob, sizeof(struct binarize));
         info->q = col->j;
         info->j = 0; /* will be set below */
         info->n = n;
         /* if u < 2^n - 1, we need one additional row for (4) */
         if (u < temp - 1)
         {  row = npp_add_row(npp), nrows++;
            row->lb = -DBL_MAX, row->ub = u;
         }
         else
            row = NULL;
         /* in the transformed problem variable x[q] becomes binary
            variable x[0], so its objective and constraint coefficients
            are not changed */
         col->ub = 1.0;
         /* include x[0] into constraint (4) */
         if (row != NULL)
            npp_add_aij(npp, row, col, 1.0);
         /* add other binary variables x[1], ..., x[n-1] */
         for (k = 1, temp = 2; k < n; k++, temp += temp)
         {  /* add new binary variable x[k] */
            bin = npp_add_col(npp);
            bin->is_int = 1;
            bin->lb = 0.0, bin->ub = 1.0;
            bin->coef = (double)temp * col->coef;
            /* store column reference number for x[1] */
            if (info->j == 0)
               info->j = bin->j;
            else
               xassert(info->j + (k-1) == bin->j);
            /* duplicate constraint coefficients for x[k]; this also
               automatically includes x[k] into constraint (4) */
            for (aij = col->ptr; aij != NULL; aij = aij->c_next)
               npp_add_aij(npp, aij->row, bin, (double)temp * aij->val);
         }
      }
      if (nvars > 0)
         xprintf("%d integer variable(s) were replaced by %d binary one"
            "s\n", nvars, nbins);
      if (nrows > 0)
         xprintf("%d row(s) were added due to binarization\n", nrows);
      if (nfails > 0)
         xprintf("Binarization failed for %d integer variable(s)\n",
            nfails);
      return nfails;
}