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

- File List
- File Members

# /home/coin/SVN-release/OS-2.3.5/OS/v2.0/OSCoinSolver.cpp

Go to the documentation of this file.

    00001
    00020 #define DEBUG
    00021
    00022 #include "OSCoinSolver.h"
    00023 #include "OSInstance.h"
    00024 #include "OSFileUtil.h"
    00025 #include "CoinTime.hpp"
    00026 #include "CglPreProcess.hpp"
    00027 #include "CglGomory.hpp"
    00028 #include "CglSimpleRounding.hpp"
    00029 #include "CglMixedIntegerRounding2.hpp"
    00030 #include "CglKnapsackCover.hpp"
    00031 #include "CglFlowCover.hpp"
    00032 #include "CbcModel.hpp"
    00033 #include "CbcBranchActual.hpp" //for CbcSOS
    00034
    00035 #include "OsiClpSolverInterface.hpp"
    00036 #include "OsiSymSolverInterface.hpp"
    00037 #include "OsiVolSolverInterface.hpp"
    00038
    00039 #include "OSDataStructures.h"
    00040 #include "OSParameters.h"
    00041 #include "OSCommonUtil.h"
    00042 #include "OSMathUtil.h"
    00043
    00044 #include<map>
    00045
    00046 #include <iostream>
    00047 #ifdef HAVE_CTIME
    00048 # include <ctime>
    00049 #else
    00050 # ifdef HAVE_TIME_H
    00051 #  include <time.h>
    00052 # else
    00053 #  error "don't have header file for time"
    00054 # endif
    00055 #endif
    00056 using std::cout;
    00057 using std::endl;
    00058 using std::ostringstream;
    00059
    00060
    00061
    00062 CoinSolver::CoinSolver() :
    00063 osiSolver(NULL),
    00064 m_osilreader(NULL),
    00065 m_osolreader(NULL),
    00066 m_CoinPackedMatrix(NULL),
    00067 cbc_argv( NULL),
    00068 num_cbc_argv( 0),
    00069 cpuTime( 0)
    00070
    00071 {
    00072 osrlwriter = new OSrLWriter();
    00073 }
    00074
    00075 CoinSolver::~CoinSolver() {
    00076         #ifdef DEBUG
    00077         cout << "inside CoinSolver destructor" << endl;
    00078         #endif
    00079         if(m_osilreader != NULL) delete m_osilreader;
    00080         m_osilreader = NULL;
    00081         if(m_osolreader != NULL) delete m_osolreader;
    00082         m_osolreader = NULL;
    00083         delete m_CoinPackedMatrix;
    00084         m_CoinPackedMatrix = NULL;
    00085         delete osiSolver;
    00086         if(osiSolver != NULL) osiSolver = NULL;
    00087         delete osrlwriter;
    00088         osrlwriter = NULL;
    00089         delete osresult;
    00090         osresult = NULL;
    00091         if(num_cbc_argv > 0){
    00092                 int i;
    00093                 for(i = 0; i < num_cbc_argv; i++){
    00094                         //delete cbc_argv[ i];
    00095                 }
    00096                 //delete[] cbc_argv;
    00097                 cbc_argv = NULL;
    00098         }
    00099         cout << "leaving CoinSolver destructor" << endl;
    00100 }
    00101
    00102
    00103 void CoinSolver::buildSolverInstance() throw (ErrorClass) {
    00104         try{
    00105                 osresult = new OSResult();
    00106                         if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
    00107                         clock_t start, finish;
    00108                         double duration;
    00109                         start = clock();
    00110                         if(osinstance == NULL){
    00111                                 m_osilreader = new OSiLReader();
    00112                                 osinstance = m_osilreader->readOSiL( osil);
    00113                         }
    00114                         finish = clock();
    00115                         duration = (double) (finish - start) / CLOCKS_PER_SEC;
    00116                         cout << "Parsing took (seconds): "<< duration << endl;
    00117                                 cout << "Start Solve with a Coin Solver" << endl;
    00118                         // get the type of solver requested from OSoL string
    00119                         bool solverIsDefined = false;
    00120                         std::cout << "SOLVER NAME =  " << sSolverName << std::endl;
    00121                         if( sSolverName.find("clp") != std::string::npos){
    00122                                 solverIsDefined = true;
    00123                                 osiSolver = new OsiClpSolverInterface();
    00124                         }
    00125                         else{
    00126                                 if( sSolverName.find("vol") != std::string::npos){
    00127                      #ifdef COIN_HAS_VOL
    00128                                         solverIsDefined = true;
    00129                                         osiSolver = new OsiVolSolverInterface();
    00130                      #endif
    00131                                 }
    00132                                 else{
    00133                                         if( sSolverName.find( "cplex") != std::string::npos){
    00134                                                 #ifdef COIN_HAS_CPX
    00135                                                 solverIsDefined = true;
    00136                                                 osiSolver = new OsiCpxSolverInterface();
    00137                                                 #endif
    00138                                         }
    00139                                         else{
    00140                                                 if(sSolverName.find( "glpk") != std::string::npos){
    00141                                                         #ifdef COIN_HAS_GLPK
    00142                                                         solverIsDefined = true;
    00143                                                         osiSolver = new OsiGlpkSolverInterface();
    00144                                                         #endif
    00145                                                 }
    00146                                                 else{
    00147                                                         if(sSolverName.find( "dylp") != std::string::npos){
    00148                                                                 #ifdef COIN_HAS_DYLP
    00149                                                                 solverIsDefined = true;
    00150                                                                 osiSolver = new OsiDylpSolverInterface();
    00151                                                                 #endif
    00152                                                         }
    00153                                                         else{
    00154                                                                 if( sSolverName.find( "symphony") != std::string::npos) {
    00155                                                                         #ifdef COIN_HAS_SYMPHONY
    00156                                                                         solverIsDefined = true;
    00157                                                                         osiSolver = new OsiSymSolverInterface();
    00158                                                                         #endif
    00159                                                                 }
    00160                                                                 else{
    00161                                                                         // default solver is CBC
    00162                                                                         solverIsDefined = true;
    00163                                                                         osiSolver = new OsiClpSolverInterface();
    00164                                                                 }
    00165                                                         }
    00166                                                 }
    00167                                         }
    00168                                 }
    00169                         }
    00170
    00171                         if(solverIsDefined == false) throw ErrorClass("a supported solver was not defined");
    00172                         if(osinstance->getConstraintNumber() <= 0)throw ErrorClass("Coin solver Needs Constraints");
    00173                         if(osinstance->getVariableNumber() <= 0)throw ErrorClass("Coin solver requires decision variables");
    00174                         if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Coin solver needs an objective function");
    00175                         if(osinstance->getLinearConstraintCoefficientNumber() <= 0) throw ErrorClass("Coin solver needs linear constraints");
    00176                         if(!setCoinPackedMatrix() ) throw ErrorClass("Problem generating coin packed matrix");
    00177                         osiSolver->loadProblem(*m_CoinPackedMatrix, osinstance->getVariableLowerBounds(),
    00178                                 osinstance->getVariableUpperBounds(),
    00179                                 osinstance->getDenseObjectiveCoefficients()[0],
    00180                                 osinstance->getConstraintLowerBounds(), osinstance->getConstraintUpperBounds()
    00181                         );
    00182                         //dataEchoCheck();
    00183                         if(osinstance->getObjectiveNumber() == 0) throw ErrorClass("there is no objective function");
    00184                         if( osinstance->getObjectiveMaxOrMins()[0] == "min") osiSolver->setObjSense(1.0);
    00185                         else osiSolver->setObjSense(-1.0);
    00186                         // set the integer variables
    00187                         int *intIndex = NULL;
    00188                         int i = 0;
    00189                         int k = 0;
    00190                         char *varType;
    00191                         int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
    00192                         if(numOfIntVars > 0) {
    00193                                 intIndex = new int[ numOfIntVars];
    00194                                 varType = osinstance->getVariableTypes();
    00195                                 for(i = 0; i < osinstance->getVariableNumber(); i++){
    00196                                         if( (varType[i] == 'B') || (varType[i]) == 'I' ) {
    00197                                                 intIndex[k++] = i;
    00198                                         }
    00199                                 }
    00200                                 osiSolver->setInteger( intIndex,  numOfIntVars);
    00201                         }
    00202                         if(numOfIntVars > 0){
    00203                                 delete[] intIndex;
    00204                                 intIndex = NULL;
    00205                         }
    00206                         bCallbuildSolverInstance = true;
    00207         }
    00208         catch(const ErrorClass& eclass){
    00209                 std::cout << "THERE IS AN ERROR" << std::endl;
    00210                 osresult->setGeneralMessage( eclass.errormsg);
    00211                 osresult->setGeneralStatusType( "error");
    00212                 osrl = osrlwriter->writeOSrL( osresult);
    00213                 throw ErrorClass( osrl) ;
    00214         }
    00215 }//end buildSolverInstance()
    00216
    00217
    00218
    00219 void CoinSolver::setSolverOptions() throw (ErrorClass) {
    00220
    00221
    00222
    00223         // the osi maps
    00224         // the OsiHintParamameter Map
    00225         std::map<std::string, OsiHintParam> hintParamMap;
    00226         hintParamMap["OsiDoPresolveInInitial"] = OsiDoPresolveInInitial;
    00227         hintParamMap["OsiDoDualInInitial"] = OsiDoDualInInitial;
    00228         hintParamMap["OsiDoPresolveInResolve"] = OsiDoPresolveInResolve;
    00229         hintParamMap["OsiDoDualInResolve"] = OsiDoDualInResolve;
    00230         hintParamMap["OsiDoScale"] = OsiDoScale;
    00231         hintParamMap["OsiDoCrash"] = OsiDoCrash;
    00232         hintParamMap["OsiDoReducePrint"] = OsiDoReducePrint;
    00233         hintParamMap["OsiDoInBranchAndCut"] =  OsiDoInBranchAndCut;
    00234         hintParamMap["OsiLastHintParam"] = OsiLastHintParam;
    00235         //
    00236         // the OsiHintStrength Map
    00237         std::map<std::string, OsiHintStrength> hintStrengthMap;
    00238         hintStrengthMap["OsiHintIgnore"] = OsiHintIgnore;
    00239         hintStrengthMap["OsiHintTry"] = OsiHintTry;
    00240         hintStrengthMap["OsiHintDo"] = OsiHintDo;
    00241         hintStrengthMap["OsiForceDo"] = OsiForceDo;
    00242         //
    00243         // the OsiStrParam Map
    00244         std::map<std::string, OsiStrParam> strParamMap;
    00245         strParamMap["OsiProbName"] = OsiProbName;
    00246         strParamMap["OsiSolverName"] = OsiSolverName;
    00247         strParamMap["OsiLastStrParam"] = OsiLastStrParam;
    00248         //
    00249         // the OsiDblParam Map
    00250         std::map<std::string, OsiDblParam>  dblParamMap;
    00251         dblParamMap["OsiDualObjectiveLimit"] = OsiDualObjectiveLimit;
    00252         dblParamMap["OsiPrimalObjectiveLimit"] = OsiPrimalObjectiveLimit;
    00253         dblParamMap["OsiDualTolerance"] = OsiDualTolerance;
    00254         dblParamMap["OsiPrimalTolerance"] = OsiPrimalTolerance;
    00255         dblParamMap["OsiObjOffset"] = OsiObjOffset;
    00256         dblParamMap["OsiLastDblParam"] = OsiLastDblParam;
    00257         //
    00258         //
    00259         // the OsiIntParam Map
    00260         std::map<std::string, OsiIntParam>  intParamMap;
    00261         intParamMap["OsiMaxNumIteration"] = OsiMaxNumIteration;
    00262         intParamMap["OsiMaxNumIterationHotStart"] = OsiMaxNumIterationHotStart;
    00263         intParamMap["OsiNameDiscipline"] = OsiNameDiscipline;
    00264         intParamMap["OsiLastIntParam"] = OsiLastIntParam;
    00265         //
    00266         //
    00267         // initialize low level of printing
    00268
    00269
    00270         /*
    00271          * start default settings -- these get set
    00272          * even when the OSOption object is NULL
    00273          *
    00274          * */
    00275         OsiHintStrength hintStrength = OsiHintTry; //don't want too much output
    00276         osiSolver->setHintParam(OsiDoReducePrint, true, hintStrength);
    00277         osiSolver->setDblParam(OsiObjOffset, osinstance->getObjectiveConstants()[0]);
    00278         /*
    00279          * end default settings
    00280          *
    00281          * */
    00282
    00283         //
    00284         try{
    00285                 if(osoption == NULL && osol.length() > 0)
    00286                 {
    00287                         m_osolreader = new OSoLReader();
    00288                         osoption = m_osolreader->readOSoL( osol);
    00289                 }
    00290
    00291                 if(osoption != NULL){
    00292
    00293                         std::cout << "number of solver options "  <<  osoption->getNumberOfSolverOptions() << std::endl;
    00294                         if( osoption->getNumberOfSolverOptions() <= 0) return;
    00295                         this->bSetSolverOptions = true;
    00296                         std::vector<SolverOption*> optionsVector;
    00297                         //get the osi options
    00298                         optionsVector = osoption->getSolverOptions( "osi");
    00299                         int num_osi_options = optionsVector.size();
    00300                         int i;
    00301                         char *pEnd;
    00302                         bool yesNo;
    00303
    00304                         for(i = 0; i < num_osi_options; i++){
    00305                                 std::cout << "osi solver option  "  << optionsVector[ i]->name << std::endl;
    00306                                 if (optionsVector[ i]->type == "OsiHintStrength" ){
    00307                                         if( hintStrengthMap.find( optionsVector[ i]->name ) != hintStrengthMap.end() ){
    00308                                                 hintStrength = hintStrengthMap[ optionsVector[ i]->name] ;
    00309                                         }
    00310                                 }
    00311                         }
    00312                         for(i = 0; i < num_osi_options; i++){
    00313                                 std::cout << "osi solver option  "  << optionsVector[ i]->name << std::endl;
    00314
    00315                                 if (optionsVector[ i]->type == "OsiHintParam" ){
    00316
    00317                                         if( optionsVector[ i]->value == "true" ) {
    00318                                                 yesNo = true;
    00319                                         }
    00320                                         else{
    00321                                                 yesNo = false;
    00322                                         }
    00323                                         if( hintParamMap.find( optionsVector[ i]->name ) != hintParamMap.end() ){
    00324
    00325                                                 osiSolver->setHintParam( hintParamMap[ optionsVector[ i]->name] , yesNo, hintStrength);
    00326                                         }
    00327
    00328                                 }
    00329                                 else if(optionsVector[ i]->type == "OsiStrParam" ){
    00330
    00331                                         if( strParamMap.find( optionsVector[ i]->name ) != strParamMap.end() ){
    00332
    00333                                                 osiSolver->setStrParam( strParamMap[ optionsVector[ i]->name] , optionsVector[ i]->value);
    00334                                         }
    00335
    00336                                 }
    00337                                 else if(optionsVector[ i]->type == "OsiDblParam" ){
    00338
    00339                                         if( dblParamMap.find( optionsVector[ i]->name ) != dblParamMap.end() ){
    00340
    00341                                                 osiSolver->setDblParam( dblParamMap[ optionsVector[ i]->name] , os_strtod( optionsVector[ i]->value.c_str(), &pEnd ));
    00342                                         }
    00343
    00344                                 }
    00345                                 else if(optionsVector[ i]->type == "OsiIntParam" ){
    00346
    00347
    00348                                         if( intParamMap.find( optionsVector[ i]->name ) != intParamMap.end() ){
    00349
    00350                                                 osiSolver->setIntParam( intParamMap[ optionsVector[ i]->name] , atoi( optionsVector[ i]->value.c_str() ) );
    00351                                         }
    00352
    00353                                 }
    00354                         }
    00355
    00356                         // treat Cbc separately to take advantage of CbcMain1()
    00357
    00358
    00359
    00360
    00361
    00362                         //if(optionsVector.size() > 0) optionsVector.clear();
    00363 //                      if( !optionsVector.empty() ) optionsVector.clear();     //HIG: This must eventually come out
    00364
    00365                         if( sSolverName.find( "cbc") != std::string::npos) {
    00366                                 // get Cbc options
    00367                                 optionsVector = osoption->getSolverOptions( "cbc");
    00368                                 int num_cbc_options = optionsVector.size();
    00369                                 char *cstr;
    00370                                 std::string cbc_option;
    00371                                 // we are going to add a log level option -- it can be overridden
    00372                                 num_cbc_argv = optionsVector.size() + 2;
    00373                                 cbc_argv = new const char*[ num_cbc_argv];
    00374
    00375                                 // the first option
    00376                                 cbc_option = "OS";
    00377                                 cstr = new char [cbc_option.size() + 1];
    00378                                 strcpy (cstr, cbc_option.c_str());
    00379                                 cbc_argv[ 0] = cstr;
    00380
    00381
    00382                                 for(i = 0; i < num_cbc_options; i++){
    00383                                         std::cout << "cbc solver option  "  << optionsVector[ i]->name << std::endl;
    00384                                         std::cout << "cbc solver value  "  << optionsVector[ i]->value << std::endl;
    00385                                         if(optionsVector[ i]->value.length() > 0){
    00386                                                 cbc_option = "-" + optionsVector[ i]->name +"="+optionsVector[ i]->value;
    00387                                         }
    00388                                         else{
    00389                                                 cbc_option = "-" + optionsVector[ i]->name ;
    00390                                         }
    00391                                         cstr = new char [cbc_option.size() + 1];
    00392                                         strcpy (cstr, cbc_option.c_str());
    00393                                         cbc_argv[i +  1] = cstr;
    00394                                 }
    00395
    00396                                 // the quit option
    00397                                 cbc_option = "-quit";
    00398                                 cstr = new char [cbc_option.size() + 1];
    00399                                 strcpy (cstr, cbc_option.c_str());
    00400                                 cbc_argv[ num_cbc_argv - 1] = cstr;
    00401
    00402                         }//end of cbc if
    00403
    00404                         // also need to treat SYMPHONY differently
    00405
    00406
    00407                         // set some OSI options
    00408         #ifdef COIN_HAS_SYMPHONY
    00409                         //if(optionsVector.size() > 0) optionsVector.clear();
    00410                         if( !optionsVector.empty() ) optionsVector.clear();
    00411                         //first the number of processors -- applies only to SYMPHONY
    00412                         if( sSolverName.find( "symphony") != std::string::npos) {
    00413                                 OsiSymSolverInterface * si =
    00414                                 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
    00415
    00416                                 optionsVector = osoption->getSolverOptions( "symphony");
    00417                                 int num_sym_options = optionsVector.size();
    00418
    00419
    00420                                 for(i = 0; i < num_sym_options; i++){
    00421                                         std::cout << "symphony solver option  "  << optionsVector[ i]->name << std::endl;
    00422                                         std::cout << "symphony solver value  "  << optionsVector[ i]->value << std::endl;
    00423                                         if( optionsVector[ i]->name  ==  "max_active_nodes"){
    00424                                                 si->setSymParam("max_active_nodes",   optionsVector[ i]->value);
    00425                                         }
    00426                                         else{
    00427                                                 //ignore for now
    00428                                         }
    00429                                 }
    00430                         }
    00431         #endif     //symphony end
    00432
    00433
    00434                         //now set initial values
    00435                         int n,m,k;
    00436                         if (osoption != NULL)
    00437                                 m = osoption->getNumberOfInitVarValues();
    00438                         else
    00439                                 m = 0;
    00440 #ifdef DEBUG
    00441                         cout << "number of variables initialed: " << m << endl;
    00442 #endif
    00443
    00444                         if (m > 0)
    00445                         {
    00446 #ifdef DEBUG
    00447                         cout << "get initial values " << endl;
    00448 #endif
    00449                                 n = osinstance->getVariableNumber();
    00450                                 double* denseInitVarVector;
    00451                                 denseInitVarVector = new double[n];
    00452                                 bool* initialed;
    00453                                 initialed = new bool[n];
    00454
    00455                                 for(k = 0; k < n; k++)
    00456                                         initialed[k] = false;
    00457
    00458                                 InitVarValue**  initVarVector = osoption->getInitVarValuesSparse();
    00459 #ifdef DEBUG
    00460                                 cout << "done " << endl;
    00461 #endif
    00462
    00463                                 double initval;
    00464                                 for(k = 0; k < m; k++)
    00465                                 {       cout << "process component " << k << " -- index " << initVarVector[k]->idx << endl;
    00466                                         i = initVarVector[k]->idx;
    00467                                         if (initVarVector[k]->idx > n)
    00468                                                 throw ErrorClass ("Illegal index value in variable initialization");
    00469
    00470                                                 initval = initVarVector[k]->value;
    00471                                                 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
    00472                                                 {       if (osinstance->instanceData->variables->var[k]->lb > initval)
    00473                                                                 throw ErrorClass ("Initial value outside of bounds");
    00474                                                 }
    00475                                                 else
    00476                                                         if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
    00477                                                         {       if (osinstance->instanceData->variables->var[k]->ub < initval)
    00478                                                                         throw ErrorClass ("Initial value outside of bounds");
    00479                                                         }
    00480                                                         else
    00481                                                         {       if ((osinstance->instanceData->variables->var[k]->lb > initval) ||
    00482                                                                         (osinstance->instanceData->variables->var[k]->ub < initval))
    00483                                                                         throw ErrorClass ("Initial value outside of bounds");
    00484                                                         }
    00485
    00486                                         denseInitVarVector[initVarVector[k]->idx] = initval;
    00487                                         initialed[initVarVector[k]->idx] = true;
    00488                                 }
    00489
    00490                                 double default_initval;
    00491                                 default_initval = 0.0;
    00492
    00493                                 for(k = 0; k < n; k++)
    00494                                 {       cout << "verify component " << k << endl;
    00495                                         if (!initialed[k])
    00496                                                 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
    00497                                                         if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
    00498                                                                 denseInitVarVector[k] = default_initval;
    00499                                                         else
    00500                                                                 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
    00501                                                 else
    00502                                                         if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
    00503                                                                 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
    00504                                                                         denseInitVarVector[k] = default_initval;
    00505                                                                 else
    00506                                                                         denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
    00507                                                         else
    00508                                                                 if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
    00509                                                                         (osinstance->instanceData->variables->var[k]->ub >= default_initval))
    00510                                                                         denseInitVarVector[k] = default_initval;
    00511                                                                 else
    00512                                                                         if (osinstance->instanceData->variables->var[k]->lb > default_initval)
    00513                                                                                 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
    00514                                                                         else
    00515                                                                                 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
    00516                                                                         denseInitVarVector[k] = default_initval;
    00517                                                                         denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
    00518                                 }
    00519 #ifdef DEBUG
    00520                                 cout << "set initial values: " << endl;
    00521                                 for (k=0; k < n; k++)
    00522                                         cout << "  " << k << ": " << denseInitVarVector[k] << endl;
    00523 #endif
    00524                                 osiSolver->setColSolution( denseInitVarVector);
    00525                                 delete[] denseInitVarVector;
    00526                                 delete[] initialed;
    00527 #ifdef DEBUG
    00528                         cout << "done " << endl;
    00529 #endif
    00530
    00531                         }  //  end if (m > 0)
    00532                 }// end of osoption if
    00533
    00534
    00535         }//end of try
    00536         catch(const ErrorClass& eclass){
    00537                 std::cout << "THERE IS AN ERROR" << std::endl;
    00538                 osresult->setGeneralMessage( eclass.errormsg);
    00539                 osresult->setGeneralStatusType( "error");
    00540                 osrl = osrlwriter->writeOSrL( osresult);
    00541                 throw ErrorClass( osrl) ;
    00542         }
    00543 }//end setSolverOptions()
    00544
    00545
    00546 bool CoinSolver::setCoinPackedMatrix(){
    00547         bool columnMajor = osinstance->getLinearConstraintCoefficientMajor();
    00548         try{
    00549                 int maxGap = 0;
    00550                 m_CoinPackedMatrix = new CoinPackedMatrix(
    00551                         columnMajor, //Column or Row Major
    00552                         columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(), //Minor Dimension
    00553                         columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(), //Major Dimension
    00554                         osinstance->getLinearConstraintCoefficientNumber(), //Number of nonzeroes
    00555                         columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->values : osinstance->getLinearConstraintCoefficientsInRowMajor()->values, //Pointer to matrix nonzeroes
    00556                         columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes : osinstance->getLinearConstraintCoefficientsInRowMajor()->indexes, //Pointer to start of minor dimension indexes -- change to allow for row storage
    00557                         columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts : osinstance->getLinearConstraintCoefficientsInRowMajor()->starts, //Pointers to start of columns.
    00558                         0,   0, maxGap );
    00559
    00560                 return true;
    00561         }
    00562         catch(const ErrorClass& eclass){
    00563                 osresult->setGeneralMessage( eclass.errormsg);
    00564                 osresult->setGeneralStatusType( "error");
    00565                 osrl = osrlwriter->writeOSrL( osresult);
    00566                 throw ;
    00567         }
    00568 } // end setCoinPackedMatrix
    00569
    00570 void CoinSolver::solve() throw (ErrorClass) {
    00571         // make sure the solver instance exists
    00572         if( this->bCallbuildSolverInstance == false) buildSolverInstance();
    00573         if( this->bSetSolverOptions == false) setSolverOptions();
    00574
    00575         // first check the various solvers and see if they are of the proper problem type
    00576         if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
    00577                 // throw an exception if we have a solver that cannot do integer programming
    00578                 if( sSolverName.find("clp") != std::string::npos) throw ErrorClass( "Clp cannot do integer programming");
    00579                 if( sSolverName.find("vol") != std::string::npos) throw ErrorClass( "Vol cannot do integer programming");
    00580                 if( sSolverName.find("dylp") != std::string::npos) throw ErrorClass( "DyLP cannot do integer programming");
    00581                 if( sSolverName.find("ipopt") != std::string::npos) throw ErrorClass( "Ipopt cannot do integer programming");
    00582         }
    00583         if( (osinstance->getNumberOfNonlinearExpressions() > 0)
    00584                 || (osinstance->getNumberOfQuadraticTerms() > 0) ){
    00585                 throw ErrorClass( "This COIN-OR Solver is not configured for nonlinear programming");
    00586         }
    00587         // if we are throw an exception if the problem is nonlinear
    00588
    00589         // resultHeader information
    00590         if(osresult->setServiceName("Solved with Coin Solver: " + sSolverName) != true)
    00591                 throw ErrorClass("OSResult error: setServiceName");
    00592         if(osresult->setInstanceName(  osinstance->getInstanceName()) != true)
    00593                 throw ErrorClass("OSResult error: setInstanceName");
    00594         //if(osresult->setJobID( osresultdata->jobID) != true)
    00595         //      throw ErrorClass("OSResult error: setJobID");
    00596         //if(osresult->setGeneralMessage( osresultdata->message) != true)
    00597         //      throw ErrorClass("OSResult error: setGeneralMessage");
    00598         // set basic problem parameters
    00599         if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
    00600                 throw ErrorClass("OSResult error: setVariableNumer");
    00601         if(osresult->setObjectiveNumber( 1) != true)
    00602                 throw ErrorClass("OSResult error: setObjectiveNumber");
    00603         if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
    00604                 throw ErrorClass("OSResult error: setConstraintNumber");
    00605         if(osresult->setSolutionNumber(  1) != true)
    00606                 throw ErrorClass("OSResult error: setSolutionNumer");
    00607         //
    00608         try{
    00609                 double start = CoinCpuTime();
    00610                 try{
    00611                         if( sSolverName.find( "cbc") != std::string::npos){
    00612                         //if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
    00613                         // just use simple branch and bound for anything but cbc
    00614                                 CbcModel model(  *osiSolver);
    00615                                 CbcMain0(  model);
    00616
    00617
    00618                                 // make sure we define cbc_argv if not done already when reading options
    00619                                 if(num_cbc_argv <= 0){
    00620                                         char *cstr;
    00621                                         std::string cbc_option;
    00622                                         num_cbc_argv = 4;
    00623                                         cbc_argv = new const char*[ num_cbc_argv];
    00624
    00625                                         // the first option
    00626                                         cbc_option = "OS";
    00627                                         cstr = new char [cbc_option.size() + 1];
    00628                                         strcpy (cstr, cbc_option.c_str());
    00629                                         cbc_argv[ 0] = cstr;
    00630
    00631
    00632                                         // the log option -- by default minimal printing
    00633                                         cbc_option = "-log=0";
    00634                                         cstr = new char [cbc_option.size() + 1];
    00635                                         strcpy (cstr, cbc_option.c_str());
    00636                                         cbc_argv[ 1] = cstr;
    00637
    00638
    00639                                         // the solve option
    00640                                         cbc_option = "-solve";
    00641                                         cstr = new char [cbc_option.size() + 1];
    00642                                         strcpy (cstr, cbc_option.c_str());
    00643                                         cbc_argv[ 2] = cstr;
    00644
    00645                                         // the quit option
    00646                                         cbc_option = "-quit";
    00647                                         cstr = new char [cbc_option.size() + 1];
    00648                                         strcpy (cstr, cbc_option.c_str());
    00649                                         cbc_argv[ 3] = cstr;
    00650
    00651                                 }
    00652                                 std::cout << "CALLING THE CBC SOLVER CBCMAIN1()" << std::endl;
    00653                                 int i;
    00654                                 for(i = 0; i < num_cbc_argv; i++){
    00655                                         std::cout << "Cbc Option: "  << cbc_argv[ i]   <<  std::endl;
    00656                                 }
    00657                                 CbcMain1( num_cbc_argv, cbc_argv, model);
    00658
    00659                                 //do the garbage collection on cbc_argv
    00660                                 for(i = 0; i < num_cbc_argv; i++){
    00661                                         delete[]  cbc_argv[ i];
    00662                                         cbc_argv[i] = NULL;
    00663                                 }
    00664                                 delete[] cbc_argv;
    00665                                 cbc_argv = NULL;
    00666
    00667
    00668                                 // create a solver
    00669                                 OsiSolverInterface *solver = model.solver();
    00670                                 cpuTime = CoinCpuTime() - start;
    00671
    00672                                 writeResult( solver);
    00673                         }
    00674                         else{ // use other solvers
    00675                                 //if an LP just do initial solve
    00676                                 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
    00677                                         osiSolver->branchAndBound();
    00678                                 }
    00679                                 else{
    00680                                         osiSolver->initialSolve();
    00681                                 }
    00682                                 cpuTime = CoinCpuTime() - start;
    00683
    00684                                 writeResult( osiSolver);
    00685                         }
    00686
    00687
    00688                 }
    00689                 catch(CoinError e){
    00690                         std::string errmsg;
    00691                         errmsg = "Coin Solver Error: " + e.message() + "\n" + " see method "
    00692                                 + e.methodName() + " in class " + e.className();
    00693                         throw ErrorClass( errmsg );
    00694                 }
    00695
    00696         }
    00697         catch(const ErrorClass& eclass){
    00698                 osresult->setGeneralMessage( eclass.errormsg);
    00699                 osresult->setGeneralStatusType( "error");
    00700                 osrl = osrlwriter->writeOSrL( osresult);
    00701                 throw ;
    00702         }
    00703 } // end solve
    00704
    00705 std::string CoinSolver::getCoinSolverType(std::string lcl_osol){
    00706 // this is deprecated, but keep it around
    00707         try{
    00708                 if( lcl_osol.find( "clp") != std::string::npos){
    00709                         return "coin_solver_glpk";
    00710                 }
    00711                 else{
    00712                         if( lcl_osol.find( "cbc") != std::string::npos){
    00713                                 return "coin_solver_cpx";
    00714                         }
    00715                         else{
    00716                                 if( lcl_osol.find( "cpx") != std::string::npos){
    00717                                         return "coin_solver_clp";
    00718                                 }
    00719                                 else{
    00720                                         if(lcl_osol.find( "glpk") != std::string::npos){
    00721                                                 return "";
    00722                                         }
    00723                                         else throw ErrorClass("a supported solver was not defined");
    00724                                 }
    00725                         }
    00726                 }
    00727         }
    00728         catch(const ErrorClass& eclass){
    00729                 osresult->setGeneralMessage( eclass.errormsg);
    00730                 osresult->setGeneralStatusType( "error");
    00731                 osrl = osrlwriter->writeOSrL( osresult);
    00732                 throw ;
    00733         }
    00734 } // end getCoinSolverType
    00735
    00736 void CoinSolver::dataEchoCheck(){
    00737         int i;
    00738         // print out problem parameters
    00739         cout << "This is problem:  " << osinstance->getInstanceName() << endl;
    00740         cout << "The problem source is:  " << osinstance->getInstanceSource() << endl;
    00741         cout << "The problem description is:  " << osinstance->getInstanceDescription() << endl;
    00742         cout << "number of variables = " << osinstance->getVariableNumber() << endl;
    00743         cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
    00744
    00745         // print out the variable information
    00746         if(osinstance->getVariableNumber() > 0){
    00747                 for(i = 0; i < osinstance->getVariableNumber(); i++){
    00748                         if(osinstance->getVariableNames() != NULL) cout << "variable Names  " << osinstance->getVariableNames()[ i]  << endl;
    00749                         if(osinstance->getVariableTypes() != NULL) cout << "variable Types  " << osinstance->getVariableTypes()[ i]  << endl;
    00750                         if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds  " << osinstance->getVariableLowerBounds()[ i]  << endl;
    00751                         if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds  " <<  osinstance->getVariableUpperBounds()[i] << endl;
    00752                 }
    00753         }
    00754
    00755         // print out objective function information
    00756         if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0){
    00757                 if( osinstance->getObjectiveMaxOrMins()[0] == "min")  cout <<  "problem is a minimization" << endl;
    00758                 else cout <<  "problem is a maximization" << endl;
    00759                 for(i = 0; i < osinstance->getVariableNumber(); i++){
    00760                         cout << "OBJ COEFFICIENT =  " <<  osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
    00761                 }
    00762         }
    00763         // print out constraint information
    00764         if(osinstance->getConstraintNumber() > 0){
    00765                 for(i = 0; i < osinstance->getConstraintNumber(); i++){
    00766                         if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] <<  endl;
    00767                         if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] <<  endl;
    00768                         if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] <<  endl;
    00769                 }
    00770         }
    00771
    00772         // print out linear constraint data
    00773         if(m_CoinPackedMatrix != NULL) m_CoinPackedMatrix->dumpMatrix();
    00774 } // end dataEchoCheck
    00775
    00776
    00777
    00778 void CoinSolver::writeResult(OsiSolverInterface *solver){
    00779         double *x = NULL;
    00780         double *y = NULL;
    00781         double *z = NULL;
    00782         int i = 0;
    00783         std::string *rcost = NULL;
    00784         int solIdx = 0;
    00785         int n, m;
    00786         std::string description = "";
    00787         osresult->setGeneralStatusType("normal");
    00788 //      osresult->resultHeader->time = os_dtoa_format(  cpuTime);
    00789         osresult->addTimingInformation("cpuTime","total","second","",cpuTime);
    00790         if (solver->isProvenOptimal() == true){
    00791                 osresult->setSolutionStatus(solIdx, "optimal", description);
    00792                 /* Retrieve the solution */
    00793                 x = new double[osinstance->getVariableNumber() ];
    00794                 y = new double[osinstance->getConstraintNumber() ];
    00795                 z = new double[1];
    00796                 n = osinstance->getVariableNumber();
    00797                 m = osinstance->getConstraintNumber();
    00798                 rcost = new std::string[ osinstance->getVariableNumber()];
    00799                 //
    00800                 *(z + 0)  =  solver->getObjValue();
    00801                 osresult->setObjectiveValues(solIdx, z, 1);
    00802                 for(i=0; i < osinstance->getVariableNumber(); i++){
    00803                         *(x + i) = solver->getColSolution()[i];
    00804                 }
    00805                 osresult->setPrimalVariableValues(solIdx, x, n);
    00806                 // Symphony does not get dual prices
    00807                 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0) {
    00808                         for(i=0; i <  osinstance->getConstraintNumber(); i++){
    00809                                 *(y + i) = solver->getRowPrice()[ i];
    00810                         }
    00811                         osresult->setDualVariableValues(solIdx, y, osinstance->getConstraintNumber());
    00812                 }
    00813                 //
    00814                 //
    00815                 // now put the reduced costs into the osrl
    00816                 // Symphony does not get reduced costs
    00817                 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0){
    00818                         int numberOfOtherVariableResults = 1;
    00819                         int otherIdx = 0;
    00820                         // first set the number of Other Variable Results
    00821                         osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
    00822                         ostringstream outStr;
    00823                         int numberOfVar =  osinstance->getVariableNumber();
    00824                         for(i=0; i < numberOfVar; i++){
    00825                                 rcost[ i] = os_dtoa_format( solver->getReducedCost()[ i]);
    00826                         }
    00827                         osresult->setAnOtherVariableResult(solIdx, otherIdx, "reduced costs", "the variable reduced costs", rcost, osinstance->getVariableNumber());
    00828                         // end of settiing reduced costs
    00829                 }
    00830         }
    00831         else{
    00832                 if(solver->isProvenPrimalInfeasible() == true)
    00833                         osresult->setSolutionStatus(solIdx, "infeasible", description);
    00834                 else
    00835                         if(solver->isProvenDualInfeasible() == true)
    00836                                 osresult->setSolutionStatus(solIdx, "dualinfeasible", description);
    00837                         else
    00838                                 osresult->setSolutionStatus(solIdx, "other", description);
    00839         }
    00840         osrl = osrlwriter->writeOSrL( osresult);
    00841         if(osinstance->getVariableNumber() > 0) delete[] x;
    00842         x = NULL;
    00843         if(osinstance->getConstraintNumber()) delete[] y;
    00844         y = NULL;
    00845         delete[] z;
    00846         z = NULL;
    00847         if(osinstance->getVariableNumber() > 0){
    00848                 delete[] rcost;
    00849                 rcost = NULL;
    00850         }
    00851 }
    00852