00001
00019 #include "OSCoinSolver.h"
00020 #include "OSInstance.h"
00021 #include "OSFileUtil.h"
00022 #include "OSOutput.h"
00023 #include "CoinTime.hpp"
00024 #include "CglPreProcess.hpp"
00025 #include "CglGomory.hpp"
00026 #include "CglSimpleRounding.hpp"
00027 #include "CglMixedIntegerRounding2.hpp"
00028 #include "CglKnapsackCover.hpp"
00029 #include "CglFlowCover.hpp"
00030 #include "CbcBranchActual.hpp"
00031 #include "CoinMessageHandler.hpp"
00032 #include "CoinMessage.hpp"
00033
00034 #include "OsiClpSolverInterface.hpp"
00035 #include "CoinWarmStartBasis.hpp"
00036
00037 #ifdef COIN_HAS_SYMPHONY
00038 #include "OsiSymSolverInterface.hpp"
00039 #endif
00040
00041 #ifdef COIN_HAS_VOL
00042 #include "OsiVolSolverInterface.hpp"
00043 #endif
00044
00045 #ifdef COIN_HAS_DYLP
00046 #include "OsiDylpSolverInterface.hpp"
00047 #endif
00048
00049 #ifdef COIN_HAS_GLPK
00050 #include "OsiGlpkSolverInterface.hpp"
00051 #endif
00052
00053 #ifdef COIN_HAS_CPX
00054 #include "OsiCpxSolverInterface.hpp"
00055 #endif
00056
00057 #include "OSGeneral.h"
00058 #include "OSParameters.h"
00059 #include "OSMathUtil.h"
00060
00061 #include <map>
00062
00063 #include <iostream>
00064 #ifdef HAVE_CTIME
00065 # include <ctime>
00066 #else
00067 # ifdef HAVE_TIME_H
00068 # include <time.h>
00069 # else
00070 # error "don't have header file for time"
00071 # endif
00072 #endif
00073
00074 using std::cout;
00075 using std::endl;
00076 using std::ostringstream;
00077
00078
00079
00080 CoinSolver::CoinSolver() :
00081 osiSolver(NULL),
00082 m_osilreader(NULL),
00083 m_osolreader(NULL),
00084 m_CoinPackedMatrix(NULL),
00085 cbc_argv( NULL),
00086 num_cbc_argv( 0),
00087 cpuTime( 0)
00088
00089 {
00090 osrlwriter = new OSrLWriter();
00091 }
00092
00093 CoinSolver::~CoinSolver()
00094 {
00095 #ifndef NDEBUG
00096 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "inside CoinSolver destructor\n");
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 {
00112 int i;
00113 for(i = 0; i < num_cbc_argv; i++)
00114 {
00115
00116 }
00117
00118 cbc_argv = NULL;
00119 }
00120 #ifndef NDEBUG
00121 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace, "Leaving CoinSolver destructor\n");
00122 #endif
00123 }
00124
00125
00126 void CoinSolver::buildSolverInstance() throw (ErrorClass)
00127 {
00128 try
00129 {
00130
00131 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
00132 clock_t start, finish;
00133 double duration;
00134 start = clock();
00135 if(osinstance == NULL)
00136 {
00137 m_osilreader = new OSiLReader();
00138 osinstance = m_osilreader->readOSiL( osil);
00139 }
00140 finish = clock();
00141 duration = (double) (finish - start) / CLOCKS_PER_SEC;
00142
00143
00144 if (osinstance->getObjectiveNumber() > 1)
00145 throw ErrorClass("Solver cannot handle multiple objectives --- please delete all but one");
00146
00147
00148 if (sSolverName == "clp")
00149 osiSolver = new OsiClpSolverInterface();
00150
00151 else if (sSolverName == "cbc")
00152 osiSolver = new OsiClpSolverInterface();
00153
00154 else if (sSolverName == "vol")
00155 #ifdef COIN_HAS_VOL
00156 osiSolver = new OsiVolSolverInterface();
00157 #else
00158 throw ErrorClass("This OSSolverService was built without solver vol");
00159 #endif
00160
00161 else if (sSolverName == "cplex")
00162 #ifdef COIN_HAS_CPX
00163 osiSolver = new OsiCpxSolverInterface();
00164 #else
00165 throw ErrorClass("This OSSolverService was built without solver cplex");
00166 #endif
00167
00168 else if (sSolverName == "glpk")
00169 #ifdef COIN_HAS_GLPK
00170 osiSolver = new OsiGlpkSolverInterface();
00171 #else
00172 throw ErrorClass("This OSSolverService was built without solver glpk");
00173 #endif
00174
00175 else if (sSolverName == "dylp")
00176 #ifdef COIN_HAS_DYLP
00177 osiSolver = new OsiDylpSolverInterface();
00178 #else
00179 throw ErrorClass("This OSSolverService was built without solver dylp");
00180 #endif
00181
00182 else if (sSolverName == "symphony")
00183 #ifdef COIN_HAS_SYMPHONY
00184 osiSolver = new OsiSymSolverInterface();
00185 #else
00186 throw ErrorClass("This OSSolverService was built without solver symphony");
00187 #endif
00188
00189 else if (sSolverName == "")
00190 {
00191
00192 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0 ||
00193 sSolverName.find( "cbc") != std::string::npos ) sSolverName = "cbc";
00194 else sSolverName = "clp";
00195 osiSolver = new OsiClpSolverInterface();
00196 }
00197 else
00198 throw ErrorClass("Solver selected is not supported by this version of OSSolverService");
00199
00200
00201 if( (osinstance->getNumberOfNonlinearExpressions() > 0)
00202 || (osinstance->getNumberOfQuadraticTerms() > 0) )
00203 {
00204 throw ErrorClass( "This COIN-OR Solver is not configured for nonlinear programming");
00205 }
00206
00207 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00208 {
00209 if( sSolverName.find("clp") != std::string::npos) throw ErrorClass( "Clp cannot do integer programming");
00210 if( sSolverName.find("vol") != std::string::npos) throw ErrorClass( "Vol cannot do integer programming");
00211 if( sSolverName.find("dylp") != std::string::npos) throw ErrorClass( "DyLP cannot do integer programming");
00212
00213 }
00214
00215 if( osinstance->getNumberOfSemiIntegerVariables() + osinstance->getNumberOfSemiContinuousVariables() > 0)
00216 {
00217 throw ErrorClass( "Semi-integer and semi-continuous variables not supported");
00218
00219
00220
00221
00222 }
00223
00224
00225
00226 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Coin solver: " + sSolverName + " needs an objective function");
00227 if(osinstance->getNumberOfStringVariables() > 0) throw ErrorClass("Coin solver: " + sSolverName + " can only handle numeric variables");
00228 if(osinstance->getLinearConstraintCoefficientNumber() <= 0 && sSolverName == "symphony") throw ErrorClass("Coin solver: " + sSolverName + " needs a positive number of constraints");
00229
00230 if(!setCoinPackedMatrix() ) throw ErrorClass("Problem generating coin packed matrix");
00231 osiSolver->loadProblem(*m_CoinPackedMatrix, osinstance->getVariableLowerBounds(),
00232 osinstance->getVariableUpperBounds(),
00233 osinstance->getDenseObjectiveCoefficients()[0],
00234 osinstance->getConstraintLowerBounds(), osinstance->getConstraintUpperBounds()
00235 );
00236 #ifndef NDEBUG
00237
00238 #endif
00239 if( osinstance->getObjectiveMaxOrMins()[0] == "min") osiSolver->setObjSense(1.0);
00240 else osiSolver->setObjSense(-1.0);
00241
00242 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
00243 if(numOfIntVars > 0)
00244 {
00245 int *intIndex = NULL;
00246 int i = 0;
00247 int k = 0;
00248 char *varType;
00249 intIndex = new int[ numOfIntVars];
00250 varType = osinstance->getVariableTypes();
00251 for(i = 0; i < osinstance->getVariableNumber(); i++)
00252 {
00253 if( (varType[i] == 'B') || (varType[i]) == 'I' )
00254 {
00255 intIndex[k++] = i;
00256 }
00257 }
00258 osiSolver->setInteger( intIndex, numOfIntVars);
00259
00260 delete[] intIndex;
00261 intIndex = NULL;
00262 }
00263 bCallbuildSolverInstance = true;
00264 }
00265 catch(const ErrorClass& eclass)
00266 {
00267 osresult = new OSResult();
00268 osresult->setGeneralMessage( eclass.errormsg);
00269 osresult->setGeneralStatusType( "error");
00270 osrl = osrlwriter->writeOSrL( osresult);
00271 throw ErrorClass( osrl) ;
00272 }
00273 }
00274
00275
00276
00277 void CoinSolver::setSolverOptions() throw (ErrorClass)
00278 {
00279 std::ostringstream outStr;
00280
00281 #ifndef NDEBUG
00282 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "build solver options\n");
00283 #endif
00284 this->bSetSolverOptions = true;
00285
00286
00287 std::map<std::string, OsiHintParam> hintParamMap;
00288 hintParamMap["OsiDoPresolveInInitial"] = OsiDoPresolveInInitial;
00289 hintParamMap["OsiDoDualInInitial"] = OsiDoDualInInitial;
00290 hintParamMap["OsiDoPresolveInResolve"] = OsiDoPresolveInResolve;
00291 hintParamMap["OsiDoDualInResolve"] = OsiDoDualInResolve;
00292 hintParamMap["OsiDoScale"] = OsiDoScale;
00293 hintParamMap["OsiDoCrash"] = OsiDoCrash;
00294 hintParamMap["OsiDoReducePrint"] = OsiDoReducePrint;
00295 hintParamMap["OsiDoInBranchAndCut"] = OsiDoInBranchAndCut;
00296 hintParamMap["OsiLastHintParam"] = OsiLastHintParam;
00297
00298
00299 std::map<std::string, OsiHintStrength> hintStrengthMap;
00300 hintStrengthMap["OsiHintIgnore"] = OsiHintIgnore;
00301 hintStrengthMap["OsiHintTry"] = OsiHintTry;
00302 hintStrengthMap["OsiHintDo"] = OsiHintDo;
00303 hintStrengthMap["OsiForceDo"] = OsiForceDo;
00304
00305
00306 std::map<std::string, OsiStrParam> strParamMap;
00307 strParamMap["OsiProbName"] = OsiProbName;
00308 strParamMap["OsiSolverName"] = OsiSolverName;
00309 strParamMap["OsiLastStrParam"] = OsiLastStrParam;
00310
00311
00312 std::map<std::string, OsiDblParam> dblParamMap;
00313 dblParamMap["OsiDualObjectiveLimit"] = OsiDualObjectiveLimit;
00314 dblParamMap["OsiPrimalObjectiveLimit"] = OsiPrimalObjectiveLimit;
00315 dblParamMap["OsiDualTolerance"] = OsiDualTolerance;
00316 dblParamMap["OsiPrimalTolerance"] = OsiPrimalTolerance;
00317 dblParamMap["OsiObjOffset"] = OsiObjOffset;
00318 dblParamMap["OsiLastDblParam"] = OsiLastDblParam;
00319
00320
00321
00322 std::map<std::string, OsiIntParam> intParamMap;
00323 intParamMap["OsiMaxNumIteration"] = OsiMaxNumIteration;
00324 intParamMap["OsiMaxNumIterationHotStart"] = OsiMaxNumIterationHotStart;
00325 intParamMap["OsiNameDiscipline"] = OsiNameDiscipline;
00326 intParamMap["OsiLastIntParam"] = OsiLastIntParam;
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 OsiHintStrength hintStrength = OsiHintTry;
00338 osiSolver->setHintParam(OsiDoReducePrint, true, hintStrength);
00339
00340
00341 osiSolver->setDblParam(OsiObjOffset, -osinstance->getObjectiveConstants()[0]);
00342
00343
00344
00345
00346 #ifdef COIN_HAS_SYMPHONY
00347 if( sSolverName.find( "symphony") != std::string::npos)
00348 {
00349 OsiSymSolverInterface * si =
00350 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00351
00352 si->setSymParam("verbosity", -2);
00353 }
00354 #endif //symphony end
00355
00356
00357
00358
00359
00360
00361 try
00362 {
00363 if(osoption == NULL && osol.length() > 0)
00364 {
00365 m_osolreader = new OSoLReader();
00366 osoption = m_osolreader->readOSoL( osol);
00367 }
00368
00369 if(osoption != NULL)
00370 {
00371 int i;
00372
00373 #ifndef NDEBUG
00374 outStr.str("");
00375 outStr.clear();
00376 outStr << "number of solver options " << osoption->getNumberOfSolverOptions() << std::endl;
00377 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
00378 #endif
00379 if( osoption->getNumberOfSolverOptions() > 0)
00380 {
00381
00382 std::vector<SolverOption*> optionsVector;
00383
00384
00385 optionsVector = osoption->getSolverOptions( "osi",true);
00386 int num_osi_options = optionsVector.size();
00387 char *pEnd;
00388 bool yesNo;
00389
00394 for(i = 0; i < num_osi_options; i++)
00395 {
00396 #ifndef NDEBUG
00397 outStr.str("");
00398 outStr.clear();
00399 outStr << "osi solver option " << optionsVector[ i]->name << std::endl;
00400 outStr << "osi solver value " << optionsVector[ i]->value << std::endl;
00401 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace, outStr.str());
00402 #endif
00403 if (optionsVector[ i]->type == "OsiHintStrength" )
00404 {
00405 if( hintStrengthMap.find( optionsVector[ i]->name ) != hintStrengthMap.end() )
00406 {
00407 hintStrength = hintStrengthMap[ optionsVector[ i]->name] ;
00408 }
00409 }
00410 }
00411
00415 for(i = 0; i < num_osi_options; i++)
00416 {
00417 #ifndef NDEBUG
00418 outStr.str("");
00419 outStr.clear();
00420 outStr << "osi solver option " << optionsVector[ i]->name << std::endl;
00421 outStr << "osi solver value " << optionsVector[ i]->value << std::endl;
00422 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace, outStr.str());
00423 #endif
00424 if (optionsVector[ i]->type == "OsiHintParam" )
00425 {
00426 if( optionsVector[ i]->value == "true" )
00427 {
00428 yesNo = true;
00429 }
00430 else
00431 {
00432 yesNo = false;
00433 }
00434 if( hintParamMap.find( optionsVector[ i]->name ) != hintParamMap.end() )
00435 {
00436 osiSolver->setHintParam( hintParamMap[ optionsVector[ i]->name] , yesNo, hintStrength);
00437 }
00438 }
00439 else if(optionsVector[ i]->type == "OsiStrParam" )
00440 {
00441 if( strParamMap.find( optionsVector[ i]->name ) != strParamMap.end() )
00442 {
00443 osiSolver->setStrParam( strParamMap[ optionsVector[ i]->name] , optionsVector[ i]->value);
00444 }
00445 }
00446 else if(optionsVector[ i]->type == "OsiDblParam" )
00447 {
00448 if( dblParamMap.find( optionsVector[ i]->name ) != dblParamMap.end() )
00449 {
00450 osiSolver->setDblParam( dblParamMap[ optionsVector[ i]->name] , os_strtod( optionsVector[ i]->value.c_str(), &pEnd ));
00451 }
00452
00453 }
00454 else if(optionsVector[ i]->type == "OsiIntParam" )
00455 {
00456 if( intParamMap.find( optionsVector[ i]->name ) != intParamMap.end() )
00457 {
00458 osiSolver->setIntParam( intParamMap[ optionsVector[ i]->name] , atoi( optionsVector[ i]->value.c_str() ) );
00459 }
00460 }
00461 else if (optionsVector[ i]->type == "bool" )
00462 {
00463 if( optionsVector[ i]->name == "primalSimplex" )
00464 {
00465 if (optionsVector[ i]->value != "false")
00466 osiSolver->enableSimplexInterface((optionsVector[ i]->value != "false"));
00467 }
00468 }
00469 }
00470
00471
00472
00473 if( sSolverName.find( "cbc") != std::string::npos)
00474 {
00475
00476 if(optionsVector.size() > 0) optionsVector.clear();
00477 optionsVector = osoption->getSolverOptions( "cbc",true);
00478
00479 int num_cbc_options = optionsVector.size();
00480 char *cstr;
00481 std::string cbc_option;
00482 num_cbc_argv = optionsVector.size() + 3;
00483 cbc_argv = new const char*[ num_cbc_argv];
00484
00485
00486 cbc_option = "OS";
00487 cstr = new char [cbc_option.size() + 1];
00488 strcpy (cstr, cbc_option.c_str());
00489 cbc_argv[ 0] = cstr;
00490
00491 for(i = 0; i < num_cbc_options; i++)
00492 {
00493 #ifndef NDEBUG
00494 outStr.str("");
00495 outStr.clear();
00496 outStr << "cbc solver option " << optionsVector[ i]->name << std::endl;
00497 outStr << "cbc solver value " << optionsVector[ i]->name << std::endl;
00498 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
00499 #endif
00500
00501 if(optionsVector[ i]->value.length() > 0 )
00502 {
00503 cbc_option = "-" + optionsVector[ i]->name +"="+optionsVector[ i]->value;
00504 }
00505 else
00506 {
00507 cbc_option = "-" + optionsVector[ i]->name ;
00508 }
00509 cstr = new char [cbc_option.size() + 1];
00510 strcpy (cstr, cbc_option.c_str());
00511 cbc_argv[i + 1] = cstr;
00512 }
00513
00514
00515 cbc_option = "-solve";
00516 cstr = new char [cbc_option.size() + 1];
00517 strcpy (cstr, cbc_option.c_str());
00518 cbc_argv[ num_cbc_argv - 2] = cstr;
00519
00520
00521 cbc_option = "-quit";
00522 cstr = new char [cbc_option.size() + 1];
00523 strcpy (cstr, cbc_option.c_str());
00524 cbc_argv[ num_cbc_argv - 1] = cstr;
00525
00526 }
00527
00528
00529
00530
00531 #ifdef COIN_HAS_SYMPHONY
00532 if(optionsVector.size() > 0) optionsVector.clear();
00533
00534
00535 if( sSolverName.find( "symphony") != std::string::npos)
00536 {
00537 OsiSymSolverInterface * si =
00538 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00539 optionsVector = osoption->getSolverOptions( "symphony",true);
00540 int num_sym_options = optionsVector.size();
00541 for(i = 0; i < num_sym_options; i++)
00542 {
00543 #ifndef NDEBUG
00544 outStr.str("");
00545 outStr.clear();
00546 outStr << "symphony solver option " << optionsVector[ i]->name << std::endl;
00547 outStr << "symphony solver value " << optionsVector[ i]->name << std::endl;
00548 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
00549 #endif
00550 si->setSymParam(optionsVector[ i]->name, optionsVector[ i]->value);
00551 }
00552 }
00553 #endif //symphony end
00554
00555 }
00556
00557 int n,m,k;
00558 if (osoption != NULL)
00559 m = osoption->getNumberOfInitVarValues();
00560 else
00561 m = 0;
00562 #ifndef NDEBUG
00563 outStr.str("");
00564 outStr.clear();
00565 outStr << "number of variables initialed: " << m << std::endl;
00566 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
00567 #endif
00568
00569 if (m > 0)
00570 {
00571 #ifndef NDEBUG
00572 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "get initial values\n");
00573 #endif
00574 n = osinstance->getVariableNumber();
00575 double* denseInitVarVector;
00576 denseInitVarVector = new double[n];
00577 bool* initialed;
00578 initialed = new bool[n];
00579
00580 for(k = 0; k < n; k++)
00581 initialed[k] = false;
00582
00583 InitVarValue** initVarVector = osoption->getInitVarValuesSparse();
00584 #ifndef NDEBUG
00585 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "done\n");
00586 #endif
00587
00588 double initval;
00589 for(k = 0; k < m; k++)
00590 {
00591 i = initVarVector[k]->idx;
00592 if (initVarVector[k]->idx >= n)
00593 throw ErrorClass ("Illegal index value in variable initialization");
00594
00595 initval = initVarVector[k]->value;
00596 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00597 {
00598 if (osinstance->instanceData->variables->var[k]->lb > initval)
00599 throw ErrorClass ("Initial value outside of bounds");
00600 }
00601 else if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00602 {
00603 if (osinstance->instanceData->variables->var[k]->ub < initval)
00604 throw ErrorClass ("Initial value outside of bounds");
00605 }
00606 else
00607 {
00608 if ((osinstance->instanceData->variables->var[k]->lb > initval) ||
00609 (osinstance->instanceData->variables->var[k]->ub < initval))
00610 throw ErrorClass ("Initial value outside of bounds");
00611 }
00612
00613 denseInitVarVector[initVarVector[k]->idx] = initval;
00614 initialed[initVarVector[k]->idx] = true;
00615 }
00616
00617 double default_initval;
00618 default_initval = 0.0;
00619
00620 for(k = 0; k < n; k++)
00621 {
00622 if (!initialed[k])
00623 {
00624 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00625 if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
00626 denseInitVarVector[k] = default_initval;
00627 else
00628 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00629 else if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00630 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
00631 denseInitVarVector[k] = default_initval;
00632 else
00633 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00634 else if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
00635 (osinstance->instanceData->variables->var[k]->ub >= default_initval))
00636 denseInitVarVector[k] = default_initval;
00637 else if (osinstance->instanceData->variables->var[k]->lb > default_initval)
00638 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00639 else
00640 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00641 }
00642
00643
00644 }
00645 #ifndef NDEBUG
00646 outStr.str("");
00647 outStr.clear();
00648 outStr << "set initial values: " << std::endl;
00649 for (k=0; k < n; k++)
00650 outStr << " " << k << ": " << denseInitVarVector[k] << std::endl;
00651 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
00652 #endif
00653 osiSolver->setColSolution( denseInitVarVector);
00654 delete[] denseInitVarVector;
00655 delete[] initialed;
00656 #ifndef NDEBUG
00657 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "done\n");
00658 #endif
00659
00660 }
00661
00662
00663
00664
00665 if (sSolverName == "clp" || sSolverName == "cbc")
00666 {
00667 if ( osoption != NULL &&
00668 osoption->optimization != NULL &&
00669 ((osoption->optimization->variables != NULL &&
00670 osoption->optimization->variables->initialBasisStatus != NULL) ||
00671 (osoption->optimization->constraints != NULL &&
00672 osoption->optimization->constraints->initialBasisStatus != NULL)) )
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 {
00686 int nsBas,naBas,nsUpp,naUpp,nsLow,naLow,nvar,ncon;
00687 int* tmpBas = NULL;
00688 CoinWarmStartBasis* warmstart = new CoinWarmStartBasis();
00689 nvar = osinstance->getVariableNumber();
00690 ncon = osinstance->getConstraintNumber();
00691 warmstart->setSize(nvar, ncon);
00692
00693
00694 if ( osoption->optimization->variables != NULL &&
00695 osoption->optimization->variables->initialBasisStatus != NULL )
00696 {
00697 nsBas = osoption->getNumberOfInitialBasisElements(ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_basic);
00698 nsUpp = osoption->getNumberOfInitialBasisElements(ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_atUpper);
00699 nsLow = osoption->getNumberOfInitialBasisElements(ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_atLower);
00700 }
00701 else
00702 {
00703 nsBas = 0;
00704 nsUpp = 0;
00705 nsLow = 0;
00706 }
00707 if ( osoption->optimization->constraints != NULL &&
00708 osoption->optimization->constraints->initialBasisStatus != NULL )
00709 {
00710 naBas = osoption->getNumberOfInitialBasisElements(ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_basic);
00711 naUpp = osoption->getNumberOfInitialBasisElements(ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_atUpper);
00712 naLow = osoption->getNumberOfInitialBasisElements(ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_atLower);
00713 }
00714 else
00715 {
00716 naBas = 0;
00717 naUpp = 0;
00718 naLow = 0;
00719 }
00720
00721
00722 if (nsBas > 0)
00723 {
00724 tmpBas = new int[nsBas];
00725 osoption->getInitialBasisElements(ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_basic,tmpBas);
00726 for (int i=0; i<nsBas; i++)
00727 warmstart->setStructStatus(tmpBas[i], (CoinWarmStartBasis::Status)0x01);
00728 delete [] tmpBas;
00729 }
00730 if (naBas > 0)
00731 {
00732 tmpBas = new int[naBas];
00733 osoption->getInitialBasisElements(ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_basic,tmpBas);
00734 for (int i=0; i<naBas; i++)
00735 warmstart->setArtifStatus(tmpBas[i], (CoinWarmStartBasis::Status)0x01);
00736 delete [] tmpBas;
00737 }
00738
00739 if (nsUpp > 0)
00740 {
00741 tmpBas = new int[nsUpp];
00742 osoption->getInitialBasisElements(ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_atUpper,tmpBas);
00743 for (int i=0; i<nsUpp; i++)
00744 warmstart->setStructStatus(tmpBas[i], (CoinWarmStartBasis::Status)0x02);
00745 delete [] tmpBas;
00746 }
00747 if (naUpp > 0)
00748 {
00749 tmpBas = new int[naUpp];
00750 osoption->getInitialBasisElements(ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_atUpper,tmpBas);
00751 for (int i=0; i<naUpp; i++)
00752 warmstart->setArtifStatus(tmpBas[i], (CoinWarmStartBasis::Status)0x02);
00753 delete [] tmpBas;
00754 }
00755
00756 if (nsLow > 0)
00757 {
00758 tmpBas = new int[nsLow];
00759 osoption->getInitialBasisElements(ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_atLower,tmpBas);
00760 for (int i=0; i<nsLow; i++)
00761 warmstart->setStructStatus(tmpBas[i], (CoinWarmStartBasis::Status)0x03);
00762 delete [] tmpBas;
00763 }
00764 if (naLow > 0)
00765 {
00766 tmpBas = new int[naLow];
00767 osoption->getInitialBasisElements(ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_atLower,tmpBas);
00768 for (int i=0; i<naLow; i++)
00769 warmstart->setArtifStatus(tmpBas[i], (CoinWarmStartBasis::Status)0x03);
00770 delete [] tmpBas;
00771 }
00772
00773 osiSolver->setWarmStart(warmstart);
00774
00775 }
00776 }
00777
00778 }
00779
00780 #ifndef NDEBUG
00781 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "solver options set\n");
00782 #endif
00783 }
00784
00785 catch(const ErrorClass& eclass)
00786 {
00787 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_error, "THERE IS AN ERROR\n");
00788 osresult = new OSResult();
00789 osresult->setGeneralMessage( eclass.errormsg);
00790 osresult->setGeneralStatusType( "error");
00791 osrl = osrlwriter->writeOSrL( osresult);
00792 throw ErrorClass( osrl) ;
00793 }
00794 }
00795
00796
00797 bool CoinSolver::setCoinPackedMatrix()
00798 {
00799 bool columnMajor = osinstance->getLinearConstraintCoefficientMajor();
00800 try
00801 {
00802 double maxGap = 0;
00803 if(osinstance->getLinearConstraintCoefficientNumber() > 0)
00804 {
00805 m_CoinPackedMatrix = new CoinPackedMatrix(
00806 columnMajor,
00807 columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(),
00808 columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(),
00809 osinstance->getLinearConstraintCoefficientNumber(),
00810 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->values : osinstance->getLinearConstraintCoefficientsInRowMajor()->values,
00811 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes : osinstance->getLinearConstraintCoefficientsInRowMajor()->indexes,
00812 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts : osinstance->getLinearConstraintCoefficientsInRowMajor()->starts,
00813 0, 0, maxGap );
00814 }
00815 else
00816 {
00817 int* start = new int[osinstance->getVariableNumber()+1];
00818 for (int i=0; i <= osinstance->getVariableNumber(); i++)
00819 start[i] = 0;
00820 m_CoinPackedMatrix = new CoinPackedMatrix(
00821 columnMajor,
00822 columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(),
00823 columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(),
00824 osinstance->getLinearConstraintCoefficientNumber(),
00825 NULL,
00826 NULL,
00827 start,
00828 NULL, 0.0, maxGap );
00829 }
00830
00831
00832 return true;
00833 }
00834 catch(const ErrorClass& eclass)
00835 {
00836 osresult = new OSResult();
00837 osresult->setGeneralMessage( eclass.errormsg);
00838 osresult->setGeneralStatusType( "error");
00839 osrl = osrlwriter->writeOSrL( osresult);
00840 throw ErrorClass( osrl) ;
00841 }
00842 }
00843
00844 void CoinSolver::solve() throw (ErrorClass)
00845 {
00846 std::ostringstream outStr;
00847 if(osresult != NULL) delete osresult;
00848 osresult = new OSResult();
00849 try
00850 {
00851
00852 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00853
00854 if( this->bSetSolverOptions == false) setSolverOptions();
00855 }
00856 catch(const ErrorClass& eclass)
00857 {
00858 throw ErrorClass( osrl) ;
00859 }
00860
00861
00862 if(osresult->setSolverInvoked("COIN-OR " + sSolverName) != true)
00863 throw ErrorClass("OSResult error: SetSolverInvoked");
00864 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00865 throw ErrorClass("OSResult error: setInstanceName");
00866
00867
00868
00869
00870
00871
00872 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00873 throw ErrorClass("OSResult error: setVariableNumer");
00874 if(osresult->setObjectiveNumber( 1) != true)
00875 throw ErrorClass("OSResult error: setObjectiveNumber");
00876 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00877 throw ErrorClass("OSResult error: setConstraintNumber");
00878 if(osresult->setSolutionNumber( 1) != true)
00879 throw ErrorClass("OSResult error: setSolutionNumer");
00880
00881
00882 try
00883 {
00884 double start = CoinCpuTime();
00885 try
00886 {
00887 if( sSolverName.find( "cbc") != std::string::npos)
00888 {
00889
00890
00891 CbcModel model( *osiSolver);
00892
00893
00894
00895
00896
00897
00898
00899 CbcMain0( model);
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 if(num_cbc_argv <= 0)
00919 {
00920 char *cstr;
00921 std::string cbc_option;
00922 num_cbc_argv = 4;
00923 cbc_argv = new const char*[ num_cbc_argv];
00924
00925
00926 cbc_option = "OS";
00927 cstr = new char [cbc_option.size() + 1];
00928 strcpy (cstr, cbc_option.c_str());
00929 cbc_argv[ 0] = cstr;
00930
00931
00932
00933 cbc_option = "-log=0";
00934 cstr = new char [cbc_option.size() + 1];
00935 strcpy (cstr, cbc_option.c_str());
00936 cbc_argv[ 1] = cstr;
00937
00938
00939
00940 cbc_option = "-solve";
00941 cstr = new char [cbc_option.size() + 1];
00942 strcpy (cstr, cbc_option.c_str());
00943 cbc_argv[ 2] = cstr;
00944
00945
00946 cbc_option = "-quit";
00947 cstr = new char [cbc_option.size() + 1];
00948 strcpy (cstr, cbc_option.c_str());
00949 cbc_argv[ 3] = cstr;
00950
00951 }
00952 int i;
00953
00954 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "CALLING THE CBC SOLVER CBCMAIN1()\n");
00955 #ifndef NDEBUG
00956 outStr.str("");
00957 outStr.clear();
00958 for(i = 0; i < num_cbc_argv; i++)
00959 {
00960 outStr << "Cbc Option: " << cbc_argv[ i] << std::endl;
00961 }
00962 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
00963 #endif
00964 CbcMain1( num_cbc_argv, cbc_argv, model);
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983 for(i = 0; i < num_cbc_argv; i++)
00984 {
00985 delete[] cbc_argv[ i];
00986 cbc_argv[i] = NULL;
00987 }
00988 if( num_cbc_argv > 0)
00989 {
00990 delete[] cbc_argv;
00991 cbc_argv = NULL;
00992 num_cbc_argv = 0;
00993 }
00994
00995
00996
00997 cpuTime = CoinCpuTime() - start;
00998
00999
01000 OsiSolverInterface *solver = model.solver();
01001 if(osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
01002 {
01003 writeResult( &model);
01004 }
01005 else
01006 {
01007 writeResult( solver);
01008 }
01009 }
01010 else
01011 {
01012
01013 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
01014 {
01015 osiSolver->branchAndBound();
01016 }
01017 else
01018 {
01019 osiSolver->initialSolve();
01020 }
01021 cpuTime = CoinCpuTime() - start;
01022
01023 writeResult( osiSolver);
01024 }
01025
01026
01027 }
01028 catch(CoinError e)
01029 {
01030 std::string errmsg;
01031 errmsg = "Coin Solver Error: " + e.message() + "\n" + " see method "
01032 + e.methodName() + " in class " + e.className();
01033 throw ErrorClass( errmsg );
01034 }
01035
01036 }
01037 catch(const ErrorClass& eclass)
01038 {
01039 std::string::size_type pos1 = eclass.errormsg.find( "<osrl");
01040 if(pos1 == std::string::npos)
01041 {
01042 osresult->setGeneralMessage(eclass.errormsg);
01043 osresult->setGeneralStatusType("error");
01044 osrl = osrlwriter->writeOSrL(osresult);
01045 }
01046 else
01047 {
01048 osrl = eclass.errormsg;
01049 }
01050
01051
01052
01053 throw ErrorClass( osrl);
01054 }
01055 }
01056
01057 std::string CoinSolver::getCoinSolverType(std::string lcl_osol)
01058 {
01059
01060 try
01061 {
01062 if( lcl_osol.find( "clp") != std::string::npos)
01063 {
01064 return "coin_solver_glpk";
01065 }
01066 else
01067 {
01068 if( lcl_osol.find( "cbc") != std::string::npos)
01069 {
01070 return "coin_solver_cpx";
01071 }
01072 else
01073 {
01074 if( lcl_osol.find( "cpx") != std::string::npos)
01075 {
01076 return "coin_solver_clp";
01077 }
01078 else
01079 {
01080 if(lcl_osol.find( "glpk") != std::string::npos)
01081 {
01082 return "";
01083 }
01084 else throw ErrorClass("a supported solver was not defined");
01085 }
01086 }
01087 }
01088 }
01089 catch(const ErrorClass& eclass)
01090 {
01091 osresult->setGeneralMessage( eclass.errormsg);
01092 osresult->setGeneralStatusType( "error");
01093 osrl = osrlwriter->writeOSrL( osresult);
01094 throw ErrorClass( osrl) ;
01095 }
01096 }
01097
01098 #ifndef NDEBUG
01099 void CoinSolver::dataEchoCheck()
01100 {
01101 int i;
01102
01103 cout << "This is problem: " << osinstance->getInstanceName() << endl;
01104 cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
01105 cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
01106 cout << "number of variables = " << osinstance->getVariableNumber() << endl;
01107 cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
01108
01109
01110 if(osinstance->getVariableNumber() > 0)
01111 {
01112 for(i = 0; i < osinstance->getVariableNumber(); i++)
01113 {
01114 if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
01115 if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
01116 if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
01117 if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
01118 }
01119 }
01120
01121
01122 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0)
01123 {
01124 if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
01125 else cout << "problem is a maximization" << endl;
01126 for(i = 0; i < osinstance->getVariableNumber(); i++)
01127 {
01128 cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
01129 }
01130 }
01131
01132 if(osinstance->getConstraintNumber() > 0)
01133 {
01134 for(i = 0; i < osinstance->getConstraintNumber(); i++)
01135 {
01136 if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
01137 if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
01138 if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
01139 }
01140 }
01141
01142
01143 if(m_CoinPackedMatrix != NULL) m_CoinPackedMatrix->dumpMatrix();
01144 }
01145 #endif
01146
01147
01148 void CoinSolver::writeResult(OsiSolverInterface *solver)
01149 {
01150
01151 double *x = NULL;
01152 double *y = NULL;
01153 double *z = NULL;
01154 int *cbasis = NULL;
01155 int *rbasis = NULL;
01156 int *idx = NULL;
01157 int kount;
01158
01159
01160
01161 std::vector<int> freeVars;
01162 std::vector<int> basicVars;
01163 std::vector<int> nonBasicLower;
01164 std::vector<int> nonBasicUpper;
01165 std::vector<int>::iterator vit;
01166 int **basisIdx;
01167 basisIdx = new int*[ 4];
01168
01169
01170 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
01171 std::string *rcost = NULL;
01172 if( solver->getNumCols() > 0 ) x = new double[solver->getNumCols() ];
01173
01174
01175
01176
01177 if( (solver->getNumCols() > 0) && (sSolverName.find( "vol") == std::string::npos)
01178 && (sSolverName.find( "symphony") == std::string::npos) &&
01179 (sSolverName.find( "dylp") == std::string::npos) &&
01180 (sSolverName.find( "glpk") == std::string::npos) )
01181 cbasis = new int[solver->getNumCols() ];
01182
01183 if( (osinstance->getConstraintNumber() > 0) && (sSolverName.find( "vol") == std::string::npos)
01184 && (sSolverName.find( "symphony") == std::string::npos) &&
01185 (sSolverName.find( "dylp") == std::string::npos) &&
01186 (sSolverName.find( "glpk") == std::string::npos) )
01187 rbasis = new int[solver->getNumRows() ];
01188
01189
01190 if( solver->getNumRows() > 0 ) y = new double[solver->getNumRows() ];
01191 if( solver->getNumCols() > 0 ) idx = new int[ solver->getNumCols() ];
01192 z = new double[1];
01193 if( solver->getNumCols() > 0 ) rcost = new std::string[ solver->getNumCols()];
01194 int numberOfVar = solver->getNumCols();
01195 int numberOfCon = solver->getNumRows();
01196 int solIdx = 0;
01197 int i = 0;
01198 int numberOfOtherVariableResults = 1;
01199 int otherIdx = 0;
01200 std::string description = "";
01201
01202 try
01203 {
01204
01205 osresult->setGeneralStatusType("normal");
01206 osresult->setTime(cpuTime);
01207 osresult->setServiceName( OSgetVersionInfo() );
01208 osresult->setSolverInvoked( "COIN-OR " + sSolverName );
01209 if (solver->isProvenOptimal() == true)
01210 {
01211 osresult->setSolutionStatus(solIdx, "optimal", description);
01212 if( (sSolverName.find( "vol") == std::string::npos) &&
01213 (sSolverName.find( "symphony") == std::string::npos) &&
01214 (sSolverName.find( "dylp") == std::string::npos) &&
01215 (sSolverName.find( "glpk") == std::string::npos) )
01216 {
01217 solver->getBasisStatus( cbasis, rbasis);
01218 }
01219
01220 }
01221 else
01222 {
01223 if(solver->isProvenPrimalInfeasible() == true)
01224 osresult->setSolutionStatus(solIdx, "infeasible", "the problem is primal infeasible");
01225 else
01226 {
01227 if(solver->isProvenDualInfeasible() == true)
01228 osresult->setSolutionStatus(solIdx, "unbounded", "the problem is unbounded");
01229 else
01230 {
01231 if(solver->isPrimalObjectiveLimitReached() == true)
01232 {
01233 osresult->setSolutionStatus(solIdx, "other", "primal objective limit reached");
01234 if( (sSolverName.find( "vol") == std::string::npos) &&
01235 (sSolverName.find( "symphony") == std::string::npos) &&
01236 (sSolverName.find( "dylp") == std::string::npos) &&
01237 (sSolverName.find( "glpk") == std::string::npos) )
01238 {
01239 solver->getBasisStatus( cbasis, rbasis);
01240 }
01241 }
01242 else
01243 {
01244 if(solver->isDualObjectiveLimitReached() == true)
01245 {
01246 osresult->setSolutionStatus(solIdx, "other", "dual objective limit reached");
01247 if( (sSolverName.find( "vol") == std::string::npos) &&
01248 (sSolverName.find( "symphony") == std::string::npos) &&
01249 (sSolverName.find( "dylp") == std::string::npos) &&
01250 (sSolverName.find( "glpk") == std::string::npos) )
01251 {
01252 solver->getBasisStatus( cbasis, rbasis);
01253 }
01254 }
01255 else
01256 {
01257 if(solver->isIterationLimitReached() == true)
01258 {
01259 osresult->setSolutionStatus(solIdx, "other", "iteration limit reached");
01260 if( (sSolverName.find( "vol") == std::string::npos) &&
01261 (sSolverName.find( "symphony") == std::string::npos) &&
01262 (sSolverName.find( "dylp") == std::string::npos) &&
01263 (sSolverName.find( "glpk") == std::string::npos) )
01264 {
01265 solver->getBasisStatus( cbasis, rbasis);
01266 }
01267 }
01268 else
01269 {
01270 if(solver->isAbandoned() == true)
01271 osresult->setSolutionStatus(solIdx, "other", "there are numerical difficulties");
01272 if( solver->getNumCols() == 0) osresult->setSolutionMessage(solIdx, "Warning: this problem has zero decision variables!");
01273 else
01274 osresult->setSolutionStatus(solIdx, "other", description);
01275 }
01276 }
01277 }
01278 }
01279 }
01280 }
01281
01282
01283
01284
01285
01286 *(z + 0) = solver->getObjValue();
01287
01288 osresult->setObjectiveValuesDense(solIdx, z);
01289
01290
01291
01292 for(i=0; i < numberOfVar; i++)
01293 {
01294
01295 *(x + i) = solver->getColSolution()[i];
01296 *(idx + i) = i;
01297
01298
01299 if( (cbasis != NULL) && (solver->isProvenOptimal() == true) )
01300 {
01301
01302
01303 switch (cbasis[ i] )
01304 {
01305 case 0:
01306 {
01307
01308 freeVars.push_back( i);
01309 break;
01310 }
01311
01312 case 1:
01313 {
01314
01315 basicVars.push_back( i);
01316 break;
01317 }
01318
01319 case 2:
01320 {
01321
01322 nonBasicUpper.push_back( i );
01323 break;
01324 }
01325
01326 case 3:
01327 {
01328
01329 nonBasicLower.push_back( i) ;
01330 break;
01331 }
01332 default:
01333 throw ErrorClass("unknown result from Osi getBasisStatus when getting variable basis status");
01334
01335 }
01336
01337 }
01338
01339 }
01340
01341
01342 if(freeVars.size() > 0)
01343 {
01344
01345 kount = 0;
01346
01347 basisIdx[ 0] = new int[ freeVars.size()];
01348
01349 for(vit = freeVars.begin(); vit < freeVars.end(); vit++)
01350 {
01351 basisIdx[0][ kount++] = *vit;
01352 }
01353
01354 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_isFree, basisIdx[ 0], kount);
01355 delete[] basisIdx[ 0];
01356 freeVars.clear();
01357 }
01358
01359
01360
01361 if(basicVars.size() > 0)
01362 {
01363 kount = 0;
01364
01365 basisIdx[ 1] = new int[ basicVars.size()];
01366
01367 for(vit = basicVars.begin(); vit < basicVars.end(); vit++)
01368 {
01369
01370 basisIdx[1][ kount++] = *vit;
01371 }
01372
01373 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_basic, basisIdx[ 1], kount);
01374 delete[] basisIdx[ 1];
01375 basicVars.clear();
01376 }
01377
01378
01379
01380 if(nonBasicUpper.size() > 0)
01381 {
01382 kount = 0;
01383
01384 basisIdx[ 2] = new int[ nonBasicUpper.size()];
01385
01386 for(vit = nonBasicUpper.begin(); vit < nonBasicUpper.end(); vit++)
01387 {
01388 basisIdx[2][ kount++] = *vit;
01389 }
01390
01391 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_atUpper, basisIdx[ 2], kount);
01392 delete[] basisIdx[ 2];
01393 nonBasicUpper.clear();
01394 }
01395
01396
01397 if(nonBasicLower.size() > 0)
01398 {
01399 kount = 0;
01400
01401 basisIdx[ 3] = new int[ nonBasicLower.size()];
01402
01403 for(vit = nonBasicLower.begin(); vit < nonBasicLower.end(); vit++)
01404 {
01405 basisIdx[3][ kount++] = *vit;
01406 }
01407
01408 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_atLower, basisIdx[ 3], kount);
01409 delete[] basisIdx[ 3];
01410 nonBasicLower.clear();
01411 }
01412
01413
01414 osresult->setPrimalVariableValuesDense(solIdx, x);
01415
01416 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0)
01417 {
01418
01419
01420
01421
01422
01423 for(i = 0; i < numberOfCon; i++)
01424 {
01425
01426 *(y + i) = solver->getRowPrice()[ i];
01427
01428
01429
01430
01431 if((rbasis != NULL) && (solver->isProvenOptimal() == true) )
01432 {
01433 switch (rbasis[ i] )
01434 {
01435 case 0:
01436 {
01437
01438 freeVars.push_back( i);
01439 break;
01440 }
01441
01442 case 1:
01443
01444 {
01445
01446 basicVars.push_back( i);
01447 break;
01448 }
01449
01450 case 2:
01451 {
01452
01453 nonBasicUpper.push_back( i );
01454 break;
01455 }
01456
01457 case 3:
01458 {
01459
01460 nonBasicLower.push_back( i) ;
01461 break;
01462 }
01463 default:
01464 throw ErrorClass("unknown result from Osi getBasisStatus when getting row basis status");
01465
01466 }
01467
01468 }
01469
01470
01471 }
01472
01473 osresult->setDualVariableValuesDense(solIdx, y);
01474
01475
01476
01477 if(freeVars.size() > 0)
01478 {
01479 kount = 0;
01480
01481 basisIdx[ 0] = new int[ freeVars.size()];
01482
01483 for(vit = freeVars.begin(); vit < freeVars.end(); vit++)
01484 {
01485 basisIdx[0][ kount++] = *vit;
01486 }
01487
01488 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_isFree, basisIdx[ 0], kount);
01489 delete[] basisIdx[ 0];
01490 freeVars.clear();
01491 }
01492
01493
01494 if(basicVars.size() > 0)
01495 {
01496 kount = 0;
01497
01498 basisIdx[ 1] = new int[ basicVars.size()];
01499
01500 for(vit = basicVars.begin(); vit < basicVars.end(); vit++)
01501 {
01502 basisIdx[1][ kount++] = *vit;
01503 }
01504
01505 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_basic, basisIdx[ 1], kount);
01506 delete[] basisIdx[ 1];
01507 basicVars.clear();
01508 }
01509
01510
01511
01512 if(nonBasicUpper.size() > 0)
01513 {
01514
01515 kount = 0;
01516
01517 basisIdx[ 2] = new int[ nonBasicUpper.size()];
01518
01519 for(vit = nonBasicUpper.begin(); vit < nonBasicUpper.end(); vit++)
01520 {
01521 basisIdx[2][ kount++] = *vit;
01522 }
01523
01524 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_atUpper, basisIdx[ 2], kount);
01525 delete[] basisIdx[ 2];
01526 nonBasicUpper.clear();
01527 }
01528
01529
01530 if(nonBasicLower.size() > 0)
01531 {
01532 kount = 0;
01533
01534 basisIdx[ 3] = new int[ nonBasicLower.size()];
01535
01536 for(vit = nonBasicLower.begin(); vit < nonBasicLower.end(); vit++)
01537 {
01538 basisIdx[3][ kount++] = *vit;
01539 }
01540
01541 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_atLower, basisIdx[ 3], kount);
01542 delete[] basisIdx[ 3];
01543 nonBasicLower.clear();
01544
01545 }
01546
01547
01548
01549 }
01550
01551
01552
01553
01554 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0)
01555 {
01556
01557 if(numOfIntVars <= 0)
01558 {
01559 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
01560 for(i=0; i < numberOfVar; i++)
01561 {
01562 rcost[ i] = os_dtoa_format( solver->getReducedCost()[ i]);
01563 }
01564 osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced_costs", "", "the variable reduced costs", idx, rcost, solver->getNumCols(), "", "double", "");
01565
01566 }
01567 }
01568
01569 ostringstream temp;
01570 temp << solver->getIterationCount();
01571 if (!osresult->setAnOtherSolutionResult(0,"iterations",temp.str(),"","",0,NULL))
01572 throw ErrorClass("error setting iteration count");
01573
01574 osrl = osrlwriter->writeOSrL( osresult);
01575
01576
01577 if(solver->getNumRows() > 0)
01578 {
01579 delete[] y;
01580 y = NULL;
01581 if( (sSolverName.find( "vol") == std::string::npos) &&
01582 (sSolverName.find( "symphony") == std::string::npos) &&
01583 (sSolverName.find( "glpk") == std::string::npos) ) delete[] rbasis;
01584 rbasis = NULL;
01585 }
01586
01587 delete[] z;
01588 z = NULL;
01589
01590 delete[] basisIdx;
01591 basisIdx = NULL;
01592
01593 if(solver->getNumCols() > 0)
01594 {
01595
01596 if( (sSolverName.find( "vol") == std::string::npos) &&
01597 (sSolverName.find( "symphony") == std::string::npos) &&
01598 (sSolverName.find( "glpk") == std::string::npos) ) delete[] cbasis;
01599 cbasis = NULL;
01600
01601 delete[] x;
01602 x = NULL;
01603 delete[] rcost;
01604 rcost = NULL;
01605 delete[] idx;
01606 idx = NULL;
01607 }
01608
01609 }
01610
01611 catch(const ErrorClass& eclass)
01612 {
01613 if(solver->getNumRows() > 0)
01614 {
01615 delete[] y;
01616 y = NULL;
01617 if( (sSolverName.find( "vol") == std::string::npos) &&
01618 (sSolverName.find( "symphony") == std::string::npos) &&
01619 (sSolverName.find( "glpk") == std::string::npos) ) delete[] rbasis;
01620 rbasis = NULL;
01621 }
01622
01623 delete[] z;
01624 z = NULL;
01625
01626 if(solver->getNumCols() > 0)
01627 {
01628 if( (sSolverName.find( "vol") == std::string::npos) &&
01629 (sSolverName.find( "symphony") == std::string::npos) &&
01630 (sSolverName.find( "glpk") == std::string::npos) ) delete[] cbasis;
01631 cbasis = NULL;
01632
01633 delete[] x;
01634 x = NULL;
01635 delete[] rcost;
01636 rcost = NULL;
01637 delete[] idx;
01638 idx = NULL;
01639 }
01640
01641 osresult->setGeneralMessage( eclass.errormsg);
01642 osresult->setGeneralStatusType( "error");
01643 osrl = osrlwriter->writeOSrL( osresult);
01644 throw ErrorClass( osrl) ;
01645 }
01646 }
01647
01648
01649 void CoinSolver::writeResult(CbcModel *model)
01650 {
01651 double *x = NULL;
01652 double *y = NULL;
01653
01654 double *z = NULL;
01655 int *idx = NULL;
01656 std::string *rcost = NULL;
01657
01658 if( model->getNumCols() > 0 ) x = new double[model->getNumCols() ];
01659 if( model->getNumRows() > 0 ) y = new double[model->getNumRows() ];
01660 if( model->getNumCols() > 0 ) idx = new int[ model->getNumCols() ];
01661 z = new double[1];
01662 if( model->getNumCols() > 0 ) rcost = new std::string[ model->getNumCols()];
01663
01664 int numberOfOtherVariableResults = 1;
01665 int otherIdx = 0;
01666 int numberOfVar = model->getNumCols();
01667 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
01668 int i = 0;
01669 int solIdx = 0;
01670 std::string description = "";
01671 osresult->setGeneralStatusType("normal");
01672 osresult->setTime(cpuTime);
01673 osresult->setServiceName( OSgetVersionInfo() );
01674
01675
01676 int numberIntegerInfeasibilities = 0;
01677 int numberObjectInfeasibilities = 0;
01678 bool isFeasible = false;
01679 isFeasible = model->feasibleSolution( numberIntegerInfeasibilities,
01680 numberObjectInfeasibilities);
01681 std::string statusMsg;
01682 if(isFeasible == true)
01683 {
01684 statusMsg = "feasible";
01685 }
01686 else
01687 {
01688 statusMsg = "infeasible";
01689 }
01690
01691
01692 if (model->isProvenOptimal() == true )
01693 {
01694 osresult->setSolutionStatus(solIdx, "optimal", description);
01695 }
01696 else
01697 {
01698 if(model->isProvenInfeasible() == true)
01699 osresult->setSolutionStatus(solIdx, "infeasible", "the integer program is infeasible");
01700 else
01701 {
01702 if(model->isProvenDualInfeasible() == true)
01703 osresult->setSolutionStatus(solIdx, "infeasible", "the continuous relaxation is dual infeasible");
01704 else
01705 {
01706 if(model->isContinuousUnbounded() == true)
01707 osresult->setSolutionStatus(solIdx, statusMsg, "the continuous relaxation is unbounded");
01708 else
01709 {
01710 if(model->isNodeLimitReached() == true)
01711 osresult->setSolutionStatus(solIdx, statusMsg, "node limit reached");
01712 else
01713 {
01714 if(model->isSecondsLimitReached() == true)
01715 osresult->setSolutionStatus(solIdx, statusMsg, "time limit reached");
01716 else
01717 {
01718 if(model->isSolutionLimitReached() == true)
01719 osresult->setSolutionStatus(solIdx, statusMsg, "solution limit reached");
01720 else
01721 {
01722 if(model->isAbandoned() == true)
01723 osresult->setSolutionStatus(solIdx, statusMsg, "there are numerical difficulties");
01724 else
01725 osresult->setSolutionStatus(solIdx, statusMsg,"unknown");
01726 }
01727 }
01728 }
01729 }
01730 }
01731 }
01732 }
01733
01734
01735 if(numOfIntVars > 0) *(z + 0) = model->getObjValue();
01736 osresult->setObjectiveValuesDense(solIdx, z);
01737 for(i=0; i < model->getNumCols(); i++)
01738 {
01739 *(x + i) = model->getColSolution()[i];
01740 *(idx + i) = i;
01741 }
01742 osresult->setPrimalVariableValuesDense(solIdx, x);
01743 for(i=0; i < model->getNumRows(); i++)
01744 {
01745 *(y + i) = model->getRowPrice()[ i];
01746 }
01747 if(numOfIntVars <= 0) osresult->setDualVariableValuesDense(solIdx, y);
01748
01749
01750 if(numOfIntVars <= 0)
01751 {
01752 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
01753 for(i=0; i < numberOfVar; i++)
01754 {
01755 rcost[ i] = os_dtoa_format( model->getReducedCost()[ i]);
01756 }
01757 osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced_costs", "", "the variable reduced costs", idx, rcost, model->getNumCols());
01758 }
01759
01760 osrl = osrlwriter->writeOSrL( osresult);
01761
01762 if(model->getNumCols() > 0) delete[] x;
01763 x = NULL;
01764 if(model->getNumRows() > 0) delete[] y;
01765 y = NULL;
01766 delete[] z;
01767 z = NULL;
01768 if(model->getNumCols() > 0)
01769 {
01770 delete[] rcost;
01771 rcost = NULL;
01772 delete[] idx;
01773 idx = NULL;
01774 }
01775 }
01776
01777