Esempio n. 1
0
STATIC int write_lprow(lprec *lp, int rowno, void *userhandle, write_modeldata_func write_modeldata, int maxlen)
{
  int     i, ie, j, nchars;
  REAL    a;
  MATrec  *mat = lp->matA;
  MYBOOL  first = TRUE, elements;

  if(rowno == 0) {
    i = 1;
    ie = lp->columns+1;
  }
  else {
    i = mat->row_end[rowno-1];
    ie = mat->row_end[rowno];
  }
  elements = ie - i;
  if(write_modeldata != NULL) {
    nchars = 0;
    for(; i < ie; i++) {
      if(rowno == 0) {
	j = i;
	a = get_mat(lp, 0, i);
	if(a == 0)
	  continue;
      }
      else {
	j = ROW_MAT_COLNR(i);
	a = ROW_MAT_VALUE(i);
	a = my_chsign(is_chsign(lp, rowno), a);
	a = unscaled_mat(lp, a, rowno, j);
      }
      if(is_splitvar(lp, j))
	continue;
      if(!first)
	nchars += write_data(userhandle, write_modeldata, " ");
      else
	first = FALSE;
      if(a == -1)
	nchars += write_data(userhandle, write_modeldata, "-");
      else if(a == 1)
	nchars += write_data(userhandle, write_modeldata, "+");
      else
	nchars += write_data(userhandle, write_modeldata, "%+.12g ", (double)a);
      nchars += write_data(userhandle, write_modeldata, "%s", get_col_name(lp, j));
      /* Check if we should add a linefeed */
      if((maxlen > 0) && (nchars >= maxlen) && (i < ie-1)) {
	write_data(userhandle, write_modeldata, "%s", "\n");
	nchars = 0;
      }
    }
  }
  return(elements);
}
Esempio n. 2
0
/* 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);
}
Esempio n. 3
0
MYBOOL __WINAPI write_lpex(lprec *lp, void *userhandle, write_modeldata_func write_modeldata)
{
  int    i, j, b,
         nrows = lp->rows,
         ncols = lp->columns,
         nchars, maxlen = LP_MAXLINELEN;
  MYBOOL ok;
  REAL   a;
  char   *ptr;

  if(lp->matA->is_roworder) {
    report(lp, IMPORTANT, "LP_writefile: Cannot write to LP file while in row entry mode.\n");
    return(FALSE);
  }
  if(!mat_validate(lp->matA)) {
    report(lp, IMPORTANT, "LP_writefile: Could not validate the data matrix.\n");
    return(FALSE);
  }

  /* Write name of model */
  ptr = get_lp_name(lp);
  if(ptr != NULL)
    if(*ptr)
      write_lpcomment(userhandle, write_modeldata, ptr, FALSE);
    else
      ptr = NULL;

  /* Write the objective function */
  write_lpcomment(userhandle, write_modeldata, "Objective function", (MYBOOL) (ptr != NULL));
  if(is_maxim(lp))
    write_data(userhandle, write_modeldata, "max: ");
  else
    write_data(userhandle, write_modeldata, "min: ");

  write_lprow(lp, 0, userhandle, write_modeldata, maxlen);
  a = get_rh(lp, 0);
  if(a != 0)
    write_data(userhandle, write_modeldata, " %+.12g", a);
  write_data(userhandle, write_modeldata, ";\n");

  /* Write constraints */
  if(nrows > 0)
    write_lpcomment(userhandle, write_modeldata, "Constraints", TRUE);
  for(j = 1; j <= nrows; j++) {
    if(((lp->names_used) && (lp->row_name[j] != NULL)) || (write_lprow(lp, j, userhandle, NULL, maxlen) == 1))
      ptr = get_row_name(lp, j);
    else
      ptr = NULL;
    if((ptr != NULL) && (*ptr))
      write_data(userhandle, write_modeldata, "%s: ", ptr);

#ifndef SingleBoundedRowInLP
    /* Write the ranged part of the constraint, if specified */
    if ((lp->orig_upbo[j]) && (lp->orig_upbo[j] < lp->infinite)) {
      if(my_chsign(is_chsign(lp, j), lp->orig_rhs[j]) == -lp->infinite)
        write_data(userhandle, write_modeldata, "-Inf %s ", (is_chsign(lp, j)) ? ">=" : "<=");
      else if(my_chsign(is_chsign(lp, j), lp->orig_rhs[j]) == lp->infinite)
        write_data(userhandle, write_modeldata, "+Inf %s ", (is_chsign(lp, j)) ? ">=" : "<=");
      else
        write_data(userhandle, write_modeldata, "%+.12g %s ",
                (lp->orig_upbo[j]-lp->orig_rhs[j]) * (is_chsign(lp, j) ? 1.0 : -1.0) / (lp->scaling_used ? lp->scalars[j] : 1.0),
                (is_chsign(lp, j)) ? ">=" : "<=");
    }
#endif

    if((!write_lprow(lp, j, userhandle, write_modeldata, maxlen)) && (ncols >= 1))
      write_data(userhandle, write_modeldata, "0 %s", get_col_name(lp, 1));

    if(lp->orig_upbo[j] == 0)
      write_data(userhandle, write_modeldata, " =");
    else if(is_chsign(lp, j))
      write_data(userhandle, write_modeldata, " >=");
    else
      write_data(userhandle, write_modeldata, " <=");
    if(fabs(get_rh(lp, j) + lp->infinite) < 1)
      write_data(userhandle, write_modeldata, " -Inf;\n");
    else if(fabs(get_rh(lp, j) - lp->infinite) < 1)
      write_data(userhandle, write_modeldata, " +Inf;\n");
    else
      write_data(userhandle, write_modeldata, " %.12g;\n", get_rh(lp, j));

#ifdef SingleBoundedRowInLP
    /* Write the ranged part of the constraint, if specified */
    if ((lp->orig_upbo[j]) && (lp->orig_upbo[j] < lp->infinite)) {
      if(((lp->names_used) && (lp->row_name[j] != NULL)) || (write_lprow(lp, j, userhandle, NULL, maxlen) == 1))
        ptr = get_row_name(lp, j);
      else
        ptr = NULL;
      if((ptr != NULL) && (*ptr))
        write_data(userhandle, write_modeldata, "%s: ", ptr);
      if((!write_lprow(lp, j, userhandle, write_modeldata, maxlen)) && (get_Ncolumns(lp) >= 1))
        write_data(userhandle, write_modeldata, "0 %s", get_col_name(lp, 1));
      write_data(userhandle, write_modeldata, " %s %g;\n",
                     (is_chsign(lp, j)) ? "<=" : ">=",
                     (lp->orig_upbo[j]-lp->orig_rhs[j]) * (is_chsign(lp, j) ? 1.0 : -1.0) / (lp->scaling_used ? lp->scalars[j] : 1.0));
    }
#endif
  }

  /* Write bounds on variables */
  ok = FALSE;
  for(i = nrows + 1; i <= lp->sum; i++)
    if(!is_splitvar(lp, i - nrows)) {
      if(lp->orig_lowbo[i] == lp->orig_upbo[i]) {
        if(!ok) {
	  write_lpcomment(userhandle, write_modeldata, "Variable bounds", TRUE);
	  ok = TRUE;
	}
        write_data(userhandle, write_modeldata, "%s = %.12g;\n", get_col_name(lp, i - nrows), get_upbo(lp, i - nrows));
      }
      else {
#ifndef SingleBoundedRowInLP
        if((lp->orig_lowbo[i] != 0) && (lp->orig_upbo[i] < lp->infinite)) {
          if(!ok) {
	    write_lpcomment(userhandle, write_modeldata, "Variable bounds", TRUE);
	    ok = TRUE;
	  }
          if(lp->orig_lowbo[i] == -lp->infinite)
            write_data(userhandle, write_modeldata, "-Inf");
          else
            write_data(userhandle, write_modeldata, "%.12g", get_lowbo(lp, i - nrows));
          write_data(userhandle, write_modeldata, " <= %s <= ", get_col_name(lp, i - nrows));
          if(lp->orig_lowbo[i] == lp->infinite)
            write_data(userhandle, write_modeldata, "+Inf");
          else
            write_data(userhandle, write_modeldata, "%.12g", get_upbo(lp, i - nrows));
          write_data(userhandle, write_modeldata, ";\n");
	}
        else
#endif
        {
          if(lp->orig_lowbo[i] != 0) {
            if(!ok) {
	      write_lpcomment(userhandle, write_modeldata, "Variable bounds", TRUE);
	      ok = TRUE;
	    }
      	    if(lp->orig_lowbo[i] == -lp->infinite)
	      write_data(userhandle, write_modeldata, "%s >= -Inf;\n", get_col_name(lp, i - nrows));
      	    else if(lp->orig_lowbo[i] == lp->infinite)
	      write_data(userhandle, write_modeldata, "%s >= +Inf;\n", get_col_name(lp, i - nrows));
	    else
              write_data(userhandle, write_modeldata, "%s >= %.12g;\n",
                              get_col_name(lp, i - nrows), get_lowbo(lp, i - nrows));
	  }
	  if(lp->orig_upbo[i] != lp->infinite) {
            if(!ok) {
	      write_lpcomment(userhandle, write_modeldata, "Variable bounds", TRUE);
	      ok = TRUE;
	    }
            write_data(userhandle, write_modeldata, "%s <= %.12g;\n",
                            get_col_name(lp, i - nrows), get_upbo(lp, i - nrows));
	  }
        }
      }
    }

  /* Write optional integer section */
  if(lp->int_vars > 0) {
    write_lpcomment(userhandle, write_modeldata, "Integer definitions", TRUE);
    i = 1;
    while((i <= ncols) && !is_int(lp, i))
      i++;
    if(i <= ncols) {
      nchars = write_data(userhandle, write_modeldata, "int %s", get_col_name(lp, i));
      i++;
      for(; i <= ncols; i++)
        if((!is_splitvar(lp, i)) && (is_int(lp, i))) {
          if((maxlen!= 0) && (nchars > maxlen)) {
            write_data(userhandle, write_modeldata, "%s", "\n");
            nchars = 0;
          }
          write_data(userhandle, write_modeldata, ",%s", get_col_name(lp, i));
        }
      write_data(userhandle, write_modeldata, ";\n");
    }
  }

  /* Write optional SEC section */
  if(lp->sc_vars > 0) {
    write_lpcomment(userhandle, write_modeldata, "Semi-continuous variables", TRUE);
    i = 1;
    while((i <= ncols) && !is_semicont(lp, i))
      i++;
    if(i <= ncols) {
      nchars = write_data(userhandle, write_modeldata, "sec %s", get_col_name(lp, i));
      i++;
      for(; i <= ncols; i++)
        if((!is_splitvar(lp, i)) && (is_semicont(lp, i))) {
          if((maxlen != 0) && (nchars > maxlen)) {
            write_data(userhandle, write_modeldata, "%s", "\n");
            nchars = 0;
          }
          nchars += write_data(userhandle, write_modeldata, ",%s", get_col_name(lp, i));
        }
      write_data(userhandle, write_modeldata, ";\n");
    }
  }

  /* Write optional SOS section */
  if(SOS_count(lp) > 0) {
    SOSgroup *SOS = lp->SOS;
    write_lpcomment(userhandle, write_modeldata, "SOS definitions", TRUE);
    write_data(userhandle, write_modeldata, "SOS\n");
    for(b = 0, i = 0; i < SOS->sos_count; b = SOS->sos_list[i]->priority, i++) {
      nchars = write_data(userhandle, write_modeldata, "%s: ",
              (SOS->sos_list[i]->name == NULL) ||
              (*SOS->sos_list[i]->name==0) ? "SOS" : SOS->sos_list[i]->name); /* formatnumber12((double) lp->sos_list[i]->priority) */

      for(a = 0.0, j = 1; j <= SOS->sos_list[i]->size; a = SOS->sos_list[i]->weights[j], j++) {
        if((maxlen != 0) && (nchars > maxlen)) {
          write_data(userhandle, write_modeldata, "%s", "\n");
          nchars = 0;
        }
        if(SOS->sos_list[i]->weights[j] == ++a)
          nchars += write_data(userhandle, write_modeldata, "%s%s",
                  (j > 1) ? "," : "",
                  get_col_name(lp, SOS->sos_list[i]->members[j]));
        else
          nchars += write_data(userhandle, write_modeldata, "%s%s:%.12g",
                  (j > 1) ? "," : "",
                  get_col_name(lp, SOS->sos_list[i]->members[j]),
		  SOS->sos_list[i]->weights[j]);
      }
      if(SOS->sos_list[i]->priority == ++b)
        nchars += write_data(userhandle, write_modeldata, " <= %d;\n", SOS->sos_list[i]->type);
      else
        nchars += write_data(userhandle, write_modeldata, " <= %d:%d;\n", SOS->sos_list[i]->type, SOS->sos_list[i]->priority);
    }
  }

  ok = TRUE;

  return(ok);
}
Esempio n. 4
0
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector)
{
  MYBOOL *isnz = NULL, status = FALSE;
  REAL   *values = NULL, *violation = NULL,
         eps = lp->epsprimal,
         *value, error, upB, loB, sortorder = -1.0;
  int    i, j, jj, n, *rownr, *colnr, *slkpos = NULL,
         nrows = lp->rows, ncols = lp->columns, nsum = lp->sum;
  int    *basisnr;
  MATrec *mat = lp->matA;

  if(!mat_validate(mat))
    return( status );

  /* Create helper arrays, providing for multiple use of the violation array */
  if(!allocREAL(lp, &values, nsum+1, TRUE) ||
     !allocREAL(lp, &violation, nsum+1, TRUE))
    goto Finish;

  /* Compute the values of the constraints for the given guess vector */
  i = 0;
  n = get_nonzeros(lp);
  rownr = &COL_MAT_ROWNR(i);
  colnr = &COL_MAT_COLNR(i);
  value = &COL_MAT_VALUE(i);
  for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep)
    values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) *
                      guessvector[*colnr];
  MEMMOVE(values+nrows+1, guessvector+1, ncols);

  /* Initialize bound "violation" or primal non-degeneracy measures, expressed
     as the absolute value of the differences from the closest bound. */
  for(i = 1; i <= nsum; i++) {
    if(i <= nrows) {
      loB = get_rh_lower(lp, i);
      upB = get_rh_upper(lp, i);
    }
    else {
      loB = get_lowbo(lp, i-nrows);
      upB = get_upbo(lp, i-nrows);
    }

    /* Free constraints/variables */
    if(my_infinite(lp, loB) && my_infinite(lp, upB))
      error = 0;
    /* Violated constraints/variable bounds */
    else if(values[i]+eps < loB)
      error = loB-values[i];
    else if(values[i]-eps > upB)
      error = values[i]-upB;
    /* Non-violated constraints/variables bounds */
    else if(my_infinite(lp, upB))
      error = MAX(0, values[i]-loB);
    else if(my_infinite(lp, loB))
      error = MAX(0, upB-values[i]);
    else
      error = MIN(upB-values[i], values[i]-loB); /* MAX(upB-values[i], values[i]-loB); */
    if(error != 0)
      violation[i] = sortorder*error;
    basisvector[i] = i;
  }

  /* Sort decending , meaning that variables with the largest
     "violations" will be designated basic. Effectively, we are performing a
     greedy type algorithm, but start at the "least interesting" end. */
  sortByREAL(basisvector, violation, nsum, 1, FALSE);
  error = violation[1]; /* Used for setting the return value */

  /* Let us check for obvious row singularities and try to fix these.
     Note that we reuse the memory allocated to the violation array.
     First assemble necessary basis statistics... */
  slkpos = (int *) violation;
  n = nrows+1;
  MEMCLEAR(slkpos, n);
  isnz = (MYBOOL *) (slkpos+n+1);
  MEMCLEAR(isnz, n);
  for(i = 1; i <= nrows; i++) {
    j = abs(basisvector[i]);
    if(j <= nrows) {
      isnz[j] = TRUE;
      slkpos[j] = i;
    }
    else {
      j-= nrows;
      jj = mat->col_end[j-1];
      jj = COL_MAT_ROWNR(jj);
      isnz[jj] = TRUE;
    }
  }
  for(; i <= nsum; i++) {
    j = abs(basisvector[i]);
    if(j <= nrows)
      slkpos[j] = i;
  }

  /* ...then set the corresponding slacks basic for row rank deficient positions */
  for(j = 1; j <= nrows; j++) {
    if(slkpos[j] == 0)
      report(lp, SEVERE, "guess_basis: Internal error");
    if(!isnz[j]) {
      isnz[j] = TRUE;
      i = slkpos[j];
      swapINT(&basisvector[i], &basisvector[j]);
      basisvector[j] = abs(basisvector[j]);
    }
  }

  /* Adjust the non-basic indeces for the (proximal) bound state */
  for(i = nrows+1, basisnr = basisvector+i; i <= nsum; i++, basisnr++) {
    n = *basisnr;
    if(n <= nrows) {
      values[n] -= get_rh_lower(lp, n);
      if(values[n] <= eps)
        *basisnr = -(*basisnr);
    }
    else
      if(values[n]-eps <= get_lowbo(lp, n-nrows))
        *basisnr = -(*basisnr);
  }

