25#include "CoinTime.hpp"
26#include "CglPreProcess.hpp"
27#include "CglGomory.hpp"
28#include "CglSimpleRounding.hpp"
29#include "CglMixedIntegerRounding2.hpp"
30#include "CglKnapsackCover.hpp"
31#include "CglFlowCover.hpp"
32#include "CbcModel.hpp"
33#include "CbcBranchActual.hpp"
35#include "OsiClpSolverInterface.hpp"
36#include "OsiSymSolverInterface.hpp"
37#include "OsiVolSolverInterface.hpp"
41#include "OSCommonUtil.h"
53# error "don't have header file for time"
58using std::ostringstream;
66m_CoinPackedMatrix(NULL),
77 cout <<
"inside CoinSolver destructor" << endl;
99 cout <<
"leaving CoinSolver destructor" << endl;
106 if(
osil.length() == 0 &&
osinstance == NULL)
throw ErrorClass(
"there is no instance");
107 clock_t start, finish;
115 duration = (double) (finish - start) / CLOCKS_PER_SEC;
116 cout <<
"Parsing took (seconds): "<< duration << endl;
117 cout <<
"Start Solve with a Coin Solver" << endl;
119 bool solverIsDefined =
false;
120 std::cout <<
"SOLVER NAME = " <<
sSolverName << std::endl;
122 solverIsDefined =
true;
128 solverIsDefined =
true;
133 if(
sSolverName.find(
"cplex") != std::string::npos){
135 solverIsDefined =
true;
140 if(
sSolverName.find(
"glpk") != std::string::npos){
142 solverIsDefined =
true;
143 osiSolver =
new OsiGlpkSolverInterface();
147 if(
sSolverName.find(
"dylp") != std::string::npos){
149 solverIsDefined =
true;
150 osiSolver =
new OsiDylpSolverInterface();
154 if(
sSolverName.find(
"symphony") != std::string::npos) {
155 #ifdef COIN_HAS_SYMPHONY
156 solverIsDefined =
true;
162 solverIsDefined =
true;
171 if(solverIsDefined ==
false)
throw ErrorClass(
"a supported solver was not defined");
172 if(
osinstance->getConstraintNumber() <= 0)
throw ErrorClass(
"Coin solver Needs Constraints");
173 if(
osinstance->getVariableNumber() <= 0)
throw ErrorClass(
"Coin solver requires decision variables");
174 if(
osinstance->getObjectiveNumber() <= 0)
throw ErrorClass(
"Coin solver needs an objective function");
175 if(
osinstance->getLinearConstraintCoefficientNumber() <= 0)
throw ErrorClass(
"Coin solver needs linear constraints");
179 osinstance->getDenseObjectiveCoefficients()[0],
183 if(
osinstance->getObjectiveNumber() == 0)
throw ErrorClass(
"there is no objective function");
187 int *intIndex = NULL;
191 int numOfIntVars =
osinstance->getNumberOfIntegerVariables() +
osinstance->getNumberOfBinaryVariables();
192 if(numOfIntVars > 0) {
193 intIndex =
new int[ numOfIntVars];
195 for(i = 0; i <
osinstance->getVariableNumber(); i++){
196 if( (varType[i] ==
'B') || (varType[i]) ==
'I' ) {
200 osiSolver->setInteger( intIndex, numOfIntVars);
202 if(numOfIntVars > 0){
208 catch(
const ErrorClass& eclass){
209 std::cout <<
"THERE IS AN ERROR" << std::endl;
211 osresult->setGeneralStatusType(
"error");
213 throw ErrorClass(
osrl) ;
225 std::map<std::string, OsiHintParam> hintParamMap;
226 hintParamMap[
"OsiDoPresolveInInitial"] = OsiDoPresolveInInitial;
227 hintParamMap[
"OsiDoDualInInitial"] = OsiDoDualInInitial;
228 hintParamMap[
"OsiDoPresolveInResolve"] = OsiDoPresolveInResolve;
229 hintParamMap[
"OsiDoDualInResolve"] = OsiDoDualInResolve;
230 hintParamMap[
"OsiDoScale"] = OsiDoScale;
231 hintParamMap[
"OsiDoCrash"] = OsiDoCrash;
232 hintParamMap[
"OsiDoReducePrint"] = OsiDoReducePrint;
233 hintParamMap[
"OsiDoInBranchAndCut"] = OsiDoInBranchAndCut;
234 hintParamMap[
"OsiLastHintParam"] = OsiLastHintParam;
237 std::map<std::string, OsiHintStrength> hintStrengthMap;
238 hintStrengthMap[
"OsiHintIgnore"] = OsiHintIgnore;
239 hintStrengthMap[
"OsiHintTry"] = OsiHintTry;
240 hintStrengthMap[
"OsiHintDo"] = OsiHintDo;
241 hintStrengthMap[
"OsiForceDo"] = OsiForceDo;
244 std::map<std::string, OsiStrParam> strParamMap;
245 strParamMap[
"OsiProbName"] = OsiProbName;
246 strParamMap[
"OsiSolverName"] = OsiSolverName;
247 strParamMap[
"OsiLastStrParam"] = OsiLastStrParam;
250 std::map<std::string, OsiDblParam> dblParamMap;
251 dblParamMap[
"OsiDualObjectiveLimit"] = OsiDualObjectiveLimit;
252 dblParamMap[
"OsiPrimalObjectiveLimit"] = OsiPrimalObjectiveLimit;
253 dblParamMap[
"OsiDualTolerance"] = OsiDualTolerance;
254 dblParamMap[
"OsiPrimalTolerance"] = OsiPrimalTolerance;
255 dblParamMap[
"OsiObjOffset"] = OsiObjOffset;
256 dblParamMap[
"OsiLastDblParam"] = OsiLastDblParam;
260 std::map<std::string, OsiIntParam> intParamMap;
261 intParamMap[
"OsiMaxNumIteration"] = OsiMaxNumIteration;
262 intParamMap[
"OsiMaxNumIterationHotStart"] = OsiMaxNumIterationHotStart;
263 intParamMap[
"OsiNameDiscipline"] = OsiNameDiscipline;
264 intParamMap[
"OsiLastIntParam"] = OsiLastIntParam;
275 OsiHintStrength hintStrength = OsiHintTry;
276 osiSolver->setHintParam(OsiDoReducePrint,
true, hintStrength);
285 if(osoption == NULL && osol.length() > 0)
287 m_osolreader = new OSoLReader();
288 osoption = m_osolreader->readOSoL( osol);
293 std::cout <<
"number of solver options " << osoption->getNumberOfSolverOptions() << std::endl;
294 if( osoption->getNumberOfSolverOptions() <= 0) return;
295 this->bSetSolverOptions = true;
296 std::vector<SolverOption*> optionsVector;
298 optionsVector = osoption->getSolverOptions(
"osi");
299 int num_osi_options = optionsVector.size();
304 for(i = 0; i < num_osi_options; i++){
305 std::cout <<
"osi solver option " << optionsVector[ i]->name << std::endl;
306 if (optionsVector[ i]->type ==
"OsiHintStrength" ){
307 if( hintStrengthMap.find( optionsVector[ i]->name ) != hintStrengthMap.end() ){
308 hintStrength = hintStrengthMap[ optionsVector[ i]->name] ;
312 for(i = 0; i < num_osi_options; i++){
313 std::cout <<
"osi solver option " << optionsVector[ i]->name << std::endl;
315 if (optionsVector[ i]->type ==
"OsiHintParam" ){
317 if( optionsVector[ i]->value ==
"true" ) {
323 if( hintParamMap.find( optionsVector[ i]->name ) != hintParamMap.end() ){
325 osiSolver->setHintParam( hintParamMap[ optionsVector[ i]->name] , yesNo, hintStrength);
329 else if(optionsVector[ i]->type ==
"OsiStrParam" ){
331 if( strParamMap.find( optionsVector[ i]->name ) != strParamMap.end() ){
333 osiSolver->setStrParam( strParamMap[ optionsVector[ i]->name] , optionsVector[ i]->value);
337 else if(optionsVector[ i]->type ==
"OsiDblParam" ){
339 if( dblParamMap.find( optionsVector[ i]->name ) != dblParamMap.end() ){
341 osiSolver->setDblParam( dblParamMap[ optionsVector[ i]->name] ,
os_strtod( optionsVector[ i]->value.c_str(), &pEnd ));
345 else if(optionsVector[ i]->type ==
"OsiIntParam" ){
348 if( intParamMap.find( optionsVector[ i]->name ) != intParamMap.end() ){
350 osiSolver->setIntParam( intParamMap[ optionsVector[ i]->name] , atoi( optionsVector[ i]->value.c_str() ) );
365 if( sSolverName.find(
"cbc") != std::string::npos) {
367 optionsVector = osoption->getSolverOptions(
"cbc");
368 int num_cbc_options = optionsVector.size();
370 std::string cbc_option;
372 num_cbc_argv = optionsVector.size() + 2;
373 cbc_argv = new const char*[ num_cbc_argv];
377 cstr = new char [cbc_option.size() + 1];
378 strcpy (cstr, cbc_option.c_str());
382 for(i = 0; i < num_cbc_options; i++){
383 std::cout <<
"cbc solver option " << optionsVector[ i]->name << std::endl;
384 std::cout <<
"cbc solver value " << optionsVector[ i]->value << std::endl;
385 if(optionsVector[ i]->value.length() > 0){
386 cbc_option =
"-" + optionsVector[ i]->name +
"="+optionsVector[ i]->value;
389 cbc_option =
"-" + optionsVector[ i]->name ;
391 cstr = new char [cbc_option.size() + 1];
392 strcpy (cstr, cbc_option.c_str());
393 cbc_argv[i + 1] = cstr;
397 cbc_option =
"-quit";
398 cstr =
new char [cbc_option.size() + 1];
399 strcpy (cstr, cbc_option.c_str());
400 cbc_argv[ num_cbc_argv - 1] = cstr;
408 #ifdef COIN_HAS_SYMPHONY
410 if( !optionsVector.empty() ) optionsVector.clear();
412 if( sSolverName.find(
"symphony") != std::string::npos) {
413 OsiSymSolverInterface * si =
414 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
416 optionsVector = osoption->getSolverOptions(
"symphony");
417 int num_sym_options = optionsVector.size();
420 for(i = 0; i < num_sym_options; i++){
421 std::cout <<
"symphony solver option " << optionsVector[ i]->name << std::endl;
422 std::cout <<
"symphony solver value " << optionsVector[ i]->value << std::endl;
423 if( optionsVector[ i]->name ==
"max_active_nodes"){
424 si->setSymParam(
"max_active_nodes", optionsVector[ i]->value);
437 m =
osoption->getNumberOfInitVarValues();
441 cout <<
"number of variables initialed: " << m << endl;
447 cout <<
"get initial values " << endl;
449 n = osinstance->getVariableNumber();
450 double* denseInitVarVector;
451 denseInitVarVector =
new double[n];
453 initialed =
new bool[n];
455 for(k = 0; k < n; k++)
456 initialed[k] =
false;
460 cout <<
"done " << endl;
464 for(k = 0; k < m; k++)
465 { cout <<
"process component " << k <<
" -- index " << initVarVector[k]->
idx << endl;
466 i = initVarVector[k]->
idx;
467 if (initVarVector[k]->idx > n)
468 throw ErrorClass (
"Illegal index value in variable initialization");
470 initval = initVarVector[k]->
value;
471 if (osinstance->instanceData->variables->var[k]->ub ==
OSDBL_MAX)
472 {
if (osinstance->instanceData->variables->var[k]->lb > initval)
473 throw ErrorClass (
"Initial value outside of bounds");
476 if (osinstance->instanceData->variables->var[k]->lb == -
OSDBL_MAX)
477 {
if (osinstance->instanceData->variables->var[k]->ub < initval)
478 throw ErrorClass (
"Initial value outside of bounds");
481 {
if ((osinstance->instanceData->variables->var[k]->lb > initval) ||
482 (osinstance->instanceData->variables->var[k]->ub < initval))
483 throw ErrorClass (
"Initial value outside of bounds");
486 denseInitVarVector[initVarVector[k]->
idx] = initval;
487 initialed[initVarVector[k]->idx] =
true;
490 double default_initval;
491 default_initval = 0.0;
493 for(k = 0; k < n; k++)
494 { cout <<
"verify component " << k << endl;
496 if (osinstance->instanceData->variables->var[k]->ub ==
OSDBL_MAX)
497 if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
498 denseInitVarVector[k] = default_initval;
500 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
502 if (osinstance->instanceData->variables->var[k]->lb == -
OSDBL_MAX)
503 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
504 denseInitVarVector[k] = default_initval;
506 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
508 if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
509 (osinstance->instanceData->variables->var[k]->ub >= default_initval))
510 denseInitVarVector[k] = default_initval;
512 if (osinstance->instanceData->variables->var[k]->lb > default_initval)
513 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
515 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
516 denseInitVarVector[k] = default_initval;
517 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
520 cout <<
"set initial values: " << endl;
521 for (k=0; k < n; k++)
522 cout <<
" " << k <<
": " << denseInitVarVector[k] << endl;
524 osiSolver->setColSolution( denseInitVarVector);
525 delete[] denseInitVarVector;
528 cout <<
"done " << endl;
537 std::cout <<
"THERE IS AN ERROR" << std::endl;
539 osresult->setGeneralStatusType(
"error");
540 osrl = osrlwriter->writeOSrL(
osresult);
547 bool columnMajor =
osinstance->getLinearConstraintCoefficientMajor();
554 osinstance->getLinearConstraintCoefficientNumber(),
555 columnMajor?
osinstance->getLinearConstraintCoefficientsInColumnMajor()->values :
osinstance->getLinearConstraintCoefficientsInRowMajor()->values,
556 columnMajor?
osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes :
osinstance->getLinearConstraintCoefficientsInRowMajor()->indexes,
557 columnMajor?
osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts :
osinstance->getLinearConstraintCoefficientsInRowMajor()->starts,
562 catch(
const ErrorClass& eclass){
564 osresult->setGeneralStatusType(
"error");
578 if( sSolverName.find(
"clp") != std::string::npos) throw ErrorClass(
"Clp cannot do integer programming");
579 if( sSolverName.find(
"vol") != std::string::npos) throw ErrorClass(
"Vol cannot do integer programming");
580 if( sSolverName.find(
"dylp") != std::string::npos) throw ErrorClass(
"DyLP cannot do integer programming");
581 if( sSolverName.find(
"ipopt") != std::string::npos) throw ErrorClass(
"Ipopt cannot do integer programming");
583 if( (
osinstance->getNumberOfNonlinearExpressions() > 0)
584 || (
osinstance->getNumberOfQuadraticTerms() > 0) ){
585 throw ErrorClass(
"This COIN-OR Solver is not configured for nonlinear programming");
591 throw ErrorClass(
"OSResult error: setServiceName");
593 throw ErrorClass(
"OSResult error: setInstanceName");
600 throw ErrorClass(
"OSResult error: setVariableNumer");
601 if(
osresult->setObjectiveNumber( 1) !=
true)
602 throw ErrorClass(
"OSResult error: setObjectiveNumber");
604 throw ErrorClass(
"OSResult error: setConstraintNumber");
605 if(
osresult->setSolutionNumber( 1) !=
true)
606 throw ErrorClass(
"OSResult error: setSolutionNumer");
609 double start = CoinCpuTime();
611 if(
sSolverName.find(
"cbc") != std::string::npos){
621 std::string cbc_option;
627 cstr =
new char [cbc_option.size() + 1];
628 strcpy (cstr, cbc_option.c_str());
633 cbc_option =
"-log=0";
634 cstr =
new char [cbc_option.size() + 1];
635 strcpy (cstr, cbc_option.c_str());
640 cbc_option =
"-solve";
641 cstr =
new char [cbc_option.size() + 1];
642 strcpy (cstr, cbc_option.c_str());
646 cbc_option =
"-quit";
647 cstr =
new char [cbc_option.size() + 1];
648 strcpy (cstr, cbc_option.c_str());
652 std::cout <<
"CALLING THE CBC SOLVER CBCMAIN1()" << std::endl;
655 std::cout <<
"Cbc Option: " <<
cbc_argv[ i] << std::endl;
669 OsiSolverInterface *solver = model.solver();
670 cpuTime = CoinCpuTime() - start;
682 cpuTime = CoinCpuTime() - start;
691 errmsg =
"Coin Solver Error: " + e.message() +
"\n" +
" see method "
692 + e.methodName() +
" in class " + e.className();
693 throw ErrorClass( errmsg );
697 catch(
const ErrorClass& eclass){
699 osresult->setGeneralStatusType(
"error");
708 if( lcl_osol.find(
"clp") != std::string::npos){
709 return "coin_solver_glpk";
712 if( lcl_osol.find(
"cbc") != std::string::npos){
713 return "coin_solver_cpx";
716 if( lcl_osol.find(
"cpx") != std::string::npos){
717 return "coin_solver_clp";
720 if(lcl_osol.find(
"glpk") != std::string::npos){
723 else throw ErrorClass(
"a supported solver was not defined");
728 catch(
const ErrorClass& eclass){
730 osresult->setGeneralStatusType(
"error");
739 cout <<
"This is problem: " <<
osinstance->getInstanceName() << endl;
740 cout <<
"The problem source is: " <<
osinstance->getInstanceSource() << endl;
741 cout <<
"The problem description is: " <<
osinstance->getInstanceDescription() << endl;
742 cout <<
"number of variables = " <<
osinstance->getVariableNumber() << endl;
743 cout <<
"number of Rows = " <<
osinstance->getConstraintNumber() << endl;
747 for(i = 0; i <
osinstance->getVariableNumber(); i++){
748 if(
osinstance->getVariableNames() != NULL) cout <<
"variable Names " <<
osinstance->getVariableNames()[ i] << endl;
749 if(
osinstance->getVariableTypes() != NULL) cout <<
"variable Types " <<
osinstance->getVariableTypes()[ i] << endl;
750 if(
osinstance->getVariableLowerBounds() != NULL) cout <<
"variable Lower Bounds " <<
osinstance->getVariableLowerBounds()[ i] << endl;
751 if(
osinstance->getVariableUpperBounds() != NULL) cout <<
"variable Upper Bounds " <<
osinstance->getVariableUpperBounds()[i] << endl;
756 if(
osinstance->getVariableNumber() > 0 ||
osinstance->instanceData->objectives->obj != NULL ||
osinstance->instanceData->objectives->numberOfObjectives > 0){
757 if(
osinstance->getObjectiveMaxOrMins()[0] ==
"min") cout <<
"problem is a minimization" << endl;
758 else cout <<
"problem is a maximization" << endl;
759 for(i = 0; i <
osinstance->getVariableNumber(); i++){
760 cout <<
"OBJ COEFFICIENT = " <<
osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
765 for(i = 0; i <
osinstance->getConstraintNumber(); i++){
766 if(
osinstance->getConstraintNames() != NULL) cout <<
"row name = " <<
osinstance->getConstraintNames()[i] << endl;
767 if(
osinstance->getConstraintLowerBounds() != NULL) cout <<
"row lower bound = " <<
osinstance->getConstraintLowerBounds()[i] << endl;
768 if(
osinstance->getConstraintUpperBounds() != NULL) cout <<
"row upper bound = " <<
osinstance->getConstraintUpperBounds()[i] << endl;
783 std::string *rcost = NULL;
786 std::string description =
"";
787 osresult->setGeneralStatusType(
"normal");
790 if (solver->isProvenOptimal() ==
true){
791 osresult->setSolutionStatus(solIdx,
"optimal", description);
793 x =
new double[
osinstance->getVariableNumber() ];
794 y =
new double[
osinstance->getConstraintNumber() ];
798 rcost =
new std::string[
osinstance->getVariableNumber()];
800 *(z + 0) = solver->getObjValue();
801 osresult->setObjectiveValues(solIdx, z, 1);
802 for(i=0; i <
osinstance->getVariableNumber(); i++){
803 *(x + i) = solver->getColSolution()[i];
805 osresult->setPrimalVariableValues(solIdx, x, n);
807 if(
sSolverName.find(
"symphony") == std::string::npos &&
osinstance->getNumberOfIntegerVariables() == 0 &&
osinstance->getNumberOfBinaryVariables() == 0) {
808 for(i=0; i <
osinstance->getConstraintNumber(); i++){
809 *(y + i) = solver->getRowPrice()[ i];
817 if(
sSolverName.find(
"symphony") == std::string::npos &&
osinstance->getNumberOfIntegerVariables() == 0 &&
osinstance->getNumberOfBinaryVariables() == 0){
818 int numberOfOtherVariableResults = 1;
821 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
822 ostringstream outStr;
823 int numberOfVar =
osinstance->getVariableNumber();
824 for(i=0; i < numberOfVar; i++){
827 osresult->setAnOtherVariableResult(solIdx, otherIdx,
"reduced costs",
"the variable reduced costs", rcost,
osinstance->getVariableNumber());
832 if(solver->isProvenPrimalInfeasible() ==
true)
833 osresult->setSolutionStatus(solIdx,
"infeasible", description);
835 if(solver->isProvenDualInfeasible() ==
true)
836 osresult->setSolutionStatus(solIdx,
"dualinfeasible", description);
838 osresult->setSolutionStatus(solIdx,
"other", description);
841 if(
osinstance->getVariableNumber() > 0)
delete[] x;
843 if(
osinstance->getConstraintNumber())
delete[] y;
std::string os_dtoa_format(double x)
double os_strtod(const char *s00, char **se)
const char ** cbc_argv
when Cbc is the solver, these are the arguments sent to Cbc Solve
virtual void setSolverOptions()
The implementation of the corresponding virtual function.
virtual void buildSolverInstance()
The implementation of the corresponding virtual function.
int num_cbc_argv
the number of arguments in the argument list to the Cbc Solver
CoinPackedMatrix * m_CoinPackedMatrix
m_CoinPackedMatrix is a Coin Packed Matrix ojbect
std::string getCoinSolverType(std::string osol_)
Get the solver type, e.g. clp or glpk.
OSiLReader * m_osilreader
m_osilreader is an OSiLReader object used to create an osinstance from an osil string if needed
OsiSolverInterface * osiSolver
osiSolver is the osi solver object – in this case clp, glpk, cbc, cplex, symphony or dylp
CoinSolver()
The class constructor.
~CoinSolver()
The class destructor.
OSoLReader * m_osolreader
m_osolreader is an OSoLReader object used to create an osoption from an osol string if needed
void writeResult(OsiSolverInterface *solver)
OSrLWriter * osrlwriter
osrlwriter object used to write osrl from an OSResult object
virtual void solve()
The implementation of the corresponding virtual function.
void dataEchoCheck()
Print out problem parameters.
bool setCoinPackedMatrix()
Create a CoinPackedMatrix.
std::string sSolverName
sSolverName is the name of the Coin solver used, e.g.
bool bSetSolverOptions
bSetSolverOptions is set to true if setSolverOptions has been called, false otherwise
std::string osrl
osrl holds the solution or result of the model
OSInstance * osinstance
osinstance holds the problem instance in-memory as an OSInstance object
bool bCallbuildSolverInstance
bCallbuildSolverInstance is set to true if buildSolverService has been called
std::string osil
osil holds the problem instance as a std::string
OSOption * osoption
osoption holds the solver options in-memory as an OSOption object
OSResult * osresult
osresult holds the solution or result of the model in-memory as an OSResult object
used for throwing exceptions.
std::string errormsg
errormsg is the error that is causing the exception to be thrown
double value
initial value
Take an OSResult object and write a string that validates against OSrL.
This file defines the OSInstance class along with its supporting classes.