Exemplo n.º 1
0
/* Barrier initial solve */
COINLIBAPI int COINLINKAGE
Clp_initialBarrierNoCrossSolve(Clp_Simplex * model0)
{
     ClpSimplex *model = model0->model_;

     return model->initialBarrierNoCrossSolve();

}
Exemplo n.º 2
0
/* tryhard values:
   tryhard & 7:
      0: NOT lightweight, 105 iterations within a pass (when mu stays fixed)
      1: lightweight, but focus more on optimality (mu is high)
         (23 iters in a pass)
      2: lightweight, but focus more on feasibility (11 iters in a pass)
      3: lightweight, but focus more on feasibility (23 iters in a pass, so it
         goes closer to opt than option 2)
   tryhard >> 3:
      number of passes, the larger the number the closer it gets to optimality
*/
COINLIBAPI void COINLINKAGE
Clp_idiot(Clp_Simplex * model, int tryhard)
{
     ClpSimplex *clp = model->model_;
     Idiot info(*clp);
     int numberpass = tryhard >> 3;
     int lightweight = tryhard & 7;
     info.setLightweight(lightweight);
     info.crash(numberpass, clp->messageHandler(), clp->messagesPointer(), false);
}
int main (int argc, const char *argv[])
{
  ClpSimplex  model;
  int status;
  if (argc < 2)
    status=model.readMps("dovetail.mps");
  else
    status=model.readMps(argv[1]);
  if (!status) {
    model.primal();
  }
  return 0;
} 
Exemplo n.º 4
0
int main()
{
	CoinBigIndex Hcol[3] = {0,1,1};
	int Hrow[1] = {1};
	double H[1] = {1.0};
	double f[2] = {0,0};
	double lb[2] = {-0.5,0.85};
	double ub[2] = {-0.35,1};

	CoinBigIndex Acol[3] = {0,2,4};
	int Arow[4] = {0,1,0,1};
	double A[4] = {1,1,1,-1};
	double rl[2] = {-COIN_DBL_MAX,-COIN_DBL_MAX};
	double ru[2] = {1.5,1.2};

	ClpSimplex simplex;
	simplex.loadProblem(2,2,Acol,Arow,A,lb,ub,f,rl,ru);
	simplex.loadQuadraticObjective(2,Hcol,Hrow,H);
	simplex.setLogLevel(4);
	simplex.initialSolve();
	return 0;
}
Exemplo n.º 5
0
int main(int argc, const char *argv[])
{
     ClpSimplex  model;
     int status;
     if (argc < 2) {
#if defined(SAMPLEDIR)
/*
  SAMPLEDIR should "path/to/Data/Sample/"
  Include the quotes and final path separator.
*/
          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) {
          model.primal();
     }
     return 0;
}
Exemplo n.º 6
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;
  }
