Example #1
0
void
CoinPackedVector::gutsOfSetConstant(int size,
				   const int * inds, double value,
				   bool testForDuplicateIndex,
				   const char * method)
{
   if ( size != 0 ) {
      reserve(size);
      nElements_ = size;
      CoinDisjointCopyN(inds, size, indices_);
      CoinFillN(elements_, size, value);
      CoinIotaN(origIndices_, size, 0);
   }
   try {
      CoinPackedVectorBase::setTestForDuplicateIndex(testForDuplicateIndex);
   }
   catch (CoinError e) {
      throw CoinError("duplicate index", method, "CoinPackedVector");
   }
}
void CoinPresolveMatrix::setVariableType (bool allIntegers, int lenParam)

{ int len ;

  if (lenParam < 0)
  { len = ncols_ ; }
  else
  if (lenParam > ncols0_)
  { throw CoinError("length exceeds allocated size",
		    "setIntegerType","CoinPresolveMatrix") ; }
  else
  { len = lenParam ; }

  if (integerType_ == 0) integerType_ = new unsigned char [ncols0_] ;

  const unsigned char value = 1 ;

  if (allIntegers == true)
  { CoinFillN(integerType_,len,value) ; }
  else
  { CoinZeroN(integerType_,len) ; }

  return ; }
Example #3
0
int main(int argc, const char *argv[])
{
#if COIN_BIG_INDEX<2
     ClpSimplex  model;
     int status;
     int maxIts = 0;
     int maxFactor = 100;
     if (argc < 2) {
#if defined(SAMPLEDIR)
          status = model.readMps(SAMPLEDIR "/p0033.mps", true);
#else
          fprintf(stderr, "Do not know where to find sample MPS files.\n");
          exit(1);
#endif
     } else
          status = model.readMps(argv[1]);
     if (status) {
          printf("errors on input\n");
          exit(77);
     }
     if (argc > 2) {
          maxFactor = atoi(argv[2]);
          printf("max factor %d\n", maxFactor);
     }
     if (argc > 3) {
          maxIts = atoi(argv[3]);
          printf("max its %d\n", maxIts);
     }
     // For now scaling off
     model.scaling(0);
     if (maxIts) {
          // Do partial dantzig
          ClpPrimalColumnSteepest dantzig(5);
          model.setPrimalColumnPivotAlgorithm(dantzig);
          //model.messageHandler()->setLogLevel(63);
          model.setFactorizationFrequency(maxFactor);
          model.setMaximumIterations(maxIts);
          model.primal();
          if (!model.status())
               exit(1);
     }
     // find gub
     int numberRows = model.numberRows();
     int * gubStart = new int[numberRows+1];
     int * gubEnd = new int[numberRows];
     int * which = new int[numberRows];
     int * whichGub = new int[numberRows];
     int numberColumns = model.numberColumns();
     int * mark = new int[numberColumns];
     int iRow, iColumn;
     // delete variables fixed to zero
     const double * columnLower = model.columnLower();
     const double * columnUpper = model.columnUpper();
     int numberDelete = 0;
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          if (columnUpper[iColumn] == 0.0 && columnLower[iColumn] == 0.0)
               mark[numberDelete++] = iColumn;
     }
     if (numberDelete) {
          model.deleteColumns(numberDelete, mark);
          numberColumns -= numberDelete;
          columnLower = model.columnLower();
          columnUpper = model.columnUpper();
#if 0
          CoinMpsIO writer;
          writer.setMpsData(*model.matrix(), COIN_DBL_MAX,
                            model.getColLower(), model.getColUpper(),
                            model.getObjCoefficients(),
                            (const char*) 0 /*integrality*/,
                            model.getRowLower(), model.getRowUpper(),
                            NULL, NULL);
          writer.writeMps("cza.mps", 0, 0, 1);
#endif
     }
     double * lower = new double[numberRows];
     double * upper = new double[numberRows];
     const double * rowLower = model.rowLower();
     const double * rowUpper = model.rowUpper();
     for (iColumn = 0; iColumn < numberColumns; iColumn++)
          mark[iColumn] = -1;
     CoinPackedMatrix * matrix = model.matrix();
     // get row copy
     CoinPackedMatrix rowCopy = *matrix;
     rowCopy.reverseOrdering();
     const int * column = rowCopy.getIndices();
     const int * rowLength = rowCopy.getVectorLengths();
     const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
     const double * element = rowCopy.getElements();
     int putGub = numberRows;
     int putNonGub = numberRows;
     int * rowIsGub = new int [numberRows];
     for (iRow = numberRows - 1; iRow >= 0; iRow--) {
          bool gubRow = true;
          int first = numberColumns + 1;
          int last = -1;
          for (int j = rowStart[iRow]; j < rowStart[iRow] + rowLength[iRow]; j++) {
               if (element[j] != 1.0) {
                    gubRow = false;
                    break;
               } else {
                    int iColumn = column[j];
                    if (mark[iColumn] >= 0) {
                         gubRow = false;
                         break;
                    } else {
                         last = CoinMax(last, iColumn);
                         first = CoinMin(first, iColumn);
                    }
               }
          }
          if (last - first + 1 != rowLength[iRow] || !gubRow) {
               which[--putNonGub] = iRow;
               rowIsGub[iRow] = 0;
          } else {
               for (int j = rowStart[iRow]; j < rowStart[iRow] + rowLength[iRow]; j++) {
                    int iColumn = column[j];
                    mark[iColumn] = iRow;
               }
               rowIsGub[iRow] = -1;
               putGub--;
               gubStart[putGub] = first;
               gubEnd[putGub] = last + 1;
               lower[putGub] = rowLower[iRow];
               upper[putGub] = rowUpper[iRow];
               whichGub[putGub] = iRow;
          }
     }
     int numberNonGub = numberRows - putNonGub;
     int numberGub = numberRows - putGub;
     if (numberGub > 0) {
          printf("** %d gub rows\n", numberGub);
          int numberNormal = 0;
          const int * row = matrix->getIndices();
          const int * columnLength = matrix->getVectorLengths();
          const CoinBigIndex * columnStart = matrix->getVectorStarts();
          const double * elementByColumn = matrix->getElements();
          int numberElements = 0;
          bool doLower = false;
          bool doUpper = false;
          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
               if (mark[iColumn] < 0) {
                    mark[numberNormal++] = iColumn;
               } else {
                    numberElements += columnLength[iColumn];
                    if (columnLower[iColumn] != 0.0)
                         doLower = true;
                    if (columnUpper[iColumn] < 1.0e20)
                         doUpper = true;
               }
          }
          if (!numberNormal) {
               printf("Putting back one gub row to make non-empty\n");
               for (iColumn = gubStart[putGub]; iColumn < gubEnd[putGub]; iColumn++)
                    mark[numberNormal++] = iColumn;
               putGub++;
               numberGub--;
          }
          ClpSimplex model2(&model, numberNonGub, which + putNonGub, numberNormal, mark);
          int numberGubColumns = numberColumns - numberNormal;
          // sort gubs so monotonic
          int * which = new int[numberGub];
          int i;
          for (i = 0; i < numberGub; i++)
               which[i] = i;
          CoinSort_2(gubStart + putGub, gubStart + putGub + numberGub, which);
          int * temp1 = new int [numberGub];
          for (i = 0; i < numberGub; i++) {
               int k = which[i];
               temp1[i] = gubEnd[putGub+k];
          }
          memcpy(gubEnd + putGub, temp1, numberGub * sizeof(int));
          delete [] temp1;
          double * temp2 = new double [numberGub];
          for (i = 0; i < numberGub; i++) {
               int k = which[i];
               temp2[i] = lower[putGub+k];
          }
          memcpy(lower + putGub, temp2, numberGub * sizeof(double));
          for (i = 0; i < numberGub; i++) {
               int k = which[i];
               temp2[i] = upper[putGub+k];
          }
          memcpy(upper + putGub, temp2, numberGub * sizeof(double));
          delete [] temp2;
          delete [] which;
          numberElements -= numberGubColumns;
          int * start2 = new int[numberGubColumns+1];
          int * row2 = new int[numberElements];
          double * element2 = new double[numberElements];
          double * cost2 = new double [numberGubColumns];
          double * lowerColumn2 = NULL;
          if (doLower) {
               lowerColumn2 = new double [numberGubColumns];
               CoinFillN(lowerColumn2, numberGubColumns, 0.0);
          }
          double * upperColumn2 = NULL;
          if (doUpper) {
               upperColumn2 = new double [numberGubColumns];
               CoinFillN(upperColumn2, numberGubColumns, COIN_DBL_MAX);
          }
          numberElements = 0;
          int numberNonGubRows = 0;
          for (iRow = 0; iRow < numberRows; iRow++) {
               if (!rowIsGub[iRow])
                    rowIsGub[iRow] = numberNonGubRows++;
          }
          numberColumns = 0;
          gubStart[0] = 0;
          start2[0] = 0;
          const double * cost = model.objective();
          for (int iSet = 0; iSet < numberGub; iSet++) {
               int iStart = gubStart[iSet+putGub];
               int iEnd = gubEnd[iSet+putGub];
               for (int k = iStart; k < iEnd; k++) {
                    cost2[numberColumns] = cost[k];
                    if (columnLower[k])
                         lowerColumn2[numberColumns] = columnLower[k];
                    if (columnUpper[k] < 1.0e20)
                         upperColumn2[numberColumns] = columnUpper[k];
                    for (int j = columnStart[k]; j < columnStart[k] + columnLength[k]; j++) {
                         int iRow = rowIsGub[row[j]];
                         if (iRow >= 0) {
                              row2[numberElements] = iRow;
                              element2[numberElements++] = elementByColumn[j];
                         }
                    }
                    start2[++numberColumns] = numberElements;
               }
               gubStart[iSet+1] = numberColumns;
          }
          model2.replaceMatrix(new ClpGubDynamicMatrix(&model2, numberGub,
                               numberColumns, gubStart,
                               lower + putGub, upper + putGub,
                               start2, row2, element2, cost2,
                               lowerColumn2, upperColumn2));
          delete [] rowIsGub;
          delete [] start2;
          delete [] row2;
          delete [] element2;
          delete [] cost2;
          delete [] lowerColumn2;
          delete [] upperColumn2;
          // For now scaling off
          model2.scaling(0);
          // Do partial dantzig
          ClpPrimalColumnSteepest dantzig(5);
          model2.setPrimalColumnPivotAlgorithm(dantzig);
          //model2.messageHandler()->setLogLevel(63);
          model2.setFactorizationFrequency(maxFactor);
          model2.setMaximumIterations(4000000);
          double time1 = CoinCpuTime();
          model2.primal();
          {
               ClpGubDynamicMatrix * gubMatrix =
                    dynamic_cast< ClpGubDynamicMatrix*>(model2.clpMatrix());
               assert(gubMatrix);
               const double * solution = model2.primalColumnSolution();
               int numberGubColumns = gubMatrix->numberGubColumns();
               int firstOdd = gubMatrix->firstDynamic();
               int lastOdd = gubMatrix->firstAvailable();
               int numberTotalColumns = firstOdd + numberGubColumns;
               int numberRows = model2.numberRows();
               char * status = new char [numberTotalColumns];
               double * gubSolution = new double [numberTotalColumns];
               int numberSets = gubMatrix->numberSets();
               const int * id = gubMatrix->id();
               int i;
               const double * lowerColumn = gubMatrix->lowerColumn();
               const double * upperColumn = gubMatrix->upperColumn();
               for (i = 0; i < numberGubColumns; i++) {
                    if (gubMatrix->getDynamicStatus(i) == ClpGubDynamicMatrix::atUpperBound) {
                         gubSolution[i+firstOdd] = upperColumn[i];
                         status[i+firstOdd] = 2;
                    } else if (gubMatrix->getDynamicStatus(i) == ClpGubDynamicMatrix::atLowerBound && lowerColumn) {
                         gubSolution[i+firstOdd] = lowerColumn[i];
                         status[i+firstOdd] = 1;
                    } else {
                         gubSolution[i+firstOdd] = 0.0;
                         status[i+firstOdd] = 1;
                    }
               }
               for (i = 0; i < firstOdd; i++) {
                    ClpSimplex::Status thisStatus = model2.getStatus(i);
                    if (thisStatus == ClpSimplex::basic)
                         status[i] = 0;
                    else if (thisStatus == ClpSimplex::atLowerBound)
                         status[i] = 1;
                    else if (thisStatus == ClpSimplex::atUpperBound)
                         status[i] = 2;
                    else if (thisStatus == ClpSimplex::isFixed)
                         status[i] = 3;
                    else
                         abort();
                    gubSolution[i] = solution[i];
               }
               for (i = firstOdd; i < lastOdd; i++) {
                    int iBig = id[i-firstOdd] + firstOdd;
                    ClpSimplex::Status thisStatus = model2.getStatus(i);
                    if (thisStatus == ClpSimplex::basic)
                         status[iBig] = 0;
                    else if (thisStatus == ClpSimplex::atLowerBound)
                         status[iBig] = 1;
                    else if (thisStatus == ClpSimplex::atUpperBound)
                         status[iBig] = 2;
                    else if (thisStatus == ClpSimplex::isFixed)
                         status[iBig] = 3;
                    else
                         abort();
                    gubSolution[iBig] = solution[i];
               }
               char * rowStatus = new char[numberRows];
               for (i = 0; i < numberRows; i++) {
                    ClpSimplex::Status thisStatus = model2.getRowStatus(i);
                    if (thisStatus == ClpSimplex::basic)
                         rowStatus[i] = 0;
                    else if (thisStatus == ClpSimplex::atLowerBound)
                         rowStatus[i] = 1;
                    else if (thisStatus == ClpSimplex::atUpperBound)
                         rowStatus[i] = 2;
                    else if (thisStatus == ClpSimplex::isFixed)
                         rowStatus[i] = 3;
                    else
                         abort();
               }
               char * setStatus = new char[numberSets];
               int * keyVariable = new int[numberSets];
               memcpy(keyVariable, gubMatrix->keyVariable(), numberSets * sizeof(int));
               for (i = 0; i < numberSets; i++) {
                    int iKey = keyVariable[i];
                    if (iKey > lastOdd)
                         iKey = numberTotalColumns + i;
                    else
                         iKey = id[iKey-firstOdd] + firstOdd;
                    keyVariable[i] = iKey;
                    ClpSimplex::Status thisStatus = gubMatrix->getStatus(i);
                    if (thisStatus == ClpSimplex::basic)
                         setStatus[i] = 0;
                    else if (thisStatus == ClpSimplex::atLowerBound)
                         setStatus[i] = 1;
                    else if (thisStatus == ClpSimplex::atUpperBound)
                         setStatus[i] = 2;
                    else if (thisStatus == ClpSimplex::isFixed)
                         setStatus[i] = 3;
                    else
                         abort();
               }
               FILE * fp = fopen("xx.sol", "w");
               fwrite(gubSolution, sizeof(double), numberTotalColumns, fp);
               fwrite(status, sizeof(char), numberTotalColumns, fp);
               const double * rowsol = model2.primalRowSolution();
               int originalNumberRows = model.numberRows();
               double * rowsol2 = new double[originalNumberRows];
               memset(rowsol2, 0, originalNumberRows * sizeof(double));
               model.times(1.0, gubSolution, rowsol2);
               for (i = 0; i < numberRows; i++)
                    assert(fabs(rowsol[i] - rowsol2[i]) < 1.0e-3);
               //for (;i<originalNumberRows;i++)
               //printf("%d %g\n",i,rowsol2[i]);
               delete [] rowsol2;
               fwrite(rowsol, sizeof(double), numberRows, fp);
               fwrite(rowStatus, sizeof(char), numberRows, fp);
               fwrite(setStatus, sizeof(char), numberSets, fp);
               fwrite(keyVariable, sizeof(int), numberSets, fp);
               fclose(fp);
               delete [] status;
               delete [] gubSolution;
               delete [] setStatus;
               delete [] keyVariable;
               // ** if going to rstart as dynamic need id_
               // also copy coding in useEf.. from ClpGubMatrix (i.e. test for basis)
          }
          printf("obj offset is %g\n", model2.objectiveOffset());
          printf("Primal took %g seconds\n", CoinCpuTime() - time1);
          //model2.primal(1);
     }
     delete [] mark;
     delete [] gubStart;
     delete [] gubEnd;
     delete [] which;
     delete [] whichGub;
     delete [] lower;
     delete [] upper;
