// ----------------------------------------------------------------------------------- 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); } }
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)); }
CbcHeuristicCrossover::CbcHeuristicCrossover(CbcModel & model) : CbcHeuristic(model), numberSolutions_(0), useNumber_(3) { setWhen(1); for (int i = 0; i < 10; i++) random_[i] = model.randomNumberGenerator()->randomDouble(); }
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; }
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) ; }
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; }
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; }
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(); }
// 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; }
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"); } }
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; } }
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; }
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
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; } }
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_ = ¶mVec ; 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) ; }
// ----------------------------------------------------------------------------------- void CBCSolver::solveModel(CbcModel& model) { model.messageHandler()->setLogLevel(0); // turn off all output model.solver()->messageHandler()->setLogLevel(0); // turn off all output model.branchAndBound(); }
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; }