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

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

Generated on Thu Mar 31 03:13:18 2011 by  doxygen 1.4.7