コード例 #1
0
ファイル: lp_report.c プロジェクト: JensAdamczak/lpSolveAPI
/* Report the traditional tableau corresponding to the current basis */
MYBOOL REPORT_tableau(lprec *lp)
{
  int  j, row_nr, *coltarget;
  LPSREAL *prow = NULL;
  FILE *stream = lp->outstream;

  if(lp->outstream == NULL)
    return(FALSE);

  if(!lp->model_is_valid || !has_BFP(lp) ||
     (get_total_iter(lp) == 0) || (lp->spx_status == NOTRUN)) {
    lp->spx_status = NOTRUN;
    return(FALSE);
  }
  if(!allocREAL(lp, &prow,lp->sum + 1, TRUE)) {
    lp->spx_status = NOMEMORY;
    return(FALSE);
  }

  fprintf(stream, "\n");
  fprintf(stream, "Tableau at iter %.0f:\n", (double) get_total_iter(lp));

  for(j = 1; j <= lp->sum; j++)
    if (!lp->is_basic[j])
      fprintf(stream, "%15d", (j <= lp->rows ?
                               (j + lp->columns) * ((lp->orig_upbo[j] == 0) ||
                                                    (is_chsign(lp, j)) ? 1 : -1) : j - lp->rows) *
                              (lp->is_lower[j] ? 1 : -1));
  fprintf(stream, "\n");

  coltarget = (int *) mempool_obtainVector(lp->workarrays, lp->columns+1, sizeof(*coltarget));
  if(!get_colIndexA(lp, SCAN_USERVARS+USE_NONBASICVARS, coltarget, FALSE)) {
    mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE);
    return(FALSE);
  }
  for(row_nr = 1; (row_nr <= lp->rows + 1); row_nr++) {
    if (row_nr <= lp->rows)
      fprintf(stream, "%3d", (lp->var_basic[row_nr] <= lp->rows ?
                              (lp->var_basic[row_nr] + lp->columns) * ((lp->orig_upbo[lp->var_basic [row_nr]] == 0) ||
                                                                       (is_chsign(lp, lp->var_basic[row_nr])) ? 1 : -1) : lp->var_basic[row_nr] - lp->rows) *
                             (lp->is_lower[lp->var_basic [row_nr]] ? 1 : -1));
    else
      fprintf(stream, "   ");
    bsolve(lp, row_nr <= lp->rows ? row_nr : 0, prow, NULL, lp->epsmachine*DOUBLEROUND, 1.0);
    prod_xA(lp, coltarget, prow, NULL, lp->epsmachine, 1.0,
                                       prow, NULL, MAT_ROUNDDEFAULT);

    for(j = 1; j <= lp->rows + lp->columns; j++)
      if (!lp->is_basic[j])
        fprintf(stream, "%15.7f", prow[j] * (lp->is_lower[j] ? 1 : -1) *
                                            (row_nr <= lp->rows ? 1 : -1));
    fprintf(stream, "%15.7f", lp->rhs[row_nr <= lp->rows ? row_nr : 0] *
                              (double) ((row_nr <= lp->rows) || (is_maxim(lp)) ? 1 : -1));
    fprintf(stream, "\n");
  }
  fflush(stream);

  mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE);
  FREE(prow);
  return(TRUE);
}
コード例 #2
0
ファイル: lp_pricePSE.c プロジェクト: Rafael-Baltazar/jcute
STATIC void updatePricer(lprec *lp, int rownr, int colnr, REAL *pcol, REAL *prow, int *nzprow)
{
  REAL   *vEdge = NULL, cEdge, hold, *newEdge, *w = NULL;
  int    i, m, n, exitcol, errlevel = DETAILED;
  MYBOOL forceRefresh = FALSE, isDual, isDEVEX;

  if(!applyPricer(lp))
    return;

  /* Make sure we have something to update */
  hold = lp->edgeVector[0];
  if(hold < 0)
    return;
  isDual = (MYBOOL) (hold > 0);

  /* Do common initializations and computations */
  m = lp->rows;
  n = lp->sum;
  isDEVEX = is_piv_rule(lp, PRICER_DEVEX);
  exitcol = lp->var_basic[rownr];

  /* Solve/copy Bw = a */
/*  formWeights(lp, colnr, NULL, &w);  Experimental */
  formWeights(lp, colnr, pcol, &w);

  /* Price norms for the dual simplex - the basic columns */
  if(isDual) {
    REAL rw;
    int  targetcol;

    /* Don't need to compute cross-products with DEVEX */
    if(!isDEVEX) {
      allocREAL(lp, &vEdge, m+1, FALSE);

    /* Extract the row of the inverse containing the leaving variable
       and then form the dot products against the other variables, i.e. "Tau" */
#if 0 /* Extract row explicitly */
      bsolve(lp, rownr, vEdge, 0, 0.0);
#else /* Reuse previously extracted row data */
      MEMCOPY(vEdge, prow, m+1);
      vEdge[0] = 0;
#endif
      lp->bfp_ftran_normal(lp, vEdge, NULL);
    }

   /* Deal with the variable entering the basis to become a new leaving candidate */
    cEdge = lp->edgeVector[exitcol];
    rw = w[rownr];
    hold = 1 / rw;
    lp->edgeVector[colnr] = (hold*hold) * cEdge;

   /* Possibly adjust initial value in case of Devex */
    if(isDEVEX && !DEVEX_ENHANCED && (lp->edgeVector[colnr] < DEVEX_MINVALUE))
      lp->edgeVector[colnr] = DEVEX_MINVALUE;

#ifdef Paranoia
    if(lp->edgeVector[colnr] <= lp->epsmachine)
      report(lp, errlevel, "updatePricer: Invalid dual norm %g at entering index %d - iteration %d\n",
                           lp->edgeVector[colnr], rownr, lp->total_iter+lp->current_iter);
#endif

   /* Then loop over all basic variables, but skip the leaving row */
    for(i = 1; i <= m; i++) {
      if(i == rownr)
        continue;
      targetcol = lp->var_basic[i];
      hold = w[i];
      if(hold == 0)
        continue;
      hold /= rw;
      if(fabs(hold) < lp->epsmachine)
        continue;

      newEdge = &(lp->edgeVector[targetcol]);
      *newEdge += (hold*hold) * cEdge;
      if(isDEVEX) {
        if((*newEdge) > DEVEX_RESTARTLIMIT) {
          forceRefresh = TRUE;
          break;
        }
      }
      else {
        *newEdge -= 2*hold*vEdge[i];
#ifdef xxApplySteepestEdgeMinimum
        *newEdge = my_max(*newEdge, hold*hold+1); /* Kludge; use the primal lower bound */
#else
        if(*newEdge <= 0) {
          report(lp, errlevel, "updatePricer: Invalid dual norm %g at index %d - iteration %d\n",
                                *newEdge, i, lp->total_iter+lp->current_iter);
          forceRefresh = TRUE;
          break;
        }
#endif
      }
    }


  }
  /* Price norms for the primal simplex - the non-basic columns */
  else {

    REAL *vTemp, *vAlpha, cAlpha;
    int  *coltarget;

    allocREAL(lp, &vTemp, m+1, TRUE);
    allocREAL(lp, &vAlpha, n+1, TRUE);

    /* Check if we have strategy fallback for the primal */
    if(!isDEVEX)
      isDEVEX = is_piv_mode(lp, PRICE_PRIMALFALLBACK);

    /* Initialize column target array */
    coltarget = (int *) mempool_obtainVector(lp->workarrays, lp->sum+1, sizeof(*coltarget));
    if(!get_colIndexA(lp, SCAN_ALLVARS+USE_NONBASICVARS, coltarget, FALSE)) {
      mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE);
      return;
    }

    /* Don't need to compute cross-products with DEVEX */
    if(!isDEVEX) {
      vEdge = (REAL *) calloc((n + 1), sizeof(*vEdge));

      /* Compute v and then N'v */
      MEMCOPY(vTemp, w, m+1);
      bsolve(lp, -1, vTemp, NULL, lp->epsmachine*DOUBLEROUND, 0.0);
      vTemp[0] = 0;
      prod_xA(lp, coltarget, vTemp, NULL, XRESULT_FREE, lp->epsmachine, 0.0,
                             vEdge, NULL);
    }

    /* Compute Sigma and then Alpha */
    bsolve(lp, rownr, vTemp, NULL, 0*DOUBLEROUND, 0.0);
    vTemp[0] = 0;
    prod_xA(lp, coltarget, vTemp, NULL, XRESULT_FREE, lp->epsmachine, 0.0,
                           vAlpha, NULL);
    mempool_releaseVector(lp->workarrays, (char *) coltarget, FALSE);

    /* Update the squared steepest edge norms; first store some constants */
    cEdge = lp->edgeVector[colnr];
    cAlpha = vAlpha[colnr];

    /* Deal with the variable leaving the basis to become a new entry candidate */
    hold = 1 / cAlpha;
    lp->edgeVector[exitcol] = (hold*hold) * cEdge;

   /* Possibly adjust initial value in case of Devex */
    if(isDEVEX && !DEVEX_ENHANCED && (lp->edgeVector[exitcol] < DEVEX_MINVALUE))
      lp->edgeVector[exitcol] = DEVEX_MINVALUE;

#ifdef Paranoia
    if(lp->edgeVector[exitcol] <= lp->epsmachine)
      report(lp, errlevel, "updatePricer: Invalid primal norm %g at leaving index %d - iteration %d\n",
                          lp->edgeVector[exitcol], exitcol, lp->total_iter+lp->current_iter);
#endif

    /* Then loop over all non-basic variables, but skip the entering column */
    for(i = 1; i <= lp->sum; i++) {
      if(lp->is_basic[i] || (i == colnr))
        continue;
      hold = vAlpha[i];
      if(hold == 0)
        continue;
      hold /= cAlpha;
      if(fabs(hold) < lp->epsmachine)
        continue;

      newEdge = &(lp->edgeVector[i]);
      *newEdge += (hold*hold) * cEdge;
      if(isDEVEX) {
        if((*newEdge) > DEVEX_RESTARTLIMIT) {
          forceRefresh = TRUE;
          break;
        }
      }
      else {
        *newEdge -= 2*hold*vEdge[i];
#ifdef ApplySteepestEdgeMinimum
        *newEdge = my_max(*newEdge, hold*hold+1);
#else
        if(*newEdge < 0) {
          report(lp, errlevel, "updatePricer: Invalid primal norm %g at index %d - iteration %d\n",
                               *newEdge, i, lp->total_iter+lp->current_iter);
          if(lp->spx_trace)
            report(lp, errlevel, "Error detail: (RelAlpha=%g, vEdge=%g, cEdge=%g)\n", hold, vEdge[i], cEdge);
          forceRefresh = TRUE;
          break;
        }
#endif
      }
    }

    FREE(vAlpha);
    FREE(vTemp);

  }

  if(vEdge != NULL)
    FREE(vEdge);
  freeWeights(w);

  if(forceRefresh)
    restartPricer(lp, AUTOMATIC);

}