Пример #1
0
// -----------------------------------------------------------------------------------
void CBCSolver::populateSolution(CbcModel& model, std::vector<VariablePtr>& variables) {
  int ncol = model.solver()->getNumCols();
  const double* solution = model.solver()->getColSolution();
  
  for (int i = 0; i < variables.size(); i++) {
    any value = solution[i]; 
    switch(variables.at(i)->type()) { 
    case Variable::INT:
      value = (int) solution[i];
      break;
    }
    variables.at(i)->setValue(value);
  }
}
Пример #2
0
CbcHeuristicLocal::CbcHeuristicLocal(CbcModel & model)
        : CbcHeuristic(model)
{
    numberSolutions_ = 0;
    swap_ = 0;
    lastRunDeep_ = -1000000;
    // Get a copy of original matrix
    assert(model.solver());
    if (model.solver()->getNumRows()) {
        matrix_ = *model.solver()->getMatrixByCol();
    }
    int numberColumns = model.solver()->getNumCols();
    used_ = new int[numberColumns];
    memset(used_, 0, numberColumns*sizeof(int));
}
Пример #3
0
CbcHeuristicCrossover::CbcHeuristicCrossover(CbcModel & model)
        : CbcHeuristic(model),
        numberSolutions_(0),
        useNumber_(3)
{
    setWhen(1);
    for (int i = 0; i < 10; i++)
        random_[i] = model.randomNumberGenerator()->randomDouble();
}
Пример #4
0
CbcHeuristicVND::CbcHeuristicVND(CbcModel & model)
        : CbcHeuristic(model)
{
    numberSolutions_ = 0;
    numberSuccesses_ = 0;
    numberTries_ = 0;
    lastNode_ = -999999;
    howOften_ = 100;
    decayFactor_ = 0.5;
    assert(model.solver());
    int numberColumns = model.solver()->getNumCols();
    baseSolution_ = new double [numberColumns];
    memset(baseSolution_, 0, numberColumns*sizeof(double));
    whereFrom_ = 1 + 8 + 255 * 256;
    stepSize_ = 0;
    k_ = 0;
    kmax_ = 0;
    nDifferent_ = 0;
}
Пример #5
0
int changeCbcSolver (CoinParam *param)

{
    assert (param != 0) ;
    CbcGenParam *genParam = dynamic_cast<CbcGenParam *>(param) ;
    assert (genParam != 0) ;
    CbcGenCtlBlk *ctlBlk = genParam->obj() ;
    assert (ctlBlk != 0) ;
    CoinMessageHandler *msghandler = ctlBlk->messageHandler() ;
    /*
      Setup to return nonfatal/fatal error (1/-1) by default.
    */
    int retval ;
    if (CoinParamUtils::isInteractive()) {
        retval = 1 ;
    } else {
        retval = -1 ;
    }
    /*
      Try to locate the solver specified by the user.
    */
    const std::string solverName = genParam->kwdVal() ;
    OsiSolverInterface *protoOsi = solvers[solverName] ;
    if (protoOsi == 0) {
        std::cerr
            << "Can't find solver \"" << solverName
            << "\" in the solvers vector." << std::endl ;
        return (retval) ;
    }
    ctlBlk->dfltSolver_ = protoOsi ;
    /*
      We have a solver.
    */
    ctlBlk->message(CBCGEN_NEW_SOLVER)
    << solverName << CoinMessageEol ;
    CbcModel *model = ctlBlk->model_ ;
    assert (model != 0) ;
    OsiSolverInterface *newOsi = protoOsi->clone() ;
    model->assignSolver(newOsi) ;

    return (0) ;
}
Пример #6
0
double
CbcParam::doubleParameter (CbcModel &model) const
{
    double value;
    switch (type_) {
    case CBC_PARAM_DBL_INFEASIBILITYWEIGHT:
        value = model.getDblParam(CbcModel::CbcInfeasibilityWeight);
        break;
    case CBC_PARAM_DBL_INTEGERTOLERANCE:
        value = model.getDblParam(CbcModel::CbcIntegerTolerance);
        break;
    case CBC_PARAM_DBL_INCREMENT:
        value = model.getDblParam(CbcModel::CbcCutoffIncrement);
    case CBC_PARAM_DBL_ALLOWABLEGAP:
        value = model.getDblParam(CbcModel::CbcAllowableGap);
        break;
    case CLP_PARAM_DBL_TIMELIMIT: {
        value = model.getDblParam(CbcModel::CbcMaximumSeconds) ;
        break ;
    }
    case CLP_PARAM_DBL_DUALTOLERANCE:
    case CLP_PARAM_DBL_PRIMALTOLERANCE:
        value = doubleParameter(model.solver());
        break;
    default:
        abort();
    }
    return value;
}
Пример #7
0
int
CbcParam::intParameter (CbcModel &model) const
{
    int value;
    switch (type_) {
    case CLP_PARAM_INT_LOGLEVEL:
        value = model.messageHandler()->logLevel();
        break;
    case CLP_PARAM_INT_SOLVERLOGLEVEL:
        value = model.solver()->messageHandler()->logLevel();
        break;
    case CBC_PARAM_INT_MAXNODES:
        value = model.getIntParam(CbcModel::CbcMaxNumNode);
        break;
    case CBC_PARAM_INT_STRONGBRANCHING:
        value = model.numberStrong();
        break;
    default:
        abort();
    }
    return value;
}
Пример #8
0
    void AddRules(CbcModel& model, const Graph& gr) {
        vector<CbcBranchAllDifferent*> objects;

        ForEachEdge(gr, [&](Node n_1, Node n_2) {
            int arr[2] = {n_1, n_2};
            objects.push_back(new CbcBranchAllDifferent(&model, 2, arr));
        });
        model.addObjects(objects.size(), (CbcObject**)objects.data());

        for (auto obj : objects) {
            delete obj;
        }
        objects.clear();
    }
