/home/coin/SVN-release/OS-2.0.1/OS/src/OSSolverInterfaces/OSCoinSolver.cpp

Go to the documentation of this file.
00001 /* $Id: OSCoinSolver.cpp 2777 2009-07-04 06:29:35Z kmartin $ */
00021 //#define DEBUG
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" //for CbcSOS
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 "OSDataStructures.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                         //delete cbc_argv[ i];
00114                 }
00115                 //delete[] cbc_argv;
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                 osresult = new OSResult();
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                         // get the type of solver requested from OSoL string
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                                                                         // default solver is CBC
00180                                                                         sSolverName = "cbc";
00181                                                                         solverIsDefined = true;
00182                                                                         osiSolver = new OsiClpSolverInterface();
00183                                                                 }
00184                                                         }
00185                                                 }
00186                                         }
00187                                 }
00188                         }
00189 
00190                         if(solverIsDefined == false) throw ErrorClass("a supported solver was not defined");
00191 
00192                         // first check the various solvers and see if they are of the proper problem type
00193                         if( (osinstance->getNumberOfNonlinearExpressions() > 0)
00194                                 || (osinstance->getNumberOfQuadraticTerms() > 0) ){
00195                                 throw ErrorClass( "This COIN-OR Solver is not configured for nonlinear programming");
00196                         }
00197                         // throw an exception if we have a solver that cannot do integer programming
00198                         if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00199                                 if( sSolverName.find("clp") != std::string::npos) throw ErrorClass( "Clp cannot do integer programming");
00200                                 if( sSolverName.find("vol") != std::string::npos) throw ErrorClass( "Vol cannot do integer programming");
00201                                 if( sSolverName.find("dylp") != std::string::npos) throw ErrorClass( "DyLP cannot do integer programming");
00202                                 if( sSolverName.find("ipopt") != std::string::npos) throw ErrorClass( "Ipopt cannot do integer programming");
00203                         }
00204                         // check other trivial solver limitations
00205                         if(osinstance->getConstraintNumber() <= 0)throw ErrorClass("Coin solver cannot handle unconstrained problems");
00206                         if(osinstance->getVariableNumber() <= 0)throw ErrorClass("Coin solver requires decision variables");
00207                         if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Coin solver needs an objective function");
00208                         if(osinstance->getNumberOfStringVariables() > 0) throw ErrorClass("Coin solver can only handle numeric variables");
00209                         if(osinstance->getLinearConstraintCoefficientNumber() <= 0) throw ErrorClass("Coin solver needs linear constraints");
00210 
00211                         if(!setCoinPackedMatrix() ) throw ErrorClass("Problem generating coin packed matrix");
00212                         osiSolver->loadProblem(*m_CoinPackedMatrix, osinstance->getVariableLowerBounds(), 
00213                                 osinstance->getVariableUpperBounds(),  
00214                                 osinstance->getDenseObjectiveCoefficients()[0], 
00215                                 osinstance->getConstraintLowerBounds(), osinstance->getConstraintUpperBounds()
00216                         );
00217                         //dataEchoCheck();      
00218 //                      if(osinstance->getObjectiveNumber() == 0) throw ErrorClass("there is no objective function");
00219                         if( osinstance->getObjectiveMaxOrMins()[0] == "min") osiSolver->setObjSense(1.0);
00220                         else osiSolver->setObjSense(-1.0);
00221                         // set the integer variables
00222                         int *intIndex = NULL;
00223                         int i = 0;
00224                         int k = 0;
00225                         char *varType;
00226                         int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
00227                         if(numOfIntVars > 0) {
00228                                 intIndex = new int[ numOfIntVars];
00229                                 varType = osinstance->getVariableTypes();
00230                                 for(i = 0; i < osinstance->getVariableNumber(); i++){
00231                                         if( (varType[i] == 'B') || (varType[i]) == 'I' ) {
00232                                                 intIndex[k++] = i;
00233                                         }
00234                                 }
00235                                 osiSolver->setInteger( intIndex,  numOfIntVars);
00236                         }
00237                         if(numOfIntVars > 0){ 
00238                                 delete[] intIndex;
00239                                 intIndex = NULL;
00240                         }
00241                         bCallbuildSolverInstance = true;
00242         }
00243         catch(const ErrorClass& eclass){
00244                 osresult->setGeneralMessage( eclass.errormsg);
00245                 osresult->setGeneralStatusType( "error");
00246                 osrl = osrlwriter->writeOSrL( osresult);
00247                 throw ErrorClass( osrl) ;
00248         }                               
00249 }//end buildSolverInstance()
00250 
00251 
00252 
00253 void CoinSolver::setSolverOptions() throw (ErrorClass) {
00254 
00255           
00256 
00257         // the osi maps
00258         // the OsiHintParameter Map
00259         std::map<std::string, OsiHintParam> hintParamMap;
00260         hintParamMap["OsiDoPresolveInInitial"] = OsiDoPresolveInInitial;
00261         hintParamMap["OsiDoDualInInitial"] = OsiDoDualInInitial;
00262         hintParamMap["OsiDoPresolveInResolve"] = OsiDoPresolveInResolve;
00263         hintParamMap["OsiDoDualInResolve"] = OsiDoDualInResolve;
00264         hintParamMap["OsiDoScale"] = OsiDoScale;
00265         hintParamMap["OsiDoCrash"] = OsiDoCrash;
00266         hintParamMap["OsiDoReducePrint"] = OsiDoReducePrint;
00267         hintParamMap["OsiDoInBranchAndCut"] =  OsiDoInBranchAndCut;
00268         hintParamMap["OsiLastHintParam"] = OsiLastHintParam;
00269         //
00270         // the OsiHintStrength Map
00271         std::map<std::string, OsiHintStrength> hintStrengthMap;
00272         hintStrengthMap["OsiHintIgnore"] = OsiHintIgnore;
00273         hintStrengthMap["OsiHintTry"] = OsiHintTry;
00274         hintStrengthMap["OsiHintDo"] = OsiHintDo;
00275         hintStrengthMap["OsiForceDo"] = OsiForceDo;
00276         //
00277         // the OsiStrParam Map
00278         std::map<std::string, OsiStrParam> strParamMap;
00279         strParamMap["OsiProbName"] = OsiProbName;
00280         strParamMap["OsiSolverName"] = OsiSolverName;
00281         strParamMap["OsiLastStrParam"] = OsiLastStrParam;
00282         //
00283         // the OsiDblParam Map
00284         std::map<std::string, OsiDblParam>  dblParamMap;
00285         dblParamMap["OsiDualObjectiveLimit"] = OsiDualObjectiveLimit;
00286         dblParamMap["OsiPrimalObjectiveLimit"] = OsiPrimalObjectiveLimit;
00287         dblParamMap["OsiDualTolerance"] = OsiDualTolerance;     
00288         dblParamMap["OsiPrimalTolerance"] = OsiPrimalTolerance;
00289         dblParamMap["OsiObjOffset"] = OsiObjOffset;
00290         dblParamMap["OsiLastDblParam"] = OsiLastDblParam;
00291         //
00292         //
00293         // the OsiIntParam Map
00294         std::map<std::string, OsiIntParam>  intParamMap;
00295         intParamMap["OsiMaxNumIteration"] = OsiMaxNumIteration;
00296         intParamMap["OsiMaxNumIterationHotStart"] = OsiMaxNumIterationHotStart;
00297         intParamMap["OsiNameDiscipline"] = OsiNameDiscipline;   
00298         intParamMap["OsiLastIntParam"] = OsiLastIntParam;
00299         //
00300         //
00301         // initialize low level of printing
00302         
00303         
00304         /* 
00305          * start default settings -- these get set
00306          * even when the OSOption object is NULL
00307          * 
00308          * */
00309         OsiHintStrength hintStrength = OsiHintTry; //don't want too much output
00310         osiSolver->setHintParam(OsiDoReducePrint, true, hintStrength);
00311         osiSolver->setDblParam(OsiObjOffset, osinstance->getObjectiveConstants()[0]);
00312         
00313         
00314         // treat symphony differently
00315 #ifdef COIN_HAS_SYMPHONY
00316         if( sSolverName.find( "symphony") != std::string::npos) {
00317                 OsiSymSolverInterface * si =
00318                 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00319                 //set default verbosity to -2
00320                 si->setSymParam("verbosity",   -2);     
00321         }
00322 #endif     //symphony end       
00323         /* 
00324          * end default settings 
00325          * 
00326          * */
00327         
00328         //
00329         try{
00330                 if(osoption == NULL && osol.length() > 0)
00331                 {
00332                         m_osolreader = new OSoLReader();
00333                         osoption = m_osolreader->readOSoL( osol);
00334                 }
00335 
00336                 if(osoption != NULL){
00337 
00338                         //std::cout << "number of solver options "  <<  osoption->getNumberOfSolverOptions() << std::endl;
00339                         if( osoption->getNumberOfSolverOptions() <= 0) return;
00340                         this->bSetSolverOptions = true;
00341                         std::vector<SolverOption*> optionsVector;
00342                         //get the osi options
00343                         optionsVector = osoption->getSolverOptions( "osi");
00344                         int num_osi_options = optionsVector.size();
00345                         int i;
00346                         char *pEnd;
00347                         bool yesNo;
00348 
00349                         for(i = 0; i < num_osi_options; i++){
00350                                 std::cout << "osi solver option  "  << optionsVector[ i]->name << std::endl;
00351                                 if (optionsVector[ i]->type == "OsiHintStrength" ){
00352                                         if( hintStrengthMap.find( optionsVector[ i]->name ) != hintStrengthMap.end() ){
00353                                                 hintStrength = hintStrengthMap[ optionsVector[ i]->name] ;
00354                                         }
00355                                 }
00356                         }
00357                         for(i = 0; i < num_osi_options; i++){
00358                                 std::cout << "osi solver option  "  << optionsVector[ i]->name << std::endl;
00359 
00360                                 if (optionsVector[ i]->type == "OsiHintParam" ){
00361                                         
00362                                         if( optionsVector[ i]->value == "true" ) {
00363                                                 yesNo = true;
00364                                         }
00365                                         else{
00366                                                 yesNo = false;
00367                                         }       
00368                                         if( hintParamMap.find( optionsVector[ i]->name ) != hintParamMap.end() ){
00369                                                 
00370                                                 osiSolver->setHintParam( hintParamMap[ optionsVector[ i]->name] , yesNo, hintStrength);
00371                                         }
00372                                         
00373                                 }
00374                                 else if(optionsVector[ i]->type == "OsiStrParam" ){
00375                                         
00376                                         if( strParamMap.find( optionsVector[ i]->name ) != strParamMap.end() ){
00377                                                 
00378                                                 osiSolver->setStrParam( strParamMap[ optionsVector[ i]->name] , optionsVector[ i]->value);
00379                                         }       
00380 
00381                                 }
00382                                 else if(optionsVector[ i]->type == "OsiDblParam" ){
00383                                         
00384                                         if( dblParamMap.find( optionsVector[ i]->name ) != dblParamMap.end() ){
00385                                                 
00386                                                 osiSolver->setDblParam( dblParamMap[ optionsVector[ i]->name] , os_strtod( optionsVector[ i]->value.c_str(), &pEnd ));
00387                                         }                               
00388                                         
00389                                 }
00390                                 else if(optionsVector[ i]->type == "OsiIntParam" ){
00391                                         
00392                                         
00393                                         if( intParamMap.find( optionsVector[ i]->name ) != intParamMap.end() ){
00394                                                 
00395                                                 osiSolver->setIntParam( intParamMap[ optionsVector[ i]->name] , atoi( optionsVector[ i]->value.c_str() ) );
00396                                         }                                               
00397                                         
00398                                 }
00399                         }
00400                         
00401                         // treat Cbc separately to take advantage of CbcMain1()
00402                         
00403                         if( sSolverName.find( "cbc") != std::string::npos) {    
00404                                 // get Cbc options      
00405                                 if(optionsVector.size() > 0) optionsVector.clear();     
00406                                 optionsVector = osoption->getSolverOptions( "cbc");
00407                                 int num_cbc_options = optionsVector.size();     
00408                                 char *cstr;
00409                                 std::string cbc_option;
00410                                 num_cbc_argv = optionsVector.size() + 3;
00411                                 cbc_argv = new const char*[ num_cbc_argv];
00412                                 
00413                                 // the first option
00414                                 cbc_option = "OS";
00415                                 cstr = new char [cbc_option.size() + 1];
00416                                 strcpy (cstr, cbc_option.c_str());
00417                                 cbc_argv[ 0] = cstr;
00418                                 
00419                                 
00420                                 for(i = 0; i < num_cbc_options; i++){
00421                                         std::cout << "cbc solver option  "  << optionsVector[ i]->name << std::endl;
00422                                         std::cout << "cbc solver value  "  << optionsVector[ i]->value << std::endl;
00423                                         if(optionsVector[ i]->value.length() > 0){
00424                                                 cbc_option = "-" + optionsVector[ i]->name +"="+optionsVector[ i]->value;
00425                                         }
00426                                         else{
00427                                                 cbc_option = "-" + optionsVector[ i]->name ;
00428                                         }
00429                                         cstr = new char [cbc_option.size() + 1];
00430                                         strcpy (cstr, cbc_option.c_str());
00431                                         cbc_argv[i +  1] = cstr;                
00432                                 }
00433                                 
00434                                 // the solve option
00435                                 cbc_option = "-solve";
00436                                 cstr = new char [cbc_option.size() + 1];
00437                                 strcpy (cstr, cbc_option.c_str());
00438                                 cbc_argv[ num_cbc_argv - 2] = cstr;
00439                                 
00440                                 // the quit option
00441                                 cbc_option = "-quit";
00442                                 cstr = new char [cbc_option.size() + 1];
00443                                 strcpy (cstr, cbc_option.c_str());
00444                                 cbc_argv[ num_cbc_argv - 1] = cstr;
00445 
00446                         }//end of cbc if
00447                         
00448                         // also need to treat SYMPHONY differently
00449         
00450         // treat symphony differently
00451         #ifdef COIN_HAS_SYMPHONY
00452                         if(optionsVector.size() > 0) optionsVector.clear();
00453                         //if( !optionsVector.empty() ) optionsVector.clear();   
00454                         //first the number of processors -- applies only to SYMPHONY
00455                         if( sSolverName.find( "symphony") != std::string::npos) {
00456                                 OsiSymSolverInterface * si =
00457                                 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00458                                 optionsVector = osoption->getSolverOptions( "symphony");
00459                                 int num_sym_options = optionsVector.size();
00460                                 for(i = 0; i < num_sym_options; i++){
00461                                         std::cout << "symphony solver option  "  << optionsVector[ i]->name << std::endl;
00462                                         std::cout << "symphony solver value  "  << optionsVector[ i]->value << std::endl;
00463                                         si->setSymParam(optionsVector[ i]->name,   optionsVector[ i]->value);
00464                                 }                               
00465                         }
00466         #endif     //symphony end                       
00467                         
00468                         //now set initial values
00469                         int n,m,k;
00470                         if (osoption != NULL)
00471                                 m = osoption->getNumberOfInitVarValues();
00472                         else
00473                                 m = 0;
00474 #ifdef DEBUG
00475                         cout << "number of variables initialed: " << m << endl;
00476 #endif
00477 
00478                         if (m > 0)
00479                         {
00480 #ifdef DEBUG
00481                         cout << "get initial values " << endl;
00482 #endif
00483                                 n = osinstance->getVariableNumber();
00484                                 double* denseInitVarVector;
00485                                 denseInitVarVector = new double[n];
00486                                 bool* initialed;
00487                                 initialed = new bool[n];
00488 
00489                                 for(k = 0; k < n; k++)
00490                                         initialed[k] = false;
00491 
00492                                 InitVarValue**  initVarVector = osoption->getInitVarValuesSparse();
00493 #ifdef DEBUG
00494                                 cout << "done " << endl;
00495 #endif
00496 
00497                                 double initval;
00498                                 for(k = 0; k < m; k++){
00499                                         i = initVarVector[k]->idx;
00500                                         if (initVarVector[k]->idx > n)
00501                                                 throw ErrorClass ("Illegal index value in variable initialization");
00502 
00503                                                 initval = initVarVector[k]->value;
00504                                                 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00505                                                 {       if (osinstance->instanceData->variables->var[k]->lb > initval)
00506                                                                 throw ErrorClass ("Initial value outside of bounds");
00507                                                 }
00508                                                 else
00509                                                         if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00510                                                         {       if (osinstance->instanceData->variables->var[k]->ub < initval)
00511                                                                         throw ErrorClass ("Initial value outside of bounds");
00512                                                         }
00513                                                         else
00514                                                         {       if ((osinstance->instanceData->variables->var[k]->lb > initval) ||
00515                                                                         (osinstance->instanceData->variables->var[k]->ub < initval))
00516                                                                         throw ErrorClass ("Initial value outside of bounds");
00517                                                         }
00518 
00519                                         denseInitVarVector[initVarVector[k]->idx] = initval;
00520                                         initialed[initVarVector[k]->idx] = true;
00521                                 }
00522 
00523                                 double default_initval;
00524                                 default_initval = 0.0;
00525 
00526                                 for(k = 0; k < n; k++){
00527                                         if (!initialed[k])
00528                                                 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00529                                                         if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
00530                                                                 denseInitVarVector[k] = default_initval;
00531                                                         else
00532                                                                 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00533                                                 else
00534                                                         if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00535                                                                 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
00536                                                                         denseInitVarVector[k] = default_initval;
00537                                                                 else
00538                                                                         denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00539                                                         else
00540                                                                 if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) && 
00541                                                                         (osinstance->instanceData->variables->var[k]->ub >= default_initval))
00542                                                                         denseInitVarVector[k] = default_initval;
00543                                                                 else
00544                                                                         if (osinstance->instanceData->variables->var[k]->lb > default_initval)
00545                                                                                 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00546                                                                         else
00547                                                                                 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00548                                                                         denseInitVarVector[k] = default_initval;
00549                                                                         denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00550                                 }
00551 #ifdef DEBUG
00552                                 cout << "set initial values: " << endl;
00553                                 for (k=0; k < n; k++)
00554                                         cout << "  " << k << ": " << denseInitVarVector[k] << endl;     
00555 #endif
00556                                 osiSolver->setColSolution( denseInitVarVector);
00557                                 delete[] denseInitVarVector;
00558                                 delete[] initialed;
00559 #ifdef DEBUG
00560                         cout << "done " << endl;
00561 #endif
00562 
00563                         }  //  end if (m > 0)           
00564                 }// end of osoption if  
00565                 
00566                 
00567         }//end of try 
00568         catch(const ErrorClass& eclass){
00569                 std::cout << "THERE IS AN ERROR" << std::endl;
00570                 osresult->setGeneralMessage( eclass.errormsg);
00571                 osresult->setGeneralStatusType( "error");
00572                 osrl = osrlwriter->writeOSrL( osresult);
00573                 throw ErrorClass( osrl) ;
00574         }                               
00575 }//end setSolverOptions() 
00576 
00577 
00578 bool CoinSolver::setCoinPackedMatrix(){
00579         bool columnMajor = osinstance->getLinearConstraintCoefficientMajor();
00580         try{
00581                 int maxGap = 0;
00582                 m_CoinPackedMatrix = new CoinPackedMatrix(
00583                         columnMajor, //Column or Row Major
00584                         columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(), //Minor Dimension
00585                         columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(), //Major Dimension
00586                         osinstance->getLinearConstraintCoefficientNumber(), //Number of nonzeroes
00587                         columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->values : osinstance->getLinearConstraintCoefficientsInRowMajor()->values, //Pointer to matrix nonzeroes
00588                         columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes : osinstance->getLinearConstraintCoefficientsInRowMajor()->indexes, //Pointer to start of minor dimension indexes -- change to allow for row storage
00589                         columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts : osinstance->getLinearConstraintCoefficientsInRowMajor()->starts, //Pointers to start of columns.
00590                         0,   0, maxGap ); 
00591 
00592                 return true;
00593         }
00594         catch(const ErrorClass& eclass){
00595                 osresult->setGeneralMessage( eclass.errormsg);
00596                 osresult->setGeneralStatusType( "error");
00597                 osrl = osrlwriter->writeOSrL( osresult);
00598                 throw ErrorClass( osrl) ;
00599         }
00600 } // end setCoinPackedMatrix
00601 
00602 void CoinSolver::solve() throw (ErrorClass) {
00603         try{
00604                 // make sure the solver instance exists
00605                 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00606                 //set the options
00607                 if( this->bSetSolverOptions == false) setSolverOptions();
00608         }
00609         catch(const ErrorClass& eclass){
00610                 throw ErrorClass( osrl) ;
00611         }
00612         
00613         // resultHeader information
00614         if(osresult->setServiceName("Solved with Coin Solver: " + sSolverName) != true)
00615                 throw ErrorClass("OSResult error: setServiceName");
00616         if(osresult->setInstanceName(  osinstance->getInstanceName()) != true)
00617                 throw ErrorClass("OSResult error: setInstanceName");
00618         //if(osresult->setJobID( osresultdata->jobID) != true)
00619         //      throw ErrorClass("OSResult error: setJobID");
00620         //if(osresult->setGeneralMessage( osresultdata->message) != true)
00621         //      throw ErrorClass("OSResult error: setGeneralMessage");
00622         // set basic problem parameters
00623         if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00624                 throw ErrorClass("OSResult error: setVariableNumer");
00625         if(osresult->setObjectiveNumber( 1) != true)
00626                 throw ErrorClass("OSResult error: setObjectiveNumber");
00627         if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00628                 throw ErrorClass("OSResult error: setConstraintNumber");
00629         if(osresult->setSolutionNumber(  1) != true)
00630                 throw ErrorClass("OSResult error: setSolutionNumer");   
00631         //
00632         try{
00633                 double start = CoinCpuTime();
00634                 try{
00635                         if( sSolverName.find( "cbc") != std::string::npos){
00636                         //if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00637                         // just use simple branch and bound for anything but cbc
00638                                 CbcModel model(  *osiSolver);
00639                                 //CoinMessages coinMessages;
00640                                 //int numberOfMessages;
00641                                 //CoinOneMessage currentMessage;
00642                                 //CoinMessageHandler * generalMessageHandler;
00643                                 //CoinOneMessage **coinOneMessage;
00644                                 //CoinOneMessage *oneMessage;
00645                                 
00646                                 
00647                                 CbcMain0(  model);      
00648                                 /*
00649                                 coinMessages = model.messages();
00650                                 numberOfMessages = coinMessages.numberMessages_;
00651                                 for(int i = 0; i < numberOfMessages - 1; i++){
00652                                         oneMessage = coinMessages.message_[ i] ;
00653                                 //      std::cout << "ONE MESSAGE = " << oneMessage->message() << std::endl;
00654                                 }
00655                         
00656                                 generalMessageHandler = model.messageHandler();
00657                                 currentMessage = generalMessageHandler->currentMessage();
00658                                 std::cout << "GAIL HONDA =  "  << currentMessage.message() << std::endl;
00659                                 std::cout << "HIGHEST NUMBER =  "  << generalMessageHandler->highestNumber() << std::endl;
00660                                 std::cout << "CURRENT SOURCE =  "  << generalMessageHandler->currentSource() << std::endl;
00661                                 std::cout << "MESSAGE BUFFER =  "  << generalMessageHandler->messageBuffer() << std::endl;
00662                                 */
00663                                 
00664                                 //CoinMessages generalMessages = model.getModelPtr()->messages();                               
00665                                 // make sure we define cbc_argv if not done already when reading options
00666                                 if(num_cbc_argv <= 0){
00667                                         char *cstr;
00668                                         std::string cbc_option;
00669                                         num_cbc_argv = 4;
00670                                         cbc_argv = new const char*[ num_cbc_argv];
00671                         
00672                                         // the first option
00673                                         cbc_option = "OS";
00674                                         cstr = new char [cbc_option.size() + 1];
00675                                         strcpy (cstr, cbc_option.c_str());
00676                                         cbc_argv[ 0] = cstr;
00677                                         
00678                                         
00679                                         // the log option -- by default minimal printing
00680                                         cbc_option = "-log=0";
00681                                         cstr = new char [cbc_option.size() + 1];
00682                                         strcpy (cstr, cbc_option.c_str());
00683                                         cbc_argv[ 1] = cstr;
00684                                         
00685                                         
00686                                         // the solve option
00687                                         cbc_option = "-solve";
00688                                         cstr = new char [cbc_option.size() + 1];
00689                                         strcpy (cstr, cbc_option.c_str());
00690                                         cbc_argv[ 2] = cstr;
00691                         
00692                                         // the quit option
00693                                         cbc_option = "-quit";
00694                                         cstr = new char [cbc_option.size() + 1];
00695                                         strcpy (cstr, cbc_option.c_str());
00696                                         cbc_argv[ 3] = cstr;
00697                                                                 
00698                                 }
00699                                 int i;
00700 /*
00701                                 std::cout << "CALLING THE CBC SOLVER CBCMAIN1()" << std::endl;
00702                                 for(i = 0; i < num_cbc_argv; i++){
00703                                         std::cout << "Cbc Option: "  << cbc_argv[ i]   <<  std::endl;
00704                                 }
00705 */
00706                                 
00707                                 CbcMain1( num_cbc_argv, cbc_argv, model);       
00708                                 /*
00709                                 coinMessages = model.messages();
00710                                 numberOfMessages = coinMessages.numberMessages_;
00711                                 for(int i = 0; i < 5; i++){
00712                                         oneMessage = coinMessages.message_[ i] ;
00713                                         std::cout << "ONE MESSAGE = " << oneMessage->message() << std::endl;
00714                                 }
00715                                 numberOfMessages = coinMessages.numberMessages_;
00716                                 generalMessageHandler = model.messageHandler();
00717                                 currentMessage = generalMessageHandler->currentMessage();
00718                                 std::cout << "GAIL HONDA =  "  << currentMessage.message() << std::endl;
00719                                 std::cout << "HIGHEST NUMBER =  "  << generalMessageHandler->highestNumber() << std::endl;
00720                                 std::cout << "CURRENT SOURCE =  "  << generalMessageHandler->currentSource() << std::endl;
00721                                 std::cout << "MESSAGE BUFFER =  "  << generalMessageHandler->messageBuffer() << std::endl;
00722                                 std::cout << "NUMBER OF STRING FIELDS  =  "  << generalMessageHandler->numberStringFields() << std::endl;
00723                                 exit( 1);
00724                                 */
00725                                 //do the garbage collection on cbc_argv
00726                                 for(i = 0; i < num_cbc_argv; i++){
00727                                         delete[]  cbc_argv[ i]; 
00728                                         cbc_argv[i] = NULL;
00729                                 }
00730                                 if( num_cbc_argv > 0){
00731                                         delete[] cbc_argv;
00732                                         cbc_argv = NULL;
00733                                         num_cbc_argv = 0;
00734                                 }
00735                                 
00736                                 
00737 
00738                                 cpuTime = CoinCpuTime() - start;
00739                                 
00740                                 // create a solver 
00741                                 OsiSolverInterface *solver = model.solver();
00742                                 if(osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){                   
00743                                         writeResult( &model);
00744                                 }else{
00745                                         writeResult( solver);
00746                                 }
00747                         }
00748                         else{ // use other solvers
00749                                 //if an LP just do initial solve
00750                                 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00751                                         osiSolver->branchAndBound();
00752                                 }
00753                                 else{
00754                                         osiSolver->initialSolve();
00755                                 }
00756                                 cpuTime = CoinCpuTime() - start;
00757                         
00758                                 writeResult( osiSolver);
00759                         }
00760                         
00761 
00762                 }
00763                 catch(CoinError e){
00764                         std::string errmsg;
00765                         errmsg = "Coin Solver Error: " + e.message() + "\n" + " see method "  
00766                                 + e.methodName() + " in class " + e.className();
00767                         throw ErrorClass( errmsg );
00768                 }
00769 
00770         }
00771         catch(const ErrorClass& eclass){
00772                 osresult->setGeneralMessage( eclass.errormsg);
00773                 osresult->setGeneralStatusType( "error");
00774                 osrl = osrlwriter->writeOSrL( osresult);
00775                 throw ErrorClass( osrl) ;
00776         }
00777 } // end solve
00778 
00779 std::string CoinSolver::getCoinSolverType(std::string lcl_osol){
00780 // this is deprecated, but keep it around
00781         try{
00782                 if( lcl_osol.find( "clp") != std::string::npos){
00783                         return "coin_solver_glpk";
00784                 }
00785                 else{
00786                         if( lcl_osol.find( "cbc") != std::string::npos){
00787                                 return "coin_solver_cpx";
00788                         }
00789                         else{
00790                                 if( lcl_osol.find( "cpx") != std::string::npos){
00791                                         return "coin_solver_clp";
00792                                 }
00793                                 else{
00794                                         if(lcl_osol.find( "glpk") != std::string::npos){
00795                                                 return "";
00796                                         }
00797                                         else throw ErrorClass("a supported solver was not defined");
00798                                 }
00799                         }
00800                 }
00801         }
00802         catch(const ErrorClass& eclass){
00803                 osresult->setGeneralMessage( eclass.errormsg);
00804                 osresult->setGeneralStatusType( "error");
00805                 osrl = osrlwriter->writeOSrL( osresult);
00806                 throw ErrorClass( osrl) ;
00807         }
00808 } // end getCoinSolverType
00809 
00810 void CoinSolver::dataEchoCheck(){
00811         int i;
00812         // print out problem parameters
00813         cout << "This is problem:  " << osinstance->getInstanceName() << endl;
00814         cout << "The problem source is:  " << osinstance->getInstanceSource() << endl;
00815         cout << "The problem description is:  " << osinstance->getInstanceDescription() << endl;
00816         cout << "number of variables = " << osinstance->getVariableNumber() << endl;
00817         cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
00818 
00819         // print out the variable information
00820         if(osinstance->getVariableNumber() > 0){
00821                 for(i = 0; i < osinstance->getVariableNumber(); i++){
00822                         if(osinstance->getVariableNames() != NULL) cout << "variable Names  " << osinstance->getVariableNames()[ i]  << endl;
00823                         if(osinstance->getVariableTypes() != NULL) cout << "variable Types  " << osinstance->getVariableTypes()[ i]  << endl;
00824                         if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds  " << osinstance->getVariableLowerBounds()[ i]  << endl;
00825                         if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds  " <<  osinstance->getVariableUpperBounds()[i] << endl;
00826                 }
00827         }
00828         
00829         // print out objective function information
00830         if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0){
00831                 if( osinstance->getObjectiveMaxOrMins()[0] == "min")  cout <<  "problem is a minimization" << endl;
00832                 else cout <<  "problem is a maximization" << endl;
00833                 for(i = 0; i < osinstance->getVariableNumber(); i++){
00834                         cout << "OBJ COEFFICIENT =  " <<  osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
00835                 }
00836         }
00837         // print out constraint information
00838         if(osinstance->getConstraintNumber() > 0){
00839                 for(i = 0; i < osinstance->getConstraintNumber(); i++){
00840                         if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] <<  endl;
00841                         if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] <<  endl;
00842                         if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] <<  endl; 
00843                 }
00844         }
00845         
00846         // print out linear constraint data
00847         if(m_CoinPackedMatrix != NULL) m_CoinPackedMatrix->dumpMatrix();
00848 } // end dataEchoCheck
00849 
00850 
00851 
00852 void CoinSolver::writeResult(OsiSolverInterface *solver){
00853         double *x = NULL;
00854         double *y = NULL;
00855         double *z = NULL;
00856         int *idx = NULL;
00857         std::string *rcost = NULL;
00858         x = new double[osinstance->getVariableNumber() ];
00859         y = new double[osinstance->getConstraintNumber() ];
00860         idx = new int[ osinstance->getVariableNumber() ];
00861         z = new double[1];
00862         rcost = new std::string[ osinstance->getVariableNumber()];
00863         int numberOfVar =  osinstance->getVariableNumber();
00864         int solIdx = 0;
00865         int i = 0;
00866         int numberOfOtherVariableResults = 1;
00867         int otherIdx = 0;
00868         std::string description = "";
00869         osresult->setGeneralStatusType("normal");
00870         osresult->setTime(cpuTime);
00871         if (solver->isProvenOptimal() == true){
00872                 osresult->setSolutionStatus(solIdx, "optimal", description);                                    
00873         }
00874         else{ 
00875                 if(solver->isProvenPrimalInfeasible() == true) 
00876                         osresult->setSolutionStatus(solIdx, "infeasible", "the problem is primal infeasible");
00877                 else
00878                         if(solver->isProvenDualInfeasible() == true) 
00879                                 osresult->setSolutionStatus(solIdx, "unbounded", "the problem is unbounded");
00880                         else
00881                                 if(solver->isPrimalObjectiveLimitReached() == true) 
00882                                         osresult->setSolutionStatus(solIdx, "other", "primal objective limit reached");
00883                                 else
00884                                         if(solver->isDualObjectiveLimitReached() == true) 
00885                                                 osresult->setSolutionStatus(solIdx, "other", "dual objective limit reached");
00886                                         else
00887                                                 if(solver->isIterationLimitReached() == true) 
00888                                                         osresult->setSolutionStatus(solIdx, "other", "iteration limit reached");
00889                                                 else
00890                                                         if(solver->isAbandoned() == true) 
00891                                                                 osresult->setSolutionStatus(solIdx, "other", "there are numerical difficulties");
00892                                                         else
00893                                                                 osresult->setSolutionStatus(solIdx, "other", description);
00894         }
00895         
00896         /* Retrieve the solution */
00897         //
00898         *(z + 0)  =  solver->getObjValue();
00899         osresult->setObjectiveValuesDense(solIdx, z); 
00900         for(i=0; i < osinstance->getVariableNumber(); i++){
00901                 *(x + i) = solver->getColSolution()[i];
00902                 *(idx + i) = i;
00903         }
00904         osresult->setPrimalVariableValuesDense(solIdx, x); 
00905         // Symphony does not get dual prices
00906         if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0) {
00907                 for(i=0; i <  osinstance->getConstraintNumber(); i++){
00908                         *(y + i) = solver->getRowPrice()[ i];
00909                 }
00910                 osresult->setDualVariableValuesDense(solIdx, y); 
00911         }
00912         // now put the reduced costs into the osrl
00913         // Symphony does not get reduced costs
00914         if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0){
00915                 // first set the number of Other Variable Results
00916                 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
00917                 for(i=0; i < numberOfVar; i++){
00918                         rcost[ i] = os_dtoa_format( solver->getReducedCost()[ i]);
00919                 }
00920                 osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", idx,  rcost, osinstance->getVariableNumber());                    
00921                 // end of setting reduced costs
00922         }
00923         osrl = osrlwriter->writeOSrL( osresult);
00924         if(osinstance->getVariableNumber() > 0) delete[] x;
00925         x = NULL;
00926         if(osinstance->getConstraintNumber()) delete[] y;
00927         y = NULL;
00928         delete[] z;     
00929         z = NULL;
00930         if(osinstance->getVariableNumber() > 0){
00931                 delete[] rcost;
00932                 rcost = NULL;
00933                 delete[] idx;
00934                 idx = NULL;
00935         }
00936 }//writeResult(OsiSolverInterface)
00937 
00938 
00939 void CoinSolver::writeResult(CbcModel *model){
00940         double *x = NULL;
00941         double *y = NULL;
00942         double *z = NULL;
00943         int *idx = NULL;
00944         std::string *rcost = NULL;
00945         x = new double[osinstance->getVariableNumber() ];
00946         y = new double[osinstance->getConstraintNumber() ];
00947         idx = new int[ osinstance->getVariableNumber() ];
00948         z = new double[1];
00949         rcost = new std::string[ osinstance->getVariableNumber()];
00950 
00951         int numberOfOtherVariableResults = 1;
00952         int otherIdx = 0;       
00953         int numberOfVar =  osinstance->getVariableNumber();
00954         int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
00955         int i = 0;
00956         int solIdx = 0;
00957         std::string description = "";
00958         osresult->setGeneralStatusType("normal");
00959         osresult->setTime(cpuTime);
00960         
00961         if (model->isProvenOptimal() == true  ){
00962                 osresult->setSolutionStatus(solIdx, "optimal", description);                    
00963         }
00964         else{ 
00965                 if(model->isProvenInfeasible() == true) 
00966                         osresult->setSolutionStatus(solIdx, "infeasible", "the integer program is infeasible");
00967                 else
00968                         if(model->isProvenDualInfeasible() == true) 
00969                                 osresult->setSolutionStatus(solIdx, "infeasible", "the continuous relaxation is dual infeasible");
00970                         else
00971                                 if(model->isContinuousUnbounded() == true) 
00972                                         osresult->setSolutionStatus(solIdx, "other", "the continuous relaxation is unbounded");
00973                                 else
00974                                         if(model->isNodeLimitReached() == true) 
00975                                                 osresult->setSolutionStatus(solIdx, "other", "node limit reached");
00976                                         else
00977                                                 if(model->isSecondsLimitReached() == true) 
00978                                                         osresult->setSolutionStatus(solIdx, "other", "time limit reached");
00979                                                 else
00980                                                         if(model->isSolutionLimitReached() == true) 
00981                                                                 osresult->setSolutionStatus(solIdx, "other", "solution limit reached");
00982                                                         else
00983                                                                 if(model->isAbandoned() == true) 
00984                                                                         osresult->setSolutionStatus(solIdx, "other", "there are numerical difficulties");
00985                                                                 else
00986                                                                         osresult->setSolutionStatus(solIdx, "other","unknown");
00987         }
00988         
00989         /* Retrieve the solution -- of course it may not be optimal */
00990         if(numOfIntVars > 0) *(z + 0)  =  model->getObjValue();
00991         osresult->setObjectiveValuesDense(solIdx, z); 
00992         for(i=0; i < osinstance->getVariableNumber(); i++){
00993                 *(x + i) = model->getColSolution()[i];
00994                 *(idx + i) = i;
00995         }
00996         osresult->setPrimalVariableValuesDense(solIdx, x); 
00997         for(i=0; i <  osinstance->getConstraintNumber(); i++){
00998                 *(y + i) = model->getRowPrice()[ i];
00999         }
01000         osresult->setDualVariableValuesDense(solIdx, y); 
01001         // now put the reduced costs into the osrl
01002         // first set the number of Other Variable Results
01003         osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
01004         for(i=0; i < numberOfVar; i++){
01005                 rcost[ i] = os_dtoa_format( model->getReducedCost()[ i]);
01006         }
01007         osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", idx,  rcost, osinstance->getVariableNumber());                    
01008         // end of setting reduced costs 
01009         osrl = osrlwriter->writeOSrL( osresult);
01010         //garbage collection
01011         if(osinstance->getVariableNumber() > 0) delete[] x;
01012         x = NULL;
01013         if(osinstance->getConstraintNumber()) delete[] y;
01014         y = NULL;
01015         delete[] z;     
01016         z = NULL;
01017         if(osinstance->getVariableNumber() > 0){
01018                 delete[] rcost;
01019                 rcost = NULL;
01020                 delete[] idx;
01021                 idx = NULL;
01022         }
01023 }//writeResult( CbcModel)
01024 
01025 

Generated on Thu Oct 8 03:03:01 2009 by  doxygen 1.4.7