Exemplo n.º 7
0
int main(int argc, const char *argv[])
{
     ClpSimplex  model;
     int status;
     // Keep names
     if (argc < 2) {
          status = model.readMps("hello.mps", true);
     } else {
          status = model.readMps(argv[1], true);
     }
     if (status)
          exit(10);

     int numberColumns = model.numberColumns();
     int numberRows = model.numberRows();

     if (numberColumns > 80 || numberRows > 80) {
          printf("model too large\n");
          exit(11);
     }
     printf("This prints x wherever a non-zero element exists in the matrix.\n\n\n");

     char x[81];

     int iRow;
     // get row copy
     CoinPackedMatrix rowCopy = *model.matrix();
     rowCopy.reverseOrdering();
     const int * column = rowCopy.getIndices();
     const int * rowLength = rowCopy.getVectorLengths();
     const CoinBigIndex * rowStart = rowCopy.getVectorStarts();

     x[numberColumns] = '\0';
     for (iRow = 0; iRow < numberRows; iRow++) {
          memset(x, ' ', numberColumns);
          for (int k = rowStart[iRow]; k < rowStart[iRow] + rowLength[iRow]; k++) {
               int iColumn = column[k];
               x[iColumn] = 'x';
          }
          printf("%s\n", x);
     }
     printf("\n\n");
     return 0;
}
Exemplo n.º 8
0
CbcBranchingObject *
CbcGeneralDepth::createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int /*way*/)
{
    int numberDo = numberNodes_;
    if (whichSolution_ >= 0 && (model_->moreSpecialOptions()&33554432)==0) 
        numberDo--;
    assert (numberDo > 0);
    // create object
    CbcGeneralBranchingObject * branch = new CbcGeneralBranchingObject(model_);
    // skip solution
    branch->numberSubProblems_ = numberDo;
    // If parentBranch_ back in then will have to be 2*
    branch->numberSubLeft_ = numberDo;
    branch->setNumberBranches(numberDo);
    CbcSubProblem * sub = new CbcSubProblem[numberDo];
    int iProb = 0;
    branch->subProblems_ = sub;
    branch->numberRows_ = model_->solver()->getNumRows();
    int iNode;
    //OsiSolverInterface * solver = model_->solver();
    OsiClpSolverInterface * clpSolver
    = dynamic_cast<OsiClpSolverInterface *> (solver);
    assert (clpSolver);
    ClpSimplex * simplex = clpSolver->getModelPtr();
    int numberColumns = simplex->numberColumns();
    if ((model_->moreSpecialOptions()&33554432)==0) {
      double * lowerBefore = CoinCopyOfArray(simplex->getColLower(),
					     numberColumns);
      double * upperBefore = CoinCopyOfArray(simplex->getColUpper(),
					     numberColumns);
      ClpNodeStuff * info = nodeInfo_;
      double * weight = new double[numberNodes_];
      int * whichNode = new int [numberNodes_];
      // Sort
      for (iNode = 0; iNode < numberNodes_; iNode++) {
        if (iNode != whichSolution_) {
	  double objectiveValue = info->nodeInfo_[iNode]->objectiveValue();
	  double sumInfeasibilities = info->nodeInfo_[iNode]->sumInfeasibilities();
	  int numberInfeasibilities = info->nodeInfo_[iNode]->numberInfeasibilities();
	  double thisWeight = 0.0;
#if 1
	  // just closest
	  thisWeight = 1.0e9 * numberInfeasibilities;
	  thisWeight += sumInfeasibilities;
	  thisWeight += 1.0e-7 * objectiveValue;
	  // Try estimate
	  thisWeight = info->nodeInfo_[iNode]->estimatedSolution();
#else
	  thisWeight = 1.0e-3 * numberInfeasibilities;
	  thisWeight += 1.0e-5 * sumInfeasibilities;
	  thisWeight += objectiveValue;
#endif
	  whichNode[iProb] = iNode;
	  weight[iProb++] = thisWeight;
        }
      }
      assert (iProb == numberDo);
      CoinSort_2(weight, weight + numberDo, whichNode);
      for (iProb = 0; iProb < numberDo; iProb++) {
        iNode = whichNode[iProb];
        ClpNode * node = info->nodeInfo_[iNode];
        // move bounds
        node->applyNode(simplex, 3);
        // create subproblem
        sub[iProb] = CbcSubProblem(clpSolver, lowerBefore, upperBefore,
                                   node->statusArray(), node->depth());
        sub[iProb].objectiveValue_ = node->objectiveValue();
        sub[iProb].sumInfeasibilities_ = node->sumInfeasibilities();
        sub[iProb].numberInfeasibilities_ = node->numberInfeasibilities();
#ifdef CHECK_PATH
        if (simplex->numberColumns() == numberColumns_Z) {
	  bool onOptimal = true;
	  const double * columnLower = simplex->columnLower();
	  const double * columnUpper = simplex->columnUpper();
	  for (int i = 0; i < numberColumns_Z; i++) {
	    if (iNode == gotGoodNode_Z)
	      printf("good %d %d %g %g\n", iNode, i, columnLower[i], columnUpper[i]);
	    if (columnUpper[i] < debuggerSolution_Z[i] || columnLower[i] > debuggerSolution_Z[i] && simplex->isInteger(i)) {
	      onOptimal = false;
	      break;
	    }
	  }
	  if (onOptimal) {
	    printf("adding to node %x as %d - objs\n", this, iProb);
	    for (int j = 0; j <= iProb; j++)
	      printf("%d %g\n", j, sub[j].objectiveValue_);
	  }
        }
#endif
      }
      delete [] weight;
      delete [] whichNode;
      const double * lower = solver->getColLower();
      const double * upper = solver->getColUpper();
      // restore bounds
      for ( int j = 0; j < numberColumns; j++) {
        if (lowerBefore[j] != lower[j])
	  solver->setColLower(j, lowerBefore[j]);
        if (upperBefore[j] != upper[j])
	  solver->setColUpper(j, upperBefore[j]);
      }
      delete [] upperBefore;
      delete [] lowerBefore;
    } else {
      // from diving
      CbcSubProblem ** nodes = reinterpret_cast<CbcSubProblem **>
	(model_->temporaryPointer());
      assert (nodes);
      int adjustDepth=info->depth_;
      assert (numberDo);
      numberNodes_=0;
      for (iProb = 0; iProb < numberDo; iProb++) {
	if ((nodes[iProb]->problemStatus_&2)==0) {
	  // create subproblem (and swap way and/or make inactive)
	  sub[numberNodes_].takeOver(*nodes[iProb],true);
	  // but adjust depth
	  sub[numberNodes_].depth_+=adjustDepth;
	  numberNodes_++;
	}
	delete nodes[iProb];
      }
      branch->numberSubProblems_ = numberNodes_;
      branch->numberSubLeft_ = numberNodes_;
      branch->setNumberBranches(numberNodes_);
      if (!numberNodes_) {
	// infeasible
	delete branch;
	branch=NULL;
      }
      delete [] nodes;
    }
    return branch;
}
Exemplo n.º 9
0
int main (int argc, const char *argv[])
{

  // Define a Solver which inherits from OsiClpsolverInterface -> OsiSolverInterface
  
  ClpQuadInterface solver1;

  // Read in model using argv[1]
  if (argc <= 1) {
     printf("using %s <modelfile>\n", argv[0]);
     return 1;
  }
  // must use clp to get a quadratic model
  ClpSimplex * clp = solver1.getModelPtr();
  int numMpsReadErrors = clp->readMps(argv[1]);
  // and assert that it is a clean model
  if( numMpsReadErrors != 0 )
  {
     printf("%d errors reading MPS file\n", numMpsReadErrors);
     return numMpsReadErrors;
  }

  // This clones solver 
  CbcModel model(solver1);
  // But now model doesn't know about integers!
  const char * integerInfo = clp->integerInformation();
  int numberColumns = clp->numberColumns();
  // and point to solver
  OsiSolverInterface * solver2 = model.solver();
  for (int iColumn=0;iColumn<numberColumns;iColumn++) {
    if (integerInfo[iColumn]) 
      solver2->setInteger(iColumn);
  }
  // Okay - now we have a good MIQP solver
  // Within branch and cut it is better (at present) to switch off all objectives

  ClpQuadInterface * osiclp = dynamic_cast< ClpQuadInterface*> (solver2);
  assert (osiclp);
  // Set fake objective so Cbc not confused
  osiclp->initialize();
  solver2->setHintParam(OsiDoReducePrint,true,OsiHintTry);

  // Set up some cut generators and defaults
  // Probing first as gets tight bounds on continuous

  CglProbing generator1;
  // can not use objective
  generator1.setUsingObjective(false);
  generator1.setMaxPass(3);
  generator1.setMaxProbe(100);
  generator1.setMaxLook(50);
  generator1.setRowCuts(3);

  // Add in generators
  // Only some generators work (and even then try without first)
  model.addCutGenerator(&generator1,1,"Probing");
  // Allow rounding heuristic

  CbcRounding heuristic1(model);
  // do not add yet as don't know how to deal with quadratic objective
  //model.addHeuristic(&heuristic1);


  // Redundant definition of default branching (as Default == User)
  CbcBranchUserDecision branch;
  model.setBranchingMethod(&branch);

  // Definition of node choice
  CbcCompareUser compare;
  // breadth first
  //compare.setWeight(0.0);
  model.setNodeComparison(compare);


  // Do initial solve to continuous
  model.initialSolve();

  // Could tune more
  model.setMinimumDrop(CoinMin(1.0,
			     fabs(model.getMinimizationObjValue())*1.0e-3+1.0e-4));

  model.setMaximumCutPassesAtRoot(0);
  model.setMaximumCutPasses(0);

  // Switch off strong branching if wanted
  //model.setNumberStrong(5);
  
  model.solver()->setIntParam(OsiMaxNumIterationHotStart,10000);

  // 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
  if (model.getNumCols()<3000) {
    model.messageHandler()->setLogLevel(1);
    //model.solver()->messageHandler()->setLogLevel(0);
  } else {
    model.messageHandler()->setLogLevel(2);
    model.solver()->messageHandler()->setLogLevel(1);
  }
  model.setPrintFrequency(50);
  
  double time1 = CoinCpuTime();

  // Do complete search
  
  model.branchAndBound();

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

  // Print more statistics
  std::cout<<"Cuts at root node changed objective from "<<model.getContinuousObjective()
	   <<" to "<<model.rootObjectiveAfterCuts()<<std::endl;

  int numberGenerators = model.numberCutGenerators();
  for (int iGenerator=0;iGenerator<numberGenerators;iGenerator++) {
    CbcCutGenerator * generator = model.cutGenerator(iGenerator);
    std::cout<<generator->cutGeneratorName()<<" was tried "
	     <<generator->numberTimesEntered()<<" times and created "
	     <<generator->numberCutsInTotal()<<" cuts of which "
	     <<generator->numberCutsActive()<<" were active after adding rounds of cuts"
	     <<std::endl;
  }
  // Print solution if finished - we can't get names from Osi!

  if (!model.status()&&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;
}    
Exemplo n.º 10
0
clp_result_t clp_solve(int n_rows, int n_cols, int n_entries,
        const int *row_indices, const int *col_indices,
        const double *coeffs, const double *vec_c,
        const double *vec_b_lo, const double *vec_b_up,
        const double *vec_x_lo, const double *vec_x_up,
        int optimisation_mode, double *vec_x_soln) {

    // build column-packed coin sparse matrix from given COO data
    CoinPackedMatrix matrix(true, row_indices, col_indices,
        coeffs, (CoinBigIndex)n_entries);
    matrix.setDimensions(n_rows, n_cols);

    ClpSimplex model;

    model.loadProblem(matrix, vec_x_lo, vec_x_up, vec_c, vec_b_lo, vec_b_up);

    model.setOptimizationDirection(1.0); // minimise

    ClpSolve solve;
    if (optimisation_mode == USE_PRIMAL) {
        solve.setSolveType(ClpSolve::usePrimal);
    } else if (optimisation_mode == USE_DUAL) {
        solve.setSolveType(ClpSolve::useDual);
    } else if (optimisation_mode == USE_BARRIER) {
        solve.setSolveType(ClpSolve::useBarrier);
    }
    solve.setPresolveType(ClpSolve::presolveOn);

    model.initialSolve(solve);

    clp_result_t result;
    result.proven_optimal = model.isProvenOptimal();
    result.proven_dual_infeasible = model.isProvenDualInfeasible();
    result.proven_primal_infeasible = model.isProvenPrimalInfeasible();
    result.abandoned = model.isAbandoned();

    const double *x = model.getColSolution();
    assert(model.getNumCols() == n_cols);
    for (int i = 0; i < model.getNumCols(); ++i) {
        vec_x_soln[i] = x[i];
    }
    
    return result;
}
Exemplo n.º 11
0
// Infeasibility - large is 0.5
double
CbcGeneralDepth::infeasibility(const OsiBranchingInformation * /*info*/,
                               int &/*preferredWay*/) const
{
    whichSolution_ = -1;
    // should use genuine OsiBranchingInformation usefulInfo = model_->usefulInformation();
    // for now assume only called when correct
    //if (usefulInfo.depth_>=4&&!model_->parentModel()
    //     &&(usefulInfo.depth_%2)==0) {
    if (true) {
        OsiSolverInterface * solver = model_->solver();
        OsiClpSolverInterface * clpSolver
        = dynamic_cast<OsiClpSolverInterface *> (solver);
        if (clpSolver) {
	  if ((model_->moreSpecialOptions()&33554432)==0) {
            ClpNodeStuff * info = nodeInfo_;
            info->integerTolerance_ = model_->getIntegerTolerance();
            info->integerIncrement_ = model_->getCutoffIncrement();
            info->numberBeforeTrust_ = model_->numberBeforeTrust();
            info->stateOfSearch_ = model_->stateOfSearch();
            // Compute "small" change in branch
            int nBranches = model_->getIntParam(CbcModel::CbcNumberBranches);
            if (nBranches) {
                double average = model_->getDblParam(CbcModel::CbcSumChange) / static_cast<double>(nBranches);
                info->smallChange_ =
                    CoinMax(average * 1.0e-5, model_->getDblParam(CbcModel::CbcSmallestChange));
                info->smallChange_ = CoinMax(info->smallChange_, 1.0e-8);
            } else {
                info->smallChange_ = 1.0e-8;
            }
            int numberIntegers = model_->numberIntegers();
            double * down = new double[numberIntegers];
            double * up = new double[numberIntegers];
            int * priority = new int[numberIntegers];
            int * numberDown = new int[numberIntegers];
            int * numberUp = new int[numberIntegers];
            int * numberDownInfeasible = new int[numberIntegers];
            int * numberUpInfeasible = new int[numberIntegers];
            model_->fillPseudoCosts(down, up, priority, numberDown, numberUp,
                                    numberDownInfeasible, numberUpInfeasible);
            info->fillPseudoCosts(down, up, priority, numberDown, numberUp,
                                  numberDownInfeasible,
                                  numberUpInfeasible, numberIntegers);
            info->presolveType_ = 1;
            delete [] down;
            delete [] up;
            delete [] numberDown;
            delete [] numberUp;
            delete [] numberDownInfeasible;
            delete [] numberUpInfeasible;
            bool takeHint;
            OsiHintStrength strength;
            solver->getHintParam(OsiDoReducePrint, takeHint, strength);
            ClpSimplex * simplex = clpSolver->getModelPtr();
            int saveLevel = simplex->logLevel();
            if (strength != OsiHintIgnore && takeHint && saveLevel == 1)
                simplex->setLogLevel(0);
            clpSolver->setBasis();
            whichSolution_ = simplex->fathomMany(info);
            //printf("FAT %d nodes, %d iterations\n",
            //info->numberNodesExplored_,info->numberIterations_);
            //printf("CbcBranch %d rows, %d columns\n",clpSolver->getNumRows(),
            //     clpSolver->getNumCols());
            model_->incrementExtra(info->numberNodesExplored_,
                                   info->numberIterations_);
            // update pseudo costs
            double smallest = 1.0e50;
            double largest = -1.0;
            OsiObject ** objects = model_->objects();
#ifndef NDEBUG
            const int * integerVariable = model_->integerVariable();
#endif
            for (int i = 0; i < numberIntegers; i++) {
#ifndef NDEBUG
                CbcSimpleIntegerDynamicPseudoCost * obj =
                    dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(objects[i]) ;
                assert (obj && obj->columnNumber() == integerVariable[i]);
#else
                CbcSimpleIntegerDynamicPseudoCost * obj =
                    static_cast <CbcSimpleIntegerDynamicPseudoCost *>(objects[i]) ;
#endif
                if (info->numberUp_[i] > 0) {
                    if (info->downPseudo_[i] > largest)
                        largest = info->downPseudo_[i];
                    if (info->downPseudo_[i] < smallest)
                        smallest = info->downPseudo_[i];
                    if (info->upPseudo_[i] > largest)
                        largest = info->upPseudo_[i];
                    if (info->upPseudo_[i] < smallest)
                        smallest = info->upPseudo_[i];
                    obj->updateAfterMini(info->numberDown_[i],
                                         info->numberDownInfeasible_[i],
                                         info->downPseudo_[i],
                                         info->numberUp_[i],
                                         info->numberUpInfeasible_[i],
                                         info->upPseudo_[i]);
                }
            }
            //printf("range of costs %g to %g\n",smallest,largest);
            simplex->setLogLevel(saveLevel);
            numberNodes_ = info->nNodes_;
	  } else {
	    // Try diving
	    // See if any diving heuristics set to do dive+save
	    CbcHeuristicDive * dive=NULL;
	    for (int i = 0; i < model_->numberHeuristics(); i++) {
	      CbcHeuristicDive * possible = dynamic_cast<CbcHeuristicDive *>(model_->heuristic(i));
	      if (possible&&possible->maxSimplexIterations()==COIN_INT_MAX) {
		// if more than one then rotate later?
		//if (possible->canHeuristicRun()) {
		dive=possible;
		break;
	      }
	    }
	    assert (dive); // otherwise moreSpecial should have been turned off
	    CbcSubProblem ** nodes=NULL;
	    int branchState=dive->fathom(model_,numberNodes_,nodes);
	    if (branchState) {
	      printf("new solution\n");
	      whichSolution_=numberNodes_-1;
	    } else {
	      whichSolution_=-1;
	    }
#if 0
	    if (0) {
	      for (int iNode=0;iNode<numberNodes;iNode++) {
		//tree_->push(nodes[iNode]) ;
	      }
	      assert (node->nodeInfo());
	      if (node->nodeInfo()->numberBranchesLeft()) {
		tree_->push(node) ;
	      } else {
		node->setActive(false);
	      }
	    }
#endif
	    //delete [] nodes;
	    model_->setTemporaryPointer(reinterpret_cast<void *>(nodes));
	    // end try diving
	  }
	  int numberDo = numberNodes_;
	  if (numberDo > 0 || whichSolution_ >= 0) {
	    return 0.5;
	  } else {
	    // no solution
	    return COIN_DBL_MAX; // say infeasible
	  }
        } else {
            return -1.0;
        }
    } else {
        return -1.0;
    }
}
Exemplo n.º 12
0
static ClpSimplex * clpmodel(EKKModel * model, int startup)
{
     ClpSimplex * clp = new ClpSimplex();;
     int numberRows = ekk_getInumrows(model);
     int numberColumns = ekk_getInumcols(model);
     clp->loadProblem(numberColumns, numberRows, ekk_blockColumn(model, 0),
                      ekk_blockRow(model, 0), ekk_blockElement(model, 0),
                      ekk_collower(model), ekk_colupper(model),
                      ekk_objective(model),
                      ekk_rowlower(model), ekk_rowupper(model));
     clp->setOptimizationDirection((int) ekk_getRmaxmin(model));
     clp->setPrimalTolerance(ekk_getRtolpinf(model));
     if (ekk_getRpweight(model) != 0.1)
          clp->setInfeasibilityCost(1.0 / ekk_getRpweight(model));
     clp->setDualTolerance(ekk_getRtoldinf(model));
     if (ekk_getRdweight(model) != 0.1)
          clp->setDualBound(1.0 / ekk_getRdweight(model));
     clp->setDblParam(ClpObjOffset, ekk_getRobjectiveOffset(model));
     const int * rowStatus =  ekk_rowstat(model);
     const double * rowSolution = ekk_rowacts(model);
     int i;
     clp->createStatus();
     double * clpSolution;
     clpSolution = clp->primalRowSolution();
     memcpy(clpSolution, rowSolution, numberRows * sizeof(double));
     const double * rowLower = ekk_rowlower(model);
     const double * rowUpper = ekk_rowupper(model);
     for (i = 0; i < numberRows; i++) {
          ClpSimplex::Status status;
          if ((rowStatus[i] & 0x80000000) != 0) {
               status = ClpSimplex::basic;
          } else {
               if (!startup) {
                    // believe bits
                    int ikey = rowStatus[i] & 0x60000000;
                    if (ikey == 0x40000000) {
                         // at ub
                         status = ClpSimplex::atUpperBound;
                         clpSolution[i] = rowUpper[i];
                    } else if (ikey == 0x20000000) {
                         // at lb
                         status = ClpSimplex::atLowerBound;
                         clpSolution[i] = rowLower[i];
                    } else if (ikey == 0x60000000) {
                         // free
                         status = ClpSimplex::isFree;
                         clpSolution[i] = 0.0;
                    } else {
                         // fixed
                         status = ClpSimplex::atLowerBound;
                         clpSolution[i] = rowLower[i];
                    }
               } else {
                    status = ClpSimplex::superBasic;
               }
          }
          clp->setRowStatus(i, status);
     }

     const int * columnStatus = ekk_colstat(model);
     const double * columnSolution =  ekk_colsol(model);
     clpSolution = clp->primalColumnSolution();
     memcpy(clpSolution, columnSolution, numberColumns * sizeof(double));
     const double * columnLower = ekk_collower(model);
     const double * columnUpper = ekk_colupper(model);
     for (i = 0; i < numberColumns; i++) {
          ClpSimplex::Status status;
          if ((columnStatus[i] & 0x80000000) != 0) {
               status = ClpSimplex::basic;
          } else {
               if (!startup) {
                    // believe bits
                    int ikey = columnStatus[i] & 0x60000000;
                    if (ikey == 0x40000000) {
                         // at ub
                         status = ClpSimplex::atUpperBound;
                         clpSolution[i] = columnUpper[i];
                    } else if (ikey == 0x20000000) {
                         // at lb
                         status = ClpSimplex::atLowerBound;
                         clpSolution[i] = columnLower[i];
                    } else if (ikey == 0x60000000) {
                         // free
                         status = ClpSimplex::isFree;
                         clpSolution[i] = 0.0;
                    } else {
                         // fixed
                         status = ClpSimplex::atLowerBound;
                         clpSolution[i] = columnLower[i];
                    }
               } else {
                    status = ClpSimplex::superBasic;
               }
          }
          clp->setColumnStatus(i, status);
     }
     return clp;
}
Exemplo n.º 13
0
int main(int argc, const char *argv[])
{
     ClpSimplex  model;
     int status;
     // Keep names
     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);
     /*
       This driver is similar to minimum.cpp, but it
       sets all parameter values to their defaults.  The purpose of this
       is to give a list of most of the methods that the end user will need.

       There are also some more methods as for OsiSolverInterface e.g.
       some loadProblem methods and deleteRows and deleteColumns.

       Often two methods do the same thing, one having a name I like
       while the other adheres to OsiSolverInterface standards
     */

     // Use exact devex ( a variant of steepest edge)
     ClpPrimalColumnSteepest primalSteepest;
     model.setPrimalColumnPivotAlgorithm(primalSteepest);


     int integerValue;
     double value;

     // Infeasibility cost
     value = model.infeasibilityCost();
     std::cout << "Default value of infeasibility cost is " << value << std::endl;
     model.setInfeasibilityCost(value);

     if (!status) {
          model.primal();
     }
     // Number of rows and columns - also getNumRows, getNumCols
     std::string modelName;
     model.getStrParam(ClpProbName, modelName);
     std::cout << "Model " << modelName << " has " << model.numberRows() << " rows and " <<
               model.numberColumns() << " columns" << std::endl;

     /* Some parameters as in OsiSolverParameters.  ObjectiveLimits
        are not active yet.  dualTolerance, setDualTolerance,
        primalTolerance and setPrimalTolerance may be used as well */

     model.getDblParam(ClpDualObjectiveLimit, value);
     std::cout << "Value of ClpDualObjectiveLimit is " << value << std::endl;
     model.getDblParam(ClpPrimalObjectiveLimit, value);
     std::cout << "Value of ClpPrimalObjectiveLimit is " << value << std::endl;
     model.getDblParam(ClpDualTolerance, value);
     std::cout << "Value of ClpDualTolerance is " << value << std::endl;
     model.getDblParam(ClpPrimalTolerance, value);
     std::cout << "Value of ClpPrimalTolerance is " << value << std::endl;
     model.getDblParam(ClpObjOffset, value);
     std::cout << "Value of ClpObjOffset is " << value << std::endl;

     // setDblParam(ClpPrimalTolerance) is same as this
     model.getDblParam(ClpPrimalTolerance, value);
     model.setPrimalTolerance(value);

     model.setDualTolerance(model.dualTolerance()) ;

     // Other Param stuff

     // Can also use maximumIterations
     model.getIntParam(ClpMaxNumIteration, integerValue);
     std::cout << "Value of ClpMaxNumIteration is " << integerValue << std::endl;
     model.setMaximumIterations(integerValue);

     // Not sure this works yet
     model.getIntParam(ClpMaxNumIterationHotStart, integerValue);
     std::cout << "Value of ClpMaxNumIterationHotStart is "
               << integerValue << std::endl;

     // Can also use getIterationCount and getObjValue
     /* Status of problem:
         0 - optimal
         1 - primal infeasible
         2 - dual infeasible
         3 - stopped on iterations etc
         4 - stopped due to errors
     */
     std::cout << "Model status is " << model.status() << " after "
               << model.numberIterations() << " iterations - objective is "
               << model.objectiveValue() << std::endl;

     assert(!model.isAbandoned());
     assert(model.isProvenOptimal());
     assert(!model.isProvenPrimalInfeasible());
     assert(!model.isProvenDualInfeasible());
     assert(!model.isPrimalObjectiveLimitReached());
     assert(!model.isDualObjectiveLimitReached());
     assert(!model.isIterationLimitReached());


     // Things to help you determine if optimal
     assert(model.primalFeasible());
     assert(!model.numberPrimalInfeasibilities());
     assert(model.sumPrimalInfeasibilities() < 1.0e-7);
     assert(model.dualFeasible());
     assert(!model.numberDualInfeasibilities());
     assert(model.sumDualInfeasibilities() < 1.0e-7);

     // Save warm start and set to all slack
     unsigned char * basis1 = model.statusCopy();
     model.createStatus();

     // Now create another model and do hot start
     ClpSimplex model2 = model;
     model2.copyinStatus(basis1);
     delete [] basis1;

     // Check model has not got basis (should iterate)
     model.dual();

     // Can use getObjSense
     model2.setOptimizationDirection(model.optimizationDirection());

     // Can use scalingFlag() to check if scaling on
     // But set up scaling
     model2.scaling();

     // Could play with sparse factorization on/off
     model2.setSparseFactorization(model.sparseFactorization());

     // Sets row pivot choice algorithm in dual
     ClpDualRowSteepest dualSteepest;
     model2.setDualRowPivotAlgorithm(dualSteepest);

     // Dual bound (i.e. dual infeasibility cost)
     value = model.dualBound();
     std::cout << "Default value of dual bound is " << value << std::endl;
     model.setDualBound(value);

     // Do some deafult message handling
     // To see real use - see OsiOslSolverInterfaceTest.cpp
     CoinMessageHandler handler;
     model2.passInMessageHandler(& handler);
     model2.newLanguage(CoinMessages::us_en);

     //Increase level of detail
     model2.setLogLevel(4);

     // solve
     model2.dual();
     // flip direction twice and solve
     model2.setOptimizationDirection(-1);
     model2.dual();
     model2.setOptimizationDirection(1);
     //Decrease level of detail
     model2.setLogLevel(1);
     model2.dual();

     /*
       Now for getting at information.  This will not deal with:

       ClpMatrixBase * rowCopy() and ClpMatrixbase * clpMatrix()

       nor with

       double * infeasibilityRay() and double * unboundedRay()
       (NULL returned if none/wrong)
       Up to user to use delete [] on these arrays.

      */


     /*
       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

      */

     int numberRows = model2.numberRows();

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

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

     // Row names
     const std::vector<std::string> * rowNames = model2.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;
     }
     std::cout << "--------------------------------------" << std::endl;

     // Columns

     int numberColumns = model2.numberColumns();

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

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

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


     int iColumn;

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

     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          double value;
          std::cout << std::setw(6) << iColumn << " " << std::setw(8) << (*columnNames)[iColumn];
          value = columnPrimal[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;

     std::cout << std::resetiosflags(std::ios::fixed | std::ios::showpoint | std::ios::scientific);

     // Now matrix
     CoinPackedMatrix * matrix = model2.matrix();

     const double * element = matrix->getElements();
     const int * row = matrix->getIndices();
     const int * start = matrix->getVectorStarts();
     const int * length = matrix->getVectorLengths();

     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          std::cout << "Column " << iColumn;
          int j;
          for (j = start[iColumn]; j < start[iColumn] + length[iColumn]; j++)
               std::cout << " ( " << row[j] << ", " << element[j] << ")";
          std::cout << std::endl;
     }
     return 0;
}
Exemplo n.º 14
0
// inner part of dive
int 
CbcHeuristicDive::solution(double & solutionValue, int & numberNodes,
			   int & numberCuts, OsiRowCut ** cuts,
			   CbcSubProblem ** & nodes,
			   double * newSolution)
{
#ifdef DIVE_DEBUG
    int nRoundInfeasible = 0;
    int nRoundFeasible = 0;
#endif
    int reasonToStop = 0;
    double time1 = CoinCpuTime();
    int numberSimplexIterations = 0;
    int maxSimplexIterations = (model_->getNodeCount()) ? maxSimplexIterations_
                               : maxSimplexIterationsAtRoot_;
    // but can't be exactly coin_int_max
    maxSimplexIterations = CoinMin(maxSimplexIterations,COIN_INT_MAX>>3);
    OsiSolverInterface * solver = cloneBut(6); // was model_->solver()->clone();
# ifdef COIN_HAS_CLP
    OsiClpSolverInterface * clpSolver
    = dynamic_cast<OsiClpSolverInterface *> (solver);
    if (clpSolver) {
      ClpSimplex * clpSimplex = clpSolver->getModelPtr();
      int oneSolveIts = clpSimplex->maximumIterations();
      oneSolveIts = CoinMin(1000+2*(clpSimplex->numberRows()+clpSimplex->numberColumns()),oneSolveIts);
      clpSimplex->setMaximumIterations(oneSolveIts);
      if (!nodes) {
        // say give up easily
        clpSimplex->setMoreSpecialOptions(clpSimplex->moreSpecialOptions() | 64);
      } else {
	// get ray
	int specialOptions = clpSimplex->specialOptions();
	specialOptions &= ~0x3100000;
	specialOptions |= 32;
        clpSimplex->setSpecialOptions(specialOptions);
        clpSolver->setSpecialOptions(clpSolver->specialOptions() | 1048576);
	if ((model_->moreSpecialOptions()&16777216)!=0) {
	  // cutoff is constraint
	  clpSolver->setDblParam(OsiDualObjectiveLimit, COIN_DBL_MAX);
	}
      }
    }
# endif
    const double * lower = solver->getColLower();
    const double * upper = solver->getColUpper();
    const double * rowLower = solver->getRowLower();
    const double * rowUpper = solver->getRowUpper();
    const double * solution = solver->getColSolution();
    const double * objective = solver->getObjCoefficients();
    double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
    double primalTolerance;
    solver->getDblParam(OsiPrimalTolerance, primalTolerance);

    int numberRows = matrix_.getNumRows();
    assert (numberRows <= solver->getNumRows());
    int numberIntegers = model_->numberIntegers();
    const int * integerVariable = model_->integerVariable();
    double direction = solver->getObjSense(); // 1 for min, -1 for max
    double newSolutionValue = direction * solver->getObjValue();
    int returnCode = 0;
    // Column copy
    const double * element = matrix_.getElements();
    const int * row = matrix_.getIndices();
    const CoinBigIndex * columnStart = matrix_.getVectorStarts();
    const int * columnLength = matrix_.getVectorLengths();
#ifdef DIVE_FIX_BINARY_VARIABLES
    // Row copy
    const double * elementByRow = matrixByRow_.getElements();
    const int * column = matrixByRow_.getIndices();
    const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
    const int * rowLength = matrixByRow_.getVectorLengths();
#endif

    // Get solution array for heuristic solution
    int numberColumns = solver->getNumCols();
    memcpy(newSolution, solution, numberColumns*sizeof(double));

    // vectors to store the latest variables fixed at their bounds
    int* columnFixed = new int [numberIntegers];
    double* originalBound = new double [numberIntegers+2*numberColumns];
    double * lowerBefore = originalBound+numberIntegers;
    double * upperBefore = lowerBefore+numberColumns;
    memcpy(lowerBefore,lower,numberColumns*sizeof(double));
    memcpy(upperBefore,upper,numberColumns*sizeof(double));
    double * lastDjs=newSolution+numberColumns;
    bool * fixedAtLowerBound = new bool [numberIntegers];
    PseudoReducedCost * candidate = new PseudoReducedCost [numberIntegers];
    double * random = new double [numberIntegers];

    int maxNumberAtBoundToFix = static_cast<int> (floor(percentageToFix_ * numberIntegers));
    assert (!maxNumberAtBoundToFix||!nodes);

    // count how many fractional variables
    int numberFractionalVariables = 0;
    for (int i = 0; i < numberIntegers; i++) {
        random[i] = randomNumberGenerator_.randomDouble() + 0.3;
        int iColumn = integerVariable[i];
        double value = newSolution[iColumn];
        if (fabs(floor(value + 0.5) - value) > integerTolerance) {
            numberFractionalVariables++;
        }
    }

    const double* reducedCost = NULL;
    // See if not NLP
    if (model_->solverCharacteristics()->reducedCostsAccurate())
        reducedCost = solver->getReducedCost();

    int iteration = 0;
    while (numberFractionalVariables) {
        iteration++;

        // initialize any data
        initializeData();

        // select a fractional variable to bound
        int bestColumn = -1;
        int bestRound; // -1 rounds down, +1 rounds up
        bool canRound = selectVariableToBranch(solver, newSolution,
                                               bestColumn, bestRound);
        // if the solution is not trivially roundable, we don't try to round;
        // if the solution is trivially roundable, we try to round. However,
        // if the rounded solution is worse than the current incumbent,
        // then we don't round and proceed normally. In this case, the
        // bestColumn will be a trivially roundable variable
        if (canRound) {
            // check if by rounding all fractional variables
            // we get a solution with an objective value
            // better than the current best integer solution
            double delta = 0.0;
            for (int i = 0; i < numberIntegers; i++) {
                int iColumn = integerVariable[i];
                double value = newSolution[iColumn];
                if (fabs(floor(value + 0.5) - value) > integerTolerance) {
                    assert(downLocks_[i] == 0 || upLocks_[i] == 0);
                    double obj = objective[iColumn];
                    if (downLocks_[i] == 0 && upLocks_[i] == 0) {
                        if (direction * obj >= 0.0)
                            delta += (floor(value) - value) * obj;
                        else
                            delta += (ceil(value) - value) * obj;
                    } else if (downLocks_[i] == 0)
                        delta += (floor(value) - value) * obj;
                    else
                        delta += (ceil(value) - value) * obj;
                }
            }
            if (direction*(solver->getObjValue() + delta) < solutionValue) {
#ifdef DIVE_DEBUG
                nRoundFeasible++;
#endif
		if (!nodes||bestColumn<0) {
		  // Round all the fractional variables
		  for (int i = 0; i < numberIntegers; i++) {
                    int iColumn = integerVariable[i];
                    double value = newSolution[iColumn];
                    if (fabs(floor(value + 0.5) - value) > integerTolerance) {
		      assert(downLocks_[i] == 0 || upLocks_[i] == 0);
		      if (downLocks_[i] == 0 && upLocks_[i] == 0) {
			if (direction * objective[iColumn] >= 0.0)
			  newSolution[iColumn] = floor(value);
			else
			  newSolution[iColumn] = ceil(value);
		      } else if (downLocks_[i] == 0)
			newSolution[iColumn] = floor(value);
		      else
			newSolution[iColumn] = ceil(value);
                    }
		  }
		  break;
		} else {
		  // can't round if going to use in branching
		  int i;
		  for (i = 0; i < numberIntegers; i++) {
		    int iColumn = integerVariable[i];
		    double value = newSolution[bestColumn];
		    if (fabs(floor(value + 0.5) - value) > integerTolerance) {
		      if (iColumn==bestColumn) {
			assert(downLocks_[i] == 0 || upLocks_[i] == 0);
			double obj = objective[bestColumn];
			if (downLocks_[i] == 0 && upLocks_[i] == 0) {
			  if (direction * obj >= 0.0)
                            bestRound=-1;
			  else
                            bestRound=1;
			} else if (downLocks_[i] == 0)
			  bestRound=-1;
			else
			  bestRound=1;
			break;
		      }
		    }
		  }
		}
	    }
#ifdef DIVE_DEBUG
            else
                nRoundInfeasible++;
#endif
        }

        // do reduced cost fixing
#ifdef DIVE_DEBUG
        int numberFixed = reducedCostFix(solver);
        std::cout << "numberReducedCostFixed = " << numberFixed << std::endl;
#else
        reducedCostFix(solver);
#endif

        int numberAtBoundFixed = 0;
#ifdef DIVE_FIX_BINARY_VARIABLES
        // fix binary variables based on pseudo reduced cost
        if (binVarIndex_.size()) {
            int cnt = 0;
            int n = static_cast<int>(binVarIndex_.size());
            for (int j = 0; j < n; j++) {
                int iColumn1 = binVarIndex_[j];
                double value = newSolution[iColumn1];
                if (fabs(value) <= integerTolerance &&
                        lower[iColumn1] != upper[iColumn1]) {
                    double maxPseudoReducedCost = 0.0;
#ifdef DIVE_DEBUG
                    std::cout << "iColumn1 = " << iColumn1 << ", value = " << value << std::endl;
#endif
                    int iRow = vbRowIndex_[j];
                    double chosenValue = 0.0;
                    for (int k = rowStart[iRow]; k < rowStart[iRow] + rowLength[iRow]; k++) {
                        int iColumn2 = column[k];
#ifdef DIVE_DEBUG
                        std::cout << "iColumn2 = " << iColumn2 << std::endl;
#endif
                        if (iColumn1 != iColumn2) {
                            double pseudoReducedCost = fabs(reducedCost[iColumn2] *
                                                            elementByRow[k]);
#ifdef DIVE_DEBUG
                            int k2;
                            for (k2 = rowStart[iRow]; k2 < rowStart[iRow] + rowLength[iRow]; k2++) {
                                if (column[k2] == iColumn1)
                                    break;
                            }
                            std::cout << "reducedCost[" << iColumn2 << "] = "
                                      << reducedCost[iColumn2]
                                      << ", elementByRow[" << iColumn2 << "] = " << elementByRow[k]
                                      << ", elementByRow[" << iColumn1 << "] = " << elementByRow[k2]
                                      << ", pseudoRedCost = " << pseudoReducedCost
                                      << std::endl;
#endif
                            if (pseudoReducedCost > maxPseudoReducedCost)
                                maxPseudoReducedCost = pseudoReducedCost;
                        } else {
                            // save value
                            chosenValue = fabs(elementByRow[k]);
                        }
                    }
                    assert (chosenValue);
                    maxPseudoReducedCost /= chosenValue;
#ifdef DIVE_DEBUG
                    std::cout << ", maxPseudoRedCost = " << maxPseudoReducedCost << std::endl;
#endif
                    candidate[cnt].var = iColumn1;
                    candidate[cnt++].pseudoRedCost = maxPseudoReducedCost;
                }
            }
#ifdef DIVE_DEBUG
            std::cout << "candidates for rounding = " << cnt << std::endl;
#endif
            std::sort(candidate, candidate + cnt, compareBinaryVars);
            for (int i = 0; i < cnt; i++) {
                int iColumn = candidate[i].var;
                if (numberAtBoundFixed < maxNumberAtBoundToFix) {
                    columnFixed[numberAtBoundFixed] = iColumn;
                    originalBound[numberAtBoundFixed] = upper[iColumn];
                    fixedAtLowerBound[numberAtBoundFixed] = true;
                    solver->setColUpper(iColumn, lower[iColumn]);
                    numberAtBoundFixed++;
                    if (numberAtBoundFixed == maxNumberAtBoundToFix)
                        break;
                }
            }
        }
#endif

        // fix other integer variables that are at their bounds
        int cnt = 0;
#ifdef GAP
        double gap = 1.0e30;
#endif
        if (reducedCost && true) {
#ifndef JJF_ONE
            cnt = fixOtherVariables(solver, solution, candidate, random);
#else
#ifdef GAP
            double cutoff = model_->getCutoff() ;
            if (cutoff < 1.0e20 && false) {
                double direction = solver->getObjSense() ;
                gap = cutoff - solver->getObjValue() * direction ;
                gap *= 0.1; // Fix more if plausible
                double tolerance;
                solver->getDblParam(OsiDualTolerance, tolerance) ;
                if (gap <= 0.0)
                    gap = tolerance;
                gap += 100.0 * tolerance;
            }
            int nOverGap = 0;
#endif
            int numberFree = 0;
            int numberFixed = 0;
            for (int i = 0; i < numberIntegers; i++) {
                int iColumn = integerVariable[i];
                if (upper[iColumn] > lower[iColumn]) {
                    numberFree++;
                    double value = newSolution[iColumn];
                    if (fabs(floor(value + 0.5) - value) <= integerTolerance) {
                        candidate[cnt].var = iColumn;
                        candidate[cnt++].pseudoRedCost =
                            fabs(reducedCost[iColumn] * random[i]);
#ifdef GAP
                        if (fabs(reducedCost[iColumn]) > gap)
                            nOverGap++;
#endif
                    }
                } else {
                    numberFixed++;
                }
            }
#ifdef GAP
            int nLeft = maxNumberAtBoundToFix - numberAtBoundFixed;
#ifdef CLP_INVESTIGATE4
            printf("cutoff %g obj %g nover %d - %d free, %d fixed\n",
                   cutoff, solver->getObjValue(), nOverGap, numberFree, numberFixed);
#endif
            if (nOverGap > nLeft && true) {
                nOverGap = CoinMin(nOverGap, nLeft + maxNumberAtBoundToFix / 2);
                maxNumberAtBoundToFix += nOverGap - nLeft;
            }
#else
#ifdef CLP_INVESTIGATE4
            printf("cutoff %g obj %g - %d free, %d fixed\n",
                   model_->getCutoff(), solver->getObjValue(), numberFree, numberFixed);
#endif
#endif
#endif
        } else {
            for (int i = 0; i < numberIntegers; i++) {
                int iColumn = integerVariable[i];
                if (upper[iColumn] > lower[iColumn]) {
                    double value = newSolution[iColumn];
                    if (fabs(floor(value + 0.5) - value) <= integerTolerance) {
                        candidate[cnt].var = iColumn;
                        candidate[cnt++].pseudoRedCost = numberIntegers - i;
                    }
                }
            }
        }
        std::sort(candidate, candidate + cnt, compareBinaryVars);
        for (int i = 0; i < cnt; i++) {
            int iColumn = candidate[i].var;
            if (upper[iColumn] > lower[iColumn]) {
                double value = newSolution[iColumn];
                if (fabs(floor(value + 0.5) - value) <= integerTolerance &&
                        numberAtBoundFixed < maxNumberAtBoundToFix) {
                    // fix the variable at one of its bounds
                    if (fabs(lower[iColumn] - value) <= integerTolerance) {
                        columnFixed[numberAtBoundFixed] = iColumn;
                        originalBound[numberAtBoundFixed] = upper[iColumn];
                        fixedAtLowerBound[numberAtBoundFixed] = true;
                        solver->setColUpper(iColumn, lower[iColumn]);
                        numberAtBoundFixed++;
                    } else if (fabs(upper[iColumn] - value) <= integerTolerance) {
                        columnFixed[numberAtBoundFixed] = iColumn;
                        originalBound[numberAtBoundFixed] = lower[iColumn];
                        fixedAtLowerBound[numberAtBoundFixed] = false;
                        solver->setColLower(iColumn, upper[iColumn]);
                        numberAtBoundFixed++;
                    }
                    if (numberAtBoundFixed == maxNumberAtBoundToFix)
                        break;
                }
            }
        }
#ifdef DIVE_DEBUG
        std::cout << "numberAtBoundFixed = " << numberAtBoundFixed << std::endl;
#endif

        double originalBoundBestColumn;
        double bestColumnValue;
	int whichWay;
        if (bestColumn >= 0) {
	    bestColumnValue = newSolution[bestColumn];
            if (bestRound < 0) {
                originalBoundBestColumn = upper[bestColumn];
                solver->setColUpper(bestColumn, floor(bestColumnValue));
		whichWay=0;
            } else {
                originalBoundBestColumn = lower[bestColumn];
                solver->setColLower(bestColumn, ceil(bestColumnValue));
		whichWay=1;
            }
        } else {
            break;
        }
        int originalBestRound = bestRound;
        int saveModelOptions = model_->specialOptions();
	
        while (1) {

            model_->setSpecialOptions(saveModelOptions | 2048);
            solver->resolve();
            model_->setSpecialOptions(saveModelOptions);
            if (!solver->isAbandoned()&&!solver->isIterationLimitReached()) {
                numberSimplexIterations += solver->getIterationCount();
            } else {
                numberSimplexIterations = maxSimplexIterations + 1;
		reasonToStop += 100;
                break;
            }

            if (!solver->isProvenOptimal()) {
	        if (nodes) {
		  if (solver->isProvenPrimalInfeasible()) {
		    if (maxSimplexIterationsAtRoot_!=COIN_INT_MAX) {
		      // stop now
		      printf("stopping on first infeasibility\n");
		      break;
		    } else if (cuts) {
		      // can do conflict cut
		      printf("could do intermediate conflict cut\n");
		      bool localCut;
		      OsiRowCut * cut = model_->conflictCut(solver,localCut);
		      if (cut) {
			if (!localCut) {
			  model_->makePartialCut(cut,solver);
			  cuts[numberCuts++]=cut;
			} else {
			  delete cut;
			}
		      }
		    }
		  } else {
		    reasonToStop += 10;
		    break;
		  }
		}
                if (numberAtBoundFixed > 0) {
                    // Remove the bound fix for variables that were at bounds
                    for (int i = 0; i < numberAtBoundFixed; i++) {
                        int iColFixed = columnFixed[i];
                        if (fixedAtLowerBound[i])
                            solver->setColUpper(iColFixed, originalBound[i]);
                        else
                            solver->setColLower(iColFixed, originalBound[i]);
                    }
                    numberAtBoundFixed = 0;
                } else if (bestRound == originalBestRound) {
                    bestRound *= (-1);
		    whichWay |=2;
                    if (bestRound < 0) {
                        solver->setColLower(bestColumn, originalBoundBestColumn);
                        solver->setColUpper(bestColumn, floor(bestColumnValue));
                    } else {
                        solver->setColLower(bestColumn, ceil(bestColumnValue));
                        solver->setColUpper(bestColumn, originalBoundBestColumn);
                    }
                } else
                    break;
            } else
                break;
        }

        if (!solver->isProvenOptimal() ||
                direction*solver->getObjValue() >= solutionValue) {
            reasonToStop += 1;
        } else if (iteration > maxIterations_) {
            reasonToStop += 2;
        } else if (CoinCpuTime() - time1 > maxTime_) {
            reasonToStop += 3;
        } else if (numberSimplexIterations > maxSimplexIterations) {
            reasonToStop += 4;
            // also switch off
#ifdef CLP_INVESTIGATE
            printf("switching off diving as too many iterations %d, %d allowed\n",
                   numberSimplexIterations, maxSimplexIterations);
#endif
            when_ = 0;
        } else if (solver->getIterationCount() > 1000 && iteration > 3 && !nodes) {
            reasonToStop += 5;
            // also switch off
#ifdef CLP_INVESTIGATE
            printf("switching off diving one iteration took %d iterations (total %d)\n",
                   solver->getIterationCount(), numberSimplexIterations);
#endif
            when_ = 0;
        }

        memcpy(newSolution, solution, numberColumns*sizeof(double));
        numberFractionalVariables = 0;
	double sumFractionalVariables=0.0;
        for (int i = 0; i < numberIntegers; i++) {
            int iColumn = integerVariable[i];
            double value = newSolution[iColumn];
	    double away = fabs(floor(value + 0.5) - value);
            if (away > integerTolerance) {
                numberFractionalVariables++;
		sumFractionalVariables += away;
            }
        }
	if (nodes) {
	  // save information
	  //branchValues[numberNodes]=bestColumnValue;
	  //statuses[numberNodes]=whichWay+(bestColumn<<2);
	  //bases[numberNodes]=solver->getWarmStart();
	  ClpSimplex * simplex = clpSolver->getModelPtr();
	  CbcSubProblem * sub =
	    new CbcSubProblem(clpSolver,lowerBefore,upperBefore,
			  simplex->statusArray(),numberNodes);
	  nodes[numberNodes]=sub;
	  // other stuff
	  sub->branchValue_=bestColumnValue;
	  sub->problemStatus_=whichWay;
	  sub->branchVariable_=bestColumn;
	  sub->objectiveValue_ = simplex->objectiveValue();
	  sub->sumInfeasibilities_ = sumFractionalVariables;
	  sub->numberInfeasibilities_ = numberFractionalVariables;
	  printf("DiveNode %d column %d way %d bvalue %g obj %g\n",
		 numberNodes,sub->branchVariable_,sub->problemStatus_,
		 sub->branchValue_,sub->objectiveValue_);
	  numberNodes++;
	  if (solver->isProvenOptimal()) {
	    memcpy(lastDjs,solver->getReducedCost(),numberColumns*sizeof(double));
	    memcpy(lowerBefore,lower,numberColumns*sizeof(double));
	    memcpy(upperBefore,upper,numberColumns*sizeof(double));
	  }
	}
	if (!numberFractionalVariables||reasonToStop)
	  break;
    }
    if (nodes) {
      printf("Exiting dive for reason %d\n",reasonToStop);
      if (reasonToStop>1) {
	printf("problems in diving\n");
	int whichWay=nodes[numberNodes-1]->problemStatus_;
	CbcSubProblem * sub;
	if ((whichWay&2)==0) {
	  // leave both ways
	  sub = new CbcSubProblem(*nodes[numberNodes-1]);
	  nodes[numberNodes++]=sub;
	} else {
	  sub = nodes[numberNodes-1];
	}
	if ((whichWay&1)==0)
	  sub->problemStatus_=whichWay|1;
	else
	  sub->problemStatus_=whichWay&~1;
      }
      if (!numberNodes) {
	// was good at start! - create fake
	clpSolver->resolve();
	ClpSimplex * simplex = clpSolver->getModelPtr();
	CbcSubProblem * sub =
	  new CbcSubProblem(clpSolver,lowerBefore,upperBefore,
			    simplex->statusArray(),numberNodes);
	nodes[numberNodes]=sub;
	// other stuff
	sub->branchValue_=0.0;
	sub->problemStatus_=0;
	sub->branchVariable_=-1;
	sub->objectiveValue_ = simplex->objectiveValue();
	sub->sumInfeasibilities_ = 0.0;
	sub->numberInfeasibilities_ = 0;
	printf("DiveNode %d column %d way %d bvalue %g obj %g\n",
	       numberNodes,sub->branchVariable_,sub->problemStatus_,
	       sub->branchValue_,sub->objectiveValue_);
	numberNodes++;
	assert (solver->isProvenOptimal());
      }
      nodes[numberNodes-1]->problemStatus_ |= 256*reasonToStop;
      // use djs as well
      if (solver->isProvenPrimalInfeasible()&&cuts) {
	// can do conflict cut and re-order
	printf("could do final conflict cut\n");
	bool localCut;
	OsiRowCut * cut = model_->conflictCut(solver,localCut);
	if (cut) {
	  printf("cut - need to use conflict and previous djs\n");
	  if (!localCut) {
	    model_->makePartialCut(cut,solver);
	    cuts[numberCuts++]=cut;
	  } else {
	    delete cut;
	  }
	} else {
	  printf("bad conflict - just use previous djs\n");
	}
      }
    }
    
    // re-compute new solution value
    double objOffset = 0.0;
    solver->getDblParam(OsiObjOffset, objOffset);
    newSolutionValue = -objOffset;
    for (int i = 0 ; i < numberColumns ; i++ )
      newSolutionValue += objective[i] * newSolution[i];
    newSolutionValue *= direction;
    //printf("new solution value %g %g\n",newSolutionValue,solutionValue);
    if (newSolutionValue < solutionValue && !reasonToStop) {
      double * rowActivity = new double[numberRows];
      memset(rowActivity, 0, numberRows*sizeof(double));
      // paranoid check
      memset(rowActivity, 0, numberRows*sizeof(double));
      for (int i = 0; i < numberColumns; i++) {
	int j;
	double value = newSolution[i];
	if (value) {
	  for (j = columnStart[i];
	       j < columnStart[i] + columnLength[i]; j++) {
	    int iRow = row[j];
	    rowActivity[iRow] += value * element[j];
	  }
	}
      }
      // check was approximately feasible
      bool feasible = true;
      for (int i = 0; i < numberRows; i++) {
	if (rowActivity[i] < rowLower[i]) {
	  if (rowActivity[i] < rowLower[i] - 1000.0*primalTolerance)
	    feasible = false;
	} else if (rowActivity[i] > rowUpper[i]) {
	  if (rowActivity[i] > rowUpper[i] + 1000.0*primalTolerance)
	    feasible = false;
	}
      }
      for (int i = 0; i < numberIntegers; i++) {
	int iColumn = integerVariable[i];
	double value = newSolution[iColumn];
	if (fabs(floor(value + 0.5) - value) > integerTolerance) {
	  feasible = false;
	  break;
	}
      }
      if (feasible) {
	// new solution
	solutionValue = newSolutionValue;
	//printf("** Solution of %g found by CbcHeuristicDive\n",newSolutionValue);
	//if (cuts)
	//clpSolver->getModelPtr()->writeMps("good8.mps", 2);
	returnCode = 1;
      } else {
	// Can easily happen
	//printf("Debug CbcHeuristicDive giving bad solution\n");
      }
      delete [] rowActivity;
    }

#ifdef DIVE_DEBUG
    std::cout << "nRoundInfeasible = " << nRoundInfeasible
              << ", nRoundFeasible = " << nRoundFeasible
              << ", returnCode = " << returnCode
              << ", reasonToStop = " << reasonToStop
              << ", simplexIts = " << numberSimplexIterations
              << ", iterations = " << iteration << std::endl;
#endif

    delete [] columnFixed;
    delete [] originalBound;
    delete [] fixedAtLowerBound;
    delete [] candidate;
    delete [] random;
    delete [] downArray_;
    downArray_ = NULL;
    delete [] upArray_;
    upArray_ = NULL;
    delete solver;
    return returnCode;
}
Exemplo n.º 15
0
int main(int argc, const char *argv[])
{
     int status;
     CoinMpsIO m;
     if (argc < 2)
          status = m.readMps("model1.mps", "");
     else
          status = m.readMps(argv[1], "");

     if (status) {
          fprintf(stdout, "Bad readMps %s\n", argv[1]);
          exit(1);
     }

     // Load up model1 - so we can use known good solution
     ClpSimplex model1;
     model1.loadProblem(*m.getMatrixByCol(),
                        m.getColLower(), m.getColUpper(),
                        m.getObjCoefficients(),
                        m.getRowLower(), m.getRowUpper());
     model1.dual();
     // Get data arrays
     const CoinPackedMatrix * matrix1 = m.getMatrixByCol();
     const int * start1 = matrix1->getVectorStarts();
     const int * length1 = matrix1->getVectorLengths();
     const int * row1 = matrix1->getIndices();
     const double * element1 = matrix1->getElements();

     const double * columnLower1 = m.getColLower();
     const double * columnUpper1 = m.getColUpper();
     const double * rowLower1 = m.getRowLower();
     const double * rowUpper1 = m.getRowUpper();
     const double * objective1 = m.getObjCoefficients();

     int numberColumns = m.getNumCols();
     int numberRows = m.getNumRows();
     int numberElements = m.getNumElements();

     // Get new arrays
     int numberColumns2 = (numberColumns + 1);
     int * start2 = new int[numberColumns2+1];
     int * row2 = new int[numberElements];
     double * element2 = new double[numberElements];
     int * segstart = new int[numberColumns+1];
     double * breakpt  = new double[2*numberColumns];
     double * slope  = new double[2*numberColumns];

     double * objective2 = new double[numberColumns2];
     double * columnLower2 = new double[numberColumns2];
     double * columnUpper2 = new double[numberColumns2];
     double * rowLower2 = new double[numberRows];
     double * rowUpper2 = new double[numberRows];

     // We need to modify rhs
     memcpy(rowLower2, rowLower1, numberRows * sizeof(double));
     memcpy(rowUpper2, rowUpper1, numberRows * sizeof(double));
     double objectiveOffset = 0.0;

     // For new solution
     double * newSolution = new double [numberColumns];
     const double * oldSolution = model1.primalColumnSolution();

     int iColumn;
     for (iColumn = 0; iColumn < numberColumns; iColumn++)
          printf("%g ", oldSolution[iColumn]);
     printf("\n");

     numberColumns2 = 0;
     numberElements = 0;
     start2[0] = 0;
     int segptr = 0;

     segstart[0] = 0;

     // Now check for duplicates
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          // test if column identical to next column
          bool ifcopy = 1;
          if (iColumn < numberColumns - 1) {
               int  joff = length1[iColumn];
               for (int j = start1[iColumn]; j < start1[iColumn] + length1[iColumn]; j++) {
                    if (row1[j] != row1[j+joff]) {
                         ifcopy = 0;
                         break;
                    }
                    if (element1[j] != element1[j+joff]) {
                         ifcopy = 0;
                         break;
                    }
               }
          } else {
               ifcopy = 0;
          }
          //if (iColumn>47||iColumn<45)
          //ifcopy=0;
          if (ifcopy) {
               double lo1 = columnLower1[iColumn];
               double up1 = columnUpper1[iColumn];
               double obj1 = objective1[iColumn];
               double sol1 = oldSolution[iColumn];
               double lo2 = columnLower1[iColumn+1];
               double up2 = columnUpper1[iColumn+1];
               double obj2 = objective1[iColumn+1];
               double sol2 = oldSolution[iColumn+1];
               if (fabs(up1 - lo2) > 1.0e-8) {
                    // try other way
                    double temp;
                    temp = lo1;
                    lo1 = lo2;
                    lo2 = temp;
                    temp = up1;
                    up1 = up2;
                    up2 = temp;
                    temp = obj1;
                    obj1 = obj2;
                    obj2 = temp;
                    temp = sol1;
                    sol1 = sol2;
                    sol2 = temp;
                    assert(fabs(up1 - lo2) < 1.0e-8);
               }
               // subtract out from rhs
               double fixed = up1;
               // do offset
               objectiveOffset += fixed * obj2;
               for (int j = start1[iColumn]; j < start1[iColumn] + length1[iColumn]; j++) {
                    int iRow = row1[j];
                    double value = element1[j];
                    if (rowLower2[iRow] > -1.0e30)
                         rowLower2[iRow] -= value * fixed;
                    if (rowUpper2[iRow] < 1.0e30)
                         rowUpper2[iRow] -= value * fixed;
               }
               newSolution[numberColumns2] = fixed;
               if (fabs(sol1 - fixed) > 1.0e-8)
                    newSolution[numberColumns2] = sol1;
               if (fabs(sol2 - fixed) > 1.0e-8)
                    newSolution[numberColumns2] = sol2;
               columnLower2[numberColumns2] = lo1;
               columnUpper2[numberColumns2] = up2;
               objective2[numberColumns2] = 0.0;
               breakpt[segptr] = lo1;
               slope[segptr++] = obj1;
               breakpt[segptr] = lo2;
               slope[segptr++] = obj2;
               for (int j = start1[iColumn]; j < start1[iColumn] + length1[iColumn]; j++) {
                    row2[numberElements] = row1[j];
                    element2[numberElements++] = element1[j];
               }
               start2[++numberColumns2] = numberElements;
               breakpt[segptr] = up2;
               slope[segptr++] = COIN_DBL_MAX;
               segstart[numberColumns2] = segptr;
               iColumn++; // skip next column
          } else {
               // normal column
               columnLower2[numberColumns2] = columnLower1[iColumn];
               columnUpper2[numberColumns2] = columnUpper1[iColumn];
               objective2[numberColumns2] = objective1[iColumn];
               breakpt[segptr] = columnLower1[iColumn];
               slope[segptr++] = objective1[iColumn];
               for (int j = start1[iColumn]; j < start1[iColumn] + length1[iColumn]; j++) {
                    row2[numberElements] = row1[j];
                    element2[numberElements++] = element1[j];
               }
               newSolution[numberColumns2] = oldSolution[iColumn];
               start2[++numberColumns2] = numberElements;
               breakpt[segptr] = columnUpper1[iColumn];
               slope[segptr++] = COIN_DBL_MAX;
               segstart[numberColumns2] = segptr;
          }
     }

     // print new number of columns, elements
     printf("New number of columns  = %d\n", numberColumns2);
     printf("New number of elements = %d\n", numberElements);
     printf("Objective offset is %g\n", objectiveOffset);


     ClpSimplex  model;

     // load up
     model.loadProblem(numberColumns2, numberRows,
                       start2, row2, element2,
                       columnLower2, columnUpper2,
                       objective2,
                       rowLower2, rowUpper2);
     model.scaling(0);
     model.setDblParam(ClpObjOffset, -objectiveOffset);
     // Create nonlinear objective
     int returnCode = model.createPiecewiseLinearCosts(segstart, breakpt, slope);
     assert(!returnCode);

     // delete
     delete [] segstart;
     delete [] breakpt;
     delete [] slope;
     delete [] start2;
     delete [] row2 ;
     delete [] element2;

     delete [] objective2;
     delete [] columnLower2;
     delete [] columnUpper2;
     delete [] rowLower2;
     delete [] rowUpper2;

     // copy in solution - (should be optimal)
     model.allSlackBasis();
     memcpy(model.primalColumnSolution(), newSolution, numberColumns2 * sizeof(double));
     //memcpy(model.columnLower(),newSolution,numberColumns2*sizeof(double));
     //memcpy(model.columnUpper(),newSolution,numberColumns2*sizeof(double));
     delete [] newSolution;
     //model.setLogLevel(63);

     const double * solution = model.primalColumnSolution();
     double * saveSol = new double[numberColumns2];
     memcpy(saveSol, solution, numberColumns2 * sizeof(double));
     for (iColumn = 0; iColumn < numberColumns2; iColumn++)
          printf("%g ", solution[iColumn]);
     printf("\n");
     // solve
     model.primal(1);
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     model.primal(1);
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     model.primal();
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     model.allSlackBasis();
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     model.setLogLevel(63);
     model.primal();
     for (iColumn = 0; iColumn < numberColumns2; iColumn++) {
          if (fabs(solution[iColumn] - saveSol[iColumn]) > 1.0e-3)
               printf(" ** was %g ", saveSol[iColumn]);
          printf("%g ", solution[iColumn]);
     }
     printf("\n");
     return 0;
}
Exemplo n.º 16
0
int main (int argc, const char *argv[])
{
     const char * name;
     // problem is actually scaled for osl, dynamically for clp (slows clp)
     // default is primal, no presolve, minimise and use clp
     bool    primal = true, presolve = false;
     int useosl = 0;
     bool freeFormat = false;
     bool exportIt = false;

     EKKModel * model;
     EKKContext * context;

     if ( argc > 1 ) {
          name = argv[1];
     } else {
          name = "../../Data/Sample/p0033.mps";
     }

     /* initialize OSL environment */
     context = ekk_initializeContext();
     model = ekk_newModel(context, "");

     int i;
     printf("*** Options ");
     for (i = 2; i < argc; i++) {
          printf("%s ", argv[i]);
     }
     printf("\n");

     // see if free format needed

     for (i = 2; i < argc; i++) {
          if (!strncmp(argv[i], "free", 4)) {
               freeFormat = true;
          }
     }

     // create model from MPS file

     if (!freeFormat) {
          ekk_importModel(model, name);
     } else {
          ekk_importModelFree(model, name);
     }

     // other options
     for (i = 2; i < argc; i++) {
          if (!strncmp(argv[i], "max", 3)) {
               if (!strncmp(argv[i], "max2", 4)) {
                    // This is for testing - it just reverses signs and maximizes
                    int i, n = ekk_getInumcols(model);
                    double * objective = ekk_getObjective(model);
                    for (i = 0; i < n; i++) {
                         objective[i] = -objective[i];
                    }
                    ekk_setObjective(model, objective);
                    ekk_setMaximize(model);
               } else {
                    // maximize
                    ekk_setMaximize(model);
               }
          }
          if (!strncmp(argv[i], "dual", 4)) {
               primal = false;
          }
          if (!strncmp(argv[i], "presol", 6)) {
               presolve = true;
          }
          if (!strncmp(argv[i], "osl", 3)) {
               useosl = 1;
          }
          if (!strncmp(argv[i], "both", 4)) {
               useosl = 2;
          }
          if (!strncmp(argv[i], "export", 6)) {
               exportIt = true;
          }
     }
     if (useosl) {
          // OSL
          if (presolve)
               ekk_preSolve(model, 3, NULL);
          ekk_scale(model);

          if (primal)
               ekk_primalSimplex(model, 1);
          else
               ekk_dualSimplex(model);
          if (presolve) {
               ekk_postSolve(model, NULL);
               ekk_primalSimplex(model, 3);
          }
          if (useosl == 2)
               ekk_allSlackBasis(model); // otherwise it would be easy
     }
     if ((useosl & 2) == 0) {
          // CLP
          if (presolve)
               ekk_preSolveClp(model, true, 5);
          /* 3 is because it is ignored if no presolve, and we
             are forcing Clp to re-optimize */
          if (primal)
               ekk_primalClp(model, 1, 3);
          else
               ekk_dualClp(model, 3);
     }
     if (exportIt) {
          ClpSimplex * clp = new ClpSimplex();;
          int numberRows = ekk_getInumrows(model);
          int numberColumns = ekk_getInumcols(model);
          clp->loadProblem(numberColumns, numberRows, ekk_blockColumn(model, 0),
                           ekk_blockRow(model, 0), ekk_blockElement(model, 0),
                           ekk_collower(model), ekk_colupper(model),
                           ekk_objective(model),
                           ekk_rowlower(model), ekk_rowupper(model));
          // Do integer stuff
          int * which =  ekk_listOfIntegers(model);
          int numberIntegers =  ekk_getInumints(model);
          for (int i = 0; i < numberIntegers; i++)
               clp->setInteger(which[i]);
          ekk_free(which);
          clp->writeMps("try1.mps");
          delete clp;
     }
     ekk_deleteModel(model);
     ekk_endContext(context);
     return 0;
}
Exemplo n.º 17
0
/*
  Comments needed
  Returns 1 if solution, 0 if not */