/* Lastly normalize all basic variables to be coded as lower-bounded,
   or effectively zero-based in the case of free variables. */
  for(i = 1; i <= nrows; i++)
    basisvector[i] = -abs(basisvector[i]);

  /* Clean up and return status */
  status = (MYBOOL) (error <= eps);
Finish:
  FREE(values);
  FREE(violation);

  return( status );
}
Esempio n. 5
0
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector)
{
  MYBOOL *isnz, status = FALSE;
  REAL   *values = NULL, *violation = NULL,
         eps = lp->epsprimal,
         *value, error, upB, loB, sortorder = 1.0;
  int    i, j, jj, n, *rownr, *colnr, *slkpos,
         nrows = lp->rows, ncols = lp->columns;
  MATrec *mat = lp->matA;

  if(!mat_validate(mat))
    return( status );

  /* Create helper arrays */
  if(!allocREAL(lp, &values, lp->sum+1, TRUE) ||
     !allocREAL(lp, &violation, lp->sum+1, TRUE))
    goto Finish;

  /* Compute values of slack variables for given guess vector */
  i = 0;
  n = get_nonzeros(lp);
  rownr = &COL_MAT_ROWNR(i);
  colnr = &COL_MAT_COLNR(i);
  value = &COL_MAT_VALUE(i);
  for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep)
    values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) *
                      guessvector[*colnr];
  MEMMOVE(values+nrows+1, guessvector+1, ncols);

  /* Initialize constraint bound violation measures (expressed as positive values) */
  for(i = 1; i <= nrows; i++) {
    upB = get_rh_upper(lp, i);
    loB = get_rh_lower(lp, i);
    error = values[i] - upB;
    if(error > -eps)
      violation[i] = sortorder*MAX(0,error);
    else {
      error = loB - values[i];
      if(error > -eps)
        violation[i] = sortorder*MAX(0,error);
      else if(my_infinite(lp, loB) && my_infinite(lp, upB))
        ;
      else if(my_infinite(lp, upB))
        violation[i] = sortorder*(loB - values[i]);
      else if(my_infinite(lp, loB))
        violation[i] = sortorder*(values[i] - upB);
      else
        violation[i] = -sortorder*MAX(upB - values[i], values[i] - loB);
    }
    basisvector[i] = i;
  }

  /* Initialize user variable bound violation measures (expressed as positive values) */
  for(i = 1; i <= ncols; i++) {
    n = nrows+i;
    upB = get_upbo(lp, i);
    loB = get_lowbo(lp, i);
    error = guessvector[i] - upB;
    if(error > -eps)
      violation[n] = sortorder*MAX(0,error);
    else {
      error = loB - values[n];
      if(error > -eps)
        violation[n] = sortorder*MAX(0,error);
      else if(my_infinite(lp, loB) && my_infinite(lp, upB))
        ;
      else if(my_infinite(lp, upB))
        violation[n] = sortorder*(loB - values[n]);
      else if(my_infinite(lp, loB))
        violation[n] = sortorder*(values[n] - upB);
      else
        violation[n] = -sortorder*MAX(upB - values[n], values[n] - loB);
    }
    basisvector[n] = n;
  }

  /* Sort decending by violation; this means that variables with
     the largest violations will be designated as basic */
  sortByREAL(basisvector, violation, lp->sum, 1, FALSE);
  error = violation[1];

  /* Adjust the non-basic indeces for the (proximal) bound state */
  for(i = nrows+1, rownr = basisvector+i; i <= lp->sum; i++, rownr++) {
    if(*rownr <= nrows) {
      values[*rownr] -= lp->orig_rhs[*rownr];
      if(values[*rownr] <= eps)
        *rownr = -(*rownr);
    }
    else
      if(values[i] <= get_lowbo(lp, (*rownr)-nrows)+eps)
        *rownr = -(*rownr);
  }

  /* Let us check for obvious row singularities and try to fix these;
     First assemble necessary basis statistics... */
  isnz = (MYBOOL *) values;
  MEMCLEAR(isnz, nrows+1);
  slkpos = (int *) violation;
  MEMCLEAR(slkpos, nrows+1);
  for(i = 1; i <= nrows; i++) {
    j = abs(basisvector[i]);
    if(j <= nrows) {
      isnz[j] = TRUE;
      slkpos[j] = i;
    }
    else {
      j-= nrows;
      jj = mat->col_end[j-1];
      isnz[COL_MAT_ROWNR(jj)] = TRUE;
/*      if(++jj < mat->col_end[j])
        isnz[COL_MAT_ROWNR(jj)] = TRUE; */
    }
  }
  for(; i <= lp->sum; i++) {
    j = abs(basisvector[i]);
    if(j <= nrows)
      slkpos[j] = i;
  }

  /* ...then set the corresponding slacks basic for row rank deficient positions */
  for(j = 1; j <= nrows; j++) {
#ifdef Paranoia
    if(slkpos[j] == 0)
      report(lp, SEVERE, "guess_basis: Internal error");
#endif
    if(!isnz[j]) {
      isnz[j] = TRUE;
      i = slkpos[j];
      swapINT(&basisvector[i], &basisvector[j]);
      basisvector[j] = abs(basisvector[j]);
    }
  }

  /* Lastly normalize all basic variables to be coded as lower-bounded */
  for(i = 1; i <= nrows; i++)
    basisvector[i] = -abs(basisvector[i]);

  /* Clean up and return status */
  status = (MYBOOL) (error <= eps);