Пример #9
0
// Constructor from model
CbcHeuristicDive::CbcHeuristicDive(CbcModel & model)
        : CbcHeuristic(model)
{
    downLocks_ = NULL;
    upLocks_ = NULL;
    downArray_ = NULL;
    upArray_ = NULL;
    // Get a copy of original matrix
    assert(model.solver());
    // model may have empty matrix - wait until setModel
    const CoinPackedMatrix * matrix = model.solver()->getMatrixByCol();
    if (matrix) {
        matrix_ = *matrix;
        matrixByRow_ = *model.solver()->getMatrixByRow();
        validate();
    }
    percentageToFix_ = 0.2;
    maxIterations_ = 100;
    maxSimplexIterations_ = 10000;
    maxSimplexIterationsAtRoot_ = 1000000;
    maxTime_ = 600;
    whereFrom_ = 255 - 2 - 16 + 256;
    decayFactor_ = 1.0;
}
Пример #10
0
    void SaveModel(CbcModel& model) {
        char tmpName[64];
        strcpy(tmpName, "/tmp/XXXXXX");

        auto fd = mkstemp(tmpName);
        FILE* fp = fdopen(fd, "w");
        model.generateCpp(fp, 0);

        fclose(fp);
        close(fd);

        if (rename(tmpName, recoveryPath.c_str())) {
            throw runtime_error("unable to save model");
        }
    }