int
CbcHeuristicPivotAndFix::solution(double & /*solutionValue*/,
                                  double * /*betterSolution*/)
{

    numCouldRun_++; // Todo: Ask JJHF what this for.
    std::cout << "Entering Pivot-and-Fix Heuristic" << std::endl;

#ifdef HEURISTIC_INFORM
    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
	   heuristicName(),numRuns_,numCouldRun_,when_);
#endif
#ifdef FORNOW
    std::cout << "Lucky you! You're in the Pivot-and-Fix Heuristic" << std::endl;
    // The struct should be moved to member data



    typedef struct {
        int numberSolutions;
        int maximumSolutions;
        int numberColumns;
        double ** solution;
        int * numberUnsatisfied;
    } clpSolution;

    double start = CoinCpuTime();

    OsiClpSolverInterface * clpSolverOriginal
    = dynamic_cast<OsiClpSolverInterface *> (model_->solver());
    assert (clpSolverOriginal);
    OsiClpSolverInterface *clpSolver(clpSolverOriginal);

    ClpSimplex * simplex = clpSolver->getModelPtr();

    // Initialize the structure holding the solutions
    clpSolution solutions;
    // Set typeStruct field of ClpTrustedData struct to one.
    // This tells Clp it's "Mahdi!"
    ClpTrustedData trustedSolutions;
    trustedSolutions.typeStruct = 1;
    trustedSolutions.data = &solutions;
    solutions.numberSolutions = 0;
    solutions.maximumSolutions = 0;
    solutions.numberColumns = simplex->numberColumns();
    solutions.solution = NULL;
    solutions.numberUnsatisfied = NULL;
    simplex->setTrustedUserPointer(&trustedSolutions);

    // Solve from all slack to get some points
    simplex->allSlackBasis();
    simplex->primal();

    // -------------------------------------------------
    // Get the problem information
    // - get the number of cols and rows
    int numCols = clpSolver->getNumCols();
    int numRows = clpSolver->getNumRows();

    // - get the right hand side of the rows
    const double * rhs = clpSolver->getRightHandSide();

    // - find the integer variables
    bool * varClassInt = new bool[numCols];
    int numInt = 0;
    for (int i = 0; i < numCols; i++) {
        if (clpSolver->isContinuous(i))
            varClassInt[i] = 0;
        else {
            varClassInt[i] = 1;
            numInt++;
        }
    }

    // -Get the rows sense
    const char * rowSense;
    rowSense = clpSolver->getRowSense();

    // -Get the objective coefficients
    const double *objCoefficients = clpSolver->getObjCoefficients();
    double *originalObjCoeff = new double [numCols];
    for (int i = 0; i < numCols; i++)
        originalObjCoeff[i] = objCoefficients[i];

    // -Get the matrix of the problem
    double ** matrix = new double * [numRows];
    for (int i = 0; i < numRows; i++) {
        matrix[i] = new double[numCols];
        for (int j = 0; j < numCols; j++)
            matrix[i][j] = 0;
    }
    const CoinPackedMatrix* matrixByRow = clpSolver->getMatrixByRow();
    const double * matrixElements = matrixByRow->getElements();
    const int * matrixIndices = matrixByRow->getIndices();
    const int * matrixStarts = matrixByRow->getVectorStarts();
    for (int j = 0; j < numRows; j++) {
        for (int i = matrixStarts[j]; i < matrixStarts[j+1]; i++) {
            matrix[j][matrixIndices[i]] = matrixElements[i];
        }
    }

    // The newObj is the randomly perturbed constraint used to find new
    // corner points
    double * newObj = new double [numCols];

    // Set the random seed
    srand ( time(NULL) + 1);
    int randNum;

    // We're going to add a new row to the LP formulation
    // after finding each new solution.
    // Adding a new row requires the new elements and the new indices.
    // The elements are original objective function coefficients.
    // The indicies are the (dense) columns indices stored in addRowIndex.
    // The rhs is the value of the new solution stored in solutionValue.
    int * addRowIndex = new int[numCols];
    for (int i = 0; i < numCols; i++)
        addRowIndex[i] = i;

    // The number of feasible solutions found by the PF heuristic.
    // This controls the return code of the solution() method.
    int numFeasibles = 0;

    // Shuffle the rows
    int * index = new int [numRows];
    for (int i = 0; i < numRows; i++)
        index[i] = i;
    for (int i = 0; i < numRows; i++) {
        int temp = index[i];
        int randNumTemp = i + (rand() % (numRows - i));
        index[i] = index[randNumTemp];
        index[randNumTemp] = temp;
    }

    // In the clpSolution struct, we store a lot of column solutions.
    // For each perturb objective, we store the solution from each
    // iteration of the LP solve.
    // For each perturb objective, we look at the collection of
    // solutions to do something extremly intelligent :-)
    // We could (and should..and will :-) wipe out the block of
    // solutions when we're done with them. But for now, we just move on
    // and store the next block of solutions for the next (perturbed)
    // objective.
    // The variable startIndex tells us where the new block begins.
    int startIndex = 0;

    // At most "fixThreshold" number of integer variables can be unsatisfied
    // for calling smallBranchAndBound().
    // The PF Heuristic only fixes fixThreshold number of variables to
    // their integer values. Not more. Not less. The reason is to give
    // the smallBB some opportunity to find better solutions. If we fix
    // everything it might be too many (leading the heuristic to come up
    // with infeasibility rather than a useful result).
    // (This is an important paramater. And it is dynamically set.)
    double fixThreshold;
    /*
        if(numInt > 400)
        fixThreshold = 17*sqrt(numInt);
        if(numInt<=400 && numInt>100)
        fixThreshold = 5*sqrt(numInt);
        if(numInt<=100)
        fixThreshold = 4*sqrt(numInt);
    */
    // Initialize fixThreshold based on the number of integer
    // variables
    if (numInt <= 100)
        fixThreshold = .35 * numInt;
    if (numInt > 100 && numInt < 1000)
        fixThreshold = .85 * numInt;
    if (numInt >= 1000)
        fixThreshold = .1 * numInt;

    // Whenever the dynamic system for changing fixThreshold
    // kicks in, it changes the parameter by the
    // fixThresholdChange amount.
    // (The 25% should be member data and tuned. Another paper!)
    double fixThresholdChange = 0.25 * fixThreshold;

    // maxNode is the maximum number of nodes we allow smallBB to
    // search. It's initialized to 400 and changed dynamically.
    // The 400 should be member data, if we become virtuous.
    int maxNode = 400;

    // We control the decision to change maxNode through the boolean
    // variable  changeMaxNode. The boolean variable is initialized to
    // true and gets set to false under a condition (and is never true
    // again.)
    // It's flipped off and stays off (in the current incarnation of PF)
    bool changeMaxNode = 1;

    // The sumReturnCode is used for the dynamic system that sets
    // fixThreshold and changeMaxNode.
    //
    // We track what's happening in sumReturnCode. There are 8 switches.
    // The first 5 switches corresponds to a return code for smallBB.
    //
    // We want to know how many times we consecutively get the same
    // return code.
    //
    // If "good" return codes are happening often enough, we're happy.
    //
    // If a "bad" returncodes happen consecutively, we want to
    // change something.
    //
    // The switch 5 is the number of times PF didn't call smallBB
    // becuase the number of integer variables that took integer values
    // was less than fixThreshold.
    //
    // The swicth 6 was added for a brilliant idea...to be announced
    // later (another paper!)
    //
    // The switch 7 is the one that changes the max node. Read the
    // code. (Todo: Verbalize the brilliant idea for the masses.)
    //
    int sumReturnCode[8];
    /*
      sumReturnCode[0] ~ -1 --> problem too big for smallBB
      sumReturnCode[1] ~ 0  --> smallBB not finshed and no soln
      sumReturnCode[2] ~ 1  --> smallBB not finshed and there is a soln
      sumReturnCode[3] ~ 2  --> smallBB finished and no soln
      sumReturnCode[4] ~ 3  --> smallBB finished and there is a soln
      sumReturnCode[5] ~ didn't call smallBranchAndBound too few to fix
      sumReturnCode[6] ~ didn't call smallBranchAndBound too many unsatisfied
      sumReturnCode[7] ~ the same as sumReturnCode[1] but becomes zero just if the returnCode is not 0
    */

    for (int i = 0; i < 8; i++)
        sumReturnCode[i] = 0;
    int * colIndex = new int[numCols];
    for (int i = 0; i < numCols; i++)
        colIndex[i] = i;
    double cutoff = COIN_DBL_MAX;
    bool didMiniBB;

    // Main loop
    for (int i = 0; i < numRows; i++) {
        // track the number of mini-bb for the dynamic threshold setting
        didMiniBB = 0;

        for (int k = startIndex; k < solutions.numberSolutions; k++)
            //if the point has 0 unsatisfied variables; make sure it is
            //feasible. Check integer feasiblity and constraints.
            if (solutions.numberUnsatisfied[k] == 0) {
                double feasibility = 1;
                //check integer feasibility
                for (int icol = 0; icol < numCols; icol++) {
                    double closest = floor(solutions.solution[k][icol] + 0.5);
                    if (varClassInt[icol] && (fabs(solutions.solution[k][icol] - closest) > 1e-6)) {
                        feasibility = 0;
                        break;
                    }
                }
                //check if the solution satisfies the constraints
                for (int irow = 0; irow < numRows; irow++) {
                    double lhs = 0;
                    for (int j = 0; j < numCols; j++)
                        lhs += matrix[irow][j] * solutions.solution[k][j];
                    if (rowSense[irow] == 'L' && lhs > rhs[irow] + 1e-6) {
                        feasibility = 0;
                        break;
                    }
                    if (rowSense[irow] == 'G' && lhs < rhs[irow] - 1e-6) {
                        feasibility = 0;
                        break;
                    }
                    if (rowSense[irow] == 'E' && (lhs - rhs[irow] > 1e-6 || lhs - rhs[irow] < -1e-6)) {
                        feasibility = 0;
                        break;
                    }
                }

                //if feasible, find the objective value and set the cutoff
                // for the smallBB and add a new constraint to the LP
                // (and update the best solution found so far for the
                // return arguments)
                if (feasibility) {
                    double objectiveValue = 0;
                    for (int j = 0; j < numCols; j++)
                        objectiveValue += solutions.solution[k][j] * originalObjCoeff[j];
                    cutoff = objectiveValue;
                    clpSolver->addRow(numCols, addRowIndex, originalObjCoeff, -COIN_DBL_MAX, cutoff);

                    // Todo: pick up the best solution in the block (not
                    // the last).
                    solutionValue = objectiveValue;
                    for (int m = 0; m < numCols; m++)
                        betterSolution[m] = solutions.solution[k][m];
                    numFeasibles++;
                }
            }

        // Go through the block of solution and decide if to call smallBB
        for (int k = startIndex; k < solutions.numberSolutions; k++) {
            if (solutions.numberUnsatisfied[k] <= fixThreshold) {
                // get new copy
                OsiSolverInterface * newSolver;
                newSolver = new OsiClpSolverInterface(*clpSolver);
                newSolver->setObjSense(1);
                newSolver->setObjective(originalObjCoeff);
                int numberColumns = newSolver->getNumCols();
                int numFixed = 0;

                // Fix the first fixThreshold number of integer vars
                // that are satisfied
                for (int iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
                    if (newSolver->isInteger(iColumn)) {
                        double value = solutions.solution[k][iColumn];
                        double intValue = floor(value + 0.5);
                        if (fabs(value - intValue) < 1.0e-5) {
                            newSolver->setColLower(iColumn, intValue);
                            newSolver->setColUpper(iColumn, intValue);
                            numFixed++;
                            if (numFixed > numInt - fixThreshold)
                                break;
                        }
                    }
                }
                COIN_DETAIL_PRINT(printf("numFixed: %d\n", numFixed));
                COIN_DETAIL_PRINT(printf("fixThreshold: %f\n", fixThreshold));
		COIN_DETAIL_PRINT(printf("numInt: %d\n", numInt));
                double *newSolution = new double[numCols];
                double newSolutionValue;

                // Call smallBB on the modified problem
                int returnCode = smallBranchAndBound(newSolver, maxNode, newSolution,
                                                     newSolutionValue, cutoff, "mini");

                // If smallBB found a solution, update the better
                // solution and solutionValue (we gave smallBB our
                // cutoff, so it only finds improving solutions)
                if (returnCode == 1 || returnCode == 3) {
                    numFeasibles ++;
                    solutionValue = newSolutionValue;
                    for (int m = 0; m < numCols; m++)
                        betterSolution[m] = newSolution[m];
                    COIN_DETAIL_PRINT(printf("cutoff: %f\n", newSolutionValue));
                    COIN_DETAIL_PRINT(printf("time: %.2lf\n", CoinCpuTime() - start));
                }
                didMiniBB = 1;
                COIN_DETAIL_PRINT(printf("returnCode: %d\n", returnCode));

                //Update sumReturnCode array
                for (int iRC = 0; iRC < 6; iRC++) {
                    if (iRC == returnCode + 1)
                        sumReturnCode[iRC]++;
                    else
                        sumReturnCode[iRC] = 0;
                }
                if (returnCode != 0)
                    sumReturnCode[7] = 0;
                else
                    sumReturnCode[7]++;
                if (returnCode == 1 || returnCode == 3) {
                    cutoff = newSolutionValue;
                    clpSolver->addRow(numCols, addRowIndex, originalObjCoeff, -COIN_DBL_MAX, cutoff);
                    COIN_DETAIL_PRINT(printf("******************\n\n*****************\n"));
                }
                break;
            }
        }

        if (!didMiniBB && solutions.numberSolutions - startIndex > 0) {
            sumReturnCode[5]++;
            for (int iRC = 0; iRC < 5; iRC++)
                sumReturnCode[iRC] = 0;
        }

        //Change "fixThreshold" if needed
        // using the data we've recorded in sumReturnCode
        if (sumReturnCode[1] >= 3)
            fixThreshold -= fixThresholdChange;
        if (sumReturnCode[7] >= 3 && changeMaxNode) {
            maxNode *= 5;
            changeMaxNode = 0;
        }
        if (sumReturnCode[3] >= 3 && fixThreshold < 0.95 * numInt)
            fixThreshold += fixThresholdChange;
        if (sumReturnCode[5] >= 4)
            fixThreshold += fixThresholdChange;
        if (sumReturnCode[0] > 3)
            fixThreshold -= fixThresholdChange;

        startIndex = solutions.numberSolutions;

        //Check if the maximum iterations limit is reached
        // rlh: Ask John how this is working with the change to trustedUserPtr.
        if (solutions.numberSolutions > 20000)
            break;

        // The first time in this loop PF solves orig LP.

        //Generate the random objective function
        randNum = rand() % 10 + 1;
        randNum = fmod(randNum, 2);
        for (int j = 0; j < numCols; j++) {
            if (randNum == 1)
                if (fabs(matrix[index[i]][j]) < 1e-6)
                    newObj[j] = 0.1;
                else
                    newObj[j] = matrix[index[i]][j] * 1.1;
            else if (fabs(matrix[index[i]][j]) < 1e-6)
                newObj[j] = -0.1;
            else
                newObj[j] = matrix[index[i]][j] * 0.9;
        }
        clpSolver->setObjective(newObj);
        if (rowSense[i] == 'L')
            clpSolver->setObjSense(-1);
        else
            // Todo #1: We don't need to solve the LPs to optimality.
            // We just need corner points.
            // There's a problem in stopping Clp that needs to be looked
            // into. So for now, we solve optimality.
            clpSolver->setObjSense(1);
        //	  simplex->setMaximumIterations(100);
        clpSolver->getModelPtr()->primal(1);
        //	  simplex->setMaximumIterations(100000);
#ifdef COIN_DETAIL
        printf("cutoff: %f\n", cutoff);
        printf("time: %.2f\n", CoinCpuTime() - start);
        for (int iRC = 0; iRC < 8; iRC++)
            printf("%d ", sumReturnCode[iRC]);
        printf("\nfixThreshold: %f\n", fixThreshold);
        printf("numInt: %d\n", numInt);
        printf("\n---------------------------------------------------------------- %d\n", i);
#endif

        //temp:
        if (i > 3) break;

    }

    COIN_DETAIL_PRINT(printf("Best Feasible Found: %f\n", cutoff));
    COIN_DETAIL_PRINT(printf("Total time: %.2f\n", CoinCpuTime() - start));

    if (numFeasibles == 0) {
        return 0;
    }



    // We found something better
    std::cout << "See you soon! You're leaving the Pivot-and-Fix Heuristic" << std::endl;
    std::cout << std::endl;

    return 1;
