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

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

Generated on Wed Nov 30 03:04:23 2011 by  doxygen 1.4.7