Finish:
  FREE(values);
  FREE(violation);

  return( status );
}
Esempio n. 6
0
MYBOOL __WINAPI guess_basis(lprec *lp, REAL *guessvector, int *basisvector)
{
  MYBOOL status = FALSE;
  REAL   *values = NULL, *violation = NULL,
         *value, error, upB, loB, sortorder = 1.0;
  int    i, n, *rownr, *colnr;
  MATrec *mat = lp->matA;

  if(!mat_validate(lp->matA))
    return( status );

  /* Create helper arrays */
  if(!allocREAL(lp, &values, lp->sum+1, TRUE) ||
     !allocREAL(lp, &violation, lp->sum+1, TRUE))
    goto Finish;

  /* Compute values of slack variables for given guess vector */
  i = 0;
  n = get_nonzeros(lp);
  rownr = &COL_MAT_ROWNR(i);
  colnr = &COL_MAT_COLNR(i);
  value = &COL_MAT_VALUE(i);
  for(; i < n; i++, rownr += matRowColStep, colnr += matRowColStep, value += matValueStep)
    values[*rownr] += unscaled_mat(lp, my_chsign(is_chsign(lp, *rownr), *value), *rownr, *colnr) *
                      guessvector[*colnr];
  MEMMOVE(values+lp->rows+1, guessvector+1, lp->columns);

  /* Initialize constraint bound violation measures */
  for(i = 1; i <= lp->rows; i++) {
    upB = get_rh_upper(lp, i);
    loB = get_rh_lower(lp, i);
    error = values[i] - upB;
    if(error > lp->epsprimal)
      violation[i] = sortorder*error;
    else {
      error = loB - values[i];
      if(error > lp->epsprimal)
        violation[i] = sortorder*error;
      else if(is_infinite(lp, loB) && is_infinite(lp, upB))
        ;
      else if(is_infinite(lp, upB))
        violation[i] = sortorder*(loB - values[i]);
      else if(is_infinite(lp, loB))
        violation[i] = sortorder*(values[i] - upB);
      else
        violation[i] = - sortorder*MAX(upB - values[i], values[i] - loB);
    }
    basisvector[i] = i;
  }

  /* Initialize user variable bound violation measures */
  for(i = 1; i <= lp->columns; i++) {
    n = lp->rows+i;
    upB = get_upbo(lp, i);
    loB = get_lowbo(lp, i);
    error = guessvector[i] - upB;
    if(error > lp->epsprimal)
      violation[n] = sortorder*error;
    else {
      error = loB - values[n];
      if(error > lp->epsprimal)
        violation[n] = sortorder*error;
      else if(is_infinite(lp, loB) && is_infinite(lp, upB))
        ;
      else if(is_infinite(lp, upB))
        violation[n] = sortorder*(loB - values[n]);
      else if(is_infinite(lp, loB))
        violation[n] = sortorder*(values[n] - upB);
      else
        violation[n] = - sortorder*MAX(upB - values[n], values[n] - loB);
    }
    basisvector[n] = n;
  }

  /* Sort decending by violation; this means that variables with
     the largest violations will be designated as basic */
  sortByREAL(basisvector, violation, lp->sum, 1, FALSE);

  /* Adjust the non-basic indeces for the (proximal) bound state */
  error = lp->epsprimal;
  for(i = lp->rows+1, rownr = basisvector+i; i <= lp->sum; i++, rownr++) {
    if(*rownr <= lp->rows) {
      if(values[*rownr] <= get_rh_lower(lp, *rownr)+error)
        *rownr = -(*rownr);
    }
    else
      if(values[i] <= get_lowbo(lp, (*rownr)-lp->rows)+error)
        *rownr = -(*rownr);
  }

  /* Clean up and return status */
  status = (MYBOOL) (violation[1] == 0);
Finish:
  FREE(values);
  FREE(violation);


  return( status );
}