Пример #1
0
  void ClpInterface::
  eval(void* mem, const double** arg, double** res, int* iw, double* w) const {
    //auto m = static_cast<ClpMemory*>(mem);

    if (inputs_check_) {
      checkInputs(arg[CONIC_LBX], arg[CONIC_UBX], arg[CONIC_LBA], arg[CONIC_UBA]);
    }

    // Get inputs
    double* g=w; w += nx_;
    casadi_copy(arg[CONIC_G], nx_, g);
    double* lbx=w; w += nx_;
    casadi_copy(arg[CONIC_LBX], nx_, lbx);
    double* ubx=w; w += nx_;
    casadi_copy(arg[CONIC_UBX], nx_, ubx);
    double* lba=w; w += na_;
    casadi_copy(arg[CONIC_LBA], na_, lba);
    double* uba=w; w += na_;
    casadi_copy(arg[CONIC_UBA], na_, uba);
    double* H=w; w += nnz_in(CONIC_H);
    casadi_copy(arg[CONIC_H], nnz_in(CONIC_H), H);
    double* A=w; w += nnz_in(CONIC_A);
    casadi_copy(arg[CONIC_A], nnz_in(CONIC_A), A);

    // Create model
    ClpSimplex model;
    model.loadProblem(A_.size2(), A_.size1(), A_.colind(), A_.row(), A,
                      lbx, ubx, g, lba, uba, nullptr);

    // Solve the problem using the primal simplex algorithm
    model.primal();

    // Primal solution
    double* x = model.primalColumnSolution();
    casadi_copy(x, nx_, res[CONIC_X]);

    // Dual solution (x)
    double* minus_lam_x = model.dualColumnSolution();
    if (res[CONIC_LAM_X]) {
      casadi_copy(minus_lam_x, nx_, res[CONIC_LAM_X]);
      casadi_scal(nx_, -1., res[CONIC_LAM_X]);
    }

    // Dual solution (A)
    double* minus_lam_a = model.dualRowSolution();
    if (res[CONIC_LAM_A]) {
      casadi_copy(minus_lam_a, na_, res[CONIC_LAM_A]);
      casadi_scal(na_, -1., res[CONIC_LAM_A]);
    }

    // Optimal cost
    double f = model.rawObjectiveValue();
    if (res[CONIC_COST]) *res[CONIC_COST] = f;
  }
