示例#1
0
void lpx_get_col_info(glp_prob *lp, int j, int *tagx, double *vx,
      double *dx)
{     /* obtain column solution information */
      if (tagx != NULL) *tagx = lpx_get_col_stat(lp, j);
      if (vx != NULL) *vx = lpx_get_col_prim(lp, j);
      if (dx != NULL) *dx = lpx_get_col_dual(lp, j);
      return;
}
示例#2
0
int lpx_dual_ratio_test(LPX *lp, int len, const int ind[],
      const double val[], int how, double tol)
{     int k, m, n, t, q, tagx;
      double dir, alfa_j, abs_alfa_j, big, eps, cbar_j, temp, teta;
      if (!lpx_is_b_avail(lp))
         xfault("lpx_dual_ratio_test: LP basis is not available\n");
      if (lpx_get_dual_stat(lp) != LPX_D_FEAS)
         xfault("lpx_dual_ratio_test: current basic solution is not dua"
            "l feasible\n");
      if (!(how == +1 || how == -1))
         xfault("lpx_dual_ratio_test: how = %d; invalid parameter\n",
            how);
      m = lpx_get_num_rows(lp);
      n = lpx_get_num_cols(lp);
      dir = (lpx_get_obj_dir(lp) == LPX_MIN ? +1.0 : -1.0);
      /* compute the largest absolute value of the specified influence
         coefficients */
      big = 0.0;
      for (t = 1; t <= len; t++)
      {  temp = val[t];
         if (temp < 0.0) temp = - temp;
         if (big < temp) big = temp;
      }
      /* compute the absolute tolerance eps used to skip small entries
         of the row */
      if (!(0.0 < tol && tol < 1.0))
         xfault("lpx_dual_ratio_test: tol = %g; invalid tolerance\n",
            tol);
      eps = tol * (1.0 + big);
      /* initial settings */
      q = 0, teta = DBL_MAX, big = 0.0;
      /* walk through the entries of the specified row */
      for (t = 1; t <= len; t++)
      {  /* get ordinal number of non-basic variable */
         k = ind[t];
         if (!(1 <= k && k <= m+n))
            xfault("lpx_dual_ratio_test: ind[%d] = %d; variable number "
               "out of range\n", t, k);
         if (k <= m)
            tagx = lpx_get_row_stat(lp, k);
         else
            tagx = lpx_get_col_stat(lp, k-m);
         if (tagx == LPX_BS)
            xfault("lpx_dual_ratio_test: ind[%d] = %d; basic variable n"
               "ot allowed\n", t, k);
         /* determine unscaled reduced cost of the non-basic variable
            x[k] = xN[j] in the current basic solution */
         if (k <= m)
            cbar_j = lpx_get_row_dual(lp, k);
         else
            cbar_j = lpx_get_col_dual(lp, k-m);
         /* determine influence coefficient at the non-basic variable
            x[k] = xN[j] in the explicitly specified row and turn to
            the case of increasing the variable y in order to simplify
            program logic */
         alfa_j = (how > 0 ? +val[t] : -val[t]);
         abs_alfa_j = (alfa_j > 0.0 ? +alfa_j : -alfa_j);
         /* analyze main cases */
         switch (tagx)
         {  case LPX_NL:
               /* xN[j] is on its lower bound */
               if (alfa_j < +eps) continue;
               temp = (dir * cbar_j) / alfa_j;
               break;
            case LPX_NU:
               /* xN[j] is on its upper bound */
               if (alfa_j > -eps) continue;
               temp = (dir * cbar_j) / alfa_j;
               break;
            case LPX_NF:
               /* xN[j] is non-basic free variable */
               if (abs_alfa_j < eps) continue;
               temp = 0.0;
               break;
            case LPX_NS:
               /* xN[j] is non-basic fixed variable */
               continue;
            default:
               xassert(tagx != tagx);
         }
         /* if the reduced cost of the variable xN[j] violates its zero
            bound (slightly, because the current basis is assumed to be
            dual feasible), temp is negative; we can think this happens
            due to round-off errors and the reduced cost is exact zero;
            this allows replacing temp by zero */
         if (temp < 0.0) temp = 0.0;
         /* apply the minimal ratio test */
         if (teta > temp || teta == temp && big < abs_alfa_j)
            q = k, teta = temp, big = abs_alfa_j;
      }
      /* return the ordinal number of the chosen non-basic variable */
      return q;
}
示例#3
0
double lpx_eval_degrad(LPX *lp, int len, int ind[], double val[],
      int type, double rhs)
{     int m = lpx_get_num_rows(lp);
      int n = lpx_get_num_cols(lp);
      int dir = lpx_get_obj_dir(lp);
      int q, k;
      double y, delta;
      if (lpx_get_dual_stat(lp) != LPX_D_FEAS)
         fault("lpx_eval_degrad: LP basis is not dual feasible");
      if (!(0 <= len && len <= n))
         fault("lpx_eval_degrad: len = %d; invalid row length", len);
      if (!(type == LPX_LO || type == LPX_UP))
         fault("lpx_eval_degrad: type = %d; invalid row type", type);
      /* compute value of the row auxiliary variable */
      y = lpx_eval_row(lp, len, ind, val);
      /* the inequalitiy constraint is assumed to be violated */
      if (!(type == LPX_LO && y < rhs || type == LPX_UP && y > rhs))
         fault("lpx_eval_degrad: y = %g, rhs = %g; constraint is not vi"
            "olated", y, rhs);
      /* transform the row in order to express y through only non-basic
         variables: y = alfa[1] * xN[1] + ... + alfa[n] * xN[n] */
      len = lpx_transform_row(lp, len, ind, val);
      /* in the adjacent basis y would become non-basic, so in case of
         '>=' it increases and in case of '<=' it decreases; determine
         which non-basic variable x[q], 1 <= q <= m+n, should leave the
         basis to keep dual feasibility */
      q = lpx_dual_ratio_test(lp, len, ind, val,
         type == LPX_LO ? +1 : -1, 1e-7);
      /* q = 0 means no adjacent dual feasible basis exist */
      if (q == 0) return dir == LPX_MIN ? +DBL_MAX : -DBL_MAX;
      /* find the entry corresponding to x[q] in the list */
      for (k = 1; k <= len; k++)
         if (ind[k] == q) break;
      insist(k <= len);
      /* dy = alfa[q] * dx[q], so dx[q] = dy / alfa[q], where dy is a
         change in y, dx[q] is a change in x[q] */
      delta = (rhs - y) / val[k];
#if 0
      /* Tomlin noticed that if the variable x[q] is of integer kind,
         its change cannot be less than one in the magnitude */
      if (q > m && lpx_get_col_kind(lp, q-m) == LPX_IV)
      {  /* x[q] is structural integer variable */
         if (fabs(delta - floor(delta + 0.5)) > 1e-3)
         {  if (delta > 0.0)
               delta = ceil(delta);  /* +3.14 -> +4 */
            else
               delta = floor(delta); /* -3.14 -> -4 */
         }
      }
#endif
      /* dz = lambda[q] * dx[q], where dz is a change in the objective
         function, lambda[q] is a reduced cost of x[q] */
      if (q <= m)
         delta *= lpx_get_row_dual(lp, q);
      else
         delta *= lpx_get_col_dual(lp, q-m);
      /* delta must be >= 0 (in case of minimization) or <= 0 (in case
         of minimization); however, due to round-off errors and finite
         tolerance used to choose x[q], this condition can be slightly
         violated */
      switch (dir)
      {  case LPX_MIN: if (delta < 0.0) delta = 0.0; break;
         case LPX_MAX: if (delta > 0.0) delta = 0.0; break;
         default: insist(dir != dir);
      }
      return delta;
}