00001
00021
00022
00023 #include "OSCoinSolver.h"
00024 #include "OSInstance.h"
00025 #include "OSFileUtil.h"
00026 #include "CoinTime.hpp"
00027 #include "CglPreProcess.hpp"
00028 #include "CglGomory.hpp"
00029 #include "CglSimpleRounding.hpp"
00030 #include "CglMixedIntegerRounding2.hpp"
00031 #include "CglKnapsackCover.hpp"
00032 #include "CglFlowCover.hpp"
00033 #include "CbcBranchActual.hpp"
00034 #include "CoinMessageHandler.hpp"
00035 #include "CoinMessage.hpp"
00036
00037 #include "OsiClpSolverInterface.hpp"
00038
00039 #ifdef COIN_HAS_SYMPHONY
00040 #include "OsiSymSolverInterface.hpp"
00041 #endif
00042
00043 #ifdef COIN_HAS_VOL
00044 #include "OsiVolSolverInterface.hpp"
00045 #endif
00046
00047 #ifdef COIN_HAS_DYLP
00048 #include "OsiDylpSolverInterface.hpp"
00049 #endif
00050
00051 #ifdef COIN_HAS_GLPK
00052 #include "OsiGlpkSolverInterface.hpp"
00053 #endif
00054
00055 #ifdef COIN_HAS_CPX
00056 #include "OsiCpxSolverInterface.hpp"
00057 #endif
00058
00059 #include "OSGeneral.h"
00060 #include "OSParameters.h"
00061 #include "OSMathUtil.h"
00062
00063 #include<map>
00064
00065 #include <iostream>
00066 #ifdef HAVE_CTIME
00067 # include <ctime>
00068 #else
00069 # ifdef HAVE_TIME_H
00070 # include <time.h>
00071 # else
00072 # error "don't have header file for time"
00073 # endif
00074 #endif
00075 using std::cout;
00076 using std::endl;
00077 using std::ostringstream;
00078
00079
00080
00081 CoinSolver::CoinSolver() :
00082 osiSolver(NULL),
00083 m_osilreader(NULL),
00084 m_osolreader(NULL),
00085 m_CoinPackedMatrix(NULL),
00086 cbc_argv( NULL),
00087 num_cbc_argv( 0),
00088 cpuTime( 0)
00089
00090 {
00091 osrlwriter = new OSrLWriter();
00092 }
00093
00094 CoinSolver::~CoinSolver() {
00095 #ifdef DEBUG
00096 cout << "inside CoinSolver destructor" << endl;
00097 #endif
00098 if(m_osilreader != NULL) delete m_osilreader;
00099 m_osilreader = NULL;
00100 if(m_osolreader != NULL) delete m_osolreader;
00101 m_osolreader = NULL;
00102 delete m_CoinPackedMatrix;
00103 m_CoinPackedMatrix = NULL;
00104 delete osiSolver;
00105 if(osiSolver != NULL) osiSolver = NULL;
00106 delete osrlwriter;
00107 osrlwriter = NULL;
00108 delete osresult;
00109 osresult = NULL;
00110 if(num_cbc_argv > 0){
00111 int i;
00112 for(i = 0; i < num_cbc_argv; i++){
00113
00114 }
00115
00116 cbc_argv = NULL;
00117 }
00118 #ifdef DEBUG
00119 cout << "leaving CoinSolver destructor" << endl;
00120 #endif
00121 }
00122
00123
00124 void CoinSolver::buildSolverInstance() throw (ErrorClass) {
00125 try{
00126
00127 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
00128 clock_t start, finish;
00129 double duration;
00130 start = clock();
00131 if(osinstance == NULL){
00132 m_osilreader = new OSiLReader();
00133 osinstance = m_osilreader->readOSiL( osil);
00134 }
00135 finish = clock();
00136 duration = (double) (finish - start) / CLOCKS_PER_SEC;
00137
00138 bool solverIsDefined = false;
00139 if( sSolverName.find("clp") != std::string::npos){
00140 solverIsDefined = true;
00141 osiSolver = new OsiClpSolverInterface();
00142 }
00143 else{
00144 if( sSolverName.find("vol") != std::string::npos){
00145 #ifdef COIN_HAS_VOL
00146 solverIsDefined = true;
00147 osiSolver = new OsiVolSolverInterface();
00148 #endif
00149 }
00150 else{
00151 if( sSolverName.find( "cplex") != std::string::npos){
00152 #ifdef COIN_HAS_CPX
00153 solverIsDefined = true;
00154 osiSolver = new OsiCpxSolverInterface();
00155 #endif
00156 }
00157 else{
00158 if(sSolverName.find( "glpk") != std::string::npos){
00159 #ifdef COIN_HAS_GLPK
00160 solverIsDefined = true;
00161 osiSolver = new OsiGlpkSolverInterface();
00162 #endif
00163 }
00164 else{
00165 if(sSolverName.find( "dylp") != std::string::npos){
00166 #ifdef COIN_HAS_DYLP
00167 solverIsDefined = true;
00168 osiSolver = new OsiDylpSolverInterface();
00169 #endif
00170 }
00171 else{
00172 if( sSolverName.find( "symphony") != std::string::npos) {
00173 #ifdef COIN_HAS_SYMPHONY
00174 solverIsDefined = true;
00175 osiSolver = new OsiSymSolverInterface();
00176 #endif
00177 }
00178 else{
00179
00180
00181 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0) sSolverName = "cbc";
00182 else sSolverName = "clp";
00183 solverIsDefined = true;
00184 osiSolver = new OsiClpSolverInterface();
00185 }
00186 }
00187 }
00188 }
00189 }
00190 }
00191
00192 if(solverIsDefined == false) throw ErrorClass("a supported solver was not defined");
00193
00194
00195 if( (osinstance->getNumberOfNonlinearExpressions() > 0)
00196 || (osinstance->getNumberOfQuadraticTerms() > 0) ){
00197 throw ErrorClass( "This COIN-OR Solver is not configured for nonlinear programming");
00198 }
00199
00200 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00201 if( sSolverName.find("clp") != std::string::npos) throw ErrorClass( "Clp cannot do integer programming");
00202 if( sSolverName.find("vol") != std::string::npos) throw ErrorClass( "Vol cannot do integer programming");
00203 if( sSolverName.find("dylp") != std::string::npos) throw ErrorClass( "DyLP cannot do integer programming");
00204
00205 }
00206
00207 if( osinstance->getNumberOfSemiIntegerVariables() + osinstance->getNumberOfSemiContinuousVariables() > 0){
00208 throw ErrorClass( "Semi-integer and semi-continuous variables not supported");
00209
00210
00211
00212
00213 }
00214
00215
00216
00217 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Coin solver:" + sSolverName + " needs an objective function");
00218 if(osinstance->getNumberOfStringVariables() > 0) throw ErrorClass("Coin solver:" + sSolverName + " can only handle numeric variables");
00219 if(osinstance->getLinearConstraintCoefficientNumber() <= 0 && sSolverName == "symphony") throw ErrorClass("Coin solver:" + sSolverName + " needs a positive number of variables");
00220
00221 if(!setCoinPackedMatrix() ) throw ErrorClass("Problem generating coin packed matrix");
00222 osiSolver->loadProblem(*m_CoinPackedMatrix, osinstance->getVariableLowerBounds(),
00223 osinstance->getVariableUpperBounds(),
00224 osinstance->getDenseObjectiveCoefficients()[0],
00225 osinstance->getConstraintLowerBounds(), osinstance->getConstraintUpperBounds()
00226 );
00227
00228
00229 if( osinstance->getObjectiveMaxOrMins()[0] == "min") osiSolver->setObjSense(1.0);
00230 else osiSolver->setObjSense(-1.0);
00231
00232 int *intIndex = NULL;
00233 int i = 0;
00234 int k = 0;
00235 char *varType;
00236 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
00237 if(numOfIntVars > 0) {
00238 intIndex = new int[ numOfIntVars];
00239 varType = osinstance->getVariableTypes();
00240 for(i = 0; i < osinstance->getVariableNumber(); i++){
00241 if( (varType[i] == 'B') || (varType[i]) == 'I' ) {
00242 intIndex[k++] = i;
00243 }
00244 }
00245 osiSolver->setInteger( intIndex, numOfIntVars);
00246 }
00247 if(numOfIntVars > 0){
00248 delete[] intIndex;
00249 intIndex = NULL;
00250 }
00251 bCallbuildSolverInstance = true;
00252 }
00253 catch(const ErrorClass& eclass){
00254 osresult = new OSResult();
00255 osresult->setGeneralMessage( eclass.errormsg);
00256 osresult->setGeneralStatusType( "error");
00257 osrl = osrlwriter->writeOSrL( osresult);
00258 throw ErrorClass( osrl) ;
00259 }
00260 }
00261
00262
00263
00264 void CoinSolver::setSolverOptions() throw (ErrorClass) {
00265
00266 #ifdef DEBUG
00267 std::cout << "build solver options" << std::endl;
00268 #endif
00269 this->bSetSolverOptions = true;
00270
00271
00272 std::map<std::string, OsiHintParam> hintParamMap;
00273 hintParamMap["OsiDoPresolveInInitial"] = OsiDoPresolveInInitial;
00274 hintParamMap["OsiDoDualInInitial"] = OsiDoDualInInitial;
00275 hintParamMap["OsiDoPresolveInResolve"] = OsiDoPresolveInResolve;
00276 hintParamMap["OsiDoDualInResolve"] = OsiDoDualInResolve;
00277 hintParamMap["OsiDoScale"] = OsiDoScale;
00278 hintParamMap["OsiDoCrash"] = OsiDoCrash;
00279 hintParamMap["OsiDoReducePrint"] = OsiDoReducePrint;
00280 hintParamMap["OsiDoInBranchAndCut"] = OsiDoInBranchAndCut;
00281 hintParamMap["OsiLastHintParam"] = OsiLastHintParam;
00282
00283
00284 std::map<std::string, OsiHintStrength> hintStrengthMap;
00285 hintStrengthMap["OsiHintIgnore"] = OsiHintIgnore;
00286 hintStrengthMap["OsiHintTry"] = OsiHintTry;
00287 hintStrengthMap["OsiHintDo"] = OsiHintDo;
00288 hintStrengthMap["OsiForceDo"] = OsiForceDo;
00289
00290
00291 std::map<std::string, OsiStrParam> strParamMap;
00292 strParamMap["OsiProbName"] = OsiProbName;
00293 strParamMap["OsiSolverName"] = OsiSolverName;
00294 strParamMap["OsiLastStrParam"] = OsiLastStrParam;
00295
00296
00297 std::map<std::string, OsiDblParam> dblParamMap;
00298 dblParamMap["OsiDualObjectiveLimit"] = OsiDualObjectiveLimit;
00299 dblParamMap["OsiPrimalObjectiveLimit"] = OsiPrimalObjectiveLimit;
00300 dblParamMap["OsiDualTolerance"] = OsiDualTolerance;
00301 dblParamMap["OsiPrimalTolerance"] = OsiPrimalTolerance;
00302 dblParamMap["OsiObjOffset"] = OsiObjOffset;
00303 dblParamMap["OsiLastDblParam"] = OsiLastDblParam;
00304
00305
00306
00307 std::map<std::string, OsiIntParam> intParamMap;
00308 intParamMap["OsiMaxNumIteration"] = OsiMaxNumIteration;
00309 intParamMap["OsiMaxNumIterationHotStart"] = OsiMaxNumIterationHotStart;
00310 intParamMap["OsiNameDiscipline"] = OsiNameDiscipline;
00311 intParamMap["OsiLastIntParam"] = OsiLastIntParam;
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 OsiHintStrength hintStrength = OsiHintTry;
00323 osiSolver->setHintParam(OsiDoReducePrint, true, hintStrength);
00324
00325
00326 osiSolver->setDblParam(OsiObjOffset, -osinstance->getObjectiveConstants()[0]);
00327
00328
00329
00330
00331 #ifdef COIN_HAS_SYMPHONY
00332 if( sSolverName.find( "symphony") != std::string::npos) {
00333 OsiSymSolverInterface * si =
00334 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00335
00336 si->setSymParam("verbosity", -2);
00337 }
00338 #endif //symphony end
00339
00340
00341
00342
00343
00344
00345 try{
00346 if(osoption == NULL && osol.length() > 0)
00347 {
00348 m_osolreader = new OSoLReader();
00349 osoption = m_osolreader->readOSoL( osol);
00350 }
00351
00352 if(osoption != NULL){
00353
00354 #ifdef DEBUG
00355 std::cout << "number of solver options " << osoption->getNumberOfSolverOptions() << std::endl;
00356 #endif
00357 if( osoption->getNumberOfSolverOptions() <= 0) return;
00358
00359 std::vector<SolverOption*> optionsVector;
00360
00361 optionsVector = osoption->getSolverOptions( "osi");
00362 int num_osi_options = optionsVector.size();
00363 int i;
00364 char *pEnd;
00365 bool yesNo;
00366
00367 for(i = 0; i < num_osi_options; i++){
00368 #ifdef DEBUG
00369 std::cout << "osi solver option " << optionsVector[ i]->name << std::endl;
00370 #endif
00371 if (optionsVector[ i]->type == "OsiHintStrength" ){
00372 if( hintStrengthMap.find( optionsVector[ i]->name ) != hintStrengthMap.end() ){
00373 hintStrength = hintStrengthMap[ optionsVector[ i]->name] ;
00374 }
00375 }
00376 }
00377 for(i = 0; i < num_osi_options; i++){
00378 #ifdef DEBUG
00379 std::cout << "osi solver option " << optionsVector[ i]->name << std::endl;
00380 #endif
00381 if (optionsVector[ i]->type == "OsiHintParam" ){
00382
00383 if( optionsVector[ i]->value == "true" ) {
00384 yesNo = true;
00385 }
00386 else{
00387 yesNo = false;
00388 }
00389 if( hintParamMap.find( optionsVector[ i]->name ) != hintParamMap.end() ){
00390
00391 osiSolver->setHintParam( hintParamMap[ optionsVector[ i]->name] , yesNo, hintStrength);
00392 }
00393
00394 }
00395 else if(optionsVector[ i]->type == "OsiStrParam" ){
00396
00397 if( strParamMap.find( optionsVector[ i]->name ) != strParamMap.end() ){
00398
00399 osiSolver->setStrParam( strParamMap[ optionsVector[ i]->name] , optionsVector[ i]->value);
00400 }
00401
00402 }
00403 else if(optionsVector[ i]->type == "OsiDblParam" ){
00404
00405 if( dblParamMap.find( optionsVector[ i]->name ) != dblParamMap.end() ){
00406
00407 osiSolver->setDblParam( dblParamMap[ optionsVector[ i]->name] , os_strtod( optionsVector[ i]->value.c_str(), &pEnd ));
00408 }
00409
00410 }
00411 else if(optionsVector[ i]->type == "OsiIntParam" ){
00412
00413
00414 if( intParamMap.find( optionsVector[ i]->name ) != intParamMap.end() ){
00415
00416 osiSolver->setIntParam( intParamMap[ optionsVector[ i]->name] , atoi( optionsVector[ i]->value.c_str() ) );
00417 }
00418
00419 }
00420 }
00421
00422
00423
00424 if( sSolverName.find( "cbc") != std::string::npos) {
00425
00426 if(optionsVector.size() > 0) optionsVector.clear();
00427 optionsVector = osoption->getSolverOptions( "cbc");
00428 int num_cbc_options = optionsVector.size();
00429 char *cstr;
00430 std::string cbc_option;
00431 num_cbc_argv = optionsVector.size() + 3;
00432 cbc_argv = new const char*[ num_cbc_argv];
00433
00434
00435 cbc_option = "OS";
00436 cstr = new char [cbc_option.size() + 1];
00437 strcpy (cstr, cbc_option.c_str());
00438 cbc_argv[ 0] = cstr;
00439
00440
00441 for(i = 0; i < num_cbc_options; i++){
00442 #ifdef DEBUG
00443 std::cout << "cbc solver option " << optionsVector[ i]->name << std::endl;
00444 std::cout << "cbc solver value " << optionsVector[ i]->value << std::endl;
00445 #endif
00446 if(optionsVector[ i]->value.length() > 0){
00447 cbc_option = "-" + optionsVector[ i]->name +"="+optionsVector[ i]->value;
00448 }
00449 else{
00450 cbc_option = "-" + optionsVector[ i]->name ;
00451 }
00452 cstr = new char [cbc_option.size() + 1];
00453 strcpy (cstr, cbc_option.c_str());
00454 cbc_argv[i + 1] = cstr;
00455 }
00456
00457
00458 cbc_option = "-solve";
00459 cstr = new char [cbc_option.size() + 1];
00460 strcpy (cstr, cbc_option.c_str());
00461 cbc_argv[ num_cbc_argv - 2] = cstr;
00462
00463
00464 cbc_option = "-quit";
00465 cstr = new char [cbc_option.size() + 1];
00466 strcpy (cstr, cbc_option.c_str());
00467 cbc_argv[ num_cbc_argv - 1] = cstr;
00468
00469 }
00470
00471
00472
00473
00474 #ifdef COIN_HAS_SYMPHONY
00475 if(optionsVector.size() > 0) optionsVector.clear();
00476
00477
00478 if( sSolverName.find( "symphony") != std::string::npos) {
00479 OsiSymSolverInterface * si =
00480 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00481 optionsVector = osoption->getSolverOptions( "symphony");
00482 int num_sym_options = optionsVector.size();
00483 for(i = 0; i < num_sym_options; i++){
00484 #ifdef DEBUG
00485 std::cout << "symphony solver option " << optionsVector[ i]->name << std::endl;
00486 std::cout << "symphony solver value " << optionsVector[ i]->value << std::endl;
00487 #endif
00488 si->setSymParam(optionsVector[ i]->name, optionsVector[ i]->value);
00489 }
00490 }
00491 #endif //symphony end
00492
00493
00494 int n,m,k;
00495 if (osoption != NULL)
00496 m = osoption->getNumberOfInitVarValues();
00497 else
00498 m = 0;
00499 #ifdef DEBUG
00500 cout << "number of variables initialed: " << m << endl;
00501 #endif
00502
00503 if (m > 0)
00504 {
00505 #ifdef DEBUG
00506 cout << "get initial values " << endl;
00507 #endif
00508 n = osinstance->getVariableNumber();
00509 double* denseInitVarVector;
00510 denseInitVarVector = new double[n];
00511 bool* initialed;
00512 initialed = new bool[n];
00513
00514 for(k = 0; k < n; k++)
00515 initialed[k] = false;
00516
00517 InitVarValue** initVarVector = osoption->getInitVarValuesSparse();
00518 #ifdef DEBUG
00519 cout << "done " << endl;
00520 #endif
00521
00522 double initval;
00523 for(k = 0; k < m; k++){
00524 i = initVarVector[k]->idx;
00525 if (initVarVector[k]->idx > n)
00526 throw ErrorClass ("Illegal index value in variable initialization");
00527
00528 initval = initVarVector[k]->value;
00529 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00530 { if (osinstance->instanceData->variables->var[k]->lb > initval)
00531 throw ErrorClass ("Initial value outside of bounds");
00532 }
00533 else
00534 if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00535 { if (osinstance->instanceData->variables->var[k]->ub < initval)
00536 throw ErrorClass ("Initial value outside of bounds");
00537 }
00538 else
00539 { if ((osinstance->instanceData->variables->var[k]->lb > initval) ||
00540 (osinstance->instanceData->variables->var[k]->ub < initval))
00541 throw ErrorClass ("Initial value outside of bounds");
00542 }
00543
00544 denseInitVarVector[initVarVector[k]->idx] = initval;
00545 initialed[initVarVector[k]->idx] = true;
00546 }
00547
00548 double default_initval;
00549 default_initval = 0.0;
00550
00551 for(k = 0; k < n; k++){
00552 if (!initialed[k])
00553 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00554 if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
00555 denseInitVarVector[k] = default_initval;
00556 else
00557 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00558 else
00559 if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00560 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
00561 denseInitVarVector[k] = default_initval;
00562 else
00563 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00564 else
00565 if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
00566 (osinstance->instanceData->variables->var[k]->ub >= default_initval))
00567 denseInitVarVector[k] = default_initval;
00568 else
00569 if (osinstance->instanceData->variables->var[k]->lb > default_initval)
00570 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00571 else
00572 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00573 denseInitVarVector[k] = default_initval;
00574 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00575 }
00576 #ifdef DEBUG
00577 cout << "set initial values: " << endl;
00578 for (k=0; k < n; k++)
00579 cout << " " << k << ": " << denseInitVarVector[k] << endl;
00580 #endif
00581 osiSolver->setColSolution( denseInitVarVector);
00582 delete[] denseInitVarVector;
00583 delete[] initialed;
00584 #ifdef DEBUG
00585 cout << "done " << endl;
00586 #endif
00587
00588 }
00589 }
00590
00591 #ifdef DEBUG
00592 std::cout << "solver options set" << std::endl;
00593 #endif
00594 }
00595 catch(const ErrorClass& eclass){
00596 std::cout << "THERE IS AN ERROR" << std::endl;
00597 osresult = new OSResult();
00598 osresult->setGeneralMessage( eclass.errormsg);
00599 osresult->setGeneralStatusType( "error");
00600 osrl = osrlwriter->writeOSrL( osresult);
00601 throw ErrorClass( osrl) ;
00602 }
00603 }
00604
00605
00606 bool CoinSolver::setCoinPackedMatrix(){
00607 bool columnMajor = osinstance->getLinearConstraintCoefficientMajor();
00608 try{
00609 double maxGap = 0;
00610 if(osinstance->getVariableNumber() > 0){
00611 m_CoinPackedMatrix = new CoinPackedMatrix(
00612 columnMajor,
00613 columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(),
00614 columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(),
00615 osinstance->getLinearConstraintCoefficientNumber(),
00616 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->values : osinstance->getLinearConstraintCoefficientsInRowMajor()->values,
00617 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes : osinstance->getLinearConstraintCoefficientsInRowMajor()->indexes,
00618 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts : osinstance->getLinearConstraintCoefficientsInRowMajor()->starts,
00619 0, 0, maxGap );
00620 }else {
00621 int start = 0;
00622 m_CoinPackedMatrix = new CoinPackedMatrix(
00623 columnMajor,
00624 columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(),
00625 columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(),
00626 osinstance->getLinearConstraintCoefficientNumber(),
00627 NULL,
00628 NULL,
00629 &start,
00630 NULL, 0.0, maxGap );
00631 }
00632
00633
00634 return true;
00635 }
00636 catch(const ErrorClass& eclass){
00637 osresult = new OSResult();
00638 osresult->setGeneralMessage( eclass.errormsg);
00639 osresult->setGeneralStatusType( "error");
00640 osrl = osrlwriter->writeOSrL( osresult);
00641 throw ErrorClass( osrl) ;
00642 }
00643 }
00644
00645 void CoinSolver::solve() throw (ErrorClass) {
00646 if(osresult != NULL) delete osresult;
00647 osresult = new OSResult();
00648 try{
00649
00650 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00651
00652 if( this->bSetSolverOptions == false) setSolverOptions();
00653 }
00654 catch(const ErrorClass& eclass){
00655 throw ErrorClass( osrl) ;
00656 }
00657
00658
00659 if(osresult->setSolverInvoked("COIN-OR " + sSolverName) != true)
00660 throw ErrorClass("OSResult error: SetSolverInvoked");
00661 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00662 throw ErrorClass("OSResult error: setInstanceName");
00663
00664
00665
00666
00667
00668
00669 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00670 throw ErrorClass("OSResult error: setVariableNumer");
00671 if(osresult->setObjectiveNumber( 1) != true)
00672 throw ErrorClass("OSResult error: setObjectiveNumber");
00673 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00674 throw ErrorClass("OSResult error: setConstraintNumber");
00675 if(osresult->setSolutionNumber( 1) != true)
00676 throw ErrorClass("OSResult error: setSolutionNumer");
00677
00678
00679 try{
00680 double start = CoinCpuTime();
00681 try{
00682 if( sSolverName.find( "cbc") != std::string::npos){
00683
00684
00685 CbcModel model( *osiSolver);
00686
00687
00688
00689
00690
00691
00692
00693 CbcMain0( model);
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 if(num_cbc_argv <= 0){
00713 char *cstr;
00714 std::string cbc_option;
00715 num_cbc_argv = 4;
00716 cbc_argv = new const char*[ num_cbc_argv];
00717
00718
00719 cbc_option = "OS";
00720 cstr = new char [cbc_option.size() + 1];
00721 strcpy (cstr, cbc_option.c_str());
00722 cbc_argv[ 0] = cstr;
00723
00724
00725
00726 cbc_option = "-log=0";
00727 cstr = new char [cbc_option.size() + 1];
00728 strcpy (cstr, cbc_option.c_str());
00729 cbc_argv[ 1] = cstr;
00730
00731
00732
00733 cbc_option = "-solve";
00734 cstr = new char [cbc_option.size() + 1];
00735 strcpy (cstr, cbc_option.c_str());
00736 cbc_argv[ 2] = cstr;
00737
00738
00739 cbc_option = "-quit";
00740 cstr = new char [cbc_option.size() + 1];
00741 strcpy (cstr, cbc_option.c_str());
00742 cbc_argv[ 3] = cstr;
00743
00744 }
00745 int i;
00746
00747 #ifdef DEBUG
00748 std::cout << "CALLING THE CBC SOLVER CBCMAIN1()" << std::endl;
00749 for(i = 0; i < num_cbc_argv; i++){
00750 std::cout << "Cbc Option: " << cbc_argv[ i] << std::endl;
00751 }
00752 #endif
00753
00754 CbcMain1( num_cbc_argv, cbc_argv, model);
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773 for(i = 0; i < num_cbc_argv; i++){
00774 delete[] cbc_argv[ i];
00775 cbc_argv[i] = NULL;
00776 }
00777 if( num_cbc_argv > 0){
00778 delete[] cbc_argv;
00779 cbc_argv = NULL;
00780 num_cbc_argv = 0;
00781 }
00782
00783
00784
00785 cpuTime = CoinCpuTime() - start;
00786
00787
00788 OsiSolverInterface *solver = model.solver();
00789 if(osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00790 writeResult( &model);
00791 }else{
00792 writeResult( solver);
00793 }
00794 }
00795 else{
00796
00797 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00798 osiSolver->branchAndBound();
00799 }
00800 else{
00801 osiSolver->initialSolve();
00802 }
00803 cpuTime = CoinCpuTime() - start;
00804
00805 writeResult( osiSolver);
00806 }
00807
00808
00809 }
00810 catch(CoinError e){
00811 std::string errmsg;
00812 errmsg = "Coin Solver Error: " + e.message() + "\n" + " see method "
00813 + e.methodName() + " in class " + e.className();
00814 throw ErrorClass( errmsg );
00815 }
00816
00817 }
00818 catch(const ErrorClass& eclass){
00819 osresult->setGeneralMessage( eclass.errormsg);
00820 osresult->setGeneralStatusType( "error");
00821 osrl = osrlwriter->writeOSrL( osresult);
00822 throw ErrorClass( osrl) ;
00823 }
00824 }
00825
00826 std::string CoinSolver::getCoinSolverType(std::string lcl_osol){
00827
00828 try{
00829 if( lcl_osol.find( "clp") != std::string::npos){
00830 return "coin_solver_glpk";
00831 }
00832 else{
00833 if( lcl_osol.find( "cbc") != std::string::npos){
00834 return "coin_solver_cpx";
00835 }
00836 else{
00837 if( lcl_osol.find( "cpx") != std::string::npos){
00838 return "coin_solver_clp";
00839 }
00840 else{
00841 if(lcl_osol.find( "glpk") != std::string::npos){
00842 return "";
00843 }
00844 else throw ErrorClass("a supported solver was not defined");
00845 }
00846 }
00847 }
00848 }
00849 catch(const ErrorClass& eclass){
00850 osresult->setGeneralMessage( eclass.errormsg);
00851 osresult->setGeneralStatusType( "error");
00852 osrl = osrlwriter->writeOSrL( osresult);
00853 throw ErrorClass( osrl) ;
00854 }
00855 }
00856
00857 void CoinSolver::dataEchoCheck(){
00858 int i;
00859
00860 cout << "This is problem: " << osinstance->getInstanceName() << endl;
00861 cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
00862 cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
00863 cout << "number of variables = " << osinstance->getVariableNumber() << endl;
00864 cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
00865
00866
00867 if(osinstance->getVariableNumber() > 0){
00868 for(i = 0; i < osinstance->getVariableNumber(); i++){
00869 if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
00870 if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
00871 if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
00872 if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
00873 }
00874 }
00875
00876
00877 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0){
00878 if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
00879 else cout << "problem is a maximization" << endl;
00880 for(i = 0; i < osinstance->getVariableNumber(); i++){
00881 cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
00882 }
00883 }
00884
00885 if(osinstance->getConstraintNumber() > 0){
00886 for(i = 0; i < osinstance->getConstraintNumber(); i++){
00887 if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
00888 if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
00889 if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
00890 }
00891 }
00892
00893
00894 if(m_CoinPackedMatrix != NULL) m_CoinPackedMatrix->dumpMatrix();
00895 }
00896
00897
00898
00899 void CoinSolver::writeResult(OsiSolverInterface *solver){
00900 double *x = NULL;
00901 double *y = NULL;
00902 double *z = NULL;
00903 int *idx = NULL;
00904 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
00905 std::string *rcost = NULL;
00906 if( osinstance->getVariableNumber() > 0 ) x = new double[osinstance->getVariableNumber() ];
00907 if( osinstance->getConstraintNumber() > 0 ) y = new double[osinstance->getConstraintNumber() ];
00908 if( osinstance->getVariableNumber() > 0 ) idx = new int[ osinstance->getVariableNumber() ];
00909 z = new double[1];
00910 if( osinstance->getVariableNumber() > 0 ) rcost = new std::string[ osinstance->getVariableNumber()];
00911 int numberOfVar = osinstance->getVariableNumber();
00912 int solIdx = 0;
00913 int i = 0;
00914 int numberOfOtherVariableResults = 1;
00915 int otherIdx = 0;
00916 std::string description = "";
00917 osresult->setGeneralStatusType("normal");
00918 osresult->setTime(cpuTime);
00919 osresult->setServiceName( getVersionInfo() );
00920 osresult->setSolverInvoked( "COIN-OR " + sSolverName );
00921 if (solver->isProvenOptimal() == true){
00922 osresult->setSolutionStatus(solIdx, "optimal", description);
00923 }
00924 else{
00925 if(solver->isProvenPrimalInfeasible() == true)
00926 osresult->setSolutionStatus(solIdx, "infeasible", "the problem is primal infeasible");
00927 else{
00928 if(solver->isProvenDualInfeasible() == true)
00929 osresult->setSolutionStatus(solIdx, "unbounded", "the problem is unbounded");
00930 else{
00931 if(solver->isPrimalObjectiveLimitReached() == true)
00932 osresult->setSolutionStatus(solIdx, "other", "primal objective limit reached");
00933 else{
00934 if(solver->isDualObjectiveLimitReached() == true)
00935 osresult->setSolutionStatus(solIdx, "other", "dual objective limit reached");
00936 else{
00937 if(solver->isIterationLimitReached() == true)
00938 osresult->setSolutionStatus(solIdx, "other", "iteration limit reached");
00939 else{
00940 if(solver->isAbandoned() == true)
00941 osresult->setSolutionStatus(solIdx, "other", "there are numerical difficulties");
00942 if( osinstance->getVariableNumber() == 0) osresult->setSolutionMessage(solIdx, "Warning: this problem has zero decision variables!");
00943 else
00944 osresult->setSolutionStatus(solIdx, "other", description);
00945 }
00946 }
00947 }
00948 }
00949 }
00950 }
00951
00952
00953
00954 *(z + 0) = solver->getObjValue();
00955
00956 osresult->setObjectiveValuesDense(solIdx, z);
00957 for(i=0; i < osinstance->getVariableNumber(); i++){
00958 *(x + i) = solver->getColSolution()[i];
00959 *(idx + i) = i;
00960 }
00961 osresult->setPrimalVariableValuesDense(solIdx, x);
00962
00963 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0) {
00964 assert(solver->getNumRows() >= osinstance->getConstraintNumber());
00965 assert(solver->getRowPrice() != NULL);
00966 for(i=0; i < osinstance->getConstraintNumber(); i++){
00967 *(y + i) = solver->getRowPrice()[ i];
00968 }
00969 if(numOfIntVars <= 0) osresult->setDualVariableValuesDense(solIdx, y);
00970 }
00971
00972
00973 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0){
00974
00975 if(numOfIntVars <= 0){
00976 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
00977 for(i=0; i < numberOfVar; i++){
00978 rcost[ i] = os_dtoa_format( solver->getReducedCost()[ i]);
00979 }
00980 osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", idx, rcost, osinstance->getVariableNumber());
00981
00982 }
00983 }
00984 osrl = osrlwriter->writeOSrL( osresult);
00985 if(osinstance->getVariableNumber() > 0) delete[] x;
00986 x = NULL;
00987 if(osinstance->getConstraintNumber() > 0) delete[] y;
00988 y = NULL;
00989 delete[] z;
00990 z = NULL;
00991 if(osinstance->getVariableNumber() > 0){
00992 delete[] rcost;
00993 rcost = NULL;
00994 delete[] idx;
00995 idx = NULL;
00996 }
00997 }
00998
00999
01000 void CoinSolver::writeResult(CbcModel *model){
01001 double *x = NULL;
01002 double *y = NULL;
01003 double *z = NULL;
01004 int *idx = NULL;
01005 std::string *rcost = NULL;
01006 if( osinstance->getVariableNumber() > 0 ) x = new double[osinstance->getVariableNumber() ];
01007 if( osinstance->getConstraintNumber() > 0 ) y = new double[osinstance->getConstraintNumber() ];
01008 if( osinstance->getVariableNumber() > 0 ) idx = new int[ osinstance->getVariableNumber() ];
01009 z = new double[1];
01010 if( osinstance->getVariableNumber() > 0 ) rcost = new std::string[ osinstance->getVariableNumber()];
01011
01012 int numberOfOtherVariableResults = 1;
01013 int otherIdx = 0;
01014 int numberOfVar = osinstance->getVariableNumber();
01015 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
01016 int i = 0;
01017 int solIdx = 0;
01018 std::string description = "";
01019 osresult->setGeneralStatusType("normal");
01020 osresult->setTime(cpuTime);
01021 osresult->setServiceName( getVersionInfo() );
01022
01023 if (model->isProvenOptimal() == true ){
01024 osresult->setSolutionStatus(solIdx, "optimal", description);
01025 }
01026 else{
01027 if(model->isProvenInfeasible() == true)
01028 osresult->setSolutionStatus(solIdx, "infeasible", "the integer program is infeasible");
01029 else{
01030 if(model->isProvenDualInfeasible() == true)
01031 osresult->setSolutionStatus(solIdx, "infeasible", "the continuous relaxation is dual infeasible");
01032 else{
01033 if(model->isContinuousUnbounded() == true)
01034 osresult->setSolutionStatus(solIdx, "other", "the continuous relaxation is unbounded");
01035 else{
01036 if(model->isNodeLimitReached() == true)
01037 osresult->setSolutionStatus(solIdx, "other", "node limit reached");
01038 else{
01039 if(model->isSecondsLimitReached() == true)
01040 osresult->setSolutionStatus(solIdx, "other", "time limit reached");
01041 else{
01042 if(model->isSolutionLimitReached() == true)
01043 osresult->setSolutionStatus(solIdx, "other", "solution limit reached");
01044 else{
01045 if(model->isAbandoned() == true)
01046 osresult->setSolutionStatus(solIdx, "other", "there are numerical difficulties");
01047 else
01048 osresult->setSolutionStatus(solIdx, "other","unknown");
01049 }
01050 }
01051 }
01052 }
01053 }
01054 }
01055 }
01056
01057
01058 if(numOfIntVars > 0) *(z + 0) = model->getObjValue();
01059 osresult->setObjectiveValuesDense(solIdx, z);
01060 for(i=0; i < osinstance->getVariableNumber(); i++){
01061 *(x + i) = model->getColSolution()[i];
01062 *(idx + i) = i;
01063 }
01064 osresult->setPrimalVariableValuesDense(solIdx, x);
01065 for(i=0; i < osinstance->getConstraintNumber(); i++){
01066 *(y + i) = model->getRowPrice()[ i];
01067 }
01068 if(numOfIntVars <= 0) osresult->setDualVariableValuesDense(solIdx, y);
01069
01070
01071 if(numOfIntVars <= 0){
01072 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
01073 for(i=0; i < numberOfVar; i++){
01074 rcost[ i] = os_dtoa_format( model->getReducedCost()[ i]);
01075 }
01076 osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", idx, rcost, osinstance->getVariableNumber());
01077 }
01078
01079 osrl = osrlwriter->writeOSrL( osresult);
01080
01081 if(osinstance->getVariableNumber() > 0) delete[] x;
01082 x = NULL;
01083 if(osinstance->getConstraintNumber() > 0) delete[] y;
01084 y = NULL;
01085 delete[] z;
01086 z = NULL;
01087 if(osinstance->getVariableNumber() > 0){
01088 delete[] rcost;
01089 rcost = NULL;
01090 delete[] idx;
01091 idx = NULL;
01092 }
01093 }
01094
01095