Пример #2
0
static int solve(EKKModel * model, int  startup, int algorithm,
                 int presolve)
{
     // values pass or not
     if (startup)
          startup = 1;
     // if scaled then be careful
     bool scaled = ekk_scaling(model) == 1;
     if (scaled)
          ekk_scaleRim(model, 1);
     void * compressInfo = NULL;
     ClpSimplex * clp;
     if (!presolve || !presolveInfo) {
          // no presolve or osl presolve - compact columns
          compressInfo = ekk_compressModel(model);
          clp = clpmodel(model, startup);;
     } else {
          // pick up clp model
          clp = presolveInfo->model();
     }

     // don't scale if alreday scaled
     if (scaled)
          clp->scaling(false);
     if (clp->numberRows() > 10000)
          clp->factorization()->maximumPivots(100 + clp->numberRows() / 100);
     if (algorithm > 0)
          clp->primal(startup);
     else
          clp->dual();

     int numberIterations = clp->numberIterations();
     if (presolve && presolveInfo) {
          // very wasteful - create a clp copy of osl model
          ClpSimplex * clpOriginal = clpmodel(model, 0);
          presolveInfo->setOriginalModel(clpOriginal);
          // do postsolve
          presolveInfo->postsolve(true);
          delete clp;
          delete presolveInfo;
          presolveInfo = NULL;
          clp = clpOriginal;
          if (presolve == 3 || (presolve == 2 && clp->status())) {
               printf("Resolving from postsolved model\n");
               clp->primal(1);
               numberIterations += clp->numberIterations();
          }
     }

     // put back solution

     double * rowDual = (double *) ekk_rowduals(model);
     int numberRows = ekk_getInumrows(model);
     int numberColumns = ekk_getInumcols(model);
     int * rowStatus = (int *) ekk_rowstat(model);
     double * rowSolution = (double *) ekk_rowacts(model);
     int i;
     int * columnStatus = (int *) ekk_colstat(model);
     double * columnSolution = (double *) ekk_colsol(model);
     memcpy(rowSolution, clp->primalRowSolution(), numberRows * sizeof(double));
     memcpy(rowDual, clp->dualRowSolution(), numberRows * sizeof(double));
     for (i = 0; i < numberRows; i++) {
          if (clp->getRowStatus(i) == ClpSimplex::basic)
               rowStatus[i] = 0x80000000;
          else
               rowStatus[i] = 0;
     }

     double * columnDual = (double *) ekk_colrcosts(model);
     memcpy(columnSolution, clp->primalColumnSolution(),
            numberColumns * sizeof(double));
     memcpy(columnDual, clp->dualColumnSolution(), numberColumns * sizeof(double));
     for (i = 0; i < numberColumns; i++) {
          if (clp->getColumnStatus(i) == ClpSimplex::basic)
               columnStatus[i] = 0x80000000;
          else
               columnStatus[i] = 0;
     }
     ekk_setIprobstat(model, clp->status());
     ekk_setRobjvalue(model, clp->objectiveValue());
     ekk_setInumpinf(model, clp->numberPrimalInfeasibilities());
     ekk_setInumdinf(model, clp->numberDualInfeasibilities());
     ekk_setIiternum(model, numberIterations);
     ekk_setRsumpinf(model, clp->sumPrimalInfeasibilities());
     ekk_setRsumdinf(model, clp->sumDualInfeasibilities());
     delete clp;
     if (compressInfo)
          ekk_decompressModel(model, compressInfo);

     if (scaled)
          ekk_scaleRim(model, 2);
     return 0;
}
Пример #3
0
//-----------------------------------------------------------------------------
void CbcSolverLongThin::resolve()
{
  int * whichRow = NULL;
  int * whichColumn = NULL;
  // problem may be small enough to do nested search
  const double * colLower = modelPtr_->columnLower();
  const double * colUpper = modelPtr_->columnUpper();
  
  int numberIntegers = model_->numberIntegers();
  const int * integerVariable = model_->integerVariable();
  int numberRows=modelPtr_->numberRows();
  int numberColumns = modelPtr_->numberColumns();
  
  int i;
  int nFix=0;
  int nNewRow=0;
  int nNewCol=0;
  int sizeDynamic = COIN_INT_MAX;
  int smallOriginalNumberRows=0;
  if (algorithm_==0) {
    for (i=0;i<numberIntegers;i++) {
      int iColumn=integerVariable[i];
      if (colLower[iColumn]==colUpper[iColumn])
        nFix++;
    }
  } else {
    whichRow = new int[numberRows];
    whichColumn = new int [numberColumns];
    // more sophisticated
    OsiCuts cs;
    tryCut->generateCuts(*this,cs);
    int numberCuts = cs.sizeColCuts();
    if (numberCuts) {
      for ( i = 0 ; i < numberCuts ; i++) {
        const OsiColCut *thisCut = cs.colCutPtr(i) ;
	const CoinPackedVector & ubs = thisCut->ubs() ;
	int n = ubs.getNumElements() ;
	const int * which = ubs.getIndices() ;
	const double * values = ubs.getElements() ;
	for (int j = 0;j<n;j++) {
	  int iColumn = which[j] ;
	  this->setColUpper(iColumn,values[j]) ;
        }
      }
    }
#if 1
    const int * duplicate = tryCut->duplicate();
    sizeDynamic = tryCut->sizeDynamic();
    int nOrig = tryCut->numberOriginalRows();
    for (i=0;i<nOrig;i++) {
      if (duplicate[i]==-1)
        whichRow[nNewRow++]=i;
      else
        modelPtr_->setRowStatus(i,ClpSimplex::basic);
    }
    smallOriginalNumberRows=nNewRow;
    for (;i<numberRows;i++) {
      whichRow[nNewRow++]=i;
    }
#else
    for (i=0;i<numberRows;i++) 
      whichRow[i]=i;
    nNewRow=numberRows;
#endif
    for (i=0;i<numberIntegers;i++) {
      int iColumn=integerVariable[i];
      if (colLower[iColumn]==colUpper[iColumn])
        nFix++;
      bool choose;
      if (algorithm_==1)
        choose = true;
      else
        choose = (node_[i]>count_-memory_&&node_[i]>0);
      if ((choose&&colUpper[i])
	  ||(modelPtr_->getStatus(i)!=ClpSimplex::atLowerBound&&
             modelPtr_->getStatus(i)!=ClpSimplex::isFixed)
	  ||colLower[i]>0.0)
	whichColumn[nNewCol++]=i;
    }
  }
  if (nestedSearch_<1.0&&model_&&model_->phase()==2) {
    if (((double) sizeDynamic)*((double) nNewCol)<1000000000&&sizeDynamic<10000000) {
      // could do Dynamic Programming
      // back to original number of rows
      nNewRow = smallOriginalNumberRows;
      // and get rid of any basics
      int nNewCol=0;
      for (i=0;i<numberColumns;i++) {
        if (colUpper[i]||colLower[i]>0.0)
          whichColumn[nNewCol++]=i;
      }
      ClpSimplex temp(modelPtr_,nNewRow,whichRow,nNewCol,whichColumn);
      int returnCode;
      double * rowLower2 = temp.rowLower();
      double * rowUpper2 = temp.rowUpper();
      int numberColumns2 = temp.numberColumns();
      double * colLower2 = temp.columnLower();
      double * colUpper2 = temp.columnUpper();
      const CoinPackedMatrix * matrix = temp.matrix();
      const double * element = matrix->getElements();
      const int * row = matrix->getIndices();
      const CoinBigIndex * columnStart = matrix->getVectorStarts();
      const int * columnLength = matrix->getVectorLengths();
      double offset=0.0;
      const double * objective = temp.objective();
      bool feasible=true;
      for (i=0;i<numberColumns2;i++) {
        double value = colLower2[i];
        if (value) {
          offset += value*objective[i];
          colLower2[i]=0.0;
          colUpper2[i] -= value;
          for (int j=columnStart[i];
               j<columnStart[i]+columnLength[i];j++) {
            int iRow=row[j];
            rowLower2[iRow] -= value*element[j]; 
            rowUpper2[iRow] -= value*element[j]; 
            if (rowUpper2[iRow]<-1.0e-8) {
              feasible=false;
              printf("odd - problem is infeasible\n");
            }
          }
        }
      }
      temp.setObjectiveOffset(-offset);
      OsiClpSolverInterface temp2(&temp);
      double * solutionDP = NULL;
      if (feasible) {
        for (i=0;i<numberColumns2;i++) 
          temp2.setInteger(i);
        CbcModel modelSmall(temp2);
        modelSmall.messageHandler()->setLogLevel(0);
        CbcFathomDynamicProgramming fathom1(modelSmall);
        // Set maximum space allowed
        fathom1.setMaximumSize(100000000);
        temp2.writeMps("small");
        returnCode=fathom1.fathom(solutionDP);
        if (returnCode!=1) {
          printf("probably not enough memory\n");
          abort();
        }
      }
      if (solutionDP) {
        double objValue = 0.0;
        double * solution = modelPtr_->primalColumnSolution();
        const double * objective = modelPtr_->objective();
        for (i=0;i<numberColumns;i++) 
          solution[i]=colLower[i];
        for (i=0;i<nNewCol;i++) {
          int iColumn = whichColumn[i];
          solution[iColumn]+=solutionDP[i];
        }
        for (i=0;i<numberColumns;i++) 
          objValue += solution[i]*objective[i];
        if (objValue<model_->getCutoff()) {
          printf("good solution %g by dynamic programming\n",objValue);
          returnCode = 0;
          // paranoid check
          double * rowLower = modelPtr_->rowLower();
          double * rowUpper = modelPtr_->rowUpper();
          // Column copy
          const CoinPackedMatrix * matrix2 = modelPtr_->matrix();
          element = matrix2->getElements();
          row = matrix2->getIndices();
          columnStart = matrix2->getVectorStarts();
          columnLength = matrix2->getVectorLengths();
          double * rowActivity = new double [numberRows];
          memset(rowActivity,0,numberRows*sizeof(double));
          for (i=0;i<numberColumns;i++) {
            int j;
            double value = solution[i];
            assert (value>=colLower[i]&&value<=colUpper[i]);
            if (value) {
              printf("%d has value %g\n",i,value);
              for (j=columnStart[i];
                   j<columnStart[i]+columnLength[i];j++) {
                int iRow=row[j];
                rowActivity[iRow] += value*element[j];
              }
            }
          }
          // check was feasible
          bool feasible=true;
          for (i=0;i<numberRows;i++) {
            if(rowActivity[i]<rowLower[i]) {
              if (rowActivity[i]<rowLower[i]-1.0e-8)
                feasible = false;
            } else if(rowActivity[i]>rowUpper[i]) {
              if (rowActivity[i]>rowUpper[i]+1.0e-8)
                feasible = false;
            }
          }
          if (!feasible) {
            printf("** Bad solution by dynamic programming\n");
            abort();
          }
          delete [] rowActivity;
          model_->setBestSolution(CBC_TREE_SOL,objValue,solution);
        } else {
          returnCode=2;
        }
      } else {
        returnCode=2;
      }
      temp2.releaseClp();
      modelPtr_->setProblemStatus(1);
      delete [] whichRow;
      delete [] whichColumn;
      return;
    }
    if (nFix>nestedSearch_*numberIntegers) {
      // Do nested search
      // back to original number of rows
      nNewRow = smallOriginalNumberRows;
      // and get rid of any basics
      int nNewCol=0;
      for (i=0;i<numberColumns;i++) {
        if (colUpper[i]||colLower[i]>0.0)
          whichColumn[nNewCol++]=i;
      }
#if 0
      // We clone from continuous solver so set some stuff
      OsiSolverInterface * solver = model_->continuousSolver();
      CbcSolverLongThin * osiclp = dynamic_cast< CbcSolverLongThin*> (solver);
      assert (osiclp);
      // up special options
      if (osiclp->specialOptions()==3)
	osiclp->setSpecialOptions(7);
      double saveNested = osiclp->getNested();
      int saveAlgorithm = osiclp->getAlgorithm();
      osiclp->setNested(1.0);
      osiclp->setAlgorithm(0);
      int numberObjects = model_->numberObjects();
      if (numberObjects>model_->numberIntegers()) {
	// for now only integers
	//assert (numberObjects == model_->numberIntegers()+1);
	model_->setNumberObjects(model_->numberIntegers());
        // try follow on
	//model_->setNumberObjects(model_->numberIntegers()+1);
      }
      double saveMaxTime = model_->getDblParam(CbcModel::CbcMaximumSeconds);
      model_->setDblParam(CbcModel::CbcMaximumSeconds,1.0e5);
      // up special options
#if 1
      int returnCode= model_->subBranchAndBound(colLower,colUpper,2000);
#else
      CbcModel * model3 = model_->cleanModel(colLower,colUpper);
      // integer presolve
      int returnCode=0;
      CbcModel * model2 = model3->integerPresolve(false);
      if (!model2||!model2->getNumRows()) {
        delete model2;
        delete model3;
        returnCode= 2;
      } else {
        if (handler_->logLevel()>1)
          printf("Reduced model has %d rows and %d columns\n",
                 model2->getNumRows(),model2->getNumCols());
        if (true) {
          OsiSolverInterface * solver = model2->solver();
          OsiSolverInterface * osiclp = dynamic_cast< OsiSolverInterface*> (solver);
          assert (osiclp);
          int * priority = new int [numberColumns+1];
          int n=0;
          int iColumn;
          for ( iColumn=0;iColumn<numberColumns;iColumn++) {
            if (solver->isInteger(iColumn)) {
              priority[n++]=10000;
            }
          }
          priority[n]=1;
          CbcObject * newObject =new CbcFollowOn2(model2);
          model2->addObjects(1,&newObject);
          delete newObject;
          model2->passInPriorities(priority,false);
          delete [] priority;
        }
        returnCode= model_->subBranchAndBound(model3,model2,4000);
      }
#endif
      model_->setDblParam(CbcModel::CbcMaximumSeconds,saveMaxTime);
      model_->setNumberObjects(numberObjects);
      osiclp->setNested(saveNested);
      osiclp->setAlgorithm(saveAlgorithm);
#else
      // start again very simply
      ClpSimplex temp(modelPtr_,nNewRow,whichRow,nNewCol,whichColumn);
      int returnCode;
      OsiClpSolverInterface temp2(&temp);
      temp2.setupForRepeatedUse(2);
      int numberColumns2 = temp.numberColumns();
      const double * colUpper2 = temp2.getColUpper();
      const double * colLower2 = temp2.getColLower();
      const double * solution2 = temp.getColSolution();
      double * cleanSolution2 = new double [numberColumns2];
      for (i=0;i<numberColumns2;i++) {
        temp2.setInteger(i);
        double value = solution2[i];
        value = CoinMin(CoinMax(value,colLower2[i]),colUpper2[i]);
        cleanSolution2[i] = value;
      }
      temp2.setColSolution(cleanSolution2);
      delete [] cleanSolution2;
      CbcModel modelSmall(temp2);
      modelSmall.setNumberStrong(0);
      CglProbing generator1;
      generator1.setUsingObjective(true);
      generator1.setMaxPass(3);
      generator1.setMaxProbe(100);
      generator1.setMaxLook(50);
      generator1.setRowCuts(3);
      
      CglGomory generator2;
      // try larger limit
      generator2.setLimit(300);
      
      CglKnapsackCover generator3;
      
      CglOddHole generator4;
      generator4.setMinimumViolation(0.005);
      generator4.setMinimumViolationPer(0.00002);
      // try larger limit
      generator4.setMaximumEntries(200);
      
      CglClique generator5;
      generator5.setStarCliqueReport(false);
      generator5.setRowCliqueReport(false);
      
      CglMixedIntegerRounding mixedGen;
      CglFlowCover flowGen;
      
      // Add in generators
      modelSmall.addCutGenerator(&generator1,-1,"Probing",true,false,false,-1);
      modelSmall.addCutGenerator(&generator2,-99,"Gomory",true,false,false,-99);
      modelSmall.addCutGenerator(&generator3,-99,"Knapsack",true,false,false,-99);
      modelSmall.addCutGenerator(&generator4,-99,"OddHole",true,false,false,-99);
      modelSmall.addCutGenerator(&generator5,-99,"Clique",true,false,false,-99);
      modelSmall.addCutGenerator(&flowGen,-99,"FlowCover",true,false,false,-99);
      modelSmall.addCutGenerator(&mixedGen,-99,"MixedIntegerRounding",true,false,false,-100);
#if 1
      const CoinPackedMatrix * matrix = temp2.getMatrixByCol();
      const int * columnLength = matrix->getVectorLengths();
      int * priority = new int [numberColumns2+1];
      // do pseudo costs and priorities - take a reasonable guess
      CbcObject ** objects = new CbcObject * [numberColumns2+1];
      int n=0;
      const double * objective = modelSmall.getObjCoefficients();
      for (i=0;i<numberColumns2;i++) {
        CbcSimpleIntegerPseudoCost * newObject =
          new CbcSimpleIntegerPseudoCost(&modelSmall,n,i,objective[i],0.5*objective[i]);
        newObject->setMethod(3);
        objects[n]= newObject;
        priority[n++]=10000-columnLength[i];
      }
      priority[n]=1;
      objects[n++]=new CbcFollowOn2(&modelSmall);
      modelSmall.addObjects(n,objects);
      for (i=0;i<n;i++)
        delete objects[i];
      delete [] objects;
      modelSmall.passInPriorities(priority,false);
      delete [] priority;
#endif
      modelSmall.setCutoff(model_->getCutoff());
      //if (!onPathX&&modelSmall.getCutoff()>480.5)
      //modelSmall.setCutoff(480.5);
      //printf("cutoff %g\n",model_->getCutoff());
      modelSmall.messageHandler()->setLogLevel(1);
      modelSmall.solver()->messageHandler()->setLogLevel(0);
      modelSmall.messagesPointer()->setDetailMessage(3,9);
      modelSmall.messagesPointer()->setDetailMessage(3,6);
      modelSmall.messagesPointer()->setDetailMessage(3,4);
      modelSmall.messagesPointer()->setDetailMessage(3,13);
      modelSmall.messagesPointer()->setDetailMessage(3,14);
      modelSmall.messagesPointer()->setDetailMessage(3,1);
      modelSmall.messagesPointer()->setDetailMessage(3,3007);
      modelSmall.branchAndBound();
      temp2.releaseClp();
      if (modelSmall.bestSolution()) {
        double objValue = 0.0;
        const double * solution2 = modelSmall.bestSolution();
        double * solution = modelPtr_->primalColumnSolution();
        const double * objective = modelPtr_->objective();
        for (i=0;i<numberColumns;i++) 
          solution[i]=colLower[i];
        for (i=0;i<nNewCol;i++) {
          int iColumn = whichColumn[i];
          solution[iColumn]=solution2[i];
        }
        for (i=0;i<numberColumns;i++) 
          objValue += solution[i]*objective[i];
        assert (objValue<model_->getCutoff());
        if (objValue<model_->getCutoff()) {
          //printf("good solution \n");
          model_->setBestSolution(CBC_TREE_SOL,objValue,solution);
          returnCode = 0;
        } else {
          returnCode=2;
        }
      } else {
        returnCode=2;
      }
#endif
      if (returnCode!=0&&returnCode!=2) {
	printf("pretending entire search done\n");
	returnCode=0;
      }
      if (returnCode==0||returnCode==2) {
	modelPtr_->setProblemStatus(1);
        delete [] whichRow;
        delete [] whichColumn;
	return;
     }
    }
  }
  if ((count_<100&&algorithm_==2)||!algorithm_) {
    delete [] whichRow;
    delete [] whichColumn;
    assert(!modelPtr_->specialOptions());
    int saveOptions = modelPtr_->specialOptions();
    int startFinishOptions;
    bool takeHint;
    OsiHintStrength strength;
    bool gotHint = (getHintParam(OsiDoInBranchAndCut,takeHint,strength));
    assert (gotHint);
    if (strength!=OsiHintIgnore&&takeHint) {
      // could do something - think about it
      //printf("thin hint %d %c\n",strength,takeHint ? 'T' :'F');
    }
    if((specialOptions_&1)==0) {
      startFinishOptions=0;
      modelPtr_->setSpecialOptions(saveOptions|(64|1024));
    } else {
      startFinishOptions=1+2+4;
      if((specialOptions_&4)==0) 
	modelPtr_->setSpecialOptions(saveOptions|(64|128|512|1024|4096));
      else
	modelPtr_->setSpecialOptions(saveOptions|(64|128|512|1024|2048|4096));
    }
    //printf("thin options %d size %d\n",modelPtr_->specialOptions(),modelPtr_->numberColumns());
    setBasis(basis_,modelPtr_);
    //modelPtr_->setLogLevel(1);
    modelPtr_->dual(0,0);
    basis_ = getBasis(modelPtr_);
    modelPtr_->setSpecialOptions(saveOptions);
    if (modelPtr_->status()==0) {
      count_++;
      double * solution = modelPtr_->primalColumnSolution();
      int i;
      for (i=0;i<numberColumns;i++) {
	if (solution[i]>1.0e-6||modelPtr_->getStatus(i)==ClpSimplex::basic) {
	  node_[i]=CoinMax(count_,node_[i]);
	  howMany_[i]++;
	}
      }
    } else {
      if (!algorithm_==2)
	printf("infeasible early on\n");
    }
  } else {
    // use counts
    int i;
    const double * lower = modelPtr_->columnLower();
    const double * upper = modelPtr_->columnUpper();
    setBasis(basis_,modelPtr_);
    ClpSimplex * temp = new ClpSimplex(modelPtr_,nNewRow,whichRow,nNewCol,whichColumn);
    //temp->setLogLevel(2);
    //printf("small has %d rows and %d columns\n",nNewRow,nNewCol);
    temp->setSpecialOptions(128+512);
    temp->setDualObjectiveLimit(1.0e50);
    temp->dual();
    if (temp->status()) {
      // In some cases we know that it must be infeasible
      if (believeInfeasible_||algorithm_==1) {
	modelPtr_->setProblemStatus(1);
	printf("assuming infeasible!\n");
	//modelPtr_->writeMps("infeas.mps");
	//temp->writeMps("infeas2.mps");
	//abort();
	delete temp;
        delete [] whichRow;
	delete [] whichColumn;
	return;
      }
    }
    double * solution = modelPtr_->primalColumnSolution();
    if (!temp->status()) {
      const double * solution2 = temp->primalColumnSolution();
      memset(solution,0,numberColumns*sizeof(double));
      for (i=0;i<nNewCol;i++) {
	int iColumn = whichColumn[i];
	solution[iColumn]=solution2[i];
	modelPtr_->setStatus(iColumn,temp->getStatus(i));
      }
      double * rowSolution = modelPtr_->primalRowSolution();
      const double * rowSolution2 = temp->primalRowSolution();
      double * dual = modelPtr_->dualRowSolution();
      const double * dual2 = temp->dualRowSolution();
      memset(dual,0,numberRows*sizeof(double));
      for (i=0;i<nNewRow;i++) {
        int iRow=whichRow[i];
        modelPtr_->setRowStatus(iRow,temp->getRowStatus(i));
        rowSolution[iRow]=rowSolution2[i];
        dual[iRow]=dual2[i];
      }
      // See if optimal
      double * dj = modelPtr_->dualColumnSolution();
      // get reduced cost for large problem
      // this assumes minimization
      memcpy(dj,modelPtr_->objective(),numberColumns*sizeof(double));
      modelPtr_->transposeTimes(-1.0,dual,dj);
      modelPtr_->setObjectiveValue(temp->objectiveValue());
      modelPtr_->setProblemStatus(0);
      int nBad=0;
      
      for (i=0;i<numberColumns;i++) {
	if (modelPtr_->getStatus(i)==ClpSimplex::atLowerBound
	    &&upper[i]>lower[i]&&dj[i]<-1.0e-5)
	  nBad++;
      }
      //modelPtr_->writeMps("bada.mps");
      //temp->writeMps("badb.mps");
      if (nBad) {
        assert (algorithm_==2);
	//printf("%d bad\n",nBad);
	timesBad_++;
	modelPtr_->primal();
      }
    } else {
      // infeasible - do all
      modelPtr_->setSpecialOptions(64+128+512);
      setBasis(basis_,modelPtr_);
      //modelPtr_->setLogLevel(1);
      modelPtr_->dual(0,0);
      basis_ = getBasis(modelPtr_);
      modelPtr_->setSpecialOptions(0);
      if (modelPtr_->status()) {
	printf("really infeasible!\n");
	delete temp;
        delete [] whichRow;
	delete [] whichColumn;
	return;
      } else {
	printf("initially infeasible\n");
      }
    }
    delete temp;
    delete [] whichRow;
    delete [] whichColumn;
    basis_ = getBasis(modelPtr_);
    modelPtr_->setSpecialOptions(0);
    count_++;
    if ((count_%100)==0&&algorithm_==2)
      printf("count %d, bad %d\n",count_,timesBad_);
    for (i=0;i<numberColumns;i++) {
      if (solution[i]>1.0e-6||modelPtr_->getStatus(i)==ClpSimplex::basic) {
	node_[i]=CoinMax(count_,node_[i]);
	howMany_[i]++;
      }
    }
    if (modelPtr_->objectiveValue()>=modelPtr_->dualObjectiveLimit())
      modelPtr_->setProblemStatus(1);
  }
}
Пример #4
0
int main(int argc, const char *argv[])
{
     ClpSimplex  model;
     int status;
     // Keep names when reading an mps file
     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], true);

     if (status) {
          fprintf(stderr, "Bad readMps %s\n", argv[1]);
          fprintf(stdout, "Bad readMps %s\n", argv[1]);
          exit(1);
     }
