コード例 #1
0
ファイル: glplpx01.c プロジェクト: BohanHsu/developer
int lpx_eval_tab_row(LPX *lp, int k, int ind[], double val[])
{     /* compute row of the simplex tableau */
      return glp_eval_tab_row(lp, k, ind, val);
}
コード例 #2
0
ファイル: gmicut.c プロジェクト: firedrakeproject/glpk
int glp_gmi_cut(glp_prob *P, int j,
      int ind[/*1+n*/], double val[/*1+n*/], double phi[/*1+m+n*/])
{     int m = P->m;
      int n = P->n;
      GLPROW *row;
      GLPCOL *col;
      GLPAIJ *aij;
      int i, k, len, kind, stat;
      double lb, ub, alfa, beta, ksi, phi1, rhs;
      /* sanity checks */
      if (!(P->m == 0 || P->valid))
      {  /* current basis factorization is not valid */
         return -1;
      }
      if (!(P->pbs_stat == GLP_FEAS && P->dbs_stat == GLP_FEAS))
      {  /* current basic solution is not optimal */
         return -2;
      }
      if (!(1 <= j && j <= n))
      {  /* column ordinal number is out of range */
         return -3;
      }
      col = P->col[j];
      if (col->kind != GLP_IV)
      {  /* x[j] is not of integral kind */
         return -4;
      }
      if (col->type == GLP_FX || col->stat != GLP_BS)
      {  /* x[j] is either fixed or non-basic */
         return -5;
      }
      if (fabs(col->prim - floor(col->prim + 0.5)) < 0.001)
      {  /* primal value of x[j] is too close to nearest integer */
         return -6;
      }
      /* compute row of the simplex tableau, which (row) corresponds
       * to specified basic variable xB[i] = x[j]; see (23) */
      len = glp_eval_tab_row(P, m+j, ind, val);
      /* determine beta[i], which a value of xB[i] in optimal solution
       * to current LP relaxation; note that this value is the same as
       * if it would be computed with formula (27); it is assumed that
       * beta[i] is fractional enough */
      beta = P->col[j]->prim;
      /* compute cut coefficients phi and right-hand side rho, which
       * correspond to formula (30); dense format is used, because rows
       * of the simplex tableau are usually dense */
      for (k = 1; k <= m+n; k++)
         phi[k] = 0.0;
      rhs = f(beta); /* initial value of rho; see (28), (32) */
      for (j = 1; j <= len; j++)
      {  /* determine original number of non-basic variable xN[j] */
         k = ind[j];
         xassert(1 <= k && k <= m+n);
         /* determine the kind, bounds and current status of xN[j] in
          * optimal solution to LP relaxation */
         if (k <= m)
         {  /* auxiliary variable */
            row = P->row[k];
            kind = GLP_CV;
            lb = row->lb;
            ub = row->ub;
            stat = row->stat;
         }
         else
         {  /* structural variable */
            col = P->col[k-m];
            kind = col->kind;
            lb = col->lb;
            ub = col->ub;
            stat = col->stat;
         }
         /* xN[j] cannot be basic */
         xassert(stat != GLP_BS);
         /* determine row coefficient ksi[i,j] at xN[j]; see (23) */
         ksi = val[j];
         /* if ksi[i,j] is too large in magnitude, report failure */
         if (fabs(ksi) > 1e+05)
            return -7;
         /* if ksi[i,j] is too small in magnitude, skip it */
         if (fabs(ksi) < 1e-10)
            goto skip;
         /* compute row coefficient alfa[i,j] at y[j]; see (26) */
         switch (stat)
         {  case GLP_NF:
               /* xN[j] is free (unbounded) having non-zero ksi[i,j];
                * report failure */
               return -8;
            case GLP_NL:
               /* xN[j] has active lower bound */
               alfa = - ksi;
               break;
            case GLP_NU:
               /* xN[j] has active upper bound */
               alfa = + ksi;
               break;
            case GLP_NS:
               /* xN[j] is fixed; skip it */
               goto skip;
            default:
               xassert(stat != stat);
         }
         /* compute cut coefficient phi'[j] at y[j]; see (21), (28) */
         switch (kind)
         {  case GLP_IV:
               /* y[j] is integer */
               if (fabs(alfa - floor(alfa + 0.5)) < 1e-10)
               {  /* alfa[i,j] is close to nearest integer; skip it */
                  goto skip;
               }
               else if (f(alfa) <= f(beta))
                  phi1 = f(alfa);
               else
                  phi1 = (f(beta) / (1.0 - f(beta))) * (1.0 - f(alfa));
               break;
            case GLP_CV:
               /* y[j] is continuous */
               if (alfa >= 0.0)
                  phi1 = + alfa;
               else
                  phi1 = (f(beta) / (1.0 - f(beta))) * (- alfa);
               break;
            default:
               xassert(kind != kind);
         }
         /* compute cut coefficient phi[j] at xN[j] and update right-
          * hand side rho; see (31), (32) */
         switch (stat)
         {  case GLP_NL:
               /* xN[j] has active lower bound */
               phi[k] = + phi1;
               rhs += phi1 * lb;
               break;
            case GLP_NU:
               /* xN[j] has active upper bound */
               phi[k] = - phi1;
               rhs -= phi1 * ub;
               break;
            default:
               xassert(stat != stat);
         }
skip:    ;
      }
      /* now the cut has the form sum_k phi[k] * x[k] >= rho, where cut
       * coefficients are stored in the array phi in dense format;
       * x[1,...,m] are auxiliary variables, x[m+1,...,m+n] are struc-
       * tural variables; see (30) */
      /* eliminate auxiliary variables in order to express the cut only
       * through structural variables; see (33) */
      for (i = 1; i <= m; i++)
      {  if (fabs(phi[i]) < 1e-10)
            continue;
         /* auxiliary variable x[i] has non-zero cut coefficient */
         row = P->row[i];
         /* x[i] cannot be fixed variable */
         xassert(row->type != GLP_FX);
         /* substitute x[i] = sum_j a[i,j] * x[m+j] */
         for (aij = row->ptr; aij != NULL; aij = aij->r_next)
            phi[m+aij->col->j] += phi[i] * aij->val;
      }
      /* convert the final cut to sparse format and substitute fixed
       * (structural) variables */
      len = 0;
      for (j = 1; j <= n; j++)
      {  if (fabs(phi[m+j]) < 1e-10)
            continue;
         /* structural variable x[m+j] has non-zero cut coefficient */
         col = P->col[j];
         if (col->type == GLP_FX)
         {  /* eliminate x[m+j] */
            rhs -= phi[m+j] * col->lb;
         }
         else
         {  len++;
            ind[len] = j;
            val[len] = phi[m+j];
         }
      }
      if (fabs(rhs) < 1e-12)
         rhs = 0.0;
      ind[0] = 0, val[0] = rhs;
      /* the cut has been successfully generated */
      return len;
}
コード例 #3
0
ファイル: glpios09.c プロジェクト: AlessiaWent/igraph
static int branch_drtom(glp_tree *T, int *_next)
{     glp_prob *mip = T->mip;
      int m = mip->m;
      int n = mip->n;
      char *non_int = T->non_int;
      int j, jj, k, t, next, kase, len, stat, *ind;
      double x, dk, alfa, delta_j, delta_k, delta_z, dz_dn, dz_up,
         dd_dn, dd_up, degrad, *val;
      /* basic solution of LP relaxation must be optimal */
      xassert(glp_get_status(mip) == GLP_OPT);
      /* allocate working arrays */
      ind = xcalloc(1+n, sizeof(int));
      val = xcalloc(1+n, sizeof(double));
      /* nothing has been chosen so far */
      jj = 0, degrad = -1.0;
      /* walk through the list of columns (structural variables) */
      for (j = 1; j <= n; j++)
      {  /* if j-th column is not marked as fractional, skip it */
         if (!non_int[j]) continue;
         /* obtain (fractional) value of j-th column in basic solution
            of LP relaxation */
         x = glp_get_col_prim(mip, j);
         /* since the value of j-th column is fractional, the column is
            basic; compute corresponding row of the simplex table */
         len = glp_eval_tab_row(mip, m+j, ind, val);
         /* the following fragment computes a change in the objective
            function: delta Z = new Z - old Z, where old Z is the
            objective value in the current optimal basis, and new Z is
            the objective value in the adjacent basis, for two cases:
            1) if new upper bound ub' = floor(x[j]) is introduced for
               j-th column (down branch);
            2) if new lower bound lb' = ceil(x[j]) is introduced for
               j-th column (up branch);
            since in both cases the solution remaining dual feasible
            becomes primal infeasible, one implicit simplex iteration
            is performed to determine the change delta Z;
            it is obvious that new Z, which is never better than old Z,
            is a lower (minimization) or upper (maximization) bound of
            the objective function for down- and up-branches. */
         for (kase = -1; kase <= +1; kase += 2)
         {  /* if kase < 0, the new upper bound of x[j] is introduced;
               in this case x[j] should decrease in order to leave the
               basis and go to its new upper bound */
            /* if kase > 0, the new lower bound of x[j] is introduced;
               in this case x[j] should increase in order to leave the
               basis and go to its new lower bound */
            /* apply the dual ratio test in order to determine which
               auxiliary or structural variable should enter the basis
               to keep dual feasibility */
            k = glp_dual_rtest(mip, len, ind, val, kase, 1e-9);
            if (k != 0) k = ind[k];
            /* if no non-basic variable has been chosen, LP relaxation
               of corresponding branch being primal infeasible and dual
               unbounded has no primal feasible solution; in this case
               the change delta Z is formally set to infinity */
            if (k == 0)
            {  delta_z =
                  (T->mip->dir == GLP_MIN ? +DBL_MAX : -DBL_MAX);
               goto skip;
            }
            /* row of the simplex table that corresponds to non-basic
               variable x[k] choosen by the dual ratio test is:
                  x[j] = ... + alfa * x[k] + ...
               where alfa is the influence coefficient (an element of
               the simplex table row) */
            /* determine the coefficient alfa */
            for (t = 1; t <= len; t++) if (ind[t] == k) break;
            xassert(1 <= t && t <= len);
            alfa = val[t];
            /* since in the adjacent basis the variable x[j] becomes
               non-basic, knowing its value in the current basis we can
               determine its change delta x[j] = new x[j] - old x[j] */
            delta_j = (kase < 0 ? floor(x) : ceil(x)) - x;
            /* and knowing the coefficient alfa we can determine the
               corresponding change delta x[k] = new x[k] - old x[k],
               where old x[k] is a value of x[k] in the current basis,
               and new x[k] is a value of x[k] in the adjacent basis */
            delta_k = delta_j / alfa;
            /* Tomlin noticed that if the variable x[k] is of integer
               kind, its change cannot be less (eventually) than one in
               the magnitude */
            if (k > m && glp_get_col_kind(mip, k-m) != GLP_CV)
            {  /* x[k] is structural integer variable */
               if (fabs(delta_k - floor(delta_k + 0.5)) > 1e-3)
               {  if (delta_k > 0.0)
                     delta_k = ceil(delta_k);  /* +3.14 -> +4 */
                  else
                     delta_k = floor(delta_k); /* -3.14 -> -4 */
               }
            }
            /* now determine the status and reduced cost of x[k] in the
               current basis */
            if (k <= m)
            {  stat = glp_get_row_stat(mip, k);
               dk = glp_get_row_dual(mip, k);
            }
            else
            {  stat = glp_get_col_stat(mip, k-m);
               dk = glp_get_col_dual(mip, k-m);
            }
            /* if the current basis is dual degenerate, some reduced
               costs which are close to zero may have wrong sign due to
               round-off errors, so correct the sign of d[k] */
            switch (T->mip->dir)
            {  case GLP_MIN:
                  if (stat == GLP_NL && dk < 0.0 ||
                      stat == GLP_NU && dk > 0.0 ||
                      stat == GLP_NF) dk = 0.0;
                  break;
               case GLP_MAX:
                  if (stat == GLP_NL && dk > 0.0 ||
                      stat == GLP_NU && dk < 0.0 ||
                      stat == GLP_NF) dk = 0.0;
                  break;
               default:
                  xassert(T != T);
            }
            /* now knowing the change of x[k] and its reduced cost d[k]
               we can compute the corresponding change in the objective
               function delta Z = new Z - old Z = d[k] * delta x[k];
               note that due to Tomlin's modification new Z can be even
               worse than in the adjacent basis */
            delta_z = dk * delta_k;
skip:       /* new Z is never better than old Z, therefore the change
               delta Z is always non-negative (in case of minimization)
               or non-positive (in case of maximization) */
            switch (T->mip->dir)
            {  case GLP_MIN: xassert(delta_z >= 0.0); break;
               case GLP_MAX: xassert(delta_z <= 0.0); break;
               default: xassert(T != T);
            }
            /* save the change in the objective fnction for down- and
               up-branches, respectively */
            if (kase < 0) dz_dn = delta_z; else dz_up = delta_z;
         }
         /* thus, in down-branch no integer feasible solution can be
            better than Z + dz_dn, and in up-branch no integer feasible
            solution can be better than Z + dz_up, where Z is value of
            the objective function in the current basis */
         /* following the heuristic by Driebeck and Tomlin we choose a
            column (i.e. structural variable) which provides largest
            degradation of the objective function in some of branches;
            besides, we select the branch with smaller degradation to
            be solved next and keep other branch with larger degradation
            in the active list hoping to minimize the number of further
            backtrackings */
         if (degrad < fabs(dz_dn) || degrad < fabs(dz_up))
         {  jj = j;
            if (fabs(dz_dn) < fabs(dz_up))
            {  /* select down branch to be solved next */
               next = GLP_DN_BRNCH;
               degrad = fabs(dz_up);
            }
            else
            {  /* select up branch to be solved next */
               next = GLP_UP_BRNCH;
               degrad = fabs(dz_dn);
            }
            /* save the objective changes for printing */
            dd_dn = dz_dn, dd_up = dz_up;
            /* if down- or up-branch has no feasible solution, we does
               not need to consider other candidates (in principle, the
               corresponding branch could be pruned right now) */
            if (degrad == DBL_MAX) break;
         }
      }
      /* free working arrays */
      xfree(ind);
      xfree(val);
      /* something must be chosen */
      xassert(1 <= jj && jj <= n);
#if 1 /* 02/XI-2009 */
      if (degrad < 1e-6 * (1.0 + 0.001 * fabs(mip->obj_val)))
      {  jj = branch_mostf(T, &next);
         goto done;
      }
#endif
      if (T->parm->msg_lev >= GLP_MSG_DBG)
      {  xprintf("branch_drtom: column %d chosen to branch on\n", jj);
         if (fabs(dd_dn) == DBL_MAX)
            xprintf("branch_drtom: down-branch is infeasible\n");
         else
            xprintf("branch_drtom: down-branch bound is %.9e\n",
               lpx_get_obj_val(mip) + dd_dn);
         if (fabs(dd_up) == DBL_MAX)
            xprintf("branch_drtom: up-branch   is infeasible\n");
         else
            xprintf("branch_drtom: up-branch   bound is %.9e\n",
               lpx_get_obj_val(mip) + dd_up);
      }
done: *_next = next;
      return jj;
}
コード例 #4
0
ファイル: glpios05.c プロジェクト: AlessiaWent/igraph
static void gen_cut(glp_tree *tree, struct worka *worka, int j)
{     /* this routine tries to generate Gomory's mixed integer cut for
         specified structural variable x[m+j] of integer kind, which is
         basic and has fractional value in optimal solution to current
         LP relaxation */
      glp_prob *mip = tree->mip;
      int m = mip->m;
      int n = mip->n;
      int *ind = worka->ind;
      double *val = worka->val;
      double *phi = worka->phi;
      int i, k, len, kind, stat;
      double lb, ub, alfa, beta, ksi, phi1, rhs;
      /* compute row of the simplex tableau, which (row) corresponds
         to specified basic variable xB[i] = x[m+j]; see (23) */
      len = glp_eval_tab_row(mip, m+j, ind, val);
      /* determine beta[i], which a value of xB[i] in optimal solution
         to current LP relaxation; note that this value is the same as
         if it would be computed with formula (27); it is assumed that
         beta[i] is fractional enough */
      beta = mip->col[j]->prim;
      /* compute cut coefficients phi and right-hand side rho, which
         correspond to formula (30); dense format is used, because rows
         of the simplex tableau is usually dense */
      for (k = 1; k <= m+n; k++) phi[k] = 0.0;
      rhs = f(beta); /* initial value of rho; see (28), (32) */
      for (j = 1; j <= len; j++)
      {  /* determine original number of non-basic variable xN[j] */
         k = ind[j];
         xassert(1 <= k && k <= m+n);
         /* determine the kind, bounds and current status of xN[j] in
            optimal solution to LP relaxation */
         if (k <= m)
         {  /* auxiliary variable */
            GLPROW *row = mip->row[k];
            kind = GLP_CV;
            lb = row->lb;
            ub = row->ub;
            stat = row->stat;
         }
         else
         {  /* structural variable */
            GLPCOL *col = mip->col[k-m];
            kind = col->kind;
            lb = col->lb;
            ub = col->ub;
            stat = col->stat;
         }
         /* xN[j] cannot be basic */
         xassert(stat != GLP_BS);
         /* determine row coefficient ksi[i,j] at xN[j]; see (23) */
         ksi = val[j];
         /* if ksi[i,j] is too large in the magnitude, do not generate
            the cut */
         if (fabs(ksi) > 1e+05) goto fini;
         /* if ksi[i,j] is too small in the magnitude, skip it */
         if (fabs(ksi) < 1e-10) goto skip;
         /* compute row coefficient alfa[i,j] at y[j]; see (26) */
         switch (stat)
         {  case GLP_NF:
               /* xN[j] is free (unbounded) having non-zero ksi[i,j];
                  do not generate the cut */
               goto fini;
            case GLP_NL:
               /* xN[j] has active lower bound */
               alfa = - ksi;
               break;
            case GLP_NU:
               /* xN[j] has active upper bound */
               alfa = + ksi;
               break;
            case GLP_NS:
               /* xN[j] is fixed; skip it */
               goto skip;
            default:
               xassert(stat != stat);
         }
         /* compute cut coefficient phi'[j] at y[j]; see (21), (28) */
         switch (kind)
         {  case GLP_IV:
               /* y[j] is integer */
               if (fabs(alfa - floor(alfa + 0.5)) < 1e-10)
               {  /* alfa[i,j] is close to nearest integer; skip it */
                  goto skip;
               }
               else if (f(alfa) <= f(beta))
                  phi1 = f(alfa);
               else
                  phi1 = (f(beta) / (1.0 - f(beta))) * (1.0 - f(alfa));
               break;
            case GLP_CV:
               /* y[j] is continuous */
               if (alfa >= 0.0)
                  phi1 = + alfa;
               else
                  phi1 = (f(beta) / (1.0 - f(beta))) * (- alfa);
               break;
            default:
               xassert(kind != kind);
         }
         /* compute cut coefficient phi[j] at xN[j] and update right-
            hand side rho; see (31), (32) */
         switch (stat)
         {  case GLP_NL:
               /* xN[j] has active lower bound */
               phi[k] = + phi1;
               rhs += phi1 * lb;
               break;
            case GLP_NU:
               /* xN[j] has active upper bound */
               phi[k] = - phi1;
               rhs -= phi1 * ub;
               break;
            default:
               xassert(stat != stat);
         }
skip:    ;
      }
      /* now the cut has the form sum_k phi[k] * x[k] >= rho, where cut
         coefficients are stored in the array phi in dense format;
         x[1,...,m] are auxiliary variables, x[m+1,...,m+n] are struc-
         tural variables; see (30) */
      /* eliminate auxiliary variables in order to express the cut only
         through structural variables; see (33) */
      for (i = 1; i <= m; i++)
      {  GLPROW *row;
         GLPAIJ *aij;
         if (fabs(phi[i]) < 1e-10) continue;
         /* auxiliary variable x[i] has non-zero cut coefficient */
         row = mip->row[i];
         /* x[i] cannot be fixed */
         xassert(row->type != GLP_FX);
         /* substitute x[i] = sum_j a[i,j] * x[m+j] */
         for (aij = row->ptr; aij != NULL; aij = aij->r_next)
            phi[m+aij->col->j] += phi[i] * aij->val;
      }
      /* convert the final cut to sparse format and substitute fixed
         (structural) variables */
      len = 0;
      for (j = 1; j <= n; j++)
      {  GLPCOL *col;
         if (fabs(phi[m+j]) < 1e-10) continue;
         /* structural variable x[m+j] has non-zero cut coefficient */
         col = mip->col[j];
         if (col->type == GLP_FX)
         {  /* eliminate x[m+j] */
            rhs -= phi[m+j] * col->lb;
         }
         else
         {  len++;
            ind[len] = j;
            val[len] = phi[m+j];
         }
      }
      if (fabs(rhs) < 1e-12) rhs = 0.0;
      /* if the cut inequality seems to be badly scaled, reject it to
         avoid numeric difficulties */
      for (k = 1; k <= len; k++)
      {  if (fabs(val[k]) < 1e-03) goto fini;
         if (fabs(val[k]) > 1e+03) goto fini;
      }
      /* add the cut to the cut pool for further consideration */
#if 0
      ios_add_cut_row(tree, pool, GLP_RF_GMI, len, ind, val, GLP_LO,
         rhs);
#else
      glp_ios_add_row(tree, NULL, GLP_RF_GMI, 0, len, ind, val, GLP_LO,
         rhs);
#endif
fini: return;
}