Пример #11
0
int
CbcParam::setIntParameter (CbcModel &model, int value) const
{
    if (value < lowerIntValue_ || value > upperIntValue_) {
        std::cout << value << " was provided for " << name_ <<
                  " - valid range is " << lowerIntValue_ << " to " <<
                  upperIntValue_ << std::endl;
        return 1;
    } else {
        int oldValue;
        switch (type_) {
        case CLP_PARAM_INT_LOGLEVEL:
            oldValue = model.messageHandler()->logLevel();
            model.messageHandler()->setLogLevel(value);
            break;
        case CLP_PARAM_INT_SOLVERLOGLEVEL:
            oldValue = model.solver()->messageHandler()->logLevel();
            model.solver()->messageHandler()->setLogLevel(value);
            break;
        case CBC_PARAM_INT_MAXNODES:
            oldValue = model.getIntParam(CbcModel::CbcMaxNumNode);
            model.setIntParam(CbcModel::CbcMaxNumNode, value);
            break;
        case CBC_PARAM_INT_STRONGBRANCHING:
            oldValue = model.numberStrong();
            model.setNumberStrong(value);
            break;
        default:
            oldValue = 0; // to avoid compiler message
            abort();
        }
        std::cout << name_ << " was changed from " << oldValue << " to "
                  << value << std::endl;
        return 0;
    }
}
Пример #12
0
int
CbcBranchUserDecision::bestBranch (CbcBranchingObject ** objects, int numberObjects,
				   int numberUnsatisfied,
				   double * changeUp, int * numberInfeasibilitiesUp,
				   double * changeDown, int * numberInfeasibilitiesDown,
				   double objectiveValue) 
{

  int bestWay=0;
  int whichObject = -1;
  if (numberObjects) {
    CbcModel * model = objects[0]->model();
    // at continuous
    //double continuousObjective = model->getContinuousObjective();
    //int continuousInfeasibilities = model->getContinuousInfeasibilities();
    
    // average cost to get rid of infeasibility
    //double averageCostPerInfeasibility = 
    //(objectiveValue-continuousObjective)/
    //(double) (abs(continuousInfeasibilities-numberUnsatisfied)+1);
    /* beforeSolution is :
       0 - before any solution
       n - n heuristic solutions but no branched one
       -1 - branched solution found
    */
    int numberSolutions = model->getSolutionCount();
    double cutoff = model->getCutoff();
    int method=0;
    int i;
    if (numberSolutions) {
      int numberHeuristic = model->getNumberHeuristicSolutions();
      if (numberHeuristic<numberSolutions) {
	method = 1;
      } else {
	method = 2;
	// look further
	for ( i = 0 ; i < numberObjects ; i++) {
	  int numberNext = numberInfeasibilitiesUp[i];
	  
	  if (numberNext<numberUnsatisfied) {
	    int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
	    double perUnsatisfied = changeUp[i]/(double) numberUp;
	    double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
	    if (estimatedObjective<cutoff) 
	      method=3;
	  }
	  numberNext = numberInfeasibilitiesDown[i];
	  if (numberNext<numberUnsatisfied) {
	    int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
	    double perUnsatisfied = changeDown[i]/(double) numberDown;
	    double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
	    if (estimatedObjective<cutoff) 
	      method=3;
	  }
	}
      }
      method=2;
    } else {
      method = 0;
    }
    // Uncomment next to force method 4
    //method=4;
    /* Methods :
       0 - fewest infeasibilities
       1 - largest min change in objective
       2 - as 1 but use sum of changes if min close
       3 - predicted best solution
       4 - take cheapest up branch if infeasibilities same
    */
    int bestNumber=COIN_INT_MAX;
    double bestCriterion=-1.0e50;
    double alternativeCriterion = -1.0;
    double bestEstimate = 1.0e100;
    switch (method) {
    case 0:
      // could add in depth as well
      for ( i = 0 ; i < numberObjects ; i++) {
	int thisNumber = CoinMin(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
	if (thisNumber<=bestNumber) {
	  int betterWay=0;
	  if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
	    if (numberInfeasibilitiesUp[i]<bestNumber) {
	      betterWay = 1;
	    } else {
	      if (changeUp[i]<bestCriterion)
		betterWay=1;
	    }
	  } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
	    if (numberInfeasibilitiesDown[i]<bestNumber) {
	      betterWay = -1;
	    } else {
	      if (changeDown[i]<bestCriterion)
		betterWay=-1;
	    }
	  } else {
	    // up and down have same number
	    bool better=false;
	    if (numberInfeasibilitiesUp[i]<bestNumber) {
	      better=true;
	    } else if (numberInfeasibilitiesUp[i]==bestNumber) {
	      if (CoinMin(changeUp[i],changeDown[i])<bestCriterion)
		better=true;;
	    }
	    if (better) {
	      // see which way
	      if (changeUp[i]<=changeDown[i])
		betterWay=1;
	      else
		betterWay=-1;
	    }
	  }
	  if (betterWay) {
	    bestCriterion = CoinMin(changeUp[i],changeDown[i]);
	    bestNumber = thisNumber;
	    whichObject = i;
	    bestWay = betterWay;
	  }
	}
      }
      break;
    case 1:
      for ( i = 0 ; i < numberObjects ; i++) {
	int betterWay=0;
	if (changeUp[i]<=changeDown[i]) {
	  if (changeUp[i]>bestCriterion)
	    betterWay=1;
	} else {
	  if (changeDown[i]>bestCriterion)
	    betterWay=-1;
	}
	if (betterWay) {
	  bestCriterion = CoinMin(changeUp[i],changeDown[i]);
	  whichObject = i;
	  bestWay = betterWay;
	}
      }
      break;
    case 2:
      for ( i = 0 ; i < numberObjects ; i++) {
	double change = CoinMin(changeUp[i],changeDown[i]);
	double sum = changeUp[i] + changeDown[i];
	bool take=false;
	if (change>1.1*bestCriterion) 
	  take=true;
	else if (change>0.9*bestCriterion&&sum+change>bestCriterion+alternativeCriterion) 
	  take=true;
	if (take) {
	  if (changeUp[i]<=changeDown[i]) {
	    if (changeUp[i]>bestCriterion)
	      bestWay=1;
	  } else {
	    if (changeDown[i]>bestCriterion)
	      bestWay=-1;
	  }
	  bestCriterion = change;
	  alternativeCriterion = sum;
	  whichObject = i;
	}
      }
      break;
    case 3:
      for ( i = 0 ; i < numberObjects ; i++) {
	int numberNext = numberInfeasibilitiesUp[i];
	
	if (numberNext<numberUnsatisfied) {
	  int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
	  double perUnsatisfied = changeUp[i]/(double) numberUp;
	  double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
	  if (estimatedObjective<bestEstimate) {
	    bestEstimate = estimatedObjective;
	    bestWay=1;
	    whichObject=i;
	  }
	}
	numberNext = numberInfeasibilitiesDown[i];
	if (numberNext<numberUnsatisfied) {
	  int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
	  double perUnsatisfied = changeDown[i]/(double) numberDown;
	  double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
	  if (estimatedObjective<bestEstimate) {
	    bestEstimate = estimatedObjective;
	    bestWay=-1;
	    whichObject=i;
	  }
	}
      }
      break;
    case 4:
      // if number infeas same then cheapest up
      // first get best number or when going down
      // now choose smallest change up amongst equal number infeas
      for ( i = 0 ; i < numberObjects ; i++) {
	int thisNumber = CoinMin(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
	if (thisNumber<=bestNumber) {
	  int betterWay=0;
	  if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
	    if (numberInfeasibilitiesUp[i]<bestNumber) {
	      betterWay = 1;
	    } else {
	      if (changeUp[i]<bestCriterion)
		betterWay=1;
	    }
	  } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
	    if (numberInfeasibilitiesDown[i]<bestNumber) {
	      betterWay = -1;
	    } else {
	      if (changeDown[i]<bestCriterion)
		betterWay=-1;
	    }
	  } else {
	    // up and down have same number
	    bool better=false;
	    if (numberInfeasibilitiesUp[i]<bestNumber) {
	      better=true;
	    } else if (numberInfeasibilitiesUp[i]==bestNumber) {
	      if (CoinMin(changeUp[i],changeDown[i])<bestCriterion)
		better=true;;
	    }
	    if (better) {
	      // see which way
	      if (changeUp[i]<=changeDown[i])
		betterWay=1;
	      else
		betterWay=-1;
	    }
	  }
	  if (betterWay) {
	    bestCriterion = CoinMin(changeUp[i],changeDown[i]);
	    bestNumber = thisNumber;
	    whichObject = i;
	    bestWay = betterWay;
	  }
	}
      }
      bestCriterion=1.0e50;
      for ( i = 0 ; i < numberObjects ; i++) {
	int thisNumber = numberInfeasibilitiesUp[i];
	if (thisNumber==bestNumber&&changeUp) {
	  if (changeUp[i]<bestCriterion) {
	    bestCriterion = changeUp[i];
	    whichObject = i;
	    bestWay = 1;
	  }
	}
      }
      break;
    }
    // set way in best
    if (whichObject>=0)
      objects[whichObject]->way(bestWay);
  }
  return whichObject;
}
Пример #13
0
int main( ){
	WindowsErrorPopupBlocker();
// test OS code samples here
	FileUtil *fileUtil = NULL; 
	fileUtil = new FileUtil();
	const char dirsep =  CoinFindDirSeparator();
 	// Set directory containing mps data files.
 	std::string dataDir;
   dataDir = dirsep == '/' ? "../data/" : "..\\data\\";
	cout << "Start Building the Model" << endl;
	try{
		// get the p0033 problem
		std::string osilFileName;
		osilFileName =  dataDir  +   "p0033.osil";
		std::cout << "Try to read a sample file" << std::endl;
		std::cout << "The file is: " ;
		std::cout <<  osilFileName << std::endl;
		std::string osil = fileUtil->getFileAsString( osilFileName.c_str() );
		OSiLReader *osilreader = NULL;
		osilreader = new OSiLReader(); 
		OSInstance *osinstance;
		osinstance = osilreader->readOSiL( osil);
		// done writing the model
		cout << "Done writing the Model" << endl;
		// now solve the model
		CoinSolver *solver  = NULL;
		solver = new CoinSolver();  
		solver->sSolverName ="cbc"; 
		solver->osinstance = osinstance;
		solver->buildSolverInstance();
		solver->osiSolver->setHintParam(OsiDoReducePrint, true, OsiHintTry);
		solver->osiSolver->initialSolve();
		cout << "Here is the initial objective value "  << solver->osiSolver->getObjValue()  << endl;
		
		CglKnapsackCover cover;
	    CglSimpleRounding round;  
		CglGomory gomory;
		CbcModel *model = new CbcModel( *solver->osiSolver);

		//model->setBestObjectiveValue(4000);
		model->setMaximumNodes(100000);
		//
		model->addCutGenerator(&gomory, 1, "Gomory");
		model->addCutGenerator(&cover, 1, "Cover");
		model->addCutGenerator(&round, 1, "Round");
		model->branchAndBound();	
		// now create a result object
		OSResult *osresult = new OSResult();
		// if we are throw an exception if the problem is nonlinear
		double *x = NULL;
		double *y = NULL;
		double *z = NULL;
		//int i = 0;
		std::string *rcost = NULL;
		// resultHeader infomration
		if(osresult->setServiceName("Solved with Coin Solver: " + solver->sSolverName) != true)
			throw ErrorClass("OSResult error: setServiceName");
		if(osresult->setInstanceName(  solver->osinstance->getInstanceName()) != true)
			throw ErrorClass("OSResult error: setInstanceName");
		if(osresult->setVariableNumber( solver->osinstance->getVariableNumber()) != true)
			throw ErrorClass("OSResult error: setVariableNumer");
		if(osresult->setObjectiveNumber( 1) != true)
			throw ErrorClass("OSResult error: setObjectiveNumber");
		if(osresult->setConstraintNumber( solver->osinstance->getConstraintNumber()) != true)
			throw ErrorClass("OSResult error: setConstraintNumber");
		if(osresult->setSolutionNumber(  1) != true)
			throw ErrorClass("OSResult error: setSolutionNumer");	
		int solIdx = 0;
		std::string description = "";
		osresult->setGeneralStatusType("success");
		std::cout << "PROVEN OPTIMAL " << model->isProvenOptimal() << std::endl;
		int i;
		if (model->isProvenOptimal() == 1){
			osresult->setSolutionStatus(solIdx, "optimal", description);
			/* Retrieve the solution */
			x = new double[solver->osinstance->getVariableNumber() ];
			y = new double[solver->osinstance->getConstraintNumber() ];
			z = new double[1];
			rcost = new std::string[ solver->osinstance->getVariableNumber()];
			//
			*(z + 0)  =  model->getObjValue();
			osresult->setObjectiveValuesDense(solIdx, z);
			for(i=0; i < solver->osinstance->getVariableNumber(); i++){
				*(x + i) = model->getColSolution()[i];
			}
			osresult->setPrimalVariableValuesDense(solIdx, x );
			//if( solver->sSolverName.find( "symphony") == std::string::npos){
			for(i=0; i <  solver->osinstance->getConstraintNumber(); i++){
				*(y + i) = model->getRowPrice()[ i];
			}
			osresult->setDualVariableValuesDense(solIdx, y);
			//
			// now put the reduced costs into the osrl
			int numberOfOtherVariableResult = 1;
			int otherIdx = 0;
			// first set the number of Other Variable Results
			osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResult);
			
			std::ostringstream outStr;
			int numberOfVar =  solver->osinstance->getVariableNumber();
			for(i=0; i < numberOfVar; i++){
				outStr << model->getReducedCost()[ i]; 
				rcost[ i] = outStr.str();
				outStr.str("");
			}
			osresult->setAnOtherVariableResultDense(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs",  
				rcost);			
			// end of settiing reduced costs			
		}
		else{ 
			if(solver->osiSolver->isProvenPrimalInfeasible() == true) 
				osresult->setSolutionStatus(solIdx, "infeasible", description);
			else
				if(solver->osiSolver->isProvenDualInfeasible() == true) 
					osresult->setSolutionStatus(solIdx, "dualinfeasible", description);
				else
					osresult->setSolutionStatus(solIdx, "other", description);
		}
		OSrLWriter *osrlwriter = new OSrLWriter();
		std::cout <<  osrlwriter->writeOSrL( osresult) << std::endl;
		if(solver->osinstance->getVariableNumber() > 0){
			delete[] x;
			x = NULL;
		}
		if(solver->osinstance->getConstraintNumber()) delete[] y;
		y = NULL;
		delete[] z;	
		z = NULL;
		if(solver->osinstance->getVariableNumber() > 0){
			delete[] rcost;
			rcost = NULL;
		}
    	// do garbage collection
		delete osresult;
		osresult = NULL;
		delete osrlwriter;
		osrlwriter = NULL;
		delete solver;
		solver = NULL;
		delete osilreader;
		osilreader = NULL;
		delete fileUtil;
		fileUtil  = NULL;
		delete model;
		model = NULL;
		cout << "Done with garbage collection" << endl;
		return 0;
	}
	catch(const ErrorClass& eclass){
		delete fileUtil;
		std::cout << eclass.errormsg <<  std::endl;
		return 0;
	} 
}// end main
Пример #14
0
int
CbcParam::setDoubleParameter (CbcModel &model, double value) const
{
    if (value < lowerDoubleValue_ || value > upperDoubleValue_) {
        std::cout << value << " was provided for " << name_ <<
                  " - valid range is " << lowerDoubleValue_ << " to " <<
                  upperDoubleValue_ << std::endl;
        return 1;
    } else {
        double oldValue;
        switch (type_) {
        case CBC_PARAM_DBL_INFEASIBILITYWEIGHT:
            oldValue = model.getDblParam(CbcModel::CbcInfeasibilityWeight);
            model.setDblParam(CbcModel::CbcInfeasibilityWeight, value);
            break;
        case CBC_PARAM_DBL_INTEGERTOLERANCE:
            oldValue = model.getDblParam(CbcModel::CbcIntegerTolerance);
            model.setDblParam(CbcModel::CbcIntegerTolerance, value);
            break;
        case CBC_PARAM_DBL_INCREMENT:
            oldValue = model.getDblParam(CbcModel::CbcCutoffIncrement);
            model.setDblParam(CbcModel::CbcCutoffIncrement, value);
        case CBC_PARAM_DBL_ALLOWABLEGAP:
            oldValue = model.getDblParam(CbcModel::CbcAllowableGap);
            model.setDblParam(CbcModel::CbcAllowableGap, value);
            break;
        case CLP_PARAM_DBL_TIMELIMIT: {
            oldValue = model.getDblParam(CbcModel::CbcMaximumSeconds) ;
            model.setDblParam(CbcModel::CbcMaximumSeconds, value) ;
            break ;
        }
        case CLP_PARAM_DBL_DUALTOLERANCE:
        case CLP_PARAM_DBL_PRIMALTOLERANCE:
            setDoubleParameter(model.solver(), value);
            return 0; // to avoid message
        default:
            oldValue = 0.0; // to avoid compiler message
            abort();
        }
        std::cout << name_ << " was changed from " << oldValue << " to "
                  << value << std::endl;
        return 0;
    }
}
Пример #15
0
int main (int argc, const char *argv[])
{
    /*
      This interior block contains all memory allocation; useful for debugging.
    */
    {
        double time1 = CoinCpuTime() ;
        double time2 ;
        /*
          Try and get all the various i/o to come out in order. Synchronise with C
          stdio and make stderr and stdout unbuffered.
        */
        std::ios::sync_with_stdio() ;
        setbuf(stderr, 0) ;
        setbuf(stdout, 0) ;
        /*
          The constructor for ctlBlk establishes the default values for cbc-generic
          parameters. A little more work is required to create the vector of available
          solvers and set the default.
        */
        CbcGenCtlBlk ctlBlk ;
        ctlBlk.setMessages() ;
        ctlBlk.setLogLevel(1) ;
        OsiSolverInterface *dfltSolver = CbcGenSolvers::setupSolvers() ;
        ctlBlk.dfltSolver_ = dfltSolver ;
        assert (ctlBlk.dfltSolver_) ;
        /*
          Now we can begin to initialise the parameter vector. Create a vector of the
          proper size, then load up the parameters that are relevant to the main
          program (specifically, values held in ctlBlk and actions evoked from the
          main program).
        */
        int numParams = 0 ;
        CoinParamVec paramVec ;
        paramVec.reserve(CbcOsiParam::CBCOSI_LASTPARAM) ;
        ctlBlk.paramVec_ = &paramVec ;
        ctlBlk.genParams_.first_ = numParams ;
        CbcGenParamUtils::addCbcGenParams(numParams, paramVec, &ctlBlk) ;
        ctlBlk.genParams_.last_ = numParams - 1 ;
        /*
          Establish a CbcModel object with the default lp solver. Install any defaults
          that are available from ctlBlk.
        */
        CbcModel *model = new CbcModel(*dfltSolver) ;
        ctlBlk.model_ = model ;
        model->messageHandler()->setLogLevel(1) ;
        model->setNumberStrong(ctlBlk.chooseStrong_.numStrong_) ;
        model->setNumberBeforeTrust(ctlBlk.chooseStrong_.numBeforeTrust_) ;
        CbcCbcParamUtils::setCbcModelDefaults(model) ;
        OsiSolverInterface *osi = model->solver() ;
        /*
          Set up the remaining classes of parameters, taking defaults from the CbcModel
          and OsiSolverInterface objects we've set up. There are parameters that
          belong to CbcModel (CbcCbcParam) and to the underlying OsiSolverInterface
          (CbcOsiParam).
        */
        ctlBlk.cbcParams_.first_ = numParams ;
        CbcCbcParamUtils::addCbcCbcParams(numParams, paramVec, model) ;
        ctlBlk.cbcParams_.last_ = numParams - 1 ;
        ctlBlk.osiParams_.first_ = numParams ;
        CbcOsiParamUtils::addCbcOsiParams(numParams, paramVec, osi) ;
        ctlBlk.osiParams_.last_ = numParams - 1 ;
        /*
          Initialise the vector that tracks parameters that have been changed by user
          command.
        */
        ctlBlk.setByUser_.resize(CbcOsiParam::CBCOSI_LASTPARAM, false) ;
        /*
          The main command parsing loop. Call getCommand to get the next parameter.
          (The user will be prompted in interactive mode.) If we find something,
          proceed to process it.

          If we don't find anything, behaviour depends on what we've seen so far:

          * An empty command/parameter and no history of previous success gets a
            brief message. If we're in interactive mode, allow the user to try again,
            otherwise quit.

          * An empty command/parameter in interactive mode with some history of
            successful commands is ignored. Iterate and try again.

          * An empty command/parameter when we're not interactive is taken
            as the end of commands. If we have a good model, force branchAndBound.
            (This is one aspect of giving the expected behaviour for
            `cbc-generic [parameters] foo.mps'.)
        */
        bool keepParsing = true ;
        bool forceImport = false ;
        std::string forceImportFile = "" ;
        std::string prompt = "cbcGen: " ;
        std::string pfx = "" ;
        while (keepParsing) {
            std::string paramName = CoinParamUtils::getCommand(argc, argv, prompt, &pfx);
            if (paramName.length() == 0) {
                if (ctlBlk.paramsProcessed_ == 0) {
                    if (CoinParamUtils::isInteractive()) {
                        std::cout
                            << "Type `?' or `help' for usage and command keywords."
                            << " Type `quit' to quit." ;
                    } else {
                        std::cout
                            << "Type `cbc-generic -help' for usage and parameter keywords." ;
                        keepParsing = false ;
                    }
                    std::cout << std::endl ;
                } else if (!CoinParamUtils::isInteractive()) {
                    keepParsing = false ;
                    if (ctlBlk.goodModel_ == true &&
                            ctlBlk.bab_.majorStatus_ == CbcGenCtlBlk::BACNotRun) {
                        paramName = "branchAndCut" ;
                        pfx = "-" ;
                    }
                }
            }
            if (paramName == "") {
                continue ;
            }
            /*
              Do we have a parameter we recognise? In command line mode, if there was no
              prefix (either `-' or `--'), the user didn't intend this as a command
              keyword.
            */
            int matchNdx ;
            if (!CoinParamUtils::isCommandLine() || pfx == "-" || pfx == "--") {
                matchNdx = CoinParamUtils::lookupParam(paramName, paramVec) ;
            } else {
                matchNdx = -3 ;
            }
            std::cout
                << "Command is `" << paramName
                << "', pfx `" << pfx
                << "', match = " << matchNdx << std::endl ;
            /*
              If matchNdx is positive, we have a unique parameter match and we can get on
              with processing. If the return value is negative, and we're not
              interactive, quit. If we're interactive, react as appropriate:
                -1: There was a `?' in the command string. Prompt again.
                -2: No `?', and one or more short matches. Prompt again.
                -3: No `?', but we didn't match anything either. If we're in command line
            	mode, and there was no `-' or `--' prefix, try forcing `import' (but
            	just once, eh). This is the other piece required to get `cbc-generic
            	[parameters] foo.mps' to work as expected.) In interactive mode,
            	we'll require the user to say `import'.  Interactive mode and no
            	history of successful commands gets the help message.
                -4: Configuration error, offer `report to maintainers' message.
            */
            if (matchNdx < 0) {
                if (matchNdx == -3) {
                    if (CoinParamUtils::isCommandLine() && pfx == "") {
                        if (!forceImport) {
                            forceImportFile = paramName ;
                            paramName = "import" ;
                            matchNdx = CoinParamUtils::lookupParam(paramName, paramVec) ;
                            forceImport = true ;
                        } else {
                            std::cout << "No commands matched `" << paramName << "'."
                                      << std::endl ;
                        }
                    } else {
                        std::cout << "No commands matched `" << paramName << "'."
                                  << std::endl ;
                        if (ctlBlk.paramsProcessed_ == 0) {
                            std::cout
                                << "Type `?' or `help' for usage and command keywords."
                                << " Type `quit' to quit." << std::endl ;
                        }
                    }
                } else if (matchNdx == -4) {
                    std::cout
                        << "Please report this error by filing a ticket at "
                        << "https://projects.coin-or.org/Cbc/wiki."
                        << std::endl ;
                }
            }
            if (matchNdx < 0) {
                keepParsing = CoinParamUtils::isInteractive() ;
                continue ;
            }
            CoinParam *param = paramVec[matchNdx] ;
            ctlBlk.paramsProcessed_++ ;
            /*
              Depending on the type, we may need a parameter. For keyword parameters, check
              that the keyword is recognised --- setKwdVal will quietly fail on a bad
              keyword.
            */
            CoinParam::CoinParamType type = param->type() ;
            int valid = 0 ;
            switch (type) {
            case CoinParam::coinParamAct: {
                break ;
            }
            case CoinParam::coinParamInt: {
                int ival = CoinParamUtils::getIntField(argc, argv, &valid) ;
                if (valid == 0) {
                    param->setIntVal(ival) ;
                }
                break ;
            }
            case CoinParam::coinParamDbl: {
                double dval = CoinParamUtils::getDoubleField(argc, argv, &valid) ;
                if (valid == 0) {
                    param->setDblVal(dval) ;
                }
                break ;
            }
            case CoinParam::coinParamStr: {
                if (forceImport) {
                    param->setStrVal(forceImportFile) ;
                } else {
                    const std::string tmp =
                        CoinParamUtils::getStringField(argc, argv, &valid) ;
                    if (valid == 0) {
                        param->setStrVal(tmp) ;
                    }
                }
                break ;
            }
            case CoinParam::coinParamKwd: {
                const std::string tmp =
                    CoinParamUtils::getStringField(argc, argv, &valid) ;
                if (valid == 0) {
                    param->setKwdVal(tmp) ;
                    if (param->kwdVal() != tmp) {
                        std::cout
                            << "Unrecognised keyword `" << tmp << "' for parameter "
                            << param->name() << std::endl ;
                        param->printKwds() ;
                        std::cout << std::endl ;
                        valid = 1 ;
                    }
                }
                break ;
            }
            default: {
                assert (false) ;
                break ;
            }
            }
            /*
              Deal with missing or incorrect values.

              If valid came back as 2, we're short a parameter. This is interpreted as a
              request to tell the user the current value.  If valid came back as 1, we
              had some sort of parse error. Print an error message.
            */
            if (valid != 0) {
                switch (valid) {
                case 1: {
                    std::cout
                        << "Could not parse the value given for parameter `"
                        << param->name() << "'." << std::endl ;
                    break ;
                }
                case 2: {
                    std::cout
                        << "Current value of " << param->name() << " parameter is `"
                        << *param << "'." << std::endl ;
                    break ;
                }
                default: {
                    std::cout
                        << "Parse status is " << valid
                        << "; this indicates internal confusion." << std::endl
                        << "Please report this error by filing a ticket at "
                        << "https://projects.coin-or.org/Cbc/wiki."
                        << std::endl ;
                }
                }
                keepParsing = CoinParamUtils::isInteractive() ;
                continue ;
            }
            /*
              Ok, call the parameter's push function to do the heavy lifting. Push and pull
              functions return 0 for success, 1 for non-fatal error, -1 for fatal error.
            */
            if (param->pushFunc() == 0) {
                std::cout << "Parameter `" << param->name()
                          << "' is not implemented." << std::endl ;
            } else {
                int retval = (param->pushFunc())(param) ;
                markAsSetByUser(ctlBlk, param) ;
                if (retval < 0) {
                    keepParsing = false ;
                }
            }
        }
        /*
          End of loop to parse and execute parameter actions. Time to do cleanup.
          The destructor for CbcGenCtlBlk will delete anything with a non-null pointer,
          so we need to be careful that the default solver is deleted only once.
        */
        ctlBlk.dfltSolver_ = 0 ;
        CbcGenSolvers::deleteSolvers() ;
        for (int i = 0 ; i < paramVec.size() ; i++) {
            if (paramVec[i] != 0) delete paramVec[i] ;
        }
    }
    /*
      End of memory allocation block. There should be no allocated objects at
      this point.
    */
    return (0) ;
}
Пример #16
0
// -----------------------------------------------------------------------------------
void CBCSolver::solveModel(CbcModel& model) {
  model.messageHandler()->setLogLevel(0); // turn off all output
  model.solver()->messageHandler()->setLogLevel(0); // turn off all output
  model.branchAndBound();
}
Пример #17
0
int main (int argc, const char *argv[])
{

  OsiClpSolverInterface solver1;
  //#define USE_OSI_NAMES
#ifdef USE_OSI_NAMES
  // Say we are keeping names (a bit slower this way)
  solver1.setIntParam(OsiNameDiscipline,1);
#endif
  // Read in model using argv[1]
  // and assert that it is a clean model
  std::string mpsFileName;
#if defined(SAMPLEDIR)
  mpsFileName = SAMPLEDIR "/p0033.mps";
#else
  if (argc < 2) {
    fprintf(stderr, "Do not know where to find sample MPS files.\n");
    exit(1);
  }
#endif
  if (argc>=2) mpsFileName = argv[1];
  int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(),"");
  if( numMpsReadErrors != 0 )
  {
     printf("%d errors reading MPS file\n", numMpsReadErrors);
     return numMpsReadErrors;
  }
  // Tell solver to return fast if presolve or initial solve infeasible
  solver1.getModelPtr()->setMoreSpecialOptions(3);

  // Pass to Cbc initialize defaults 
  CbcModel modelA(solver1);
  CbcModel * model = &modelA;
  CbcMain0(modelA);
  // Event handler
  MyEventHandler3 eventHandler;
  model->passInEventHandler(&eventHandler);
  /* Now go into code for standalone solver
     Could copy arguments and add -quit at end to be safe
     but this will do
  */
  if (argc>2) {
    CbcMain1(argc-1,argv+1,modelA,callBack);
  } else {
    const char * argv2[]={"driver6","-solve","-quit"};
    CbcMain1(3,argv2,modelA,callBack);
  }
  // Solver was cloned so get current copy
  OsiSolverInterface * solver = model->solver();
  // Print solution if finished (could get from model->bestSolution() as well

  if (model->bestSolution()) {
    
    const double * solution = solver->getColSolution();
    
    int iColumn;
    int numberColumns = solver->getNumCols();
    std::cout<<std::setiosflags(std::ios::fixed|std::ios::showpoint)<<std::setw(14);
    
    std::cout<<"--------------------------------------"<<std::endl;
#ifdef USE_OSI_NAMES
    
    for (iColumn=0;iColumn<numberColumns;iColumn++) {
      double value=solution[iColumn];
      if (fabs(value)>1.0e-7&&solver->isInteger(iColumn)) 
	std::cout<<std::setw(6)<<iColumn<<" "<<std::setw(8)<<setiosflags(std::ios::left)<<solver->getColName(iColumn)
		 <<resetiosflags(std::ios::adjustfield)<<std::setw(14)<<" "<<value<<std::endl;
    }
#else
    // names may not be in current solver - use original
    
    for (iColumn=0;iColumn<numberColumns;iColumn++) {
      double value=solution[iColumn];
      if (fabs(value)>1.0e-7&&solver->isInteger(iColumn)) 
	std::cout<<std::setw(6)<<iColumn<<" "<<std::setw(8)<<setiosflags(std::ios::left)<<solver1.getModelPtr()->columnName(iColumn)
		 <<resetiosflags(std::ios::adjustfield)<<std::setw(14)<<" "<<value<<std::endl;
    }
#endif
    std::cout<<"--------------------------------------"<<std::endl;
  
    std::cout<<std::resetiosflags(std::ios::fixed|std::ios::showpoint|std::ios::scientific);
  } else {
    std::cout<<" No solution!"<<std::endl;
  }
  return 0;
}