#else
     printf("testGub2 not available with COIN_BIG_INDEX=2\n");
#endif
     return 0;
}
Example #4
0
//  factorSparse.  Does sparse phase of factorization
//return code is <0 error, 0= finished
int CoinFactorization::factorSparseSmall()
{
  int *indexRow = indexRowU_.array();
  int *indexColumn = indexColumnU_.array();
  CoinFactorizationDouble *element = elementU_.array();
  int count = 1;
  workArea_.conditionalNew(numberRows_);
  CoinFactorizationDouble *workArea = workArea_.array();
#ifndef NDEBUG
  counter1++;
#endif
  // when to go dense
  int denseThreshold = abs(denseThreshold_);

  CoinZeroN(workArea, numberRows_);
  //get space for bit work area
  int workSize = 1000;
  workArea2_.conditionalNew(workSize);
  unsigned int *workArea2 = workArea2_.array();

  //set markRow so no rows updated
  unsigned short *markRow = reinterpret_cast< unsigned short * >(markRow_.array());
  CoinFillN(markRow, numberRows_, static_cast< unsigned short >(SMALL_UNSET));
  int status = 0;
  //do slacks first
  int *numberInRow = numberInRow_.array();
  int *numberInColumn = numberInColumn_.array();
  int *numberInColumnPlus = numberInColumnPlus_.array();
  int *startColumnU = startColumnU_.array();
  int *startColumnL = startColumnL_.array();
  if (biasLU_ < 3 && numberColumns_ == numberRows_) {
    int iPivotColumn;
    int *pivotColumn = pivotColumn_.array();
    int *nextRow = nextRow_.array();
    int *lastRow = lastRow_.array();
    for (iPivotColumn = 0; iPivotColumn < numberColumns_;
         iPivotColumn++) {
      if (numberInColumn[iPivotColumn] == 1) {
        int start = startColumnU[iPivotColumn];
        CoinFactorizationDouble value = element[start];
        if (value == slackValue_ && numberInColumnPlus[iPivotColumn] == 0) {
          // treat as slack
          int iRow = indexRow[start];
          // but only if row not marked
          if (numberInRow[iRow] > 0) {
            totalElements_ -= numberInRow[iRow];
            //take out this bit of indexColumnU
            int next = nextRow[iRow];
            int last = lastRow[iRow];

            nextRow[last] = next;
            lastRow[next] = last;
            nextRow[iRow] = numberGoodU_; //use for permute
            lastRow[iRow] = -2; //mark
            //modify linked list for pivots
            deleteLink(iRow);
            numberInRow[iRow] = -1;
            numberInColumn[iPivotColumn] = 0;
            numberGoodL_++;
            startColumnL[numberGoodL_] = 0;
            pivotColumn[numberGoodU_] = iPivotColumn;
            numberGoodU_++;
          }
        }
      }
    }
    // redo
    preProcess(4);
    CoinFillN(markRow, numberRows_, static_cast< unsigned short >(SMALL_UNSET));
  }
  numberSlacks_ = numberGoodU_;
  int *nextCount = nextCount_.array();
  int *firstCount = firstCount_.array();
  int *startRow = startRowU_.array();
  int *startColumn = startColumnU;
  //#define UGLY_COIN_FACTOR_CODING
#ifdef UGLY_COIN_FACTOR_CODING
  CoinFactorizationDouble *elementL = elementL_.array();
  int *indexRowL = indexRowL_.array();
  int *saveColumn = saveColumn_.array();
  int *nextRow = nextRow_.array();
  int *lastRow = lastRow_.array();
#endif
  double pivotTolerance = pivotTolerance_;
  int numberTrials = numberTrials_;
  int numberRows = numberRows_;
  // Put column singletons first - (if false)
  separateLinks(1, (biasLU_ > 1));
#ifndef NDEBUG
  int counter2 = 0;
#endif
  while (count <= biggerDimension_) {
#ifndef NDEBUG
    counter2++;
    int badRow = -1;
    if (counter1 == -1 && counter2 >= 0) {
      // check counts consistent
      for (int iCount = 1; iCount < numberRows_; iCount++) {
        int look = firstCount[iCount];
        while (look >= 0) {
          if (look < numberRows_) {
            int iRow = look;
            if (iRow == badRow)
              printf("row count for row %d is %d\n", iCount, iRow);
            if (numberInRow[iRow] != iCount) {
              printf("failed debug on %d entry to factorSparse and %d try\n",
                counter1, counter2);
              printf("row %d - count %d number %d\n", iRow, iCount, numberInRow[iRow]);
              abort();
            }
            look = nextCount[look];
          } else {
            int iColumn = look - numberRows;
            if (numberInColumn[iColumn] != iCount) {
              printf("failed debug on %d entry to factorSparse and %d try\n",
                counter1, counter2);
              printf("column %d - count %d number %d\n", iColumn, iCount, numberInColumn[iColumn]);
              abort();
            }
            look = nextCount[look];
          }
        }
      }
    }
#endif
    int minimumCount = COIN_INT_MAX;
    double minimumCost = COIN_DBL_MAX;

    int iPivotRow = -1;
    int iPivotColumn = -1;
    int pivotRowPosition = -1;
    int pivotColumnPosition = -1;
    int look = firstCount[count];
    int trials = 0;
    int *pivotColumn = pivotColumn_.array();

    if (count == 1 && firstCount[1] >= 0 && !biasLU_) {
      //do column singletons first to put more in U
      while (look >= 0) {
        if (look < numberRows_) {
          look = nextCount[look];
        } else {
          int iColumn = look - numberRows_;

          assert(numberInColumn[iColumn] == count);
          int start = startColumnU[iColumn];
          int iRow = indexRow[start];

          iPivotRow = iRow;
          pivotRowPosition = start;
          iPivotColumn = iColumn;
          assert(iPivotRow >= 0 && iPivotColumn >= 0);
          pivotColumnPosition = -1;
          look = -1;
          break;
        }
      } /* endwhile */
      if (iPivotRow < 0) {
        //back to singletons
        look = firstCount[1];
      }
    }
    while (look >= 0) {
      if (look < numberRows_) {
        int iRow = look;
#ifndef NDEBUG
        if (numberInRow[iRow] != count) {
          printf("failed on %d entry to factorSparse and %d try\n",
            counter1, counter2);
          printf("row %d - count %d number %d\n", iRow, count, numberInRow[iRow]);
          abort();
        }
#endif
        look = nextCount[look];
        bool rejected = false;
        int start = startRow[iRow];
        int end = start + count;

        int i;
        for (i = start; i < end; i++) {
          int iColumn = indexColumn[i];
          assert(numberInColumn[iColumn] > 0);
          double cost = (count - 1) * numberInColumn[iColumn];

          if (cost < minimumCost) {
            int where = startColumn[iColumn];
            double minimumValue = element[where];

            minimumValue = fabs(minimumValue) * pivotTolerance;
            while (indexRow[where] != iRow) {
              where++;
            } /* endwhile */
            assert(where < startColumn[iColumn] + numberInColumn[iColumn]);
            CoinFactorizationDouble value = element[where];

            value = fabs(value);
            if (value >= minimumValue) {
              minimumCost = cost;
              minimumCount = numberInColumn[iColumn];
              iPivotRow = iRow;
              pivotRowPosition = -1;
              iPivotColumn = iColumn;
              assert(iPivotRow >= 0 && iPivotColumn >= 0);
              pivotColumnPosition = i;
              rejected = false;
              if (minimumCount < count) {
                look = -1;
                break;
              }
            } else if (iPivotRow == -1) {
              rejected = true;
            }
          }
        }
        trials++;
        if (trials >= numberTrials && iPivotRow >= 0) {
          look = -1;
          break;
        }
        if (rejected) {
          //take out for moment
          //eligible when row changes
          deleteLink(iRow);
          addLink(iRow, biggerDimension_ + 1);
        }
      } else {
        int iColumn = look - numberRows;

        assert(numberInColumn[iColumn] == count);
        look = nextCount[look];
        int start = startColumn[iColumn];
        int end = start + numberInColumn[iColumn];
        CoinFactorizationDouble minimumValue = element[start];

        minimumValue = fabs(minimumValue) * pivotTolerance;
        int i;
        for (i = start; i < end; i++) {
          CoinFactorizationDouble value = element[i];

          value = fabs(value);
          if (value >= minimumValue) {
            int iRow = indexRow[i];
            int nInRow = numberInRow[iRow];
            assert(nInRow > 0);
            double cost = (count - 1) * nInRow;

            if (cost < minimumCost) {
              minimumCost = cost;
              minimumCount = nInRow;
              iPivotRow = iRow;
              pivotRowPosition = i;
              iPivotColumn = iColumn;
              assert(iPivotRow >= 0 && iPivotColumn >= 0);
              pivotColumnPosition = -1;
              if (minimumCount <= count + 1) {
                look = -1;
                break;
              }
            }
          }
        }
        trials++;
        if (trials >= numberTrials && iPivotRow >= 0) {
          look = -1;
          break;
        }
      }
    } /* endwhile */
    if (iPivotRow >= 0) {
      assert(iPivotRow < numberRows_);
      int numberDoRow = numberInRow[iPivotRow] - 1;
      int numberDoColumn = numberInColumn[iPivotColumn] - 1;

      totalElements_ -= (numberDoRow + numberDoColumn + 1);
      if (numberDoColumn > 0) {
        if (numberDoRow > 0) {
          if (numberDoColumn > 1) {
            //  if (1) {
            //need to adjust more for cache and SMP
            //allow at least 4 extra
            int increment = numberDoColumn + 1 + 4;

            if (increment & 15) {
              increment = increment & (~15);
              increment += 16;
            }
            int increment2 =

              (increment + COINFACTORIZATION_BITS_PER_INT - 1) >> COINFACTORIZATION_SHIFT_PER_INT;
            int size = increment2 * numberDoRow;

            if (size > workSize) {
              workSize = size;
              workArea2_.conditionalNew(workSize);
              workArea2 = workArea2_.array();
            }
            bool goodPivot;
#ifndef UGLY_COIN_FACTOR_CODING
            //branch out to best pivot routine
            goodPivot = pivot(iPivotRow, iPivotColumn,
              pivotRowPosition, pivotColumnPosition,
              workArea, workArea2,
              increment2, markRow,
              SMALL_SET);
#else
#define FAC_SET SMALL_SET
#include "CoinFactorization.hpp"
#undef FAC_SET
#undef UGLY_COIN_FACTOR_CODING
#endif
            if (!goodPivot) {
              status = -99;
              count = biggerDimension_ + 1;
              break;
            }
          } else {
            if (!pivotOneOtherRow(iPivotRow, iPivotColumn)) {
              status = -99;
              count = biggerDimension_ + 1;
              break;
            }
          }
        } else {
Example #5
0
//-----------------------------------------------------------------------------
// Generate Lift-and-Project cuts
//------------------------------------------------------------------- 
void CglLiftAndProject::generateCuts(const OsiSolverInterface& si, OsiCuts& cs,
				     const CglTreeInfo /*info*/)
{
  // Assumes the mixed 0-1 problem 
  //
  //   min {cx: <Atilde,x> >= btilde} 
  //
  // is in canonical form with all bounds,
  // including x_t>=0, -x_t>=-1 for x_t binary,
  // explicitly stated in the constraint matrix. 
  // See ~/COIN/Examples/Cgl2/cgl2.cpp 
  // for a general purpose "convert" function. 

  // Reference [BCC]: Balas, Ceria, and Corneujols,
  // "A lift-and-project cutting plane algorithm
  // for mixed 0-1 program", Math Prog 58, (1993) 
  // 295-324.

  // This implementation uses Normalization 1.

  // Given canonical problem and
  // the lp-relaxation solution, x,
  // the LAP cut generator attempts to construct
  // a cut for every x_j such that 0<x_j<1
  // [BCC:307]
 

  // x_j is the strictly fractional binary variable
  // the cut is generated from
  int j = 0; 

  // Get basic problem information
  // let Atilde be an m by n matrix
  const int m = si.getNumRows(); 
  const int n = si.getNumCols(); 
  const double * x = si.getColSolution();

  // Remember - Atildes may have gaps..
  const CoinPackedMatrix * Atilde = si.getMatrixByRow();
  const double * AtildeElements =  Atilde->getElements();
  const int * AtildeIndices =  Atilde->getIndices();
  const CoinBigIndex * AtildeStarts = Atilde->getVectorStarts();
  const int * AtildeLengths = Atilde->getVectorLengths();  
  const int AtildeFullSize = AtildeStarts[m];
  const double * btilde = si.getRowLower();

  // Set up memory for system (10) [BCC:307]
  // (the problem over the norm intersected 
  //  with the polar cone)
  // 
  // min <<x^T,Atilde^T>,u> + x_ju_0
  // s.t.
  //     <B,w> = (0,...,0,beta_,beta)^T
  //        w  is nonneg for all but the
  //           last two entries, which are free.
  // where 
  // w = (u,v,v_0,u_0)in BCC notation 
  //      u and v are m-vectors; u,v >=0
  //      v_0 and u_0 are free-scalars, and
  //  
  // B = Atilde^T  -Atilde^T  -e_j e_j
  //     btilde^T   e_0^T      0   0
  //     e_0^T      btilde^T   1   0

  // ^T indicates Transpose
  // e_0 is a (AtildeNCols x 1) vector of all zeros 
  // e_j is e_0 with a 1 in the jth position

  // Storing B in column order. B is a (n+2 x 2m+2) matrix 
  // But need to allow for possible gaps in Atilde.
  // At each iteration, only need to change 2 cols and objfunc
  // Sane design of OsiSolverInterface does not permit mucking
  // with matrix.
  // Because we must delete and add cols to alter matrix,
  // and we can only add columns on the end of the matrix
  // put the v_0 and u_0 columns on the end.
  // rather than as described in [BCC]
 
  // Initially allocating B with space for v_0 and u_O cols
  // but not populating, for efficiency.

  // B without u_0 and v_0 is a (n+2 x 2m) size matrix.

  int twoM = 2*m;
  int BNumRows = n+2;
  int BNumCols = twoM+2;
  int BFullSize = 2*AtildeFullSize+twoM+3;
  double * BElements = new double[BFullSize];
  int * BIndices = new int[BFullSize];
  CoinBigIndex * BStarts = new CoinBigIndex [BNumCols+1];
  int * BLengths = new int[BNumCols];


  int i, ij, k=0;
  int nPlus1=n+1;
  int offset = AtildeStarts[m]+m;
  for (i=0; i<m; i++){
    for (ij=AtildeStarts[i];ij<AtildeStarts[i]+AtildeLengths[i];ij++){
      BElements[k]=AtildeElements[ij];
      BElements[k+offset]=-AtildeElements[ij];
      BIndices[k]= AtildeIndices[ij];
      BIndices[k+offset]= AtildeIndices[ij];

      k++;
    }
    BElements[k]=btilde[i];
    BElements[k+offset]=btilde[i];
    BIndices[k]=n;
    BIndices[k+offset]=nPlus1;
    BStarts[i]= AtildeStarts[i]+i;
    BStarts[i+m]=offset+BStarts[i];// = AtildeStarts[m]+m+AtildeStarts[i]+i
    BLengths[i]= AtildeLengths[i]+1;
    BLengths[i+m]= AtildeLengths[i]+1;
    k++;
  }

  BStarts[twoM]=BStarts[twoM-1]+BLengths[twoM-1];

  // Cols that will be deleted each iteration
  int BNumColsLessOne=BNumCols-1;
  int BNumColsLessTwo=BNumCols-2;
  const int delCols[2] = {BNumColsLessOne, BNumColsLessTwo};

  // Set lower bound on u and v
  // u_0, v_0 will be reset as free
  const double solverINFINITY = si.getInfinity();
  double * BColLowers = new double[BNumCols];
  double * BColUppers = new double[BNumCols];
  CoinFillN(BColLowers,BNumCols,0.0);  
  CoinFillN(BColUppers,BNumCols,solverINFINITY); 

  // Set row lowers and uppers.
  // The rhs is zero, for but the last two rows.
  // For these the rhs is beta_
  double * BRowLowers = new double[BNumRows];
  double * BRowUppers = new double[BNumRows];
  CoinFillN(BRowLowers,BNumRows,0.0);  
  CoinFillN(BRowUppers,BNumRows,0.0);
  BRowLowers[BNumRows-2]=beta_;
  BRowUppers[BNumRows-2]=beta_;
  BRowLowers[BNumRows-1]=beta_;
  BRowUppers[BNumRows-1]=beta_;


  // Calculate base objective <<x^T,Atilde^T>,u>
  // Note: at each iteration coefficient u_0
  //       changes to <x^T,e_j>
  //       w=(u,v,beta,v_0,u_0) size 2m+3
  //       So, BOjective[2m+2]=x[j]
  double * BObjective= new double[BNumCols];
  double * Atildex = new double[m];
  CoinFillN(BObjective,BNumCols,0.0);
  Atilde->times(x,Atildex); // Atildex is size m, x is size n
  CoinDisjointCopyN(Atildex,m,BObjective); 

  // Number of cols and size of Elements vector
  // in B without the v_0 and u_0 cols
  int BFullSizeLessThree = BFullSize-3;

  // Load B matrix into a column orders CoinPackedMatrix
  CoinPackedMatrix * BMatrix = new CoinPackedMatrix(true, BNumRows,
						  BNumColsLessTwo, 
						  BFullSizeLessThree,
						  BElements,BIndices, 
						  BStarts,BLengths);
  // Assign problem into a solver interface 
  // Note: coneSi will cleanup the memory itself
  OsiSolverInterface * coneSi = si.clone(false);
  coneSi->assignProblem (BMatrix, BColLowers, BColUppers, 
		      BObjective,
		      BRowLowers, BRowUppers);

  // Problem sense should default to "min" by default, 
  // but just to be virtuous...
  coneSi->setObjSense(1.0);

  // The plot outline from here on down:
  // coneSi has been assigned B without the u_0 and v_0 columns
  // Calculate base objective <<x^T,Atilde^T>,u>
  // bool haveWarmStart = false;
  // For (j=0; j<n, j++)
  //   if (!isBinary(x_j) || x_j<=0 || x_j>=1) continue;
  //   // IMPROVEME: if(haveWarmStart) check if j attractive
  //   add {-e_j,0,-1} matrix column for v_0
  //   add {e_j,0,0} matrix column for u_0
  //   objective coefficient for u_0 is  x_j 
  //   if (haveWarmStart) 
  //      set warmstart info
  //   solve min{objw:Bw=0; w>=0,except v_0, u_0 free}
  //   if (bounded)
  //      get warmstart info
  //      haveWarmStart=true;
  //      ustar = optimal u solution
  //      ustar_0 = optimal u_0 solution
  //      alpha^T= <ustar^T,Atilde> -ustar_0e_j^T
  //      (double check <alpha^T,x> >= beta_ should be violated)
  //      add <alpha^T,x> >= beta_ to cutset 
  //   endif
  //   delete column for u_0 // this deletes all column info.
  //   delete column for v_0
  // endFor
  // clean up memory
  // return 0;

  int * nVectorIndices = new int[n];
  CoinIotaN(nVectorIndices, n, 0);

  bool haveWarmStart = false;
  bool equalObj1, equalObj2;
  CoinRelFltEq eq;

  double v_0Elements[2] = {-1,1};
  double u_0Elements[1] = {1};

  CoinWarmStart * warmStart = 0;

  double * ustar = new double[m];
  CoinFillN(ustar, m, 0.0);

  double* alpha = new double[n];
  CoinFillN(alpha, n, 0.0);

  for (j=0;j<n;j++){
    if (!si.isBinary(j)) continue; // Better to ask coneSi? No! 
                                   // coneSi has no binInfo.
    equalObj1=eq(x[j],0);
    equalObj2=eq(x[j],1);
    if (equalObj1 || equalObj2) continue;
    // IMPROVEME: if (haveWarmStart) check if j attractive;

    // AskLL:wanted to declare u_0 and v_0 packedVec outside loop
    // and setIndices, but didn't see a method to do that(?)
    // (Could "insert". Seems inefficient)
    int v_0Indices[2]={j,nPlus1};
    int u_0Indices[1]={j};
    // 
    CoinPackedVector  v_0(2,v_0Indices,v_0Elements,false);
    CoinPackedVector  u_0(1,u_0Indices,u_0Elements,false);

#if CGL_DEBUG
    const CoinPackedMatrix *see1 = coneSi->getMatrixByRow();
#endif

    coneSi->addCol(v_0,-solverINFINITY,solverINFINITY,0);
    coneSi->addCol(u_0,-solverINFINITY,solverINFINITY,x[j]);
    if(haveWarmStart) {
      coneSi->setWarmStart(warmStart);
      coneSi->resolve();
    }
    else {

#if CGL_DEBUG
      const CoinPackedMatrix *see2 = coneSi->getMatrixByRow();
#endif

      coneSi->initialSolve();
    }
    if(coneSi->isProvenOptimal()){
      warmStart = coneSi->getWarmStart();
      haveWarmStart=true;
      const double * wstar = coneSi->getColSolution();
      CoinDisjointCopyN(wstar, m, ustar);
      Atilde->transposeTimes(ustar,alpha);
      alpha[j]+=wstar[BNumCols-1]; 
      
#if debug
      int p;
      double sum;
      for(p=0;p<n;p++)sum+=alpha[p]*x[p];
      if (sum<=beta_){
	throw CoinError("Cut not violated",
			"cutGeneration",
			"CglLiftAndProject");
      }
#endif

      // add <alpha^T,x> >= beta_ to cutset
      OsiRowCut rc;
      rc.setRow(n,nVectorIndices,alpha);
      rc.setLb(beta_);
      rc.setUb(solverINFINITY);
      cs.insert(rc);
    }
    // delete col for u_o and v_0
    coneSi->deleteCols(2,delCols);

    // clean up memory
  }
  // clean up
  delete [] alpha;
  delete [] ustar;
  delete [] nVectorIndices;
  // BMatrix, BColLowers,BColUppers, BObjective, BRowLowers, BRowUppers
  // are all freed by OsiSolverInterface destructor (?)
  delete [] BLengths;
  delete [] BStarts;
  delete [] BIndices;
  delete [] BElements;
}
Example #6
0
void
CoinPostsolveMatrix::assignPresolveToPostsolve (CoinPresolveMatrix *&preObj)

{
/*
  Start with simple data --- allocated and current size.
*/
  ncols0_ = preObj->ncols0_ ;
  nrows0_ = preObj->nrows0_ ;
  nelems0_ = preObj->nelems0_ ;
  bulk0_ = preObj->bulk0_ ;

  ncols_ = preObj->ncols_ ;
  nrows_ = preObj->nrows_ ;
  nelems_ = preObj->nelems_ ;
/*
  Now bring over the column-major matrix and other problem data.
*/
  mcstrt_ = preObj->mcstrt_ ;
  preObj->mcstrt_ = 0 ;
  hincol_ = preObj->hincol_ ;
  preObj->hincol_ = 0 ;
  hrow_ = preObj->hrow_ ;
  preObj->hrow_ = 0 ;
  colels_ = preObj->colels_ ;
  preObj->colels_ = 0 ;

  cost_ = preObj->cost_ ;
  preObj->cost_ = 0 ;
  originalOffset_ = preObj->originalOffset_ ;
  clo_ = preObj->clo_ ;
  preObj->clo_ = 0 ;
  cup_ = preObj->cup_ ;
  preObj->cup_ = 0 ;
  rlo_ = preObj->rlo_ ;
  preObj->rlo_ = 0 ;
  rup_ = preObj->rup_ ;
  preObj->rup_ = 0 ;

  originalColumn_ = preObj->originalColumn_ ;
  preObj->originalColumn_ = 0 ;
  originalRow_ = preObj->originalRow_ ;
  preObj->originalRow_ = 0 ;

  ztolzb_ = preObj->ztolzb_ ;
  ztoldj_ = preObj->ztoldj_ ;
  maxmin_ = preObj->maxmin_ ;
/*
  Now the problem solution. Often this will be empty, but that's not a problem.
*/
  sol_ = preObj->sol_ ;
  preObj->sol_ = 0 ;
  rowduals_ = preObj->rowduals_ ;
  preObj->rowduals_ = 0 ;
  acts_ = preObj->acts_ ;
  preObj->acts_ = 0 ;
  rcosts_ = preObj->rcosts_ ;
  preObj->rcosts_ = 0 ;
  colstat_ = preObj->colstat_ ;
  preObj->colstat_ = 0 ;
  rowstat_ = preObj->rowstat_ ;
  preObj->rowstat_ = 0 ;
/*
  The CoinPostsolveMatrix comes with messages and a handler, but replace them
  with the versions from the CoinPresolveObject, in case they've been
  customized. Let preObj believe it's no longer responsible for the handler.
*/
  if (defaultHandler_ == true)
    delete handler_ ;
  handler_ = preObj->handler_ ;
  preObj->defaultHandler_ = false ;
  messages_ = preObj->messages_ ;
/*
  Initialise the postsolve portions of this object. Which amounts to setting
  up the thread links to match the column-major matrix representation. This
  would be trivial except that the presolve matrix is loosely packed. We can
  either compress the matrix, or record the existing free space pattern. Bet
  that the latter is more efficient. Remember that mcstrt_[ncols_] actually
  points to the end of the bulk storage area, so when we process the last
  column in the bulk storage area, we'll add the free space block at the end
  of bulk storage to the free list.

  We need to allow for a 0x0 matrix here --- a pathological case, but it slips
  in when (for example) confirming a solution in an ILP code.
*/
  free_list_ = NO_LINK ;
  maxlink_ = bulk0_ ;
  link_ = new CoinBigIndex [maxlink_] ;

  if (ncols_ > 0)
  { CoinBigIndex minkcs = -1 ;
    for (int j = 0 ; j < ncols_ ; j++)
    { CoinBigIndex kcs = mcstrt_[j] ;
      int lenj = hincol_[j] ;
      assert(lenj > 0) ;
      CoinBigIndex kce = kcs+lenj-1 ;
      CoinBigIndex k ;

      for (k = kcs ; k < kce ; k++)
      { link_[k] = k+1 ; }
      link_[k++] = NO_LINK ;

      if (preObj->clink_[j].pre == NO_LINK)
      { minkcs = kcs ; }
      int nxtj = preObj->clink_[j].suc ;
      assert(nxtj >= 0 && nxtj <= ncols_) ;
      CoinBigIndex nxtcs = mcstrt_[nxtj] ;
      for ( ; k < nxtcs ; k++)
      { link_[k] = free_list_ ;
	free_list_ = k ; } }

    assert(minkcs >= 0) ;
    if (minkcs > 0)
    { for (CoinBigIndex k = 0 ; k < minkcs ; k++)
      { link_[k] = free_list_ ;
	free_list_ = k ; } } }
  else
  { for (CoinBigIndex k = 0 ; k < maxlink_ ; k++)
    { link_[k] = free_list_ ;
      free_list_ = k ; } }
/*
  That's it, preObj can die now.
*/
  delete preObj ;
  preObj = 0 ;

# if PRESOLVE_DEBUG || PRESOLVE_CONSISTENCY
/*
  These are used to track the action of postsolve transforms during debugging.
*/
  cdone_ = new char [ncols0_] ;
  CoinFillN(cdone_,ncols_,PRESENT_IN_REDUCED) ;
  CoinZeroN(cdone_+ncols_,ncols0_-ncols_) ;
  rdone_ = new char [nrows0_] ;
  CoinFillN(rdone_,nrows_,PRESENT_IN_REDUCED) ;
  CoinZeroN(rdone_+nrows_,nrows0_-nrows_) ;
# else
  cdone_ = 0 ;
  rdone_ = 0 ;
# endif

# if PRESOLVE_CONSISTENCY
  presolve_check_free_list(this,true) ;
  presolve_check_threads(this) ;
# endif

  return ; }
Example #7
0
int main (int argc, const char *argv[])
{
     ClpSimplex  model;
     int status;
     int maxFactor = 100;
     if (argc < 2) {
          status = model.readMps("../../Data/Netlib/czprob.mps");
          if (status) {
               printf("Unable to read matrix - trying gzipped version\n");
               status = model.readMps("../../Data/Netlib/czprob.mps.gz");
          }
     } else {
          status = model.readMps(argv[1]);
     }
     if (status) {
          printf("errors on input\n");
          exit(77);
     }
     if (argc > 2) {
          maxFactor = atoi(argv[2]);
          printf("max factor %d\n", maxFactor);
     }
     if (argc > 3) {
          printf("Using ClpDynamicMatrix\n");
     } else {
          printf("Using ClpDynamicExampleMatrix\n");
     }
     // find gub
     int numberRows = model.numberRows();
     int * gubStart = new int[numberRows+1];
     int * gubEnd = new int[numberRows];
     int * which = new int[numberRows];
     int * whichGub = new int[numberRows];
     int numberColumns = model.numberColumns();
     int * mark = new int[numberColumns];
     int iRow, iColumn;
     // delete variables fixed to zero
     const double * columnLower = model.columnLower();
     const double * columnUpper = model.columnUpper();
     int numberDelete = 0;
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          if (columnUpper[iColumn] == 0.0 && columnLower[iColumn] == 0.0)
               mark[numberDelete++] = iColumn;
     }
     if (numberDelete) {
          model.deleteColumns(numberDelete, mark);
          numberColumns -= numberDelete;
          columnLower = model.columnLower();
          columnUpper = model.columnUpper();
     }
     double * lower = new double[numberRows];
     double * upper = new double[numberRows];
     const double * rowLower = model.rowLower();
     const double * rowUpper = model.rowUpper();
     for (iColumn = 0; iColumn < numberColumns; iColumn++)
          mark[iColumn] = -1;
     CoinPackedMatrix * matrix = model.matrix();
     // get row copy
     CoinPackedMatrix rowCopy = *matrix;
     rowCopy.reverseOrdering();
     const int * column = rowCopy.getIndices();
     const int * rowLength = rowCopy.getVectorLengths();
     const CoinBigIndex * rowStart = rowCopy.getVectorStarts();
     const double * element = rowCopy.getElements();
     int putGub = numberRows;
     int putNonGub = numberRows;
     int * rowIsGub = new int [numberRows];
     for (iRow = numberRows - 1; iRow >= 0; iRow--) {
          bool gubRow = true;
          int first = numberColumns + 1;
          int last = -1;
          for (int j = rowStart[iRow]; j < rowStart[iRow] + rowLength[iRow]; j++) {
               if (element[j] != 1.0) {
                    gubRow = false;
                    break;
               } else {
                    int iColumn = column[j];
                    if (mark[iColumn] >= 0) {
                         gubRow = false;
                         break;
                    } else {
                         last = CoinMax(last, iColumn);
                         first = CoinMin(first, iColumn);
                    }
               }
          }
          if (last - first + 1 != rowLength[iRow] || !gubRow) {
               which[--putNonGub] = iRow;
               rowIsGub[iRow] = 0;
          } else {
               for (int j = rowStart[iRow]; j < rowStart[iRow] + rowLength[iRow]; j++) {
                    int iColumn = column[j];
                    mark[iColumn] = iRow;
               }
               rowIsGub[iRow] = -1;
               putGub--;
               gubStart[putGub] = first;
               gubEnd[putGub] = last + 1;
               lower[putGub] = rowLower[iRow];
               upper[putGub] = rowUpper[iRow];
               whichGub[putGub] = iRow;
          }
     }
     int numberNonGub = numberRows - putNonGub;
     int numberGub = numberRows - putGub;
     if (numberGub > 0) {
          printf("** %d gub rows\n", numberGub);
          int numberNormal = 0;
          const int * row = matrix->getIndices();
          const int * columnLength = matrix->getVectorLengths();
          const CoinBigIndex * columnStart = matrix->getVectorStarts();
          const double * elementByColumn = matrix->getElements();
          int numberElements = 0;
          bool doLower = false;
          bool doUpper = false;
          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
               if (mark[iColumn] < 0) {
                    mark[numberNormal++] = iColumn;
               } else {
                    numberElements += columnLength[iColumn];
                    if (columnLower[iColumn] != 0.0)
                         doLower = true;
                    if (columnUpper[iColumn] < 1.0e20)
                         doUpper = true;
               }
          }
          if (!numberNormal) {
               printf("Putting back one gub row to make non-empty\n");
               for (iColumn = gubStart[putGub]; iColumn < gubEnd[putGub]; iColumn++)
                    mark[numberNormal++] = iColumn;
               putGub++;
               numberGub--;
          }
          ClpSimplex model2(&model, numberNonGub, which + putNonGub, numberNormal, mark);
          // and copy for restart test
          ClpSimplex model3 = model2;
          int numberGubColumns = numberColumns - numberNormal;
          // sort gubs so monotonic
          int * which = new int[numberGub];
          int i;
          for (i = 0; i < numberGub; i++)
               which[i] = i;
          CoinSort_2(gubStart + putGub, gubStart + putGub + numberGub, which);
          // move to bottom if we want to use later
          memmove(gubStart, gubStart + putGub, numberGub * sizeof(int));
          int * temp1 = new int [numberGub];
          for (i = 0; i < numberGub; i++) {
               int k = which[i];
               temp1[i] = gubEnd[putGub+k];
          }
          memcpy(gubEnd, temp1, numberGub * sizeof(int));
          delete [] temp1;
          double * temp2 = new double [numberGub];
          for (i = 0; i < numberGub; i++) {
               int k = which[i];
               temp2[i] = lower[putGub+k];
          }
          memcpy(lower, temp2, numberGub * sizeof(double));
          for (i = 0; i < numberGub; i++) {
               int k = which[i];
               temp2[i] = upper[putGub+k];
          }
          memcpy(upper, temp2, numberGub * sizeof(double));
          delete [] temp2;
          delete [] which;
          numberElements -= numberGubColumns;
          int * start2 = new int[numberGubColumns+1];
          int * row2 = new int[numberElements];
          double * element2 = new double[numberElements];
          double * cost2 = new double [numberGubColumns];
          double * lowerColumn2 = NULL;
          if (doLower) {
               lowerColumn2 = new double [numberGubColumns];
               CoinFillN(lowerColumn2, numberGubColumns, 0.0);
          }
          double * upperColumn2 = NULL;
          if (doUpper) {
               upperColumn2 = new double [numberGubColumns];
               CoinFillN(upperColumn2, numberGubColumns, COIN_DBL_MAX);
          }
          numberElements = 0;
          int numberNonGubRows = 0;
          for (iRow = 0; iRow < numberRows; iRow++) {
               if (!rowIsGub[iRow])
                    rowIsGub[iRow] = numberNonGubRows++;
          }
          numberColumns = 0;
          int iStart = gubStart[0];
          gubStart[0] = 0;
          start2[0] = 0;
          const double * cost = model.objective();
          for (int iSet = 0; iSet < numberGub; iSet++) {
               int iEnd = gubEnd[iSet];
               for (int k = iStart; k < iEnd; k++) {
                    cost2[numberColumns] = cost[k];
                    if (columnLower[k])
                         lowerColumn2[numberColumns] = columnLower[k];
                    if (columnUpper[k] < 1.0e20)
                         upperColumn2[numberColumns] = columnUpper[k];
                    for (int j = columnStart[k]; j < columnStart[k] + columnLength[k]; j++) {
                         int iRow = rowIsGub[row[j]];
                         if (iRow >= 0) {
                              row2[numberElements] = iRow;
                              element2[numberElements++] = elementByColumn[j];
                         }
                    }
                    start2[++numberColumns] = numberElements;
               }
               if (iSet < numberGub - 1)
                    iStart = gubStart[iSet+1];
               gubStart[iSet+1] = numberColumns;
          }
          printf("** Before adding matrix there are %d rows and %d columns\n",
                 model2.numberRows(), model2.numberColumns());
          if (argc > 3) {
               ClpDynamicMatrix * newMatrix = new ClpDynamicMatrix(&model2, numberGub,
                         numberColumns, gubStart,
                         lower, upper,
                         start2, row2, element2, cost2,
                         lowerColumn2, upperColumn2);
               model2.replaceMatrix(newMatrix);
               newMatrix->switchOffCheck();
               newMatrix->setRefreshFrequency(1000);
          } else {
               ClpDynamicExampleMatrix * newMatrix = new ClpDynamicExampleMatrix(&model2, numberGub,
                         numberColumns, gubStart,
                         lower, upper,
                         start2, row2, element2, cost2,
                         lowerColumn2, upperColumn2);
               model2.replaceMatrix(newMatrix);
               newMatrix->switchOffCheck();
               newMatrix->setRefreshFrequency(1000);
          }
          printf("** While after adding matrix there are %d rows and %d columns\n",
                 model2.numberRows(), model2.numberColumns());
          model2.setSpecialOptions(4); // exactly to bound
          // For now scaling off
          model2.scaling(0);
          ClpPrimalColumnSteepest steepest(5);
          model2.setPrimalColumnPivotAlgorithm(steepest);
          //model2.messageHandler()->setLogLevel(63);
          model2.setFactorizationFrequency(maxFactor);
          model2.setMaximumIterations(4000000);
          double time1 = CoinCpuTime();
          model2.primal();
          // can't use values pass
          model2.primal(0);
          // test proper restart
          if (argc > 3) {
               ClpDynamicMatrix * oldMatrix =
                    dynamic_cast< ClpDynamicMatrix*>(model2.clpMatrix());
               assert (oldMatrix);
               ClpDynamicMatrix * newMatrix = new
               ClpDynamicMatrix(&model3, numberGub,
                                numberColumns, gubStart,
                                lower, upper,
                                start2, row2, element2, cost2,
                                lowerColumn2, upperColumn2,
                                oldMatrix->gubRowStatus(), oldMatrix->dynamicStatus());
               model3.replaceMatrix(newMatrix);
               // and ordinary status (but only NON gub rows)
               memcpy(model3.statusArray(), model2.statusArray(),
                      (newMatrix->numberStaticRows() + model3.numberColumns())*sizeof(unsigned char));
               newMatrix->switchOffCheck();
               newMatrix->setRefreshFrequency(1000);
          } else {
               ClpDynamicExampleMatrix * oldMatrix =
                    dynamic_cast< ClpDynamicExampleMatrix*>(model2.clpMatrix());
               assert (oldMatrix);
               ClpDynamicExampleMatrix * newMatrix = new
               ClpDynamicExampleMatrix(&model3, numberGub,
                                       numberColumns, gubStart,
                                       lower, upper,
                                       start2, row2, element2, cost2,
                                       lowerColumn2, upperColumn2,
                                       oldMatrix->gubRowStatus(), oldMatrix->dynamicStatus(),
                                       oldMatrix->numberGubColumns(), oldMatrix->idGen());
               model3.replaceMatrix(newMatrix);
               // and ordinary status (but only NON gub rows)
               memcpy(model3.statusArray(), model2.statusArray(),
                      (newMatrix->numberStaticRows() + model3.numberColumns())*sizeof(unsigned char));
               newMatrix->switchOffCheck();
               newMatrix->setRefreshFrequency(1000);
          }
          model3.setSpecialOptions(4); // exactly to bound
          // For now scaling off
          model3.scaling(0);
          model3.setPrimalColumnPivotAlgorithm(steepest);
          model3.messageHandler()->setLogLevel(63);
          model3.setFactorizationFrequency(maxFactor);
          model3.setMaximumIterations(4000000);
          delete [] rowIsGub;
          delete [] start2;
          delete [] row2;
          delete [] element2;
          delete [] cost2;
          delete [] lowerColumn2;
          delete [] upperColumn2;
          model3.primal();
          // this code expects non gub first in original matrix
          // and only works at present for ClpDynamicMatrix
          ClpDynamicMatrix * gubMatrix =
               dynamic_cast< ClpDynamicMatrix*>(model2.clpMatrix());
          assert (gubMatrix);
          ClpDynamicExampleMatrix * gubMatrix2 =
               dynamic_cast< ClpDynamicExampleMatrix*>(model2.clpMatrix());
          if (!gubMatrix2) {
               const double * solution = model2.primalColumnSolution();
               const double * cost = model.objective();
               int numberGubColumns = gubMatrix->numberGubColumns();
               int firstOdd = gubMatrix->firstDynamic();
               int lastOdd = gubMatrix->firstAvailable();
               int numberTotalColumns = firstOdd + numberGubColumns;
               int originalNumberRows = model.numberRows();
               int numberStaticRows = gubMatrix->numberStaticRows();
               char * status = new char [numberTotalColumns];
               double * gubSolution = new double [numberTotalColumns];
               int numberSets = gubMatrix->numberSets();
               const int * id = gubMatrix->id();
               int i;
               const float * columnLower = gubMatrix->columnLower();
               const float * columnUpper = gubMatrix->columnUpper();
               for (i = 0; i < numberGubColumns; i++) {
                    if (gubMatrix->getDynamicStatus(i) == ClpDynamicMatrix::atUpperBound) {
                         gubSolution[i+firstOdd] = columnUpper[i];
                         status[i+firstOdd] = 2;
                    } else if (gubMatrix->getDynamicStatus(i) == ClpDynamicMatrix::atLowerBound && columnLower) {
                         gubSolution[i+firstOdd] = columnLower[i];
                         status[i+firstOdd] = 1;
                    } else if (gubMatrix->getDynamicStatus(i) == ClpDynamicMatrix::soloKey) {
                         int iSet = gubMatrix->whichSet(i);
                         gubSolution[i+firstOdd] = gubMatrix->keyValue(iSet);
                         status[i+firstOdd] = 0;
                    } else {
                         gubSolution[i+firstOdd] = 0.0;
                         status[i+firstOdd] = 1;
                    }
               }
               for (i = 0; i < firstOdd; i++) {
                    ClpSimplex::Status thisStatus = model2.getStatus(i);
                    if (thisStatus == ClpSimplex::basic)
                         status[i] = 0;
                    else if (thisStatus == ClpSimplex::atLowerBound)
                         status[i] = 1;
                    else if (thisStatus == ClpSimplex::atUpperBound)
                         status[i] = 2;
                    else if (thisStatus == ClpSimplex::isFixed)
                         status[i] = 3;
                    else
                         abort();
                    gubSolution[i] = solution[i];
               }
               for (i = firstOdd; i < lastOdd; i++) {
                    int iBig = id[i-firstOdd] + firstOdd;
                    ClpSimplex::Status thisStatus = model2.getStatus(i);
                    if (thisStatus == ClpSimplex::basic)
                         status[iBig] = 0;
                    else if (thisStatus == ClpSimplex::atLowerBound)
                         status[iBig] = 1;
                    else if (thisStatus == ClpSimplex::atUpperBound)
                         status[iBig] = 2;
                    else if (thisStatus == ClpSimplex::isFixed)
                         status[iBig] = 3;
                    else
                         abort();
                    gubSolution[iBig] = solution[i];
               }
               char * rowStatus = new char[originalNumberRows];
               for (i = 0; i < numberStaticRows; i++) {
                    ClpSimplex::Status thisStatus = model2.getRowStatus(i);
                    if (thisStatus == ClpSimplex::basic)
                         rowStatus[i] = 0;
                    else if (thisStatus == ClpSimplex::atLowerBound)
                         rowStatus[i] = 1;
                    else if (thisStatus == ClpSimplex::atUpperBound)
                         rowStatus[i] = 2;
                    else if (thisStatus == ClpSimplex::isFixed)
                         rowStatus[i] = 3;
                    else
                         abort();
               }
               double objValue = 0.0;
               for (i = 0; i < numberTotalColumns; i++)
                    objValue += cost[i] * gubSolution[i];
               printf("objective value is %g\n", objValue);
               for (i = 0; i < numberSets; i++) {
                    ClpSimplex::Status thisStatus = gubMatrix->getStatus(i);
                    if (thisStatus == ClpSimplex::basic)
                         rowStatus[numberStaticRows+i] = 0;
                    else if (thisStatus == ClpSimplex::atLowerBound)
                         rowStatus[numberStaticRows+i] = 1;
                    else if (thisStatus == ClpSimplex::atUpperBound)
                         rowStatus[numberStaticRows+i] = 2;
                    else if (thisStatus == ClpSimplex::isFixed)
                         rowStatus[numberStaticRows+i] = 3;
                    else
                         abort();
               }
               // Coding below may not work if gub rows not at end
               FILE * fp = fopen ("xx.sol", "w");
               fwrite(gubSolution, sizeof(double), numberTotalColumns, fp);
               fwrite(status, sizeof(char), numberTotalColumns, fp);
               const double * rowsol = model2.primalRowSolution();
               double * rowsol2 = new double[originalNumberRows];
               memset(rowsol2, 0, originalNumberRows * sizeof(double));
               model.times(1.0, gubSolution, rowsol2);
               for (i = 0; i < numberStaticRows; i++)
                    assert (fabs(rowsol[i] - rowsol2[i]) < 1.0e-3);
               for (; i < originalNumberRows; i++)
                    assert (rowsol2[i] > lower[i-numberStaticRows] - 1.0e-3 &&
                            rowsol2[i] < upper[i-numberStaticRows] + 1.0e-3);
               //for (;i<originalNumberRows;i++)
               //printf("%d %g\n",i,rowsol2[i]);
               fwrite(rowsol2, sizeof(double), originalNumberRows, fp);
               delete [] rowsol2;
               fwrite(rowStatus, sizeof(char), originalNumberRows, fp);
               fclose(fp);
               delete [] status;
               delete [] gubSolution;
               // ** if going to rstart as dynamic need id_
               // also copy coding in useEf.. from ClpGubMatrix (i.e. test for basis)
          }
          printf("obj offset is %g\n", model2.objectiveOffset());
          printf("Primal took %g seconds\n", CoinCpuTime() - time1);
     }
     delete [] mark;
     delete [] gubStart;
     delete [] gubEnd;
     delete [] which;
     delete [] whichGub;
     delete [] lower;
     delete [] upper;
     return 0;
}
Example #8
0
/** construct master problem */
STO_RTN_CODE TssBd::constructMasterProblem(TssBdSub * tssbdsub, double lowerbound)
{
#define FREE_MEMORY       \
	FREE_PTR(mat)         \
	FREE_ARRAY_PTR(clbd)  \
	FREE_ARRAY_PTR(cubd)  \
	FREE_ARRAY_PTR(ctype) \
	FREE_ARRAY_PTR(obj)   \
	FREE_ARRAY_PTR(rlbd)  \
	FREE_ARRAY_PTR(rubd)  \
	FREE_ARRAY_PTR(auxind)  \
	FREE_ARRAY_PTR(auxcoef)

	assert(model_);

	if (naux_ <= 0 || !obj_aux_ || !clbd_aux_ || !cubd_aux_)
	{
		printf("Warning: Auxiliary column information is required.\n");
		return 1;
	}

	/** master problem */
	CoinPackedMatrix * mat = NULL;
	double * clbd   = NULL;
	double * cubd   = NULL;
	double * obj    = NULL;
	char *   ctype  = NULL;
	double * rlbd   = NULL;
	double * rubd   = NULL;
	/** for recourse lower bound */
	int * auxind     = NULL;
	double * auxcoef = NULL;

	BGN_TRY_CATCH

	int ncols = model_->getNumCols(0) + naugs_ * model_->getNumCols(1) + naux_;

	/** number of integer variables in the core */
	int nIntegers = model_->getNumCoreIntegers();

	/** allocate memory */
	auxind = new int [ncols];
	auxcoef = new double [ncols];

	/** decompose model */
	STO_RTN_CHECK_THROW(model_->decompose(
			naugs_, augs_, naux_, clbd_aux_, cubd_aux_, obj_aux_,
			mat, clbd, cubd, ctype, obj, rlbd, rubd),
			"decompose", "TssModel");

	/** convert column types */
	if (par_->relaxIntegrality_[0])
	{
		for (int j = 0; j < model_->getNumCols(0); ++j)
		{
			if (ctype[j] != 'C')
				nIntegers--;
			ctype[j] = 'C';
		}
	}
	if (par_->relaxIntegrality_[1] && naugs_ > 0)
	{
		for (int j = 0; j < model_->getNumCols(1); ++j)
		{
			if (ctype[model_->getNumCols(0) + j] != 'C')
				nIntegers--;
		}
		CoinFillN(ctype + model_->getNumCols(0), naugs_ * model_->getNumCols(1), 'C');
	}

	if (nIntegers > 0)
	{
		si_ = new SolverInterfaceScip(par_);
		si_->setPrintLevel(CoinMin(par_->logLevel_ + 1, 5));
	}
	else
	{
		si_ = new SolverInterfaceSpx(par_);
		si_->setPrintLevel(CoinMax(par_->logLevel_ - 1, 0));
	}

	/** load problem data */
	si_->loadProblem(mat, clbd, cubd, obj, ctype, rlbd, rubd, "BdMaster");

	/** add row for lower bound */
	for (int j = 0; j < ncols; ++j)
		auxind[j] = j;
	CoinCopyN(obj, ncols, auxcoef);
	si_->addRow(ncols, auxind, auxcoef, lowerbound, COIN_DBL_MAX);

	/** save memory */
	FREE_MEMORY

	END_TRY_CATCH_RTN(FREE_MEMORY,STO_RTN_ERR)

	return STO_RTN_OK;

#undef FREE_MEMORY
}
Example #9
0
//#############################################################################
OsiSolverInterface *
MibSBilevel::setUpModel(OsiSolverInterface * oSolver, bool newOsi,
			const double *lpSol)
{

  /** Create lower-level model with fixed upper-level vars **/

  int probType =
    model_->MibSPar_->entry(MibSParams::bilevelProblemType);

  bool warmStartLL =
    model_->MibSPar_->entry(MibSParams::warmStartLL);

  bool doDualFixing =
    model_->MibSPar_->entry(MibSParams::doDualFixing);

  std::string feasCheckSolver =
    model_->MibSPar_->entry(MibSParams::feasCheckSolver);

  OsiSolverInterface * nSolver;

  double etol(model_->etol_);
  int i(0), j(0), index1(0), index2(0);
  int uCols(model_->getUpperDim());
  int lRows(model_->getLowerRowNum());
  int lCols(model_->getLowerDim());
  int * uColIndices = model_->getUpperColInd();
  int * lColIndices = model_->getLowerColInd();
  int * lRowIndices = model_->getLowerRowInd();

  double objSense(model_->getLowerObjSense());  
  double * lObjCoeffs = model_->getLowerObjCoeffs();
     
  const CoinPackedMatrix * matrix = oSolver->getMatrixByRow();
  double coeff(0.0);
  if (!lpSol){
     lpSol = oSolver->getColSolution();   
  }
  const double * origRowLb = model_->getOrigRowLb();
  const double * origRowUb = model_->getOrigRowUb();
  const double * origColLb = model_->getOrigColLb();
  const double * origColUb = model_->getOrigColUb();
  double * rowUb = new double[lRows];
  double * rowLb = new double[lRows];
  double * colUb = new double[lCols];
  double * colLb = new double[lCols];
  //CoinZeroN(rowUb, lRows);
  //CoinZeroN(rowLb, lRows);
  //CoinZeroN(colUb, lCols);
  //CoinZeroN(colLb, lCols);

  /** Set the row bounds **/
  
  for(i = 0; i < lRows; i++){
     rowLb[i] = origRowLb[lRowIndices[i]];
     rowUb[i] = origRowUb[lRowIndices[i]];
  }
     
  for(i = 0; i < lCols; i++){
     colLb[i] = origColLb[lColIndices[i]];
     colUb[i] = origColUb[lColIndices[i]];
  }
  
  if (newOsi){
     if (feasCheckSolver == "Cbc"){
	nSolver = new OsiCbcSolverInterface();
     }else if (feasCheckSolver == "SYMPHONY"){
	nSolver = new OsiSymSolverInterface();
     }else if (feasCheckSolver == "CPLEX"){
#ifdef USE_CPLEX
	nSolver = new OsiCpxSolverInterface();
#else
	throw CoinError("CPLEX chosen as solver, but it has not been enabled",
			"setUpModel", "MibsBilevel");
#endif
     }else{
	throw CoinError("Unknown solver chosen",
			"setUpModel", "MibsBilevel");
     }
	
     int * integerVars = new int[lCols];
     double * objCoeffs = new double[lCols];
     
     CoinFillN(integerVars, lCols, 0);
     //CoinZeroN(objCoeffs, lCols);
     
     int intCnt(0);
  
     /** Fill in array of lower-level integer variables **/
     
     for(i = 0; i < lCols; i++){
	index1 = lColIndices[i];
	if(oSolver->isInteger(index1)){
	   integerVars[intCnt] = i;
	   intCnt++;
	}
     }
     
     CoinDisjointCopyN(lObjCoeffs, lCols, objCoeffs);
     
     CoinPackedMatrix * newMat = new CoinPackedMatrix(false, 0, 0);
     newMat->setDimensions(0, lCols);
     double tmp(0.0);
     
     /*
       for(i = 0; i < lRows; i++){
       CoinPackedVector row;
       index1 = lRowIndices[i];
       start = matStarts[index1];
       end = start + matrix->getVectorSize(index1);
       for(j = start; j < end; j++){
       index2 = matIndices[j];
       //tmp = findIndex(index, lCols, lColIndices);
       tmp = binarySearch(0, lCols - 1, index2, lColIndices);
       if(tmp > -1)
       row.insert(tmp, matElements[j]);
       }
       newMat->appendRow(row);
       }
     */
     for(i = 0; i < lRows; i++){
	CoinPackedVector row;
	index1 = lRowIndices[i];
	for(j = 0; j < lCols; j++){
	   index2 = lColIndices[j];
	   tmp = matrix->getCoefficient(index1, index2);
	   row.insert(j, tmp);
	}
	newMat->appendRow(row);
     }

     /*
       nSolver->assignProblem(newMat, colLb, colUb,
       objCoeffs, rowLb, rowUb);
     */
     
     nSolver->loadProblem(*newMat, colLb, colUb,
			  objCoeffs, rowLb, rowUb);
     
     for(i = 0; i < intCnt; i++){
	nSolver->setInteger(integerVars[i]);
     }
     //nSolver->setInteger(integerVars, intCnt);
     
     nSolver->setObjSense(objSense); //1 min; -1 max
     
     nSolver->setHintParam(OsiDoReducePrint, true, OsiHintDo);

#if 0
     if(0){
	dynamic_cast<OsiCbcSolverInterface *> 
	   (nSolver)->getModelPtr()->messageHandler()->setLogLevel(0);
     }
     else{
	dynamic_cast<OsiSymSolverInterface *> 
	   (nSolver)->setSymParam("prep_level", -1);
	
	dynamic_cast<OsiSymSolverInterface *> 
	   (nSolver)->setSymParam("verbosity", -2);
	
	dynamic_cast<OsiSymSolverInterface *> 
	   (nSolver)->setSymParam("max_active_nodes", 1);
     }
#endif
     delete [] integerVars;

  }else{
     nSolver = solver_;
  }

#define SYM_VERSION_IS_WS strcmp(SYMPHONY_VERSION, "WS")  

#if SYMPHONY_VERSION_IS_WS
  if (feasCheckSolver == "SYMPHONY" && probType == 1 && warmStartLL &&
      !newOsi && doDualFixing){ //Interdiction

     /** Get upper bound from best known (feasible) lower level solution and try 
	 to fix additional variables by sensitivity analysis **/

     std::vector<std::pair<AlpsKnowledge*, double> > solutionPool;
     model_->getKnowledgeBroker()->
	getAllKnowledges(AlpsKnowledgeTypeSolution, solutionPool);

     const double * sol; 
     double objval, Ub(objSense*nSolver->getInfinity());
     BlisSolution* blisSol;
     std::vector<std::pair<AlpsKnowledge*, double> >::const_iterator si;
     for (si = solutionPool.begin(); si != solutionPool.end(); ++si){
	blisSol = dynamic_cast<BlisSolution*>(si->first);
	sol = blisSol->getValues();
	for (i = 0; i < uCols; i++){
	   if (lpSol[uColIndices[i]] > 1 - etol &&
	       sol[lColIndices[i]] > 1-etol){
	      break;
	   }
	}
	if (i == uCols && -objSense*blisSol->getQuality() < Ub){
	   Ub = -objSense*blisSol->getQuality();
	}
     }

     /** Figure out which variables get fixed by the upper level solution **/

     int *newUbInd = new int[uCols];
     int *newLbInd = new int[uCols];
     double *newUbVal = new double[uCols];
     double *newLbVal = new double[uCols];
     double newLb;
     for (i = 0; i < uCols; i++){
	newUbInd[i] = uColIndices[i];
	newLbInd[i] = uColIndices[i];
	newLbVal[i] = 0;
	if (lpSol[uColIndices[i]] > 1 - etol){
	   newUbVal[i] = 0;
	}else{
	   newUbVal[i] = 1;
	}
     }
	
     /** If we found an upper bound, then do the dual fixing **/

     if (Ub < objSense*nSolver->getInfinity()){
	sym_environment *env = 
	   dynamic_cast<OsiSymSolverInterface *>(nSolver)->getSymphonyEnvironment();

	for (i = 0; i < uCols; i++){
	   if (newUbVal[i] == 1){
	      // Try fixing it to zero
	      newUbVal[i] = 0; 
	      sym_get_lb_for_new_rhs(env, 0, NULL, NULL, uCols, newLbInd,
				     newLbVal, uCols, newUbInd, newUbVal,
				     &newLb);
	      if (objSense*newLb > Ub + etol){
		 //Victory! This variable can be fixed to 1 permanently
		 newLbVal[i] = 1;
	      }
	      //Set upper bound back to 1
	      newUbVal[i] = 1;
	      
	      if (newLbVal[i] == 0){
		 // Try fixing it to one
		 newLbVal[i] = 1;
		 sym_get_lb_for_new_rhs(env, 0, NULL, NULL, uCols, newLbInd,
					newLbVal, uCols, newUbInd, newUbVal,
					&newLb);
		 if (objSense*newLb > Ub + etol){
		    //Victory! This variable can be fixed to 0 permanently
		    newUbVal[i] = 0;
		 }
		 newLbVal[i] = 0;
	      }
	   }
	   
	}
     }
     
     /** Now set the row bounds to account for fixings **/
     
     /** This is probably very frgaile. Assuming interdiction 
	 rows come last. It would be better to set variable 
	 bounds directly, but this doesn't seem to work right now. **/
     int iRowStart = lRows-uCols; 

#if 1
     for(i = iRowStart; i < lRows; i++){
	nSolver->setRowLower(i, newLbVal[i-iRowStart]);
	nSolver->setRowUpper(i, newUbVal[i-iRowStart]);
     }
#else
     for(i = 0; i < uCols; i++){
	nSolver->setColLower(i, newLbVal[i]);
	nSolver->setColUpper(i, newUbVal[i]);
     }
#endif     
     delete[] newUbInd;
     delete[] newLbInd;
     delete[] newUbVal;
     delete[] newLbVal;
  }else{
#endif
     //FIXME: NEED TO GET ROW SENSE HERE
     
     /** Get contribution of upper-level columns **/
     
     double * upComp = new double[lRows];
     CoinFillN(upComp, lRows, 0.0);
     
     for(i = 0; i < lRows; i++){
	index1 = lRowIndices[i];
	for(j = 0; j < uCols; j++){
	   index2 = uColIndices[j];
	   coeff = matrix->getCoefficient(index1, index2);
	   if (coeff != 0){
	      upComp[i] += coeff * lpSol[index2];
	   }
	}
     }
     
     /** Correct the row bounds to account for fixed upper-level vars **/
     
     for(i = 0; i < lRows; i++){
	nSolver->setRowLower(i, rowLb[i] - upComp[i]);
	nSolver->setRowUpper(i, rowUb[i] - upComp[i]);
     }
     
     delete [] upComp;

#if SYMPHONY_VERSION_IS_WS
  }
#endif

  //I don't think this is needed
  //if(!getWarmStart())
  //  setWarmStart(nSolver->getWarmStart());

  return nSolver;

}
Example #10
0
void
BM_tm::initialize_core(BCP_vec<BCP_var_core*>& vars,
                       BCP_vec<BCP_cut_core*>& cuts,
                       BCP_lp_relax*& matrix)
{
    char* argv_[3];
    char** argv = argv_;
    argv[0] = NULL;
    argv[1] = strdup(par.entry(BM_par::NL_filename).c_str());
    argv[2] = NULL;
    
    /* Get the basic options. */
    Bonmin::BonminAmplSetup bonmin;
    bonmin.readOptionsFile(par.entry(BM_par::IpoptParamfile).c_str());
    bonmin.initialize(argv);    
    
    free(argv[1]);

    Bonmin::OsiTMINLPInterface& nlp = *bonmin.nonlinearSolver();
#if defined(BM_DISREGARD_SOS)
    const Bonmin::TMINLP::SosInfo * sos = nlp.model()->sosConstraints();
    if (sos->num > 0) {
      printf("There are SOS constraints... disregarding them...\n");
    }
#endif
    
    OsiSolverInterface& clp  = *bonmin.continuousSolver();
    
    const int numCols = clp.getNumCols();
    const int numRows = clp.getNumRows();

    const double* clb = clp.getColLower();
    const double* cub = clp.getColUpper();

    double* obj = new double[numCols];
    if (bonmin.getAlgorithm() == Bonmin::B_BB /* pure B&B */) {
      std::cout<<"Doing branch and bound"<<std::endl;
      CoinFillN(obj, numCols, 0.0);
      matrix = NULL;
    } else {
      std::cout<<"Doing hybrid"<<std::endl;
      CoinDisjointCopyN(clp.getObjCoefficients(), numCols, obj);
      cuts.reserve(numRows);
      const double* rlb = clp.getRowLower();
      const double* rub = clp.getRowUpper();
      for (int i = 0; i < numRows; ++i)	{
	cuts.push_back(new BCP_cut_core(rlb[i], rub[i]));
      }
      matrix = new BCP_lp_relax(true /*column major ordered*/);
      matrix->copyOf(*clp.getMatrixByCol(), obj, clb, cub, rlb, rub);
    }

    vars.reserve(numCols);
    for (int i = 0; i < numCols; ++i)	{
      BCP_var_t type = BCP_ContinuousVar;
      if (clp.isBinary(i)) type = BCP_BinaryVar;
      if (clp.isInteger(i)) type = BCP_IntegerVar;
      vars.push_back(new BCP_var_core(type, obj[i], clb[i], cub[i]));
    }
    delete[] obj;

    /* Initialize pseudocosts */
    int nObj = 0;
    for (int i = 0; i < numCols; ++i) {
	if (nlp.isInteger(i)) {
	    ++nObj;
	}
    }
#if ! defined(BM_DISREGARD_SOS)
    const Bonmin::TMINLP::SosInfo * sos = nlp.model()->sosConstraints();
    nObj += sos->num;
#endif
    pseudoCosts_.initialize(nObj);
}
Example #11
0
/************************************************************************

This main program reads in an integer model from an mps file.

It then tries to find SOS structure and solves using N-way variables

*************************************************************************/
int main (int argc, const char *argv[])
{
  
  // Define your favorite OsiSolver
  
  OsiClpSolverInterface solver1;
  
  // Read in model using argv[1]
  // and assert that it is a clean model
  std::string mpsFileName;
#if defined(MIPLIB3DIR)
  mpsFileName = MIPLIB3DIR "/10teams";
#else
  if (argc < 2) {
    fprintf(stderr, "Do not know where to find miplib3 MPS files.\n");
    exit(1);
  }
#endif
  if (argc>=2) mpsFileName = argv[1];
  int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),"");
  if( numMpsReadErrors != 0 )
  {
     printf("%d errors reading MPS file\n", numMpsReadErrors);
     return numMpsReadErrors;
  }
  
  int iRow, iColumn;
  int numberColumns = solver1.getNumCols();
  int numberRows = solver1.getNumRows();
  // get row copy
  const CoinPackedMatrix * matrix = solver1.getMatrixByRow();
  const double * element = matrix->getElements();
  const int * column = matrix->getIndices();
  const CoinBigIndex * rowStart = matrix->getVectorStarts();
  const int * rowLength = matrix->getVectorLengths();
  const double * rowLower = solver1.getRowLower();
  const double * rowUpper = solver1.getRowUpper();
  const double * columnLower = solver1.getColLower();
  
  // Look for possible SOS
  int numberSOS=0;
  int * mark = new int[numberColumns];
  CoinFillN(mark,numberColumns,-1);
  for (iRow=0;iRow<numberRows;iRow++) {
    if (rowLower[iRow]==1.0&&rowUpper[iRow]==1.0) {
      bool goodRow=true;
      for (int j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
        int iColumn = column[j];
        if (element[j]!=1.0||!solver1.isInteger(iColumn)||mark[iColumn]>=0||columnLower[iColumn]) {
          goodRow=false;
          break;
        }
      }
      if (goodRow) {
        // mark all
        for (int j=rowStart[iRow];j<rowStart[iRow]+rowLength[iRow];j++) {
          int iColumn = column[j];
          mark[iColumn]=numberSOS;
        }
        numberSOS++;
      }
    }
  }
  std::cout<<numberSOS<<" SOS"<<std::endl;
  if (!numberSOS)
    return 0;
  CbcModel model(solver1);
  // Do sets and priorities
  CbcObject ** objects = new CbcObject * [numberSOS];
  int numberIntegers = model.numberIntegers();
  /* model may not have created objects
     If none then create
  */
  if (!numberIntegers||!model.numberObjects()) {
    model.findIntegers(true);
    numberIntegers = model.numberIntegers();
  }
  int * priority = new int[numberSOS];
  // Set SOS priorities high
  CoinFillN(priority,numberSOS,1);
  // Set up SOS
  int * which = new int[numberColumns];
  for (int iSOS =0;iSOS<numberSOS;iSOS++) {
    int n=0;
    for (iColumn=0;iColumn<numberColumns;iColumn++) {
      if (mark[iColumn]==iSOS)
        which[n++]=iColumn;
    }
    // NULL uses 0,1,2 .. as weights
    objects[iSOS]= new CbcNWay(&model,n,which,iSOS);
  }
  delete [] mark;
  delete [] which;
  model.addObjects(numberSOS,objects);
  for (iColumn=0;iColumn<numberSOS;iColumn++)
    delete objects[iColumn];
  delete [] objects;
  model.passInPriorities(priority,true);
  delete [] priority;

  // If time is given then stop after that number of minutes
  if (argc>2) {
    int minutes = atoi(argv[2]);
    std::cout<<"Stopping after "<<minutes<<" minutes"<<std::endl;
    assert (minutes>=0);
    model.setDblParam(CbcModel::CbcMaximumSeconds,60.0*minutes);
  }
  // Switch off most output
  model.solver()->setHintParam(OsiDoReducePrint,true,OsiHintTry);
  if (model.getNumCols()<3000) {
    model.messageHandler()->setLogLevel(1);
    //model.solver()->messageHandler()->setLogLevel(0);
  } else {
    model.messageHandler()->setLogLevel(2);
    //model.solver()->messageHandler()->setLogLevel(1);
  }
  //model.messageHandler()->setLogLevel(1);
  
  double time1 = CoinCpuTime();

  // Do complete search
  
  model.branchAndBound();

  std::cout<<mpsFileName<<" took "<<CoinCpuTime()-time1<<" seconds, "
	   <<model.getNodeCount()<<" nodes with objective "
	   <<model.getObjValue()
	   <<(!model.status() ? " Finished" : " Not finished")
	   <<std::endl;

  // Print solution - we can't get names from Osi!

  if (model.getMinimizationObjValue()<1.0e50) {
    int numberColumns = model.solver()->getNumCols();
    
    const double * solution = model.solver()->getColSolution();
    
    int iColumn;
    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);
    
    std::cout<<"--------------------------------------"<<std::endl;
    for (iColumn=0;iColumn<numberColumns;iColumn++) {
      double value=solution[iColumn];
      if (fabs(value)>1.0e-7&&model.solver()->isInteger(iColumn)) 
	std::cout<<std::setw(6)<<iColumn<<" "<<value<<std::endl;
    }
    std::cout<<"--------------------------------------"<<std::endl;
  
    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);
  }
  return 0;
}    
// Returns type
int
CbcFathomDynamicProgramming::checkPossible(int allowableSize)
{
    algorithm_ = -1;
    assert(model_->solver());
    OsiSolverInterface * solver = model_->solver();
    const CoinPackedMatrix * matrix = solver->getMatrixByCol();

    int numberIntegers = model_->numberIntegers();
    int numberColumns = solver->getNumCols();
    size_ = 0;
    if (numberIntegers != numberColumns)
        return -1; // can't do dynamic programming

    const double * lower = solver->getColLower();
    const double * upper = solver->getColUpper();
    const double * rowUpper = solver->getRowUpper();

    int numberRows = model_->getNumRows();
    int i;

    // First check columns to see if possible
    double * rhs = new double [numberRows];
    CoinCopyN(rowUpper, numberRows, rhs);

    // Column copy
    const double * element = matrix->getElements();
    const int * row = matrix->getIndices();
    const CoinBigIndex * columnStart = matrix->getVectorStarts();
    const int * columnLength = matrix->getVectorLengths();
    bool bad = false;
    /* It is just possible that we could say okay as
       variables may get fixed but seems unlikely */
    for (i = 0; i < numberColumns; i++) {
        int j;
        double lowerValue = lower[i];
        assert (lowerValue == floor(lowerValue));
        for (j = columnStart[i];
                j < columnStart[i] + columnLength[i]; j++) {
            int iRow = row[j];
            double value = element[j];
            if (upper[i] > lowerValue && (value <= 0.0 || value != floor(value)))
                bad = true;
            if (lowerValue)
                rhs[iRow] -= lowerValue * value;
        }
    }
    // check possible (at present do not allow covering)
    int numberActive = 0;
    bool infeasible = false;
    bool saveBad = bad;
    for (i = 0; i < numberRows; i++) {
        if (rhs[i] < 0)
            infeasible = true;
        else if (rhs[i] > 1.0e5 || fabs(rhs[i] - floor(rhs[i] + 0.5)) > 1.0e-7)
            bad = true;
        else if (rhs[i] > 0.0)
            numberActive++;
    }
    if (bad || infeasible) {
        delete [] rhs;
        if (!saveBad && infeasible)
            return -2;
        else
            return -1;
    }
    // check size of array needed
    double size = 1.0;
    double check = COIN_INT_MAX;
    for (i = 0; i < numberRows; i++) {
        int n = static_cast<int> (floor(rhs[i] + 0.5));
        if (n) {
            n++; // allow for 0,1... n
            if (numberActive != 1) {
                // power of 2
                int iBit = 0;
                int k = n;
                k &= ~1;
                while (k) {
                    iBit++;
                    k &= ~(1 << iBit);
                }
                // See if exact power
                if (n != (1 << iBit)) {
                    // round up to next power of 2
                    n = 1 << (iBit + 1);
                }
                size *= n;
                if (size >= check)
                    break;
            } else {
                size = n; // just one constraint
            }
        }
    }
    // set size needed
    if (size >= check)
        size_ = COIN_INT_MAX;
    else
        size_ = static_cast<int> (size);

    int n01 = 0;
    int nbadcoeff = 0;
    // See if we can tighten bounds
    for (i = 0; i < numberColumns; i++) {
        int j;
        double lowerValue = lower[i];
        double gap = upper[i] - lowerValue;
        for (j = columnStart[i];
                j < columnStart[i] + columnLength[i]; j++) {
            int iRow = row[j];
            double value = element[j];
            if (value != 1.0)
                nbadcoeff++;
            if (gap*value > rhs[iRow] + 1.0e-8)
                gap = rhs[iRow] / value;
        }
        gap = lowerValue + floor(gap + 1.0e-7);
        if (gap < upper[i])
            solver->setColUpper(i, gap);
        if (gap <= 1.0)
            n01++;
    }
    if (allowableSize && size_ <= allowableSize) {
        if (n01 == numberColumns && !nbadcoeff)
            algorithm_ = 0; // easiest
        else
            algorithm_ = 1;
    }
    if (allowableSize && size_ <= allowableSize) {
        numberActive_ = numberActive;
        indices_ = new int [numberActive_];
        cost_ = new double [size_];
        CoinFillN(cost_, size_, COIN_DBL_MAX);
        // but do nothing is okay
        cost_[0] = 0.0;
        back_ = new int[size_];
        CoinFillN(back_, size_, -1);
        startBit_ = new int[numberActive_];
        numberBits_ = new int[numberActive_];
        lookup_ = new int [numberRows];
        rhs_ = new int [numberActive_];
        numberActive = 0;
        int kBit = 0;
        for (i = 0; i < numberRows; i++) {
            int n = static_cast<int> (floor(rhs[i] + 0.5));
            if (n) {
                lookup_[i] = numberActive;
                rhs_[numberActive] = n;
                startBit_[numberActive] = kBit;
                n++; // allow for 0,1... n
                int iBit = 0;
                // power of 2
                int k = n;
                k &= ~1;
                while (k) {
                    iBit++;
                    k &= ~(1 << iBit);
                }
                // See if exact power
                if (n != (1 << iBit)) {
                    // round up to next power of 2
                    iBit++;
                }
                if (numberActive != 1) {
                    n = 1 << iBit;
                    size *= n;
                    if (size >= check)
                        break;
                } else {
                    size = n; // just one constraint
                }
                numberBits_[numberActive++] = iBit;
                kBit += iBit;
            } else {
                lookup_[i] = -1;
            }
        }
        const double * rowLower = solver->getRowLower();
        if (algorithm_ == 0) {
            // rhs 1 and coefficients 1
            // Get first possible solution for printing
            target_ = -1;
            int needed = 0;
            int numberActive = 0;
            for (i = 0; i < numberRows; i++) {
                int newRow = lookup_[i];
                if (newRow >= 0) {
                    if (rowLower[i] == rowUpper[i]) {
                        needed += 1 << numberActive;
                        numberActive++;
                    }
                }
            }
            for (i = 0; i < size_; i++) {
                if ((i&needed) == needed) {
                    break;
                }
            }
            target_ = i;
        } else {
            coefficients_ = new int[numberActive_];
            // If not too many general rhs then we can be more efficient
            numberNonOne_ = 0;
            for (i = 0; i < numberActive_; i++) {
                if (rhs_[i] != 1)
                    numberNonOne_++;
            }
            if (numberNonOne_*2 < numberActive_) {
                // put rhs >1 every second
                int * permute = new int[numberActive_];
                int * temp = new int[numberActive_];
                // try different ways
                int k = 0;
                for (i = 0; i < numberRows; i++) {
                    int newRow = lookup_[i];
                    if (newRow >= 0 && rhs_[newRow] > 1) {
                        permute[newRow] = k;
                        k += 2;
                    }
                }
                // adjust so k points to last
                k -= 2;
                // and now rest
                int k1 = 1;
                for (i = 0; i < numberRows; i++) {
                    int newRow = lookup_[i];
                    if (newRow >= 0 && rhs_[newRow] == 1) {
                        permute[newRow] = k1;
                        k1++;
                        if (k1 <= k)
                            k1++;
                    }
                }
                for (i = 0; i < numberActive_; i++) {
                    int put = permute[i];
                    temp[put] = rhs_[i];
                }
                memcpy(rhs_, temp, numberActive_*sizeof(int));
                for (i = 0; i < numberActive_; i++) {
                    int put = permute[i];
                    temp[put] = numberBits_[i];
                }
                memcpy(numberBits_, temp, numberActive_*sizeof(int));
                k = 0;
                for (i = 0; i < numberActive_; i++) {
                    startBit_[i] = k;
                    k += numberBits_[i];
                }
                for (i = 0; i < numberRows; i++) {
                    int newRow = lookup_[i];
                    if (newRow >= 0)
                        lookup_[i] = permute[newRow];
                }
                delete [] permute;
                delete [] temp;
                // mark new method
                algorithm_ = 2;
            }
            // Get first possible solution for printing
            target_ = -1;
            int needed = 0;
            int * lower2 = new int[numberActive_];
            for (i = 0; i < numberRows; i++) {
                int newRow = lookup_[i];
                if (newRow >= 0) {
                    int gap = static_cast<int> (rowUpper[i] - CoinMax(0.0, rowLower[i]));
                    lower2[newRow] = rhs_[newRow] - gap;
                    int numberBits = numberBits_[newRow];
                    int startBit = startBit_[newRow];
                    if (numberBits == 1 && !gap) {
                        needed |= 1 << startBit;
                    }
                }
            }
            for (i = 0; i < size_; i++) {
                if ((i&needed) == needed) {
                    // this one may do
                    bool good = true;
                    for (int kk = 0; kk < numberActive_; kk++) {
                        int numberBits = numberBits_[kk];
                        int startBit = startBit_[kk];
                        int size = 1 << numberBits;
                        int start = 1 << startBit;
                        int mask = start * (size - 1);
                        int level = (i & mask) >> startBit;
                        if (level < lower2[kk]) {
                            good = false;
                            break;
                        }
                    }
                    if (good) {
                        break;
                    }
                }
            }
            delete [] lower2;
            target_ = i;
        }
void
OsiVolSolverInterface::assignProblem(CoinPackedMatrix*& matrix,
				     double*& collb, double*& colub,
				     double*& obj,
				     char*& rowsen, double*& rowrhs,
				     double*& rowrng)
{
   gutsOfDestructor_();
   const int rownum = matrix->getNumRows();
   const int colnum = matrix->getNumCols();
   maxNumcols_ = colnum;
   maxNumrows_ = rownum;

   if (matrix->isColOrdered()) {
      colMatrix_.swap(*matrix);
      colMatrixCurrent_ = true;
      rowMatrixCurrent_ = false;
   } else {
      rowMatrix_.swap(*matrix);
      rowMatrixCurrent_ = true;
      colMatrixCurrent_ = false;
   }
   delete matrix; matrix = 0;
      
   rowsense_  = rowsen;   rowsen = 0;
   rhs_       = rowrhs;   rowrhs = 0;
   rowrange_  = rowrng;   rowrng = 0;
   colupper_  = colub;    colub  = 0;
   collower_  = collb;    collb  = 0;
   objcoeffs_ = obj;      obj    = 0;

   if (maxNumrows_ > 0) {
      if (!rowsense_) {
	 rowsense_ = new char[maxNumrows_];
	 CoinFillN(rowsense_, rownum, 'G');
      }
      if (!rhs_) {
	 rhs_ = new double[maxNumrows_];
	 CoinFillN(rhs_, rownum, 0.0);
      }
      if (!rowrange_) {
	 rowrange_ = new double[maxNumrows_];
	 CoinFillN(rowrange_, rownum, 0.0);
      }
      rowlower_ = new double[maxNumrows_];
      rowupper_ = new double[maxNumrows_];
      rowprice_ = new double[maxNumrows_];
      lhs_      = new double[maxNumrows_];
      // Set the initial dual solution
      CoinFillN(rowprice_, rownum, 0.0);
      convertSensesToBounds_();
   }
   if (maxNumcols_ > 0) {
      if (!colupper_) {
	 colupper_ = new double[maxNumcols_];
	 CoinFillN(colupper_, colnum, OsiVolInfinity);
      }
      if (!collower_) {
	 collower_ = new double[maxNumcols_];
	 CoinFillN(collower_, colnum, -OsiVolInfinity);
      }
      if (!objcoeffs_) {
	 objcoeffs_ = new double[maxNumcols_];
	 CoinFillN(objcoeffs_, colnum, -OsiVolInfinity);
      }

      colsol_    = new double[maxNumcols_];
      int c;
      for ( c=0; c<colnum; c++ ) {
	if ( fabs(collower_[c]) < fabs(colupper_[c]) ) {
	  colsol_[c] = collower_[c];
	}
	else {
	  colsol_[c] = colupper_[c];
	}
      }

      rc_        = new double[maxNumcols_];
      continuous_ = new bool[maxNumcols_];
   }
}