#endif

    return 0;

}
Exemplo n.º 18
0
// To define the function sciclp as a C function and allow this function to be loaded easily in scilab
extern "C" int sciclp(char * fname)
{
  ClpSimplex      * modelSimplex  = NULL;
  ClpInterior     * modelInterior = NULL;
  ClpModel        * modelBase     = NULL;
  ClpCholeskyBase * cholesky      = NULL; 
  DerivedHandler  * printer       = NULL;
  ClpSolve          modelSolve; // YC: we can set some parameters via CbcSolve
  CoinPackedMatrix  A_matrix, Q_matrix;
#ifdef HANDLE_CTRLC
  MyClpEventHandler SciClpEventHandler;
  SciClpEventHandler.setInCbc(false);
#endif
  int Log = 0;
  int ncols = 0, nrows = 0, i, j, nz = 0, writemps = 0;
  int count = 0, status = 0, type;
  char  * writemps_filename = NULL;
  SciSparse S_A, S_Q;
  
  if (Rhs<LASTPARAM) 
    {
      Scierror(999,"%s: 12 inputs required in call to %s. Bug in clp.sci ?...\n", fname, fname);
      return 0;
    }
		
  /* Get pointers to input */

  int n_a,     m_a,     * a_addr     = NULL;
  int n_c,     m_c,     * c_addr     = NULL;
  int n_lhs,   m_lhs,   * lhs_addr   = NULL;
  int n_rhs,   m_rhs,   * rhs_addr   = NULL;
  int n_upper, m_upper, * upper_addr = NULL;
  int n_lower, m_lower, * lower_addr = NULL;
  int * vtype_addr = NULL;
  int * ctype_addr = NULL;
  int n_q,     m_q,     * q_addr     = NULL;
  double * c = NULL, * lhs = NULL, * rhs = NULL, * lower = NULL, * upper = NULL, * a = NULL;
  double * q = NULL;
  char * ctype = NULL, * vtype = NULL;
  SciErr _SciErr;
  
  _SciErr = getVarAddressFromPosition(pvApiCtx, C_IN, &c_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, c_addr, &n_c, &m_c, &c); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, LHS_IN, &lhs_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, lhs_addr, &n_lhs, &m_lhs, &lhs); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, RHS_IN, &rhs_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, rhs_addr, &n_rhs, &m_rhs, &rhs); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, LOWER_IN, &lower_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, lower_addr, &n_lower, &m_lower, &lower); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, UPPER_IN, &upper_addr); SCICOINOR_ERROR;
  _SciErr = getMatrixOfDouble(pvApiCtx, upper_addr, &n_upper, &m_upper, &upper); SCICOINOR_ERROR;
  _SciErr = getVarAddressFromPosition(pvApiCtx, CTYPE_IN, &ctype_addr); SCICOINOR_ERROR;
  getAllocatedSingleString(pvApiCtx, ctype_addr, &ctype);
  _SciErr = getVarAddressFromPosition(pvApiCtx, VTYPE_IN, &vtype_addr); SCICOINOR_ERROR;
  getAllocatedSingleString(pvApiCtx, vtype_addr, &vtype);

  ncols = n_c   * m_c;   /* Length of c == number of columns */
  nrows = n_rhs * m_rhs; /* length of b == number of rows    */
  if (nrows==0) nrows = n_lhs * m_lhs;