#ifdef STYLE1
     if (argc < 3 || !strstr(argv[2], "primal")) {
          // Use the dual algorithm unless user said "primal"
          model.initialDualSolve();
     } else {
          model.initialPrimalSolve();
     }
#else
     ClpSolve solvectl;


     if (argc < 3 || (!strstr(argv[2], "primal") && !strstr(argv[2], "barrier"))) {
          // Use the dual algorithm unless user said "primal" or "barrier"
          std::cout << std::endl << " Solve using Dual: " << std::endl;
          solvectl.setSolveType(ClpSolve::useDual);
          solvectl.setPresolveType(ClpSolve::presolveOn);
          model.initialSolve(solvectl);
     } else if (strstr(argv[2], "barrier")) {
          // Use the barrier algorithm if user said "barrier"
          std::cout << std::endl << " Solve using Barrier: " << std::endl;
          solvectl.setSolveType(ClpSolve::useBarrier);
          solvectl.setPresolveType(ClpSolve::presolveOn);
          model.initialSolve(solvectl);
     } else {
          std::cout << std::endl << " Solve using Primal: " << std::endl;
          solvectl.setSolveType(ClpSolve::usePrimal);
          solvectl.setPresolveType(ClpSolve::presolveOn);
          model.initialSolve(solvectl);
     }
