Example #1
0
STATIC void restartPricer(lprec *lp, MYBOOL isdual)
{
  REAL   *sEdge, seNorm, hold;
  int    i, j, m;
  MYBOOL isDEVEX;

  if(!applyPricer(lp))
    return;

  /* Store the active/current pricing type */
  if(isdual == AUTOMATIC)
    isdual = (MYBOOL) lp->edgeVector[0];
  else
    lp->edgeVector[0] = isdual;

  m = lp->rows;

  /* Determine strategy and check if we have strategy fallback for the primal */
  isDEVEX = is_piv_rule(lp, PRICER_DEVEX);
  if(!isDEVEX && !isdual)
    isDEVEX = is_piv_mode(lp, PRICE_PRIMALFALLBACK);

  /* Check if we only need to do the simple DEVEX initialization */
  if(isDEVEX && !DEVEX_ENHANCED) {
    if(isdual) {
      for(i = 1; i <= m; i++)
        lp->edgeVector[lp->var_basic[i]] = 1.0;
    }
    else {
      for(i = 1; i <= lp->sum; i++)
        if(!lp->is_basic[i])
          lp->edgeVector[i] = 1.0;
    }
    return;
  }

  /* Otherwise do the full Steepest Edge norm initialization */
  sEdge = (REAL *) malloc((m + 1) * sizeof(*sEdge));

  if(isdual) {

   /* Extract the rows of the basis inverse and compute their squared norms */

    for(i = 1; i <= m; i++) {

      bsolve(lp, i, sEdge, NULL, 0, 0.0);

      /* Compute the edge norm */
      seNorm = 0;
      for(j = 1; j <= m; j++) {
        hold = sEdge[j];
        seNorm += hold*hold;
      }

      j = lp->var_basic[i];
      lp->edgeVector[j] = seNorm;
    }

  }
  else {

   /* Solve a=Bb for b over all non-basic variables and compute their squared norms */

    for(i = 1; i <= lp->sum; i++) {
      if(lp->is_basic[i])
        continue;

      fsolve(lp, i, sEdge, NULL, 0, 0.0, FALSE);

      /* Compute the edge norm */
      seNorm = 1;
      for(j = 1; j <= m; j++) {
        hold = sEdge[j];
        seNorm += hold*hold;
      }

      lp->edgeVector[i] = seNorm;
    }

  }

  free(sEdge);

}
Example #2
0
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);

}
Example #3
0
STATIC MYBOOL restartPricer(lprec *lp, MYBOOL isdual)
{
  REAL   *sEdge = NULL, seNorm, hold;
  int    i, j, m;
  MYBOOL isDEVEX, ok = applyPricer(lp);
/* Correction from V6, apparently, via Kjell Eikland and the
** lpSolve mailing list 2014-06-18 2:57 p.m. */

  if (ok && (lp->edgeVector[0] < 0) && (isdual == AUTOMATIC))
    ok = FALSE;


  if(!ok)
    return( ok );

  /* Store the active/current pricing type */
  if(isdual == AUTOMATIC)
    isdual = (MYBOOL) lp->edgeVector[0];
  else
    lp->edgeVector[0] = isdual;

  m = lp->rows;

  /* Determine strategy and check if we have strategy fallback for the primal */
  isDEVEX = is_piv_rule(lp, PRICER_DEVEX);
  if(!isDEVEX && !isdual)
    isDEVEX = is_piv_mode(lp, PRICE_PRIMALFALLBACK);

  /* Check if we only need to do the simple DEVEX initialization */
  if(!is_piv_mode(lp, PRICE_TRUENORMINIT)) {
    if(isdual) {
      for(i = 1; i <= m; i++)
        lp->edgeVector[lp->var_basic[i]] = 1.0;
    }
    else {
      for(i = 1; i <= lp->sum; i++)
        if(!lp->is_basic[i])
          lp->edgeVector[i] = 1.0;
    }
    return( ok );
  }

  /* Otherwise do the full Steepest Edge norm initialization */
  ok = allocREAL(lp, &sEdge, m+1, FALSE);
  if(!ok)
    return( ok );

  if(isdual) {

   /* Extract the rows of the basis inverse and compute their squared norms */

    for(i = 1; i <= m; i++) {

      bsolve(lp, i, sEdge, NULL, 0, 0.0);

      /* Compute the edge norm */
      seNorm = 0;
      for(j = 1; j <= m; j++) {
        hold = sEdge[j];
        seNorm += hold*hold;
      }

      j = lp->var_basic[i];
      lp->edgeVector[j] = seNorm;
    }

  }
  else {

   /* Solve a=Bb for b over all non-basic variables and compute their squared norms */

    for(i = 1; i <= lp->sum; i++) {
      if(lp->is_basic[i])
        continue;

      fsolve(lp, i, sEdge, NULL, 0, 0.0, FALSE);

      /* Compute the edge norm */
      seNorm = 1;
      for(j = 1; j <= m; j++) {
        hold = sEdge[j];
        seNorm += hold*hold;
      }

      lp->edgeVector[i] = seNorm;
    }

  }

  FREE(sEdge);

  return( ok );

}