#ifdef DEBUG
  sciprint("DEBUG: c           size: m = %d n = %d\n", m_c,     n_c);
  sciprint("DEBUG: lhs         size: m = %d n = %d\n", m_lhs,   n_lhs);
  sciprint("DEBUG: rhs         size: m = %d n = %d\n", m_rhs,   n_rhs);
  sciprint("DEBUG: lower       size: m = %d n = %d\n", m_lower, n_lower);
  sciprint("DEBUG: upper       size: m = %d n = %d\n", m_upper, n_upper);
  sciprint("DEBUG: ctype       size: m = %d n = %d\n", m_ctype, n_ctype);
  sciprint("DEBUG: vtype       size: m = %d n = %d\n", m_vtype, n_vtype);
  sciprint("DEBUG: nrows = %d\n", nrows);
  sciprint("DEBUG: ncols = %d\n", ncols);

  sciprint("c :");
  for(i=0;i<ncols; i++) sciprint("%f ",*(c+i));
  sciprint("\n");
  sciprint("lhs :");
  for(i=0;i<nrows; i++) sciprint("%f ",*(lhs+i));
  sciprint("\n");
  sciprint("rhs :");
  for(i=0;i<nrows; i++) sciprint("%f ",*(rhs+i));
  sciprint("\n");
  sciprint("lb :");
  for(i=0;i<ncols; i++) sciprint("%f ",*(lower+i));
  sciprint("\n");
  sciprint("ub :");
  for(i=0;i<ncols; i++) sciprint("%f ",*(upper+i));
  sciprint("\n");
  sciprint("ctype = %s\n", ctype);
  sciprint("vtype = %s\n", vtype);
#endif

  //////////////////
  // The A matrix //
  //////////////////

  _SciErr = getVarAddressFromPosition(pvApiCtx, A_IN, &a_addr); SCICOINOR_ERROR;
  _SciErr = getVarType(pvApiCtx, a_addr, &type); SCICOINOR_ERROR;
  if(type!=sci_sparse)
    {
#ifdef DEBUG
      sciprint("DEBUG: A_IN is not sparse\n");
#endif
      
      _SciErr = getMatrixOfDouble(pvApiCtx, a_addr, &m_a, &n_a, &a); SCICOINOR_ERROR;
      A_matrix.setDimensions(nrows,ncols);
      
      if (a==NULL) 
	{
	  Scierror(999,"%s: invalid value of matrix a\n",fname);
	  
	  freeAllocatedSingleString(ctype);
	  freeAllocatedSingleString(vtype);
	  
	  return 0;
	}
      
      for(i=0; i<m_a; i++)
	{
	  for(j=0; j<n_a; j++)
	    {
	      if (*(a+i+j*m_a) != 0) A_matrix.modifyCoefficient(i,j,*(a+i+j*m_a));
#ifdef DEBUG
	      sciprint("%f ",*(a+i+j*m_a));
#endif
	    }
#ifdef DEBUG
	  sciprint("\n");
#endif
	}
    }
  else
    {
#ifdef DEBUG
      sciprint("DEBUG: A_IN is sparse\n");
#endif
      
      getAllocatedSparseMatrix(pvApiCtx, a_addr, &S_A.m, &S_A.n, &S_A.nel, &S_A.mnel, &S_A.icol, &S_A.R);
      A_matrix.setDimensions(nrows,ncols);
      
#ifdef DEBUG
      sciprint("A = [%d,%d]\n", m_a, n_a);
#endif
      
      nz = S_A.nel;
      
      count = 0;
      for(i=0;i<S_A.m;i++)
	{
	  if (S_A.mnel[i]!=0) 
	    {
#ifdef DEBUG
	      sciprint("mnel[%d] = %d - ",i, S_A.mnel[i]);
#endif
	      for(j=0;j<S_A.mnel[i];j++)
		{
		  count++;
		  A_matrix.modifyCoefficient(i,S_A.icol[count-1]-1,S_A.R[count-1]);
#ifdef DEBUG
		  sciprint("[%d] = %f ", S_A.icol[count-1]-1, S_A.R[count-1]);
#endif
		}
#ifdef DEBUG
	      sciprint("\n");
#endif
	    }
	}
      
      freeAllocatedSparseMatrix(S_A.mnel, S_A.icol, S_A.R);
    }
  
  /////////////////
  // Get options //
  /////////////////

#ifdef DEBUG
  sciprint("DEBUG: get options\n");