#endif
     std::string modelName;
     model.getStrParam(ClpProbName, modelName);
     std::cout << "Model " << modelName << " has " << model.numberRows() << " rows and " <<
               model.numberColumns() << " columns" << std::endl;

     // remove this to print solution

     exit(0);

     /*
       Now to print out solution.  The methods used return modifiable
       arrays while the alternative names return const pointers -
       which is of course much more virtuous.

       This version just does non-zero columns

      */
#if 0
     int numberRows = model.numberRows();

     // Alternatively getRowActivity()
     double * rowPrimal = model.primalRowSolution();
     // Alternatively getRowPrice()
     double * rowDual = model.dualRowSolution();
     // Alternatively getRowLower()
     double * rowLower = model.rowLower();
     // Alternatively getRowUpper()
     double * rowUpper = model.rowUpper();
     // Alternatively getRowObjCoefficients()
     double * rowObjective = model.rowObjective();

     // If we have not kept names (parameter to readMps) this will be 0
     assert(model.lengthNames());

     // Row names
     const std::vector<std::string> * rowNames = model.rowNames();


     int iRow;

     std::cout << "                       Primal          Dual         Lower         Upper        (Cost)"
               << std::endl;

     for (iRow = 0; iRow < numberRows; iRow++) {
          double value;
          std::cout << std::setw(6) << iRow << " " << std::setw(8) << (*rowNames)[iRow];
          value = rowPrimal[iRow];
          if (fabs(value) < 1.0e5)
               std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
          else
               std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
          value = rowDual[iRow];
          if (fabs(value) < 1.0e5)
               std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
          else
               std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
          value = rowLower[iRow];
          if (fabs(value) < 1.0e5)
               std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
          else
               std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
          value = rowUpper[iRow];
          if (fabs(value) < 1.0e5)
               std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
          else
               std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
          if (rowObjective) {
               value = rowObjective[iRow];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
          }
          std::cout << std::endl;
     }
