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

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

Generated on Thu Sep 22 03:06:04 2011 by  doxygen 1.4.7