#endif

  // Default settings
  int * param_in_addr = NULL;
  int     solverchoice = 1, loglevel = 0, fact_freq = 200, perturb = 0;
  int     presolve = 0, red_grad = 1, maximumbarrieriterations = 200;
  int     tmp_int, tmp_res;
  double  tmp_double;
  char *  tmp_char;

  initPList(pvApiCtx, PARAM_IN, &param_in_addr);
  if (!checkPList(pvApiCtx, param_in_addr))
    {
      Scierror(999, "%s: argument n° %d is not a plist\n", fname, PARAM_IN);

      return 0;
    }

  // solver option
  getIntInPList(pvApiCtx, param_in_addr, "solver", &tmp_int, &tmp_res, 1, Log, CHECK_NONE);
  if (tmp_res!=-1) solverchoice = tmp_int;

  // Load the matrix in the solver
  switch(solverchoice)
    {
    case 6:
      modelInterior = new ClpInterior;
      modelBase = (ClpModel *)modelInterior;
      break;
    default:
      modelSimplex = new ClpSimplex;
      modelBase = (ClpModel *)modelSimplex;
      break;
    }

  // maxnumiterations option
  getIntInPList(pvApiCtx, param_in_addr, "maxnumiterations", &tmp_int, &tmp_res, 1000, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setMaximumIterations(tmp_int);
      
  // maxnumseconds option
  getDoubleInPList(pvApiCtx, param_in_addr, "maxnumseconds", &tmp_double, &tmp_res, 3600, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setMaximumSeconds(tmp_double);
      
  // primaltolerance option
  getDoubleInPList(pvApiCtx, param_in_addr, "primaltolerance", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setPrimalTolerance(tmp_double);

  // dualtolerance option
  getDoubleInPList(pvApiCtx, param_in_addr, "dualtolerance", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1)   modelBase->setDualTolerance(tmp_double);				

  // verbose option
  getIntInPList(pvApiCtx, param_in_addr, "verbose", &tmp_int, &tmp_res, 0, Log, CHECK_NONE);
  if (tmp_res!=-1) 
    {
      ///////////////////////////////
      // Enable printing in Scilab //
      // and set parameters of clp //
      ///////////////////////////////
	  
      loglevel = tmp_int;

      printer = new DerivedHandler(); // assumed open	
      printer->setLogLevel(loglevel);
    }

  // optim_dir option
  getIntInPList(pvApiCtx, param_in_addr, "optim_dir", &tmp_int, &tmp_res, 1, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setOptimizationDirection(tmp_int);

  // writemps option
  getStringInPList(pvApiCtx, param_in_addr, "writemps", &tmp_char, &tmp_res, "test.mps", Log, CHECK_NONE);
  if (tmp_res!=-1) 
    {
      writemps_filename = tmp_char;
      writemps = 1;
#ifdef DEBUG
      sciprint("DEBUG: writemps_filename = %s\n", writemps_filename);
#endif
    }

  // perturb option
  getIntInPList(pvApiCtx, param_in_addr, "perturb", &tmp_int, &tmp_res, 0, Log, CHECK_NONE);
  if (tmp_res!=-1) perturb = tmp_int;

  // scaling option
  // Sets or unsets scaling:
  // - 0 -off
  // - 1 equilibrium (default)
  // - 2 geometric
  // - 3 auto
  // - 4 auto-but-as-initialSolve-in-bab. 
  getIntInPList(pvApiCtx, param_in_addr, "scaling", &tmp_int, &tmp_res, 1, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->scaling(tmp_int);

  // factorization frequency option
  getIntInPList(pvApiCtx, param_in_addr, "fact_freq", &tmp_int, &tmp_res, 200, Log, CHECK_NONE);
  if (tmp_res!=-1) fact_freq = tmp_int;

  // presolve option
  getIntInPList(pvApiCtx, param_in_addr, "presolve", &tmp_int, &tmp_res, 0, Log, CHECK_NONE);
  if (tmp_res!=-1) presolve = tmp_int;

  // reduced gradient phase option
  getIntInPList(pvApiCtx, param_in_addr, "red_grad", &tmp_int, &tmp_res, 1, Log, CHECK_NONE);
  if (tmp_res!=-1) red_grad = tmp_int;

  // maxnumiterationshotstart
  getIntInPList(pvApiCtx, param_in_addr, "maxnumiterationshotstart", &tmp_int, &tmp_res, 1000, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setIntParam(ClpMaxNumIterationHotStart, tmp_int);

  // dualobjectivelimit
  getDoubleInPList(pvApiCtx, param_in_addr, "dualobjectivelimit", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setDblParam(ClpDualObjectiveLimit, tmp_double);

  // primalobjectivelimit
  getDoubleInPList(pvApiCtx, param_in_addr, "primalobjectivelimit", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setDblParam(ClpPrimalObjectiveLimit, tmp_double);

  // obj offset
  getDoubleInPList(pvApiCtx, param_in_addr, "objoffset", &tmp_double, &tmp_res, 0.0, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setDblParam(ClpObjOffset, tmp_double);

  // presolvetolerance
  getDoubleInPList(pvApiCtx, param_in_addr, "presolvetolerance", &tmp_double, &tmp_res, 1e-7, Log, CHECK_NONE);
  if (tmp_res!=-1) modelBase->setDblParam(ClpPresolveTolerance, tmp_double);
      
  // maximumBarrierIterations
  getIntInPList(pvApiCtx, param_in_addr, "maxnumbarrieriterations", &tmp_int, &tmp_res, 200, Log, CHECK_NONE);
  if (tmp_res!=-1) maximumbarrieriterations = tmp_int;

  /////////////////////////////////////
  // Set the bounds on the variables //
  /////////////////////////////////////

  modelBase->loadProblem(A_matrix,lhs,rhs,c,lower,upper);

  for(i=0;i<ncols; i++)
    {
      modelBase->setColUpper(i, *(upper+i));
      modelBase->setColLower(i, *(lower+i));
      modelBase->setObjectiveCoefficient(i,*(c+i));
      if ((*(vtype+i)=='I')||(*(vtype+i)=='i'))
	{
	  modelBase->setInteger(i);
	}
      else
	{
	  modelBase->setContinuous(i);
	}
    }
  
  /////////////////////////////////////////
  // Set the boundary of the constraints //
  /////////////////////////////////////////

  // 'L' - smaller than - <=
  // 'E' - equality     - =
  // 'G' - greater than - >=
  // 'R' - Range        - <= + >=
  // 'N' - Free         - no constraints

#ifdef DEBUG
  sciprint("DEBUG: dealing with btype\n");
#endif
  for(i=0;i<nrows; i++)
    {
      switch(*(ctype+i))
	{
	case 'l':
	case 'L':
	  modelBase->setRowUpper(i, *(rhs+i));
	  modelBase->setRowLower(i, -COIN_DBL_MAX);
	  break;
	case 'e':
	case 'E':
	  modelBase->setRowUpper(i, *(rhs+i));
	  modelBase->setRowLower(i, *(rhs+i));
	  break;
	case 'n':
	case 'N':
	  modelBase->setRowUpper(i,  COIN_DBL_MAX);
	  modelBase->setRowLower(i, -COIN_DBL_MAX);
	  break;
	case 'r':
	case 'R':
	  modelBase->setRowUpper(i, *(rhs+i));
	  modelBase->setRowLower(i, *(lhs+i));
	  break;
	case 'g':
	case 'G':
	default:
	  modelBase->setRowUpper(i, COIN_DBL_MAX);
	  modelBase->setRowLower(i, *(lhs+i));
	  break;
	}
#ifdef DEBUG
      sciprint("row lower[%d] = %f row upper[%d] = %f\n", i, modelBase->getRowLower()[i], i, modelBase->getRowUpper()[i]);
#endif
    }
  
  ///////////////////////////////////
  // Affect names to rows and cols //
  ///////////////////////////////////

  modelBase->setIntParam(ClpNameDiscipline,0);

  ////////////////////////
  // Any quadratic part //
  ////////////////////////
  
#ifdef DEBUG
  sciprint("DEBUG: dealing with Q\n");
#endif
  _SciErr = getVarAddressFromPosition(pvApiCtx, Q_IN, &q_addr); SCICOINOR_ERROR;
  _SciErr = getVarType(pvApiCtx, q_addr, &type); SCICOINOR_ERROR;

  if(type!=sci_sparse)
    {
      _SciErr = getMatrixOfDouble(pvApiCtx, q_addr, &m_q, &n_q, &q); SCICOINOR_ERROR;
      
      if (n_q * m_q !=0)
	{
#ifdef DEBUG
	  sciprint("DEBUG: Q_IN is not sparse\n");
	  sciprint("DEBUG: Q size: n = %d m= %d\n", n_q, m_q);
#endif
	  
	  Q_matrix.setDimensions(nrows,ncols);
	  
	  nz = n_q * m_q;
	  
	  if (q==NULL) 
	    {
	      Scierror(999,"%s: invalid value of matrix q\n",fname);
	  
	      freeAllocatedSingleString(ctype);
	      freeAllocatedSingleString(vtype);

	      if (writemps_filename) FREE(writemps_filename);

	      return 0;
	    }
	  
	  for(i=0; i<m_q; i++)
	    {
	      for(j=0; j<n_q; j++)
		{
		  if (*(q+i+j*m_q)!=0) Q_matrix.modifyCoefficient(i,j,*(q+i+j*m_q));
		}
	    }
	  modelBase->loadQuadraticObjective(Q_matrix);
	}
    }
  else
    {
      getAllocatedSparseMatrix(pvApiCtx, q_addr, &S_Q.m, &S_Q.n, &S_Q.nel, &S_Q.mnel, &S_Q.icol, &S_Q.R);
      
      if (S_Q.n * S_Q.m!=0)
	{
#ifdef DEBUG
	  sciprint("DEBUG: Q_IN is sparse\n");
	  sciprint("DEBUG: Q size: n = %d m= %d\n", S_Q.n, S_Q.m);
#endif
	  Q_matrix.setDimensions(nrows,ncols);
	  
	  nz = S_Q.nel;
	  
	  count = 0;
	  for(i=0;i<S_Q.m;i++)
	    {
	      if (S_Q.mnel[i]!=0) 
		{
		  for(j=0;j<S_Q.mnel[i];j++)
		    {
		      count++;
		      Q_matrix.modifyCoefficient(i,S_Q.icol[count-1]-1,S_Q.R[count-1]);
		    }
		}
	    }
	  modelBase->loadQuadraticObjective(Q_matrix);
	}

      freeAllocatedSparseMatrix(S_Q.mnel, S_Q.icol, S_Q.R);
    }
 
  // Solver specific part
  switch(solverchoice)
    {
    case 6:
      modelInterior->setMaximumBarrierIterations(maximumbarrieriterations);
      break;
    default:
      modelSimplex->setFactorizationFrequency(fact_freq);
      modelSimplex->setPerturbation(perturb);
      break;
    }

  ///////////////////////////
  // Pre / Post resolution //
  ///////////////////////////

#ifdef HANDLE_CTRLC
  ///////////////////////////////////////////////////////////
  // Pass in the event handler, to handle ctrl+c in scilab //
  ///////////////////////////////////////////////////////////

  if (modelSimplex) 
    {
      modelSimplex->passInEventHandler(&SciClpEventHandler);
      modelSimplex->passInMessageHandler(printer);
    }
#endif

#ifdef DEBUG
  sciprint("DEBUG: presolve\n");
#endif
  // If the solver is not ClpInterior we can set the presolve option
  if (presolve && solverchoice!=6) 
    {
      TRYCATCH(modelSimplex->initialSolve(modelSolve));
      switch(presolve)
	{
	case 2:
	  TRYCATCH(modelSimplex->initialDualSolve());
	  break;
	case 3:
	  TRYCATCH(modelSimplex->initialPrimalSolve());
	  break;
	case 4:
	  TRYCATCH(modelSimplex->initialBarrierSolve());
	  break;
	case 5:
	  TRYCATCH(modelSimplex->initialBarrierNoCrossSolve());
	  break;
	default:
	  TRYCATCH(modelSimplex->initialSolve());
	  break;
	}
    }

  ////////////////////////////////////////////
  // If needed, write the problem in a file //
  ////////////////////////////////////////////

#ifdef DEBUG
  sciprint("DEBUG: dealing with writemps\n");
#endif
  if (writemps)
    {
      modelBase->writeMps(writemps_filename);
      if (loglevel) sciprint("sciclp: writing %s mps file\n",writemps_filename);
    }

  ////////////////
  // Resolution //
  ////////////////

#ifdef DEBUG
  sciprint("DEBUG: resolution\n");
  sciprint("model number columns = %d\n", modelBase->numberColumns());
  sciprint("model number rows    = %d\n", modelBase->numberRows());
#endif

  if ((solverchoice>=1)&&(solverchoice<=5))
    {
      TRYCATCH(modelSimplex->initialSolve())
    }

#ifdef HANDLE_CTRLC
  ///////////////////////////////////////////////////////////
  // Pass in the event handler, to handle ctrl+c in scilab //
  ///////////////////////////////////////////////////////////

  if (modelSimplex)  
    {
      modelSimplex->passInEventHandler(&SciClpEventHandler);
      modelSimplex->passInMessageHandler(printer);
    }
  if (modelInterior) 
    {
      modelInterior->passInEventHandler(&SciClpEventHandler);
      modelInterior->passInMessageHandler(printer);
    }
#endif

  switch (solverchoice)
    {
    case 2:
      TRYCATCH(status = modelSimplex->dual());
      break;
    case 3:
      TRYCATCH(status = modelSimplex->barrier(false));
      break;
    case 4:
      TRYCATCH(status = modelSimplex->barrier(true));
      break;
    case 5:
      TRYCATCH(status = modelSimplex->reducedGradient(red_grad));
      break;
    case 6:
      cholesky = new ClpCholeskyBase();
      cholesky->setKKT(true);
      modelInterior->setCholesky(cholesky);
      TRYCATCH(status = modelInterior->primalDual());
      break;
    case 7:
      TRYCATCH(status = modelInterior->pdco());
      break;
    default:
      TRYCATCH(status = modelSimplex->primal());
      break;
    }

#ifdef DEBUG
  if (status && loglevel) sciprint("Optimization failed\n");
#endif

  int clp_status = 0;

  clp_status  = (int)(pow(2.0,0.0)*modelBase->isAbandoned());
  clp_status += (int)(pow(2.0,1.0)*modelBase->isProvenOptimal());
  clp_status += (int)(pow(2.0,2.0)*modelBase->isProvenPrimalInfeasible());
  clp_status += (int)(pow(2.0,3.0)*modelBase->isProvenDualInfeasible());
  clp_status += (int)(pow(2.0,4.0)*modelBase->isPrimalObjectiveLimitReached());
  clp_status += (int)(pow(2.0,5.0)*modelBase->isDualObjectiveLimitReached());  
  clp_status += (int)(pow(2.0,6.0)*modelBase->isIterationLimitReached());      

  //////////////////////////////
  // Allocate for return data //
  //////////////////////////////

#ifdef DEBUG
  sciprint("DEBUG: allocating data\n");
#endif

  int m_xmin   = ncols, n_xmin   = 1;
  int m_lambda   = 1, n_lambda   = nrows;
  int * extra_addr = NULL;

  char * ListLabels [] = {"lambda","secondary_status","clp_status"};

  _SciErr = createMatrixOfDouble(pvApiCtx, XMIN_OUT, m_xmin, n_xmin, (double *)modelBase->primalColumnSolution()); SCICOINOR_ERROR;
  createScalarDouble(pvApiCtx, FMIN_OUT, modelBase->getObjValue());
  createScalarDouble(pvApiCtx, STATUS_OUT, (double)modelBase->status());

  _SciErr = createPList(pvApiCtx, EXTRA_OUT, &extra_addr, (char **)ListLabels, 3); SCICOINOR_ERROR;

  _SciErr = createColVectorOfDoubleInPList(pvApiCtx, EXTRA_OUT, extra_addr, "lambda", m_lambda*n_lambda, (double *)modelBase->dualRowSolution()); SCICOINOR_ERROR;
  _SciErr = createIntInPList(pvApiCtx, EXTRA_OUT, extra_addr, "secondary_status", modelBase->secondaryStatus()); SCICOINOR_ERROR;
  _SciErr = createIntInPList(pvApiCtx, EXTRA_OUT, extra_addr, "clp_status",       clp_status); SCICOINOR_ERROR;

#ifdef DEBUG
  sciprint("DEBUG: getting solution\n");
#endif

  //
  // status of problem:
  //  -1 - unknown e.g. before solve or if postSolve says not optimal
  //   0 - optimal
  //   1 - primal infeasible
  //   2 - dual infeasible
  //   3 - stopped on iterations or time
  //   4 - stopped due to errors
  //   5 - stopped by event handler (virtual int ClpEventHandler::event())
  //

  // Secondary status of problem - may get extended 
  // - 0 - none 
  // - 1 - primal infeasible because dual limit reached OR probably primal infeasible but can't prove it (main status 4)
  // - 2 - scaled problem optimal - unscaled problem has primal infeasibilities
  // - 3 - scaled problem optimal - unscaled problem has dual infeasibilities
  // - 4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities
  // - 5 - giving up in primal with flagged variables
  // - 6 - failed due to empty problem check
  // - 7 - postSolve says not optimal
  // - 8 - failed due to bad element check
  // - 9 - status was 3 and stopped on time 
  // - 100 up - translation of enum from ClpEventHandler.

  /////////////////////////////////
  // Copy solutions if available //
  /////////////////////////////////

#ifdef DEBUG
  sciprint("DEBUG: returning data\n");
#endif

  LhsVar(1) = XMIN_OUT;
  LhsVar(2) = FMIN_OUT;
  LhsVar(3) = STATUS_OUT;
  LhsVar(4) = EXTRA_OUT;

  //////////////////////////////
  // Delete allocated objects //
  //////////////////////////////

  if (modelSimplex)  delete modelSimplex;
  if (modelInterior) delete modelInterior;
  if (printer)       delete printer;

  freeAllocatedSingleString(ctype);
  freeAllocatedSingleString(vtype);

  if (writemps_filename) FREE(writemps_filename);

  return 0;
}
Exemplo n.º 19
0
int main(int argc, const char *argv[])
{
     // Empty model
     ClpSimplex  model;
     std::string mpsFileName;
     if (argc >= 2) mpsFileName = argv[1];
     else {
#if defined(NETLIBDIR)
          mpsFileName = NETLIBDIR "/25fv47.mps";
#else
          fprintf(stderr, "Do not know where to find netlib MPS files.\n");
          exit(1);
#endif
     }
     int status = model.readMps(mpsFileName.c_str(), true);

     if (status) {
          fprintf(stderr, "Bad readMps %s\n", mpsFileName.c_str());
          fprintf(stdout, "Bad readMps %s\n", mpsFileName.c_str());
          exit(1);
     }
     // Point to data
     int numberRows = model.numberRows();
     const double * rowLower = model.rowLower();
     const double * rowUpper = model.rowUpper();
     int numberColumns = model.numberColumns();
     const double * columnLower = model.columnLower();
     const double * columnUpper = model.columnUpper();
     const double * columnObjective = model.objective();
     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();
     //const int * row = matrix->getIndices();
     //const int * columnLength = matrix->getVectorLengths();
     //const CoinBigIndex * columnStart = matrix->getVectorStarts();
     //const double * elementByColumn = matrix->getElements();

     // solve
     model.dual();
     // Now build new model
     CoinModel build;
     double time1 = CoinCpuTime();
     // Row bounds
     int iRow;
     for (iRow = 0; iRow < numberRows; iRow++) {
          build.setRowBounds(iRow, rowLower[iRow], rowUpper[iRow]);
          // optional name
          build.setRowName(iRow, model.rowName(iRow).c_str());
     }
     // Column bounds and objective
     int iColumn;
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          build.setColumnLower(iColumn, columnLower[iColumn]);
          build.setColumnUpper(iColumn, columnUpper[iColumn]);
          build.setObjective(iColumn, columnObjective[iColumn]);
          // optional name
          build.setColumnName(iColumn, model.columnName(iColumn).c_str());
     }
     // Adds elements one by one by row (backwards by row)
     for (iRow = numberRows - 1; iRow >= 0; iRow--) {
          int start = rowStart[iRow];
          for (int j = start; j < start + rowLength[iRow]; j++)
               build(iRow, column[j], element[j]);
     }
     double time2 = CoinCpuTime();
     // Now create clpsimplex
     ClpSimplex model2;
     model2.loadProblem(build);
     double time3 = CoinCpuTime();
     printf("Time for build using CoinModel is %g (%g for loadproblem)\n", time3 - time1,
            time3 - time2);
     model2.dual();
     // Now do with strings attached
     // Save build to show how to go over rows
     CoinModel saveBuild = build;
     build = CoinModel();
     time1 = CoinCpuTime();
     // Column bounds
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          build.setColumnLower(iColumn, columnLower[iColumn]);
          build.setColumnUpper(iColumn, columnUpper[iColumn]);
     }
     // Objective - half the columns as is and half with multiplier of "1.0+multiplier"
     // Pick up from saveBuild (for no reason at all)
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          double value = saveBuild.objective(iColumn);
          if (iColumn * 2 < numberColumns) {
               build.setObjective(iColumn, columnObjective[iColumn]);
          } else {
               // create as string
               char temp[100];
               sprintf(temp, "%g + abs(%g*multiplier)", value, value);
               build.setObjective(iColumn, temp);
          }
     }
     // It then adds rows one by one but for half the rows sets their values
     //      with multiplier of "1.0+1.5*multiplier"
     for (iRow = 0; iRow < numberRows; iRow++) {
          if (iRow * 2 < numberRows) {
               // add row in simple way
               int start = rowStart[iRow];
               build.addRow(rowLength[iRow], column + start, element + start,
                            rowLower[iRow], rowUpper[iRow]);
          } else {
               // As we have to add one by one let's get from saveBuild
               CoinModelLink triple = saveBuild.firstInRow(iRow);
               while (triple.column() >= 0) {
                    int iColumn = triple.column();
                    if (iColumn * 2 < numberColumns) {
                         // just value as normal
                         build(iRow, triple.column(), triple.value());
                    } else {
                         // create as string
                         char temp[100];
                         sprintf(temp, "%g + (1.5*%g*multiplier)", triple.value(), triple.value());
                         build(iRow, iColumn, temp);
                    }
                    triple = saveBuild.next(triple);
               }
               // but remember to do rhs
               build.setRowLower(iRow, rowLower[iRow]);
               build.setRowUpper(iRow, rowUpper[iRow]);
          }
     }
     time2 = CoinCpuTime();
     // Now create ClpSimplex
     // If small switch on error printing
     if (numberColumns < 50)
          build.setLogLevel(1);
     int numberErrors = model2.loadProblem(build);
     // should fail as we never set multiplier
     assert(numberErrors);
     time3 = CoinCpuTime() - time2;
     // subtract out unsuccessful times
     time1 += time3;
     time2 += time3;
     build.associateElement("multiplier", 0.0);
     numberErrors = model2.loadProblem(build);
     assert(!numberErrors);
     time3 = CoinCpuTime();
     printf("Time for build using CoinModel is %g (%g for successful loadproblem)\n", time3 - time1,
            time3 - time2);
     build.writeMps("zero.mps");
     // It then loops with multiplier going from 0.0 to 2.0 in increments of 0.1
     for (double multiplier = 0.0; multiplier < 2.0; multiplier += 0.1) {
          build.associateElement("multiplier", multiplier);
          numberErrors = model2.loadProblem(build, true);
          assert(!numberErrors);
          model2.dual();
     }

     return 0;
}
Exemplo n.º 20
0
int main(int argc, const char *argv[])
{
     {
          // Empty model
          ClpSimplex  model;

          // Bounds on rows - as dense vector
          double lower[] = {2.0, 1.0};
          double upper[] = {COIN_DBL_MAX, 1.0};

          // Create space for 2 rows
          model.resize(2, 0);
          // Fill in
          int i;
          // Now row bounds
          for (i = 0; i < 2; i++) {
               model.setRowLower(i, lower[i]);
               model.setRowUpper(i, upper[i]);
          }
          // Now add column 1
          int column1Index[] = {0, 1};
          double column1Value[] = {1.0, 1.0};
          model.addColumn(2, column1Index, column1Value,
                          0.0, 2, 1.0);
          // Now add column 2
          int column2Index[] = {1};
          double column2Value[] = { -5.0};
          model.addColumn(1, column2Index, column2Value,
                          0.0, COIN_DBL_MAX, 0.0);
          // Now add column 3
          int column3Index[] = {0, 1};
          double column3Value[] = {1.0, 1.0};
          model.addColumn(2, column3Index, column3Value,
                          0.0, 4.0, 4.0);
          // solve
          model.dual();

          /*
            Adding one column at a time has a significant overhead so let's
            try a more complicated but faster way

            First time adding in 10000 columns one by one

          */
          model.allSlackBasis();
          ClpSimplex modelSave = model;
          double time1 = CoinCpuTime();
          int k;
          for (k = 0; k < 10000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, -5.0};
               model.addColumn(2, column2Index, column2Value,
                               0.0, 1.0, 10000.0);
          }
          printf("Time for 10000 addColumn is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          // Now use build
          CoinBuild buildObject;
          time1 = CoinCpuTime();
          for (k = 0; k < 100000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, -5.0};
               buildObject.addColumn(2, column2Index, column2Value,
                                     0.0, 1.0, 10000.0);
          }
          model.addColumns(buildObject);
          printf("Time for 100000 addColumn using CoinBuild is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          // Now use build +-1
          int del[] = {0, 1, 2};
          model.deleteColumns(3, del);
          CoinBuild buildObject2;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, 1.0, -1.0};
               int bias = k & 1;
               buildObject2.addColumn(2, column2Index, column2Value + bias,
                                      0.0, 1.0, 10000.0);
          }
          model.addColumns(buildObject2, true);
          printf("Time for 10000 addColumn using CoinBuild+-1 is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          // Now use build +-1
          model.deleteColumns(3, del);
          CoinModel modelObject2;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, 1.0, -1.0};
               int bias = k & 1;
               modelObject2.addColumn(2, column2Index, column2Value + bias,
                                      0.0, 1.0, 10000.0);
          }
          model.addColumns(modelObject2, true);
          printf("Time for 10000 addColumn using CoinModel+-1 is %g\n", CoinCpuTime() - time1);
          //model.writeMps("xx.mps");
          model.dual();
          model = modelSave;
          // Now use model
          CoinModel modelObject;
          time1 = CoinCpuTime();
          for (k = 0; k < 100000; k++) {
               int column2Index[] = {0, 1};
               double column2Value[] = {1.0, -5.0};
               modelObject.addColumn(2, column2Index, column2Value,
                                     0.0, 1.0, 10000.0);
          }
          model.addColumns(modelObject);
          printf("Time for 100000 addColumn using CoinModel is %g\n", CoinCpuTime() - time1);
          model.dual();
          // Print column solution Just first 3 columns
          int numberColumns = model.numberColumns();
          numberColumns = CoinMin(3, 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();

          int iColumn;

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

          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
               double value;
               std::cout << std::setw(6) << iColumn << " ";
               value = columnPrimal[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;
     }
     {
          // Now copy a model
          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]);
          if (status) {
               printf("errors on input\n");
               exit(77);
          }
          model.initialSolve();
          int numberRows = model.numberRows();
          int numberColumns = model.numberColumns();
          const double * rowLower = model.rowLower();
          const double * rowUpper = model.rowUpper();

          // Start off model2
          ClpSimplex model2;
          model2.addRows(numberRows, rowLower, rowUpper, NULL);

          // Build object
          CoinBuild buildObject;
          // Add columns
          const double * columnLower = model.columnLower();
          const double * columnUpper = model.columnUpper();
          const double * objective = model.objective();
          CoinPackedMatrix * matrix = model.matrix();
          const int * row = matrix->getIndices();
          const int * columnLength = matrix->getVectorLengths();
          const CoinBigIndex * columnStart = matrix->getVectorStarts();
          const double * elementByColumn = matrix->getElements();
          for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
               CoinBigIndex start = columnStart[iColumn];
               buildObject.addColumn(columnLength[iColumn], row + start, elementByColumn + start,
                                     columnLower[iColumn], columnUpper[iColumn],
                                     objective[iColumn]);
          }

          // add in
          model2.addColumns(buildObject);
          model2.initialSolve();
     }
     {
          // and again
          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]);
          if (status) {
               printf("errors on input\n");
               exit(77);
          }
          model.initialSolve();
          int numberRows = model.numberRows();
          int numberColumns = model.numberColumns();
          const double * rowLower = model.rowLower();
          const double * rowUpper = model.rowUpper();

          // Build object
          CoinModel buildObject;
          for (int iRow = 0; iRow < numberRows; iRow++)
               buildObject.setRowBounds(iRow, rowLower[iRow], rowUpper[iRow]);

          // Add columns
          const double * columnLower = model.columnLower();
          const double * columnUpper = model.columnUpper();
          const double * objective = model.objective();
          CoinPackedMatrix * matrix = model.matrix();
          const int * row = matrix->getIndices();
          const int * columnLength = matrix->getVectorLengths();
          const CoinBigIndex * columnStart = matrix->getVectorStarts();
          const double * elementByColumn = matrix->getElements();
          for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
               CoinBigIndex start = columnStart[iColumn];
               buildObject.addColumn(columnLength[iColumn], row + start, elementByColumn + start,
                                     columnLower[iColumn], columnUpper[iColumn],
                                     objective[iColumn]);
          }

          // add in
          ClpSimplex model2;
          model2.loadProblem(buildObject);
          model2.initialSolve();
     }
     return 0;
}
Exemplo n.º 21
0
int main (int argc, const char *argv[])
{
     ClpSimplex  model;
     int status;
     // Keep names
     if (argc < 2) {
          status = model.readMps("small.mps", true);
     } else {
          status = model.readMps(argv[1], false);
     }
     if (status)
          exit(10);
     /*
       This driver implements a method of treating a problem as all cuts.
       So it adds in all E rows, solves and then adds in violated rows.
     */

     double time1 = CoinCpuTime();
     ClpSimplex * model2;
     ClpPresolve pinfo;
     int numberPasses = 5; // can change this
     /* Use a tolerance of 1.0e-8 for feasibility, treat problem as
        not being integer, do "numberpasses" passes and throw away names
        in presolved model */
     model2 = pinfo.presolvedModel(model, 1.0e-8, false, numberPasses, false);
     if (!model2) {
          fprintf(stderr, "ClpPresolve says %s is infeasible with tolerance of %g\n",
                  argv[1], 1.0e-8);
          fprintf(stdout, "ClpPresolve says %s is infeasible with tolerance of %g\n",
                  argv[1], 1.0e-8);
          // model was infeasible - maybe try again with looser tolerances
          model2 = pinfo.presolvedModel(model, 1.0e-7, false, numberPasses, false);
          if (!model2) {
               fprintf(stderr, "ClpPresolve says %s is infeasible with tolerance of %g\n",
                       argv[1], 1.0e-7);
               fprintf(stdout, "ClpPresolve says %s is infeasible with tolerance of %g\n",
                       argv[1], 1.0e-7);
               exit(2);
          }
     }
     // change factorization frequency from 200
     model2->setFactorizationFrequency(100 + model2->numberRows() / 50);

     int numberColumns = model2->numberColumns();
     int originalNumberRows = model2->numberRows();

     // We will need arrays to choose rows to add
     double * weight = new double [originalNumberRows];
     int * sort = new int [originalNumberRows];
     int numberSort = 0;
     char * take = new char [originalNumberRows];

     const double * rowLower = model2->rowLower();
     const double * rowUpper = model2->rowUpper();
     int iRow, iColumn;
     // Set up initial list
     numberSort = 0;
     for (iRow = 0; iRow < originalNumberRows; iRow++) {
          weight[iRow] = 1.123e50;
          if (rowLower[iRow] == rowUpper[iRow]) {
               sort[numberSort++] = iRow;
               weight[iRow] = 0.0;
          }
     }
     numberSort /= 2;
     // Just add this number of rows each time in small problem
     int smallNumberRows = 2 * numberColumns;
     smallNumberRows = CoinMin(smallNumberRows, originalNumberRows / 20);
     // and pad out with random rows
     double ratio = ((double)(smallNumberRows - numberSort)) / ((double) originalNumberRows);
     for (iRow = 0; iRow < originalNumberRows; iRow++) {
          if (weight[iRow] == 1.123e50 && CoinDrand48() < ratio)
               sort[numberSort++] = iRow;
     }
     /* This is optional.
        The best thing to do is to miss out random rows and do a set which makes dual feasible.
        If that is not possible then make sure variables have bounds.

        One way that normally works is to automatically tighten bounds.
     */
#if 0
     // However for some we need to do anyway
     double * columnLower = model2->columnLower();
     double * columnUpper = model2->columnUpper();
     for (iColumn = 0; iColumn < numberColumns; iColumn++) {
          columnLower[iColumn] = CoinMax(-1.0e6, columnLower[iColumn]);
          columnUpper[iColumn] = CoinMin(1.0e6, columnUpper[iColumn]);
     }
#endif
     model2->tightenPrimalBounds(-1.0e4, true);
     printf("%d rows in initial problem\n", numberSort);
     double * fullSolution = model2->primalRowSolution();

     // Just do this number of passes
     int maxPass = 50;
     // And take out slack rows until this pass
     int takeOutPass = 30;
     int iPass;

     const int * start = model2->clpMatrix()->getVectorStarts();
     const int * length = model2->clpMatrix()->getVectorLengths();
     const int * row = model2->clpMatrix()->getIndices();
     int * whichColumns = new int [numberColumns];
     for (iColumn = 0; iColumn < numberColumns; iColumn++)
          whichColumns[iColumn] = iColumn;
     int numberSmallColumns = numberColumns;
     for (iPass = 0; iPass < maxPass; iPass++) {
          printf("Start of pass %d\n", iPass);
          // Cleaner this way
          std::sort(sort, sort + numberSort);
          // Create small problem
          ClpSimplex small(model2, numberSort, sort, numberSmallColumns, whichColumns);
          small.setFactorizationFrequency(100 + numberSort / 200);
          //small.setPerturbation(50);
          //small.setLogLevel(63);
          // A variation is to just do N iterations
          //if (iPass)
          //small.setMaximumIterations(100);
          // Solve
          small.factorization()->messageLevel(8);
          if (iPass) {
               small.dual();
          } else {
               small.writeMps("continf.mps");
               ClpSolve solveOptions;
               solveOptions.setSolveType(ClpSolve::useDual);
               //solveOptions.setSolveType(ClpSolve::usePrimalorSprint);
               //solveOptions.setSpecialOption(1,2,200); // idiot
               small.initialSolve(solveOptions);
          }
          bool dualInfeasible = (small.status() == 2);
          // move solution back
          double * solution = model2->primalColumnSolution();
          const double * smallSolution = small.primalColumnSolution();
          for (int j = 0; j < numberSmallColumns; j++) {
               iColumn = whichColumns[j];
               solution[iColumn] = smallSolution[j];
               model2->setColumnStatus(iColumn, small.getColumnStatus(j));
          }
          for (iRow = 0; iRow < numberSort; iRow++) {
               int kRow = sort[iRow];
               model2->setRowStatus(kRow, small.getRowStatus(iRow));
          }
          // compute full solution
          memset(fullSolution, 0, originalNumberRows * sizeof(double));
          model2->times(1.0, model2->primalColumnSolution(), fullSolution);
          if (iPass != maxPass - 1) {
               // Mark row as not looked at
               for (iRow = 0; iRow < originalNumberRows; iRow++)
                    weight[iRow] = 1.123e50;
               // Look at rows already in small problem
               int iSort;
               int numberDropped = 0;
               int numberKept = 0;
               int numberBinding = 0;
               int numberInfeasibilities = 0;
               double sumInfeasibilities = 0.0;
               for (iSort = 0; iSort < numberSort; iSort++) {
                    iRow = sort[iSort];
                    //printf("%d %g %g\n",iRow,fullSolution[iRow],small.primalRowSolution()[iSort]);
                    if (model2->getRowStatus(iRow) == ClpSimplex::basic) {
                         // Basic - we can get rid of if early on
                         if (iPass < takeOutPass && !dualInfeasible) {
                              // may have hit max iterations so check
                              double infeasibility = CoinMax(fullSolution[iRow] - rowUpper[iRow],
                                                             rowLower[iRow] - fullSolution[iRow]);
                              weight[iRow] = -infeasibility;
                              if (infeasibility > 1.0e-8) {
                                   numberInfeasibilities++;
                                   sumInfeasibilities += infeasibility;
                              } else {
                                   weight[iRow] = 1.0;
                                   numberDropped++;
                              }
                         } else {
                              // keep
                              weight[iRow] = -1.0e40;
                              numberKept++;
                         }
                    } else {
                         // keep
                         weight[iRow] = -1.0e50;
                         numberKept++;
                         numberBinding++;
                    }
               }
               // Now rest
               for (iRow = 0; iRow < originalNumberRows; iRow++) {
                    sort[iRow] = iRow;
                    if (weight[iRow] == 1.123e50) {
                         // not looked at yet
                         double infeasibility = CoinMax(fullSolution[iRow] - rowUpper[iRow],
                                                        rowLower[iRow] - fullSolution[iRow]);
                         weight[iRow] = -infeasibility;
                         if (infeasibility > 1.0e-8) {
                              numberInfeasibilities++;
                              sumInfeasibilities += infeasibility;
                         }
                    }
               }
               // sort
               CoinSort_2(weight, weight + originalNumberRows, sort);
               numberSort = CoinMin(originalNumberRows, smallNumberRows + numberKept);
               memset(take, 0, originalNumberRows);
               for (iRow = 0; iRow < numberSort; iRow++)
                    take[sort[iRow]] = 1;
               numberSmallColumns = 0;
               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
                    int n = 0;
                    for (int j = start[iColumn]; j < start[iColumn] + length[iColumn]; j++) {
                         int iRow = row[j];
                         if (take[iRow])
                              n++;
                    }
                    if (n)
                         whichColumns[numberSmallColumns++] = iColumn;
               }
               printf("%d rows binding, %d rows kept, %d rows dropped - new size %d rows, %d columns\n",
                      numberBinding, numberKept, numberDropped, numberSort, numberSmallColumns);
               printf("%d rows are infeasible - sum is %g\n", numberInfeasibilities,
                      sumInfeasibilities);
               if (!numberInfeasibilities) {
                    printf("Exiting as looks optimal\n");
                    break;
               }
               numberInfeasibilities = 0;
               sumInfeasibilities = 0.0;
               for (iSort = 0; iSort < numberSort; iSort++) {
                    if (weight[iSort] > -1.0e30 && weight[iSort] < -1.0e-8) {
                         numberInfeasibilities++;
                         sumInfeasibilities += -weight[iSort];
                    }
               }
               printf("in small model %d rows are infeasible - sum is %g\n", numberInfeasibilities,
                      sumInfeasibilities);
          }
     }
     delete [] weight;
     delete [] sort;
     delete [] whichColumns;
     delete [] take;
     // If problem is big you may wish to skip this
     model2->dual();
     int numberBinding = 0;
     for (iRow = 0; iRow < originalNumberRows; iRow++) {
          if (model2->getRowStatus(iRow) != ClpSimplex::basic)
               numberBinding++;
     }
     printf("%d binding rows at end\n", numberBinding);
     pinfo.postsolve(true);

     int numberIterations = model2->numberIterations();;
     delete model2;
     /* After this postsolve model should be optimal.
        We can use checkSolution and test feasibility */
     model.checkSolution();
     if (model.numberDualInfeasibilities() ||
               model.numberPrimalInfeasibilities())
          printf("%g dual %g(%d) Primal %g(%d)\n",
                 model.objectiveValue(),
                 model.sumDualInfeasibilities(),
                 model.numberDualInfeasibilities(),
                 model.sumPrimalInfeasibilities(),
                 model.numberPrimalInfeasibilities());
     // But resolve for safety
     model.primal(1);

     numberIterations += model.numberIterations();;
     printf("Solve took %g seconds\n", CoinCpuTime() - time1);
     return 0;
}
Exemplo n.º 22
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;
}
Exemplo n.º 23
0
int main(int argc, const char *argv[])
{
     try {
          // Empty model
          ClpSimplex  model;

          // Objective - just nonzeros
          int objIndex[] = {0, 2};
          double objValue[] = {1.0, 4.0};
          // Upper bounds - as dense vector
          double upper[] = {2.0, COIN_DBL_MAX, 4.0};

          // Create space for 3 columns
          model.resize(0, 3);
          // Fill in
          int i;
          // Virtuous way
          // First objective
          for (i = 0; i < 2; i++)
               model.setObjectiveCoefficient(objIndex[i], objValue[i]);
          // Now bounds (lower will be zero by default but do again)
          for (i = 0; i < 3; i++) {
               model.setColumnLower(i, 0.0);
               model.setColumnUpper(i, upper[i]);
          }
          /*
            We could also have done in non-virtuous way e.g.
            double * objective = model.objective();
            and then set directly
          */
          // Faster to add rows all at once - but this is easier to show
          // Now add row 1 as >= 2.0
          int row1Index[] = {0, 2};
          double row1Value[] = {1.0, 1.0};
          model.addRow(2, row1Index, row1Value,
                       2.0, COIN_DBL_MAX);
          // Now add row 2 as == 1.0
          int row2Index[] = {0, 1, 2};
          double row2Value[] = {1.0, -5.0, 1.0};
          model.addRow(3, row2Index, row2Value,
                       1.0, 1.0);
          // solve
          model.dual();

          /*
            Adding one row at a time has a significant overhead so let's
            try a more complicated but faster way

            First time adding in 10000 rows one by one
          */
          model.allSlackBasis();
          ClpSimplex modelSave = model;
          double time1 = CoinCpuTime();
          int k;
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -5.0, 1.0};
               model.addRow(3, row2Index, row2Value,
                            1.0, 1.0);
          }
          printf("Time for 10000 addRow is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          // Now use build
          CoinBuild buildObject;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -5.0, 1.0};
               buildObject.addRow(3, row2Index, row2Value,
                                  1.0, 1.0);
          }
          model.addRows(buildObject);
          printf("Time for 10000 addRow using CoinBuild is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          int del[] = {0, 1, 2};
          model.deleteRows(2, del);
          // Now use build +-1
          CoinBuild buildObject2;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -1.0, 1.0};
               buildObject2.addRow(3, row2Index, row2Value,
                                   1.0, 1.0);
          }
          model.addRows(buildObject2, true);
          printf("Time for 10000 addRow using CoinBuild+-1 is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = modelSave;
          model.deleteRows(2, del);
          // Now use build +-1
          CoinModel modelObject2;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -1.0, 1.0};
               modelObject2.addRow(3, row2Index, row2Value,
                                   1.0, 1.0);
          }
          model.addRows(modelObject2, true);
          printf("Time for 10000 addRow using CoinModel+-1 is %g\n", CoinCpuTime() - time1);
          model.dual();
          model = ClpSimplex();
          // Now use build +-1
          CoinModel modelObject3;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -1.0, 1.0};
               modelObject3.addRow(3, row2Index, row2Value,
                                   1.0, 1.0);
          }
          model.loadProblem(modelObject3, true);
          printf("Time for 10000 addRow using CoinModel load +-1 is %g\n", CoinCpuTime() - time1);
          model.writeMps("xx.mps");
          model.dual();
          model = modelSave;
          // Now use model
          CoinModel modelObject;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -5.0, 1.0};
               modelObject.addRow(3, row2Index, row2Value,
                                  1.0, 1.0);
          }
          model.addRows(modelObject);
          printf("Time for 10000 addRow using CoinModel is %g\n", CoinCpuTime() - time1);
          model.dual();
          model.writeMps("b.mps");
          // Method using least memory - but most complicated
          time1 = CoinCpuTime();
          // Assumes we know exact size of model and matrix
          // Empty model
          ClpSimplex  model2;
          {
               // Create space for 3 columns and 10000 rows
               int numberRows = 10000;
               int numberColumns = 3;
               // This is fully dense - but would not normally be so
               int numberElements = numberRows * numberColumns;
               // Arrays will be set to default values
               model2.resize(numberRows, numberColumns);
               double * elements = new double [numberElements];
               CoinBigIndex * starts = new CoinBigIndex [numberColumns+1];
               int * rows = new int [numberElements];;
               int * lengths = new int[numberColumns];
               // Now fill in - totally unsafe but ....
               // no need as defaults to 0.0 double * columnLower = model2.columnLower();
               double * columnUpper = model2.columnUpper();
               double * objective = model2.objective();
               double * rowLower = model2.rowLower();
               double * rowUpper = model2.rowUpper();
               // Columns - objective was packed
               for (k = 0; k < 2; k++) {
                    int iColumn = objIndex[k];
                    objective[iColumn] = objValue[k];
               }
               for (k = 0; k < numberColumns; k++)
                    columnUpper[k] = upper[k];
               // Rows
               for (k = 0; k < numberRows; k++) {
                    rowLower[k] = 1.0;
                    rowUpper[k] = 1.0;
               }
               // Now elements
               double row2Value[] = {1.0, -5.0, 1.0};
               CoinBigIndex put = 0;
               for (k = 0; k < numberColumns; k++) {
                    starts[k] = put;
                    lengths[k] = numberRows;
                    double value = row2Value[k];
                    for (int i = 0; i < numberRows; i++) {
                         rows[put] = i;
                         elements[put] = value;
                         put++;
                    }
               }
               starts[numberColumns] = put;
               // assign to matrix
               CoinPackedMatrix * matrix = new CoinPackedMatrix(true, 0.0, 0.0);
               matrix->assignMatrix(true, numberRows, numberColumns, numberElements,
                                    elements, rows, starts, lengths);
               ClpPackedMatrix * clpMatrix = new ClpPackedMatrix(matrix);
               model2.replaceMatrix(clpMatrix, true);
               printf("Time for 10000 addRow using hand written code is %g\n", CoinCpuTime() - time1);
               // If matrix is really big could switch off creation of row copy
               // model2.setSpecialOptions(256);
          }
          model2.dual();
          model2.writeMps("a.mps");
          // Print column solution
          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();

          int iColumn;

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

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

               std::cout << std::endl;
          }
          std::cout << "--------------------------------------" << std::endl;
          // Test CoinAssert
          std::cout << "If Clp compiled with -g below should give assert, if with -O1 or COIN_ASSERT CoinError" << std::endl;
          model = modelSave;
          model.deleteRows(2, del);
          // Deliberate error
          model.deleteColumns(1, del + 2);
          // Now use build +-1
          CoinBuild buildObject3;
          time1 = CoinCpuTime();
          for (k = 0; k < 10000; k++) {
               int row2Index[] = {0, 1, 2};
               double row2Value[] = {1.0, -1.0, 1.0};
               buildObject3.addRow(3, row2Index, row2Value,
                                   1.0, 1.0);
          }
          model.addRows(buildObject3, true);
     } catch (CoinError e) {
          e.print();
          if (e.lineNumber() >= 0)
               std::cout << "This was from a CoinAssert" << std::endl;
     }
     return 0;
}
Exemplo n.º 24
0
int main(int argc, const char *argv[])
{
     ClpSimplex  model;
     int status;
     // Keep names
     if (argc < 2) {
          status = model.readMps("small.mps", true);
     } else {
          status = model.readMps(argv[1], true);
     }
     if (status)
          exit(10);
     /*
       This driver turns a problem into all equalities, solves it and
       then creates optimal basis.
     */

     // copy of original
     ClpSimplex model2(model);
     // And another
     ClpSimplex model3(model);

     int originalNumberColumns = model.numberColumns();
     int numberRows = model.numberRows();

     int * addStarts = new int [numberRows+1];
     int * addRow = new int[numberRows];
     double * addElement = new double[numberRows];
     double * newUpper = new double[numberRows];
     double * newLower = new double[numberRows];

     double * lower = model2.rowLower();
     double * upper = model2.rowUpper();
     int iRow;
     // Simplest is to change all rhs to zero
     // One should skip E rows but this is simpler coding
     for (iRow = 0; iRow < numberRows; iRow++) {
          newUpper[iRow] = upper[iRow];
          upper[iRow] = 0.0;
          newLower[iRow] = lower[iRow];
          lower[iRow] = 0.0;
          addRow[iRow] = iRow;
          addElement[iRow] = -1.0;
          addStarts[iRow] = iRow;
     }
     addStarts[numberRows] = numberRows;
     model2.addColumns(numberRows, newLower, newUpper, NULL,
                       addStarts, addRow, addElement);
     delete [] addStarts;
     delete [] addRow;
     delete [] addElement;
     delete [] newLower;
     delete [] newUpper;

     // Modify costs
     double * randomArray = new double[numberRows];
     for (iRow = 0; iRow < numberRows; iRow++)
          randomArray[iRow] = CoinDrand48();

     model2.transposeTimes(1.0, randomArray, model2.objective());
     delete [] randomArray;
     // solve
     model2.primal();
     // first check okay if solution values back
     memcpy(model.primalColumnSolution(), model2.primalColumnSolution(),
            originalNumberColumns * sizeof(double));
     memcpy(model.primalRowSolution(), model2.primalRowSolution(),
            numberRows * sizeof(double));
     int iColumn;
     for (iColumn = 0; iColumn < originalNumberColumns; iColumn++)
          model.setColumnStatus(iColumn, model2.getColumnStatus(iColumn));

     for (iRow = 0; iRow < numberRows; iRow++) {
          if (model2.getRowStatus(iRow) == ClpSimplex::basic) {
               model.setRowStatus(iRow, ClpSimplex::basic);
          } else {
               model.setRowStatus(iRow, model2.getColumnStatus(iRow + originalNumberColumns));
          }
     }
     model.primal(0);
     // and now without solution values

     for (iColumn = 0; iColumn < originalNumberColumns; iColumn++)
          model3.setColumnStatus(iColumn, model2.getColumnStatus(iColumn));

     for (iRow = 0; iRow < numberRows; iRow++)
          model3.setRowStatus(iRow, model2.getColumnStatus(iRow + originalNumberColumns));
     model3.primal(0);
     return 0;
}
Exemplo n.º 25
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;
}
Exemplo n.º 26
0
int main(int argc, const char *argv[])
{
     int numberColumns;
     int numberRows;

     FILE * fp;
     if (argc > 1) {
          fp = fopen(argv[1], "r");
          if (!fp) {
               fprintf(stderr, "Unable to open file %s\n", argv[1]);
               exit(1);
          }
     } else {
          fp = fopen("input.130", "r");
          if (!fp) {
               fprintf(stderr, "Unable to open file input.l30 in Samples directory\n");
               exit(1);
          }
     }
     int problem;
     char temp[100];
     // read and skip
     fscanf(fp, "%s", temp);
     assert(!strcmp(temp, "BEGIN"));
     fscanf(fp, "%*s %*s %d %d %*s %*s %d %*s", &problem, &numberRows,
            &numberColumns);
     // scan down to SUPPLY
     while (fgets(temp, 100, fp)) {
          if (!strncmp(temp, "SUPPLY", 6))
               break;
     }
     if (strncmp(temp, "SUPPLY", 6)) {
          fprintf(stderr, "Unable to find SUPPLY\n");
          exit(2);
     }
     // get space for rhs
     double * lower = new double[numberRows];
     double * upper = new double[numberRows];
     int i;
     for (i = 0; i < numberRows; i++) {
          lower[i] = 0.0;
          upper[i] = 0.0;
     }
     // ***** Remember to convert to C notation
     while (fgets(temp, 100, fp)) {
          int row;
          int value;
          if (!strncmp(temp, "ARCS", 4))
               break;
          sscanf(temp, "%d %d", &row, &value);
          upper[row-1] = -value;
          lower[row-1] = -value;
     }
     if (strncmp(temp, "ARCS", 4)) {
          fprintf(stderr, "Unable to find ARCS\n");
          exit(2);
     }
     // number of columns may be underestimate
     int * head = new int[2*numberColumns];
     int * tail = new int[2*numberColumns];
     int * ub = new int[2*numberColumns];
     int * cost = new int[2*numberColumns];
     // ***** Remember to convert to C notation
     numberColumns = 0;
     while (fgets(temp, 100, fp)) {
          int iHead;
          int iTail;
          int iUb;
          int iCost;
          if (!strncmp(temp, "DEMAND", 6))
               break;
          sscanf(temp, "%d %d %d %d", &iHead, &iTail, &iCost, &iUb);
          iHead--;
          iTail--;
          head[numberColumns] = iHead;
          tail[numberColumns] = iTail;
          ub[numberColumns] = iUb;
          cost[numberColumns] = iCost;
          numberColumns++;
     }
     if (strncmp(temp, "DEMAND", 6)) {
          fprintf(stderr, "Unable to find DEMAND\n");
          exit(2);
     }
     // ***** Remember to convert to C notation
     while (fgets(temp, 100, fp)) {
          int row;
          int value;
          if (!strncmp(temp, "END", 3))
               break;
          sscanf(temp, "%d %d", &row, &value);
          upper[row-1] = value;
          lower[row-1] = value;
     }
     if (strncmp(temp, "END", 3)) {
          fprintf(stderr, "Unable to find END\n");
          exit(2);
     }
     printf("Problem %d has %d rows and %d columns\n", problem,
            numberRows, numberColumns);
     fclose(fp);
     ClpSimplex  model;
     // now build model - we have rhs so build columns - two elements
     // per column

     double * objective = new double[numberColumns];
     double * lowerColumn = new double[numberColumns];
     double * upperColumn = new double[numberColumns];

     double * element = new double [2*numberColumns];
     int * start = new int[numberColumns+1];
     int * row = new int[2*numberColumns];
     start[numberColumns] = 2 * numberColumns;
     for (i = 0; i < numberColumns; i++) {
          start[i] = 2 * i;
          element[2*i] = -1.0;
          element[2*i+1] = 1.0;
          row[2*i] = head[i];
          row[2*i+1] = tail[i];
          lowerColumn[i] = 0.0;
          upperColumn[i] = ub[i];
          objective[i] = cost[i];
     }
     // Create Packed Matrix
     CoinPackedMatrix matrix;
     int * lengths = NULL;
     matrix.assignMatrix(true, numberRows, numberColumns,
                         2 * numberColumns, element, row, start, lengths);
     ClpNetworkMatrix network(matrix);
     // load model

     model.loadProblem(network,
                       lowerColumn, upperColumn, objective,
                       lower, upper);

     delete [] lower;
     delete [] upper;
     delete [] head;
     delete [] tail;
     delete [] ub;
     delete [] cost;
     delete [] objective;
     delete [] lowerColumn;
     delete [] upperColumn;
     delete [] element;
     delete [] start;
     delete [] row;

     /* The confusing flow below is in to exercise both dual and primal
        when ClpNetworkMatrix storage used.

        For practical use just one call e.g. model.dual(); would be used.

        If network then factorization scheme is changed
        to be much faster.

        Still not as fast as a real network code, but more flexible
     */
     model.factorization()->maximumPivots(200 + model.numberRows() / 100);
     model.factorization()->maximumPivots(1000);
     //model.factorization()->maximumPivots(1);
     if (model.numberRows() < 50)
          model.messageHandler()->setLogLevel(63);
     model.dual();
     model.setOptimizationDirection(-1);
     //model.messageHandler()->setLogLevel(63);
     model.primal();
     model.setOptimizationDirection(1);
     model.primal();
     return 0;
}
Exemplo n.º 27
0
int CbcHeuristicDive::reducedCostFix (OsiSolverInterface* solver)