#endif
     std::cout << "--------------------------------------" << std::endl;

     // Columns

     int numberColumns = model.numberColumns();

     // Alternatively getColSolution()
     double * columnPrimal = model.primalColumnSolution();
     // Alternatively getReducedCost()
     double * columnDual = model.dualColumnSolution();
     // Alternatively getColLower()
     double * columnLower = model.columnLower();
     // Alternatively getColUpper()
     double * columnUpper = model.columnUpper();
     // Alternatively getObjCoefficients()
     double * columnObjective = model.objective();

     // If we have not kept names (parameter to readMps) this will be 0
     assert(model.lengthNames());

     // Column names
     const std::vector<std::string> * columnNames = model.columnNames();


     int iColumn;

     std::cout << "                       Primal          Dual         Lower         Upper          Cost"
               << std::endl;

     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          double value;
          value = columnPrimal[iColumn];
          if (fabs(value) > 1.0e-8) {
               std::cout << std::setw(6) << iColumn << " " << std::setw(8) << (*columnNames)[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnDual[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnLower[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnUpper[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;
               value = columnObjective[iColumn];
               if (fabs(value) < 1.0e5)
                    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14) << value;
               else
                    std::cout << std::setiosflags(std::ios::scientific) << std::setw(14) << value;

               std::cout << std::endl;
          }
     }
     std::cout << "--------------------------------------" << std::endl;

     return 0;
}
Пример #5
0
int main(int argc, const char *argv[])
{
     /* Read quadratic model in two stages to test loadQuadraticObjective.

        And is also possible to just read into ClpSimplex/Interior which sets it all up in one go.
        But this is only if it is in QUADOBJ format.

        If no arguments does share2qp using ClpInterior (also creates quad.mps which is in QUADOBJ format)
        If one argument uses simplex e.g. testit quad.mps
        If > one uses barrier via ClpSimplex input and then ClpInterior borrow
     */
     if (argc < 2) {
          CoinMpsIO  m;
#if defined(SAMPLEDIR)
          int status = m.readMps(SAMPLEDIR "/share2qp", "mps");
#else
          fprintf(stderr, "Do not know where to find sample MPS files.\n");
          exit(1);
#endif
          if (status) {
               printf("errors on input\n");
               exit(77);
          }
          ClpInterior model;
          model.loadProblem(*m.getMatrixByCol(), m.getColLower(), m.getColUpper(),
                            m.getObjCoefficients(),
                            m.getRowLower(), m.getRowUpper());
          // get quadratic part
          int * start = NULL;
          int * column = NULL;
          double * element = NULL;
          m.readQuadraticMps(NULL, start, column, element, 2);
          int j;
          for (j = 0; j < 79; j++) {
               if (start[j] < start[j+1]) {
                    int i;
                    printf("Column %d ", j);
                    for (i = start[j]; i < start[j+1]; i++) {
                         printf("( %d, %g) ", column[i], element[i]);
                    }
                    printf("\n");
               }
          }
          model.loadQuadraticObjective(model.numberColumns(), start, column, element);
          // share2qp is in old style qp format - convert to new so other options can use
          model.writeMps("quad.mps");
          ClpCholeskyBase * cholesky = new ClpCholeskyBase();
          cholesky->setKKT(true);
          model.setCholesky(cholesky);
          model.primalDual();
          double *primal;
          double *dual;
          primal = model.primalColumnSolution();
          dual = model.dualRowSolution();
          int i;
          int numberColumns = model.numberColumns();
          int numberRows = model.numberRows();
          for (i = 0; i < numberColumns; i++) {
               if (fabs(primal[i]) > 1.0e-8)
                    printf("%d primal %g\n", i, primal[i]);
          }
          for (i = 0; i < numberRows; i++) {
               if (fabs(dual[i]) > 1.0e-8)
                    printf("%d dual %g\n", i, dual[i]);
          }
     } else {
          // Could read into ClpInterior
          ClpSimplex model;
          if (model.readMps(argv[1])) {
               printf("errors on input\n");
               exit(77);
          }
          model.writeMps("quad");
          if (argc < 3) {
               // simplex - just primal as dual does not work
               // also I need to fix scaling of duals on output
               // (Was okay in first place - can't mix and match scaling techniques)
               // model.scaling(0);
               model.primal();
          } else {
               // barrier
               ClpInterior barrier;
               barrier.borrowModel(model);
               ClpCholeskyBase * cholesky = new ClpCholeskyBase();
               cholesky->setKKT(true);
               barrier.setCholesky(cholesky);
               barrier.primalDual();
               barrier.returnModel(model);
          }
          // Just check if share2qp (quad.mps here)
          // this is because I am not checking if variables at ub
          if (model.numberColumns() == 79) {
               double *primal;
               double *dual;
               primal = model.primalColumnSolution();
               dual = model.dualRowSolution();
               // Check duals by hand
               const ClpQuadraticObjective * quadraticObj =
                    (dynamic_cast<const ClpQuadraticObjective*>(model.objectiveAsObject()));
               assert(quadraticObj);
               CoinPackedMatrix * quad = quadraticObj->quadraticObjective();
               const int * columnQuadratic = quad->getIndices();
               const CoinBigIndex * columnQuadraticStart = quad->getVectorStarts();
               const int * columnQuadraticLength = quad->getVectorLengths();
               const double * quadraticElement = quad->getElements();
               int numberColumns = model.numberColumns();
               int numberRows = model.numberRows();
               double * gradient = new double [numberColumns];
               // move linear objective
               memcpy(gradient, quadraticObj->linearObjective(), numberColumns * sizeof(double));
               int iColumn;
               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
                    double valueI = primal[iColumn];
                    CoinBigIndex j;
                    for (j = columnQuadraticStart[iColumn];
                              j < columnQuadraticStart[iColumn] + columnQuadraticLength[iColumn]; j++) {
                         int jColumn = columnQuadratic[j];
                         double valueJ = primal[jColumn];
                         double elementValue = quadraticElement[j];
                         if (iColumn != jColumn) {
                              double gradientI = valueJ * elementValue;
                              double gradientJ = valueI * elementValue;
                              gradient[iColumn] += gradientI;
                              gradient[jColumn] += gradientJ;
                         } else {
                              double gradientI = valueI * elementValue;
                              gradient[iColumn] += gradientI;
                         }
                    }
                    if (fabs(primal[iColumn]) > 1.0e-8)
                         printf("%d primal %g\n", iColumn, primal[iColumn]);
               }
               for (int i = 0; i < numberRows; i++) {
                    if (fabs(dual[i]) > 1.0e-8)
                         printf("%d dual %g\n", i, dual[i]);
               }
               // Now use duals to get reduced costs
               // Can't use this as will try and use scaling
               // model.transposeTimes(-1.0,dual,gradient);
               // So ...
               CoinPackedMatrix * matrix = model.matrix();
               const int * row = matrix->getIndices();
               const CoinBigIndex * columnStart = matrix->getVectorStarts();
               const int * columnLength = matrix->getVectorLengths();
               const double * element = matrix->getElements();
               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
                    double dj = gradient[iColumn];
                    CoinBigIndex j;
                    for (j = columnStart[iColumn];
                              j < columnStart[iColumn] + columnLength[iColumn]; j++) {
                         int jRow = row[j];
                         dj -= element[j] * dual[jRow];
                    }
                    if (model.getColumnStatus(iColumn) == ClpSimplex::basic) {
                         assert(fabs(dj) < 1.0e-5);
                    } else {
                         assert(dj > -1.0e-5);
                    }
               }
               delete [] gradient;
          }
     }
     return 0;
}
Пример #6
0
//-----------------------------------------------------------------------------
void CbcSolver2::resolve()
{
  int numberColumns = modelPtr_->numberColumns();
  if ((count_<10&&algorithm_==2)||!algorithm_) {
    OsiClpSolverInterface::resolve();
    if (modelPtr_->status()==0) {
      count_++;
      double * solution = modelPtr_->primalColumnSolution();
      int i;
      for (i=0;i<numberColumns;i++) {
	if (solution[i]>1.0e-6||modelPtr_->getStatus(i)==ClpSimplex::basic) {
	  node_[i]=CoinMax(count_,node_[i]);
	  howMany_[i]++;
	}
      }
    } else {
      if (!algorithm_==2)
	printf("infeasible early on\n");
    }
  } else {
    // use counts
    int numberRows=modelPtr_->numberRows();
    int * whichRow = new int[numberRows];
    int * whichColumn = new int [numberColumns];
    int i;
    const double * lower = modelPtr_->columnLower();
    const double * upper = modelPtr_->columnUpper();
    const double * rowUpper = modelPtr_->rowUpper();
    bool equality=false;
    for (i=0;i<numberRows;i++) {
      if (rowUpper[i]==1.0) {
        equality=true;
        break;
      }
    }
    setBasis(basis_,modelPtr_);
    int nNewCol=0;
    // Column copy
    //const double * element = modelPtr_->matrix()->getElements();
    const int * row = modelPtr_->matrix()->getIndices();
    const CoinBigIndex * columnStart = modelPtr_->matrix()->getVectorStarts();
    const int * columnLength = modelPtr_->matrix()->getVectorLengths();
    
    int * rowActivity = new int[numberRows];
    memset(rowActivity,0,numberRows*sizeof(int));
    int * rowActivity2 = new int[numberRows];
    memset(rowActivity2,0,numberRows*sizeof(int));
    char * mark = new char[numberColumns];
    memset(mark,0,numberColumns);
    // Get rows which are satisfied
    for (i=0;i<numberColumns;i++) {
      if (lower[i]>0.0) {
        CoinBigIndex j;
        for (j=columnStart[i];
             j<columnStart[i]+columnLength[i];j++) {
          int iRow=row[j];
          rowActivity2[iRow] ++;
        }
      } else if (!upper[i]) {
        mark[i]=2; // no good
      }
    }
    // If equality - check not infeasible
    if (equality) {
      bool feasible=true;
      for (i=0;i<numberRows;i++) {
        if (rowActivity2[i]>1) {
          feasible=false;
          break;
        }
      }
      if (!feasible) {
        delete [] rowActivity;
        delete [] rowActivity2;
        modelPtr_->setProblemStatus(1);
        delete [] whichRow;
        delete [] whichColumn;
        delete [] mark;
        printf("infeasible by inspection (over)\n");
        return;
      }
    }
    int nNoGood=0;
    for (i=0;i<numberColumns;i++) {
      if (mark[i]==2) {
        nNoGood++;
        continue;
      }
      bool choose;
      if (algorithm_==1)
        choose = true;
      else
        choose = (node_[i]>count_-memory_&&node_[i]>0);
      bool any;
      if (equality) {
        // See if forced to be zero
        CoinBigIndex j;
        any=true;
        for (j=columnStart[i];
             j<columnStart[i]+columnLength[i];j++) {
          int iRow=row[j];
          if (rowActivity2[iRow])
            any=false; // can't be in
        }
      } else {
        // See if not useful
        CoinBigIndex j;
        any=false;
        for (j=columnStart[i];
             j<columnStart[i]+columnLength[i];j++) {
          int iRow=row[j];
          if (!rowActivity2[iRow])
            any=true; // useful
        }
      }
      if (!any&&!lower[i]) {
        choose=false;
        // and say can't be useful
        mark[i]=2;
        nNoGood++;
      }
      if (strategy_&&modelPtr_->getColumnStatus(i)==ClpSimplex::basic)
        choose=true;
      if (choose||lower[i]>0.0) {
        mark[i]=1;
	whichColumn[nNewCol++]=i;
        CoinBigIndex j;
        double value = upper[i];
        if (value) {
          for (j=columnStart[i];
               j<columnStart[i]+columnLength[i];j++) {
            int iRow=row[j];
            rowActivity[iRow] ++;
          }
        }
      }
    }
    // If equality add in slacks
    CoinModel build;
    if (equality) {
      int row=0;
      for (i=0;i<numberRows;i++) {
        // put in all rows if wanted
        if(strategy_)
          rowActivity2[i]=0;
        if (!rowActivity2[i]) {
          double element=1.0;
          build.addColumn(1,&row,&element,0.0,1.0,1.0e8); // large cost
          row++;
        }
      }
    }
    int nOK=0;
    int nNewRow=0;
    for (i=0;i<numberRows;i++) {
      if (rowActivity[i])
        nOK++;
      if (!rowActivity2[i])
        whichRow[nNewRow++]=i; // not satisfied
      else
        modelPtr_->setRowStatus(i,ClpSimplex::basic); // make slack basic
    }
    if (nOK<numberRows) {
      for (i=0;i<numberColumns;i++) {
        if (!mark[i]) {
          CoinBigIndex j;
          int good=0;
          for (j=columnStart[i];
               j<columnStart[i]+columnLength[i];j++) {
            int iRow=row[j];
            if (!rowActivity[iRow]) {
              rowActivity[iRow] ++;
              good++;
            }
          }
          if (good) {
            nOK+=good;
            whichColumn[nNewCol++]=i;
          }
        }
      }
    }
    delete [] rowActivity;
    delete [] rowActivity2;
    if (nOK<numberRows) {
      modelPtr_->setProblemStatus(1);
      delete [] whichRow;
      delete [] whichColumn;
      delete [] mark;
      printf("infeasible by inspection\n");
      return;
    }
    bool allIn=false;
    if (nNewCol+nNoGood+numberRows>numberColumns) {
      // add in all
      allIn=true;
      for (i=0;i<numberColumns;i++) {
        if (!mark[i]) {
          whichColumn[nNewCol++]=i;
        }
      }
    }
    ClpSimplex *  temp = new ClpSimplex(modelPtr_,nNewRow,whichRow,nNewCol,whichColumn);
    if (equality)
      temp->addColumns(build);
    temp->setLogLevel(1);
    printf("small has %d rows and %d columns (%d impossible to help) %s\n",
           nNewRow,nNewCol,nNoGood,allIn ? "all in" : "");
    temp->setSpecialOptions(128+512);
    temp->setDualObjectiveLimit(1.0e50);
    temp->dual();
    assert (!temp->status());
    double * solution = modelPtr_->primalColumnSolution();
    const double * solution2 = temp->primalColumnSolution();
    memset(solution,0,numberColumns*sizeof(double));
    for (i=0;i<nNewCol;i++) {
      int iColumn = whichColumn[i];
      solution[iColumn]=solution2[i];
      modelPtr_->setStatus(iColumn,temp->getStatus(i));
    }
    double * rowSolution = modelPtr_->primalRowSolution();
    const double * rowSolution2 = temp->primalRowSolution();
    double * dual = modelPtr_->dualRowSolution();
    const double * dual2 = temp->dualRowSolution();
    memset(dual,0,numberRows*sizeof(double));
    for (i=0;i<nNewRow;i++) {
      int iRow=whichRow[i];
      modelPtr_->setRowStatus(iRow,temp->getRowStatus(i));
      rowSolution[iRow]=rowSolution2[i];
      dual[iRow]=dual2[i];
    }
    // See if optimal
    double * dj = modelPtr_->dualColumnSolution();
    // get reduced cost for large problem
    // this assumes minimization
    memcpy(dj,modelPtr_->objective(),numberColumns*sizeof(double));
    modelPtr_->transposeTimes(-1.0,dual,dj);
    modelPtr_->setObjectiveValue(temp->objectiveValue());
    modelPtr_->setProblemStatus(0);
    int nBad=0;
    for (i=0;i<numberColumns;i++) {
      if (modelPtr_->getStatus(i)==ClpSimplex::atLowerBound
          &&upper[i]>lower[i]&&dj[i]<-1.0e-5)
        nBad++;
    }
    //modelPtr_->writeMps("bada.mps");
    //temp->writeMps("badb.mps");
    delete temp;
    if (nBad&&!allIn) {
      assert (algorithm_==2);
      //printf("%d bad\n",nBad);
      timesBad_++;
      // just non mark==2
      int nAdded=0;
      for (i=0;i<numberColumns;i++) {
        if (!mark[i]) {
          whichColumn[nNewCol++]=i;
          nAdded++;
        }
      }
      assert (nAdded);
      {
        temp = new ClpSimplex(modelPtr_,nNewRow,whichRow,nNewCol,whichColumn);
        if (equality)
          temp->addColumns(build);
        temp->setLogLevel(2);
        temp->setSpecialOptions(128+512);
        temp->setDualObjectiveLimit(1.0e50);
        temp->primal(1);
        assert (!temp->status());
        double * solution = modelPtr_->primalColumnSolution();
        const double * solution2 = temp->primalColumnSolution();
        memset(solution,0,numberColumns*sizeof(double));
        for (i=0;i<nNewCol;i++) {
          int iColumn = whichColumn[i];
          solution[iColumn]=solution2[i];
          modelPtr_->setStatus(iColumn,temp->getStatus(i));
        }
        double * rowSolution = modelPtr_->primalRowSolution();
        const double * rowSolution2 = temp->primalRowSolution();
        double * dual = modelPtr_->dualRowSolution();
        const double * dual2 = temp->dualRowSolution();
        memset(dual,0,numberRows*sizeof(double));
        for (i=0;i<nNewRow;i++) {
          int iRow=whichRow[i];
          modelPtr_->setRowStatus(iRow,temp->getRowStatus(i));
          rowSolution[iRow]=rowSolution2[i];
          dual[iRow]=dual2[i];
        }
        modelPtr_->setObjectiveValue(temp->objectiveValue());
        modelPtr_->setProblemStatus(0);
        iterationsBad_ += temp->numberIterations();
        printf("clean %d\n",temp->numberIterations());
        delete temp;
      }
    }
    delete [] mark;
    delete [] whichRow;
    delete [] whichColumn;
    basis_ = getBasis(modelPtr_);
    modelPtr_->setSpecialOptions(0);
    count_++;
    if ((count_%100)==0&&algorithm_==2)
      printf("count %d, bad %d - iterations %d\n",count_,timesBad_,iterationsBad_);
    for (i=0;i<numberColumns;i++) {
      if (solution[i]>1.0e-6||modelPtr_->getStatus(i)==ClpSimplex::basic) {
	node_[i]=CoinMax(count_,node_[i]);
	howMany_[i]++;
      }
    }
    if (modelPtr_->objectiveValue()>=modelPtr_->dualObjectiveLimit())
      modelPtr_->setProblemStatus(1);
  }
}
Пример #7
0
int main(int argc, const char *argv[])
{
     ClpSimplex  model;
     int status;

     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], true);
     if( status != 0 )
     {
        printf("Error %d reading MPS file\n", status);
        return status;
     }
     /*
       This driver uses volume algorithm
       then does dual - after adjusting costs
       then solves real problem
     */

     // do volume for a bit
     VOL_problem volprob;
     const CoinPackedMatrix* mat = model.matrix();
     const int psize = mat->getNumCols();
     const int dsize = mat->getNumRows();
     char * sense = new char[dsize];
     double * rhs = new double[dsize];
     const double * rowLower = model.rowLower();
     const double * rowUpper = model.rowUpper();
     // Set the lb/ub on the duals
     volprob.dsize = dsize;
     volprob.psize = psize;
     volprob.dual_lb.allocate(dsize);
     volprob.dual_ub.allocate(dsize);
     volprob.dsol.allocate(dsize);
     int i;
     for (i = 0; i < dsize; ++i) {
          if (rowUpper[i] == rowLower[i]) {
               // 'E':
               volprob.dual_lb[i] = -1.0e31;
               volprob.dual_ub[i] = 1.0e31;
               rhs[i] = rowUpper[i];
               sense[i] = 'E';
          } else if (rowLower[i] < -0.99e10 && rowUpper[i] < 0.99e10) {
               // 'L':
               volprob.dual_lb[i] = -1.0e31;
               volprob.dual_ub[i] = 0.0;
               rhs[i] = rowUpper[i];
               sense[i] = 'L';
          } else if (rowLower[i] > -0.99e10 && rowUpper[i] > 0.99e10) {
               // 'G':
               volprob.dual_lb[i] = 0.0;
               volprob.dual_ub[i] = 1.0e31;
               rhs[i] = rowLower[i];
               sense[i] = 'G';
          } else {
               printf("Volume Algorithm can't work if there is a non ELG row\n");
               abort();
          }
     }
     // Can't use read_param as private
     // anyway I want automatic use - so maybe this is problem
