- Main Page
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# /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