{
    //return 0; // temp
#ifndef JJF_ONE
    if (!model_->solverCharacteristics()->reducedCostsAccurate())
        return 0; //NLP
#endif
    double cutoff = model_->getCutoff() ;
    if (cutoff > 1.0e20)
        return 0;
#ifdef DIVE_DEBUG
    std::cout << "cutoff = " << cutoff << std::endl;
#endif
    double direction = solver->getObjSense() ;
    double gap = cutoff - solver->getObjValue() * direction ;
    gap *= 0.5; // Fix more
    double tolerance;
    solver->getDblParam(OsiDualTolerance, tolerance) ;
    if (gap <= 0.0)
        gap = tolerance; //return 0;
    gap += 100.0 * tolerance;
    double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);

    const double *lower = solver->getColLower() ;
    const double *upper = solver->getColUpper() ;
    const double *solution = solver->getColSolution() ;
    const double *reducedCost = solver->getReducedCost() ;

    int numberIntegers = model_->numberIntegers();
    const int * integerVariable = model_->integerVariable();

    int numberFixed = 0 ;

# ifdef COIN_HAS_CLP
    OsiClpSolverInterface * clpSolver
    = dynamic_cast<OsiClpSolverInterface *> (solver);
    ClpSimplex * clpSimplex = NULL;
    if (clpSolver)
        clpSimplex = clpSolver->getModelPtr();
