/home/coin/SVN-release/OS-2.0.0/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 

Generated on Mon Aug 3 03:02:25 2009 by  doxygen 1.4.7