#if 0
     FILE* infile = fopen("parameters", "r");
     if (!infile) {
          printf("Failure to open parameter file\n");
     } else {
          volprob.read_params("parameters");
     }
#endif
#if 0
     // should save and restore bounds
     model.tightenPrimalBounds();
#else
     double * colUpper = model.columnUpper();
     for (i = 0; i < psize; i++)
          colUpper[i] = 1.0;
#endif
     lpHook myHook(model.getColLower(), model.getColUpper(),
                   model.getObjCoefficients(),
                   rhs, sense, *mat);
     // move duals
     double * pi = model.dualRowSolution();
     memcpy(volprob.dsol.v, pi, dsize * sizeof(double));
     volprob.solve(myHook,  false /* not warmstart */);
     // For now stop as not doing any good
     exit(77);
     // create objectives
     int numberRows = model.numberRows();
     int numberColumns = model.numberColumns();
     memcpy(pi, volprob.dsol.v, numberRows * sizeof(double));
#define MODIFYCOSTS
#ifdef MODIFYCOSTS
     double * saveObj = new double[numberColumns];
     memcpy(saveObj, model.objective(), numberColumns * sizeof(double));
     memcpy(model.dualColumnSolution(), model.objective(),
            numberColumns * sizeof(double));
     model.clpMatrix()->transposeTimes(-1.0, pi, model.dualColumnSolution());
     memcpy(model.objective(), model.dualColumnSolution(),
            numberColumns * sizeof(double));
     const double * rowsol = model.primalRowSolution();
     //const double * rowLower = model.rowLower();
     //const double * rowUpper = model.rowUpper();
     double offset = 0.0;
     for (i = 0; i < numberRows; i++) {
          offset += pi[i] * rowsol[i];
     }
     double value2;
     model.getDblParam(ClpObjOffset, value2);
     printf("Offset %g %g\n", offset, value2);
     model.setRowObjective(pi);
     // zero out pi
     memset(pi, 0, numberRows * sizeof(double));
#endif
     // Could put some in basis - only partially tested
     model.allSlackBasis();
     model.factorization()->maximumPivots(1000);
     //model.setLogLevel(63);
     // solve
     model.dual(1);
     //model.primal(1);
#ifdef MODIFYCOSTS
     memcpy(model.objective(), saveObj, numberColumns * sizeof(double));
     // zero out pi
     memset(pi, 0, numberRows * sizeof(double));
     model.setRowObjective(pi);
     delete [] saveObj;
     model.primal();
#endif

     return 0;
}