# endif
    for (int i = 0 ; i < numberIntegers ; i++) {
        int iColumn = integerVariable[i] ;
        double djValue = direction * reducedCost[iColumn] ;
        if (upper[iColumn] - lower[iColumn] > integerTolerance) {
            if (solution[iColumn] < lower[iColumn] + integerTolerance && djValue > gap) {
#ifdef COIN_HAS_CLP
                // may just have been fixed before
                if (clpSimplex) {
                    if (clpSimplex->getColumnStatus(iColumn) == ClpSimplex::basic) {
#ifdef COIN_DEVELOP
                        printf("DJfix %d has status of %d, dj of %g gap %g, bounds %g %g\n",
                               iColumn, clpSimplex->getColumnStatus(iColumn),
                               djValue, gap, lower[iColumn], upper[iColumn]);
#endif
                    } else {
                        assert(clpSimplex->getColumnStatus(iColumn) == ClpSimplex::atLowerBound ||
                               clpSimplex->getColumnStatus(iColumn) == ClpSimplex::isFixed);
                    }
                }
#endif
                solver->setColUpper(iColumn, lower[iColumn]) ;
                numberFixed++ ;
            } else if (solution[iColumn] > upper[iColumn] - integerTolerance && -djValue > gap) {
#ifdef COIN_HAS_CLP
                // may just have been fixed before
                if (clpSimplex) {
                    if (clpSimplex->getColumnStatus(iColumn) == ClpSimplex::basic) {
#ifdef COIN_DEVELOP
                        printf("DJfix %d has status of %d, dj of %g gap %g, bounds %g %g\n",
                               iColumn, clpSimplex->getColumnStatus(iColumn),
                               djValue, gap, lower[iColumn], upper[iColumn]);
#endif
                    } else {
                        assert(clpSimplex->getColumnStatus(iColumn) == ClpSimplex::atUpperBound ||
                               clpSimplex->getColumnStatus(iColumn) == ClpSimplex::isFixed);
                    }
                }
#endif
                solver->setColLower(iColumn, upper[iColumn]) ;
                numberFixed++ ;
            }
        }
    }
    return numberFixed;
}
Exemplo n.º 28
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);
  }
}
Exemplo n.º 29
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;
}
Exemplo n.º 30
0
/*
  Randomized Rounding Heuristic
  Returns 1 if solution, 0 if not
*/
int
CbcHeuristicRandRound::solution(double & solutionValue,
                                double * betterSolution)
{
    // rlh: Todo: Memory Cleanup

    //  std::cout << "Entering the Randomized Rounding Heuristic" << std::endl;

    setWhen(1);  // setWhen(1) didn't have the effect I expected (e.g., run once).

    // Run only once.
    //
    //    See if at root node
    bool atRoot = model_->getNodeCount() == 0;
    int passNumber = model_->getCurrentPassNumber();
    //    Just do once
    if (!atRoot || passNumber > 1) {
        // std::cout << "Leaving the Randomized Rounding Heuristic" << std::endl;
        return 0;
    }

    std::cout << "Entering the Randomized Rounding Heuristic" << std::endl;
    typedef struct {
        int numberSolutions;
        int maximumSolutions;
        int numberColumns;
        double ** solution;
        int * numberUnsatisfied;
    } clpSolution;

    double start = CoinCpuTime();
    numCouldRun_++; //
#ifdef HEURISTIC_INFORM
    printf("Entering heuristic %s - nRuns %d numCould %d when %d\n",
	   heuristicName(),numRuns_,numCouldRun_,when_);
#endif
    // Todo: Ask JJHF what "number of times
    // the heuristic could run" means.

    OsiSolverInterface * solver = model_->solver()->clone();
    double primalTolerance ;
    solver->getDblParam(OsiPrimalTolerance, primalTolerance) ;
    OsiClpSolverInterface * clpSolver = dynamic_cast<OsiClpSolverInterface *> (solver);
    assert (clpSolver);
    ClpSimplex * simplex = clpSolver->getModelPtr();

    // Initialize the structure holding the solutions for the Simplex iterations
    clpSolution solutions;
    // Set typeStruct field of ClpTrustedData struct to 1 to indicate
    // desired behavior for  RandRound heuristic (which is what?)
    ClpTrustedData trustedSolutions;
    trustedSolutions.typeStruct = 1;
    trustedSolutions.data = &solutions;
    solutions.numberSolutions = 0;
    solutions.maximumSolutions = 0;
    solutions.numberColumns = simplex->numberColumns();
    solutions.solution = NULL;
    solutions.numberUnsatisfied = NULL;
    simplex->setTrustedUserPointer(&trustedSolutions);

    // Solve from all slack to get some points
    simplex->allSlackBasis();

    // Calling primal() invalidates pointers to some rim vectors,
    // like...row sense (!)
    simplex->primal();

    // 1. Okay - so a workaround would be to copy the data I want BEFORE
    // calling primal.
    // 2. Another approach is to ask the simplex solvers NOT to mess up my
    // rims.
    // 3. See freeCachedResults() for what is getting
    // deleted. Everything else points into the structure.
    // ...or use collower and colupper rather than rowsense.
    // ..store address of where one of these

    // Store the basic problem information
    // -Get the number of columns, rows and rhs vector
    int numCols = clpSolver->getNumCols();
    int numRows = clpSolver->getNumRows();

    // Find the integer variables (use columnType(?))
    // One if not continuous, that is binary or general integer)
    // columnType() = 0 continuous
    //              = 1 binary
    //              = 2 general integer
    bool * varClassInt = new bool[numCols];
    const char* columnType = clpSolver->columnType();
    int numGenInt = 0;
    for (int i = 0; i < numCols; i++) {
        if (clpSolver->isContinuous(i))
            varClassInt[i] = 0;
        else
            varClassInt[i] = 1;
        if (columnType[i] == 2) numGenInt++;
    }

    // Heuristic is for problems with general integer variables.
    // If there are none, quit.
    if (numGenInt++ < 1) {
        delete [] varClassInt ;
        std::cout << "Leaving the Randomized Rounding Heuristic" << std::endl;
        return 0;
    }


    // -Get the rows sense
    const char * rowSense;
    rowSense = clpSolver->getRowSense();

    // -Get the objective coefficients
    double *originalObjCoeff = CoinCopyOfArray(clpSolver->getObjCoefficients(), numCols);

    // -Get the matrix of the problem
    // rlh: look at using sparse representation
    double ** matrix = new double * [numRows];
    for (int i = 0; i < numRows; i++) {
        matrix[i] = new double[numCols];
        for (int j = 0; j < numCols; j++)
            matrix[i][j] = 0;
    }

    const CoinPackedMatrix* matrixByRow = clpSolver->getMatrixByRow();
    const double * matrixElements = matrixByRow->getElements();
    const int * matrixIndices = matrixByRow->getIndices();
    const int * matrixStarts = matrixByRow->getVectorStarts();
    for (int j = 0; j < numRows; j++) {
        for (int i = matrixStarts[j]; i < matrixStarts[j+1]; i++) {
            matrix[j][matrixIndices[i]] = matrixElements[i];
        }
    }

    double * newObj = new double [numCols];
    srand ( static_cast<unsigned int>(time(NULL) + 1));
    int randNum;

    // Shuffle the rows:
    // Put the rows in a random order
    // so that the optimal solution is a different corner point than the
    // starting point.
    int * index = new int [numRows];
    for (int i = 0; i < numRows; i++)
        index[i] = i;
    for (int i = 0; i < numRows; i++) {
        int temp = index[i];
        int randNumTemp = i + intRand(numRows - i);
        index[i] = index[randNumTemp];
        index[randNumTemp] = temp;
    }

    // Start finding corner points by iteratively doing the following:
    // - contruct a randomly tilted objective
    // - solve
    for (int i = 0; i < numRows; i++) {
        // TODO: that 10,000 could be a param in the member data
        if (solutions.numberSolutions  > 10000)
            break;
        randNum = intRand(2);
        for (int j = 0; j < numCols; j++) {
            // for row i and column j vary the coefficient "a bit"
            if (randNum == 1)
                // if the element is zero, then set the new obj
                // coefficient to 0.1 (i.e., round up)
                if (fabs(matrix[index[i]][j]) < primalTolerance)
                    newObj[j] = 0.1;
                else
                    // if the element is nonzero, then increase the new obj
                    // coefficient "a bit"
                    newObj[j] = matrix[index[i]][j] * 1.1;
            else
                // if randnum is 2, then
                // if the element is zero, then set the new obj coeffient
                // to NEGATIVE 0.1 (i.e., round down)
                if (fabs(matrix[index[i]][j]) < primalTolerance)
                    newObj[j] = -0.1;
                else
                    // if the element is nonzero, then DEcrease the new obj coeffienct "a bit"
                    newObj[j] = matrix[index[i]][j] * 0.9;
        }
        // Use the new "tilted" objective
        clpSolver->setObjective(newObj);

        // Based on the row sense, we decide whether to max or min
        if (rowSense[i] == 'L')
            clpSolver->setObjSense(-1);
        else
            clpSolver->setObjSense(1);

        // Solve with primal simplex
        simplex->primal(1);
        // rlh+ll: This was the original code. But we already have the
        // model pointer (it's in simplex). And, calling getModelPtr()
        // invalidates the cached data in the OsiClpSolverInterface
        // object, which means our precious rowsens is lost. So let's
        // not use the line below...
        /******* clpSolver->getModelPtr()->primal(1); */
        printf("---------------------------------------------------------------- %d\n", i);
    }
    // Iteratively do this process until...
    // either you reach the max number of corner points (aka 10K)
    // or all the rows have been used as an objective.

    // Look at solutions
    int numberSolutions = solutions.numberSolutions;
    //const char * integerInfo = simplex->integerInformation();
    //const double * columnLower = simplex->columnLower();
    //const double * columnUpper = simplex->columnUpper();
    printf("there are %d solutions\n", numberSolutions);

    // Up to here we have all the corner points
    // Now we need to do the random walks and roundings

    double ** cornerPoints = new double * [numberSolutions];
    for (int j = 0; j < numberSolutions; j++)
        cornerPoints[j] = solutions.solution[j];

    bool feasibility = 1;
    // rlh: use some COIN max instead of 1e30 (?)
    double bestObj = 1e30;
    std::vector< std::vector <double> > feasibles;
    int numFeasibles = 0;

    // Check the feasibility of the corner points
    int numCornerPoints = numberSolutions;

    const double * rhs = clpSolver->getRightHandSide();
    // rlh: row sense hasn't changed. why a fresh copy?
    // Delete next line.
    rowSense = clpSolver->getRowSense();

    for (int i = 0; i < numCornerPoints; i++) {
        //get the objective value for this this point
        double objValue = 0;
        for (int k = 0; k < numCols; k++)
            objValue += cornerPoints[i][k] * originalObjCoeff[k];

        if (objValue < bestObj) {
            // check integer feasibility
            feasibility = 1;
            for (int j = 0; j < numCols; j++) {
                if (varClassInt[j]) {
                    double closest = floor(cornerPoints[i][j] + 0.5);
                    if (fabs(cornerPoints[i][j] - closest) > primalTolerance) {
                        feasibility = 0;
                        break;
                    }
                }
            }
            // check all constraints satisfied
            if (feasibility) {
                for (int irow = 0; irow < numRows; irow++) {
                    double lhs = 0;
                    for (int j = 0; j < numCols; j++) {
                        lhs += matrix[irow][j] * cornerPoints[i][j];
                    }
                    if (rowSense[irow] == 'L' && lhs > rhs[irow] + primalTolerance) {
                        feasibility = 0;
                        break;
                    }
                    if (rowSense[irow] == 'G' && lhs < rhs[irow] - primalTolerance) {
                        feasibility = 0;
                        break;
                    }
                    if (rowSense[irow] == 'E' && (lhs - rhs[irow] > primalTolerance || lhs - rhs[irow] < -primalTolerance)) {
                        feasibility = 0;
                        break;
                    }
                }
            }

            if (feasibility) {
                numFeasibles++;
                feasibles.push_back(std::vector <double> (numCols));
                for (int k = 0; k < numCols; k++)
                    feasibles[numFeasibles-1][k] = cornerPoints[i][k];
                printf("obj: %f\n", objValue);
                if (objValue < bestObj)
                    bestObj = objValue;
            }
        }
    }
    int numFeasibleCorners;
    numFeasibleCorners = numFeasibles;
    //find the center of gravity of the corner points as the first random point
    double * rp = new double[numCols];
    for (int i = 0; i < numCols; i++) {
        rp[i] = 0;
        for (int j = 0; j < numCornerPoints; j++) {
            rp[i] += cornerPoints[j][i];
        }
        rp[i] = rp[i] / numCornerPoints;
    }

    //-------------------------------------------
    //main loop:
    // -generate the next random point
    // -round the random point
    // -check the feasibility of the random point
    //-------------------------------------------

    srand ( static_cast<unsigned int>(time(NULL) + 1));
    int numRandomPoints = 0;
    while (numRandomPoints < 50000) {
        numRandomPoints++;
        //generate the next random point
        int randomIndex = intRand(numCornerPoints);
        double random = CoinDrand48();
        for (int i = 0; i < numCols; i++) {
            rp[i] = (random * (cornerPoints[randomIndex][i] - rp[i])) + rp[i];
        }

        //CRISP ROUNDING
        //round the random point just generated
        double * roundRp = new double[numCols];
        for (int i = 0; i < numCols; i++) {
            roundRp[i] = rp[i];
            if (varClassInt[i]) {
                if (rp[i] >= 0) {
                    if (fmod(rp[i], 1) > 0.5)
                        roundRp[i] = floor(rp[i]) + 1;
                    else
                        roundRp[i] = floor(rp[i]);
                } else {
                    if (fabs(fmod(rp[i], 1)) > 0.5)
                        roundRp[i] = floor(rp[i]);
                    else
                        roundRp[i] = floor(rp[i]) + 1;

                }
            }
        }


        //SOFT ROUNDING
        // Look at original files for the "how to" on soft rounding;
        // Soft rounding omitted here.

        //Check the feasibility of the rounded random point
        // -Check the feasibility
        // -Get the rows sense
        rowSense = clpSolver->getRowSense();
        rhs = clpSolver->getRightHandSide();

        //get the objective value for this feasible point
        double objValue = 0;
        for (int i = 0; i < numCols; i++)
            objValue += roundRp[i] * originalObjCoeff[i];

        if (objValue < bestObj) {
            feasibility = 1;
            for (int i = 0; i < numRows; i++) {
                double lhs = 0;
                for (int j = 0; j < numCols; j++) {
                    lhs += matrix[i][j] * roundRp[j];
                }
                if (rowSense[i] == 'L' && lhs > rhs[i] + primalTolerance) {
                    feasibility = 0;
                    break;
                }
                if (rowSense[i] == 'G' && lhs < rhs[i] - primalTolerance) {
                    feasibility = 0;
                    break;
                }
                if (rowSense[i] == 'E' && (lhs - rhs[i] > primalTolerance || lhs - rhs[i] < -primalTolerance)) {
                    feasibility = 0;
                    break;
                }
            }
            if (feasibility) {
                printf("Feasible Found.\n");
                printf("%.2f\n", CoinCpuTime() - start);
                numFeasibles++;
                feasibles.push_back(std::vector <double> (numCols));
                for (int i = 0; i < numCols; i++)
                    feasibles[numFeasibles-1][i] = roundRp[i];
                printf("obj: %f\n", objValue);
                if (objValue < bestObj)
                    bestObj = objValue;
            }
        }
        delete [] roundRp;
    }
    printf("Number of Feasible Corners: %d\n", numFeasibleCorners);
    printf("Number of Feasibles Found: %d\n", numFeasibles);
    if (numFeasibles > 0)
        printf("Best Objective: %f\n", bestObj);
    printf("time: %.2f\n", CoinCpuTime() - start);

    if (numFeasibles == 0) {
        // cleanup
        delete [] varClassInt;
        for (int i = 0; i < numRows; i++)
            delete matrix[i];
        delete [] matrix;
        delete [] newObj;
        delete [] index;
        for (int i = 0; i < numberSolutions; i++)
            delete cornerPoints[i];
        delete [] cornerPoints;
        delete [] rp;
        return 0;
    }

    // We found something better
    solutionValue = bestObj;
    for (int k = 0; k < numCols; k++) {
        betterSolution[k] =  feasibles[numFeasibles-1][k];
    }
    delete [] varClassInt;
    for (int i = 0; i < numRows; i++)
        delete matrix[i];
    delete [] matrix;
    delete [] newObj;
    delete [] index;
    for (int i = 0; i < numberSolutions; i++)
        delete cornerPoints[i];
    delete [] cornerPoints;
    delete [] rp;
    std::cout << "Leaving the Randomized Rounding Heuristic" << std::endl;
    return 1;

}