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

Go to the documentation of this file.
00001 /* $Id: OSCouenneSolver.cpp 4292 2011-09-21 05:47:18Z kmartin $ */
00017 #include <iostream>
00018 
00019 
00020 //OS stuff
00021 #include "OSDataStructures.h"
00022 #include "OSParameters.h"
00023 #include "OSMathUtil.h"
00024 #include "OSCouenneSolver.h"
00025 #include "BonBonminSetup.hpp"
00026 # include <cppad/cppad.hpp>
00027 //end OS stuff
00028 
00029 
00030 // Couenne stuff
00031 
00032 #include "CouenneTypes.hpp"
00033 #include "CouenneJournalist.hpp"
00034 #include "CouenneExprClone.hpp"
00035 #include "CouenneExprGroup.hpp"
00036 #include "CouenneExprAbs.hpp"
00037 #include "CouenneExprConst.hpp"
00038 #include "CouenneExprCos.hpp"
00039 #include "CouenneExprDiv.hpp"
00040 #include "CouenneExprExp.hpp"
00041 #include "CouenneExprInv.hpp"
00042 #include "CouenneExprLog.hpp"
00043 #include "CouenneExprMax.hpp"
00044 #include "CouenneExprMin.hpp"
00045 #include "CouenneExprMul.hpp"
00046 #include "CouenneExprOpp.hpp"
00047 #include "CouenneExprPow.hpp"
00048 #include "CouenneExprSin.hpp"
00049 #include "CouenneExprSub.hpp"
00050 #include "CouenneExprSum.hpp"
00051 #include "CouenneExprVar.hpp"
00052 using namespace Couenne;
00053 // end Couenne stuff
00054 
00055 
00056 //Bonmin stuff
00057 
00058 #include "BonOsiTMINLPInterface.hpp"
00059 #include "BonIpoptSolver.hpp"
00060 
00061 
00062 #include "CoinTime.hpp"
00063 #include "BonminConfig.h"
00064 #include "BonCouenneInterface.hpp"
00065 
00066 
00067 #include "BonCouenneSetup.hpp"
00068 
00069 
00070 #ifdef COIN_HAS_FILTERSQP
00071 #include "BonFilterSolver.hpp"
00072 #endif
00073 
00074 #include "CbcCutGenerator.hpp"
00075 #include "CouenneProblem.hpp"
00076 #include "CouenneCutGenerator.hpp"
00077 
00078 
00079 # include <cstddef>
00080 # include <cstdlib>
00081 # include <cctype>
00082 # include <cassert>
00083 # include <stack>
00084 #include <string>
00085 #include<iostream>
00086 
00087 
00088 
00089 using namespace Bonmin;
00090 using std::cout;
00091 using std::endl;
00092 using std::ostringstream;
00093 
00094 
00095 CouenneSolver::CouenneSolver()
00096 {
00097     using namespace  Ipopt;
00098     osrlwriter = new OSrLWriter();
00099     osresult = new OSResult();
00100     m_osilreader = NULL;
00101     m_osolreader = NULL;
00102     couenneErrorMsg = "";
00103     couenne = NULL;
00104     con_body = NULL;
00105     obj_body = NULL;
00106 }
00107 
00108 CouenneSolver::~CouenneSolver()
00109 {
00110 #ifdef DEBUG
00111     cout << "inside CouenneSolver destructor" << endl;
00112 #endif
00113 
00114     if(couenne != NULL)
00115     {
00116         //cout << "start delete of couenne problem" << endl;
00118         //cout << "finish delete of couenne problem" << endl;
00119     }
00120     if(con_body != NULL)
00121     {
00122         //delete con_body;
00123     }
00124     if(obj_body != NULL)
00125     {
00126         //delete obj_body;
00127     }
00128     if(m_osilreader != NULL)
00129     {
00130         //cout << "start delete of osinstance" << endl;
00131         delete m_osilreader;
00132         //cout << "end delete of osinstance" << endl;
00133     }
00134     m_osilreader = NULL;
00135     if(m_osolreader != NULL) delete m_osolreader;
00136     m_osolreader = NULL;
00137     delete osresult;
00138     osresult = NULL;
00139     delete osrlwriter;
00140     osrlwriter = NULL;
00141     //delete osinstance;
00142     //osinstance = NULL;
00143 #ifdef DEBUG
00144     cout << "leaving CouenneSolver destructor" << endl;
00145 #endif
00146 
00147 }
00148 
00149 
00150 void CouenneSolver::buildSolverInstance() throw (ErrorClass)
00151 {
00152     // Much of the following is taken from Stefan Vigerske
00153     try
00154     {
00155         this->bCallbuildSolverInstance = true;
00156         // do some initialization
00157 
00158 
00159 
00160 
00161         int i, j;
00162 
00163         if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
00164         if(osinstance == NULL)
00165         {
00166             m_osilreader = new OSiLReader();
00167             osinstance = m_osilreader->readOSiL( osil);
00168         }
00169 
00170 
00171 
00172         //osinstance->initializeNonLinearStructures( );
00173         osinstance->initForAlgDiff( );
00174         //Ipopt::Journalist* jnlst = new Ipopt::Journalist();
00175         //jnlst->AddFileJournal("console", "stdout", J_STRONGWARNING);
00176         //couenne = new CouenneProblem(NULL, NULL, jnlst);
00177         couenne = new CouenneProblem(NULL, NULL, NULL);
00178         int n_allvars = osinstance->getVariableNumber();
00179         if( n_allvars < 0 )throw ErrorClass("Couenne solver Cannot have a negatiave number of Variables");
00180 #ifdef DEBUG
00181         std::cout << "NUMBER OF VARIABLES = " <<  n_allvars <<  std::endl;
00182 #endif
00183         if(n_allvars > 0)
00184         {
00185             // create room for problem's variables and bounds
00186             CouNumber *x_ = (CouNumber *) malloc ((n_allvars) * sizeof (CouNumber));
00187             CouNumber   *lb = NULL, *ub = NULL;
00188 
00189             // now get variable upper and lower bounds
00190             ub = osinstance->getVariableUpperBounds();
00191             lb = osinstance->getVariableLowerBounds();
00192 
00193             //declare the variable types
00194             char *varType;
00195             varType = osinstance->getVariableTypes();
00196             for (i = 0; i < n_allvars; ++i)
00197             {
00198                 if( (varType[i] == 'B') || (varType[i]) == 'I' )
00199                 {
00200                     couenne->addVariable(true, couenne->domain() );
00201                 }
00202                 else
00203                 {
00204 
00205                     couenne->addVariable(false, couenne->domain() );
00206 
00207                 }
00208 
00209                 x_[i] = 0.;     //HIG: This sets initial values?
00210             }
00211 
00212             couenne->domain()->push(n_allvars, x_, lb, ub);
00213             free(x_);
00214         }
00215 
00216         // now for the objective function -- assume just one for now
00217         //just worry about linear coefficients
00218 
00219         if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Couenne NEEDS AN OBJECTIVE FUNCTION");
00220 
00221 
00222         //if(n_allvars > 0){
00223         SparseVector* sv = osinstance->getObjectiveCoefficients()[ 0];
00224         int nterms = sv->number;
00225         exprGroup::lincoeff lin( nterms);
00226         for ( i = 0; i < nterms; ++i)
00227         {
00228             lin[i].first = couenne->Var( sv->indexes[ i] );
00229             if( osinstance->getObjectiveMaxOrMins()[0] == "min")
00230             {
00231                 lin[i].second = sv->values[ i];
00232             }
00233             else
00234             {
00235                 lin[i].second = -sv->values[ i];
00236 
00237             }
00238         }
00239 
00240 
00241         OSExpressionTree* exptree = osinstance->getNonlinearExpressionTree( -1);
00242         if (exptree != NULL)
00243         {
00244             expression** nl = new expression*[1];
00245             if( osinstance->getObjectiveMaxOrMins()[0] == "min")
00246             {
00247                 nl[0] = createCouenneExpression( exptree->m_treeRoot );
00248             }
00249             else
00250             {
00251                 nl[ 0] = new exprOpp(createCouenneExpression( exptree->m_treeRoot) );
00252 
00253             }
00254             obj_body = new exprGroup(osinstance->getObjectiveConstants()[0], lin, nl, 1);
00255         }
00256         else
00257         {
00258             obj_body = new exprGroup(osinstance->getObjectiveConstants()[0], lin, NULL, 0);
00259             //std::cout << "THERE WERE NO NONLINEAR TERMS IN THE OBJECTIVE FUNCTION "  << std::endl;
00260         }
00261 
00262         //}
00263         couenne->addObjective(obj_body, "min");
00264 
00265         // get the constraints in row format
00266 
00267         SparseMatrix* sm =  osinstance->getLinearConstraintCoefficientsInRowMajor();
00268 
00269         int nconss = osinstance->getConstraintNumber();
00270 
00271         int row_nonz = 0;
00272         int kount = 0;
00273         //int row_nonz_actual = 0;
00274         double *rowlb = osinstance->getConstraintLowerBounds();
00275         double *rowub = osinstance->getConstraintUpperBounds();
00276 
00277         for (i = 0; i < nconss; ++i)
00278         {
00279             //std::cout << "WE ARE PROCESSING ROW " << i << std::endl;
00280             row_nonz = 0;
00281             if( sm) row_nonz = sm->starts[ i +1] - sm->starts[ i];
00282             exprGroup::lincoeff con_lin( row_nonz);
00283             for (j = 0; j  <  row_nonz;  ++j)
00284             {
00285                 con_lin[j].first = couenne->Var( sm->indexes[ kount] );
00286                 con_lin[j].second = sm->values[ kount];
00287                 kount++;
00288             }
00289             //}
00290             OSExpressionTree* exptree = osinstance->getNonlinearExpressionTree( i);
00291             if (exptree != NULL)
00292             {
00293                 expression** nl = new expression*[1];
00294                 nl[0] = createCouenneExpression(exptree->m_treeRoot);
00295                 con_body = new exprGroup(0., con_lin, nl, 1);
00296             }
00297             else
00298             {
00299                 con_body = new exprGroup(0., con_lin, NULL, 0);
00300             }
00301 
00302             if (rowlb[ i] == rowub[ i])
00303             {
00304                 couenne->addEQConstraint(con_body, new exprConst( rowub[ i] ));
00305             }
00306             else if (rowlb[ i]  ==  -OSDBL_MAX)
00307             {
00308                 assert(rowub[ i]  !=  -OSDBL_MAX);
00309                 couenne->addLEConstraint(con_body, new exprConst( rowub[ i] ));
00310             }
00311             else if (rowub[ i] ==  OSDBL_MAX)
00312             {
00313                 assert(rowlb[ i]  != OSDBL_MAX);
00314                 couenne->addGEConstraint(con_body, new exprConst( rowlb[ i] ));
00315             }
00316             else
00317                 couenne->addRNGConstraint(con_body, new exprConst( rowlb[ i]), new
00318                                           exprConst( rowub[ i] ));
00319 
00320         }
00321     }
00322     catch(const ErrorClass& eclass)
00323     {
00324         std::cout << "THERE IS AN ERROR" << std::endl;
00325         osresult->setGeneralMessage( eclass.errormsg);
00326         osresult->setGeneralStatusType( "error");
00327         osrl = osrlwriter->writeOSrL( osresult);
00328         throw ErrorClass( osrl) ;
00329     }
00330 }//end buildSolverInstance()
00331 
00332 
00333 expression* CouenneSolver::createCouenneExpression(OSnLNode* node)
00334 {
00335     //std::cout << "NODE NUMBER =  " << node->inodeInt  << std::endl;
00336     unsigned int i;
00337     switch (node->inodeInt)
00338     {
00339     case OS_PLUS :
00340         return new exprSum(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00341     case OS_SUM :
00342         //std::cout << "I AM INSIDE A SUM NODE  "   << std::endl;
00343         //std::cout << "I HAVE THE FOLLOWING NUMBER OF CHILDREN  " <<   node->inumberOfChildren << std::endl;
00344         //switch ( node->inumberOfChildren==0 ) { // Stefan's coding
00345         switch ( node->inumberOfChildren )    //kipp modification
00346         {
00347         case 0:
00348             //std::cout << "I IN SUM CASE 0  "   << std::endl;
00349             return new exprConst(0.);
00350         case 1:
00351             //std::cout << "I IN SUM CASE 1  "   << std::endl;
00352             return createCouenneExpression(node->m_mChildren[0]);
00353         default:
00354             //std::cout << "I IN SUM CASE DEFAULT  "   << std::endl;
00355             expression** sumargs = new expression*[node->inumberOfChildren];
00356             for(i = 0;  i<  node->inumberOfChildren;  i++)
00357                 sumargs[i] = createCouenneExpression(node->m_mChildren[i]);
00358             //expression* base = new exprSum(args, node->inumberOfChildren);  //Stefan
00359             //delete[] args;  //delete Stefan's code -- causes a seg fault
00360             //return base; stefan
00361             return new exprSum(sumargs, node->inumberOfChildren);
00362         }
00363     case OS_MINUS :
00364         return new exprSub(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00365     case OS_NEGATE :
00366         return new exprOpp(createCouenneExpression(node->m_mChildren[0]));
00367     case OS_TIMES :
00368         return new exprMul(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00369     case OS_DIVIDE :
00370         // couenne does not like expressions of the form exp1/exp2 with exp1 a constant, so we write them as exp1 * 1/exp2
00371         if (node->m_mChildren[0]->inodeInt == OS_NUMBER)
00372             return new exprMul(createCouenneExpression(node->m_mChildren[0]), new exprInv(createCouenneExpression(node->m_mChildren[1])));
00373         else
00374             return new exprDiv(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00375     case OS_POWER :
00376         // couenne does not like expressions of the form exp1 ^ exp2 with exp2 not a constant, so we write them as exp(log(exp1)*exp2)
00377         if (node->m_mChildren[1]->inodeInt != OS_NUMBER)
00378             return new exprExp(new exprMul(new exprLog(createCouenneExpression(node->m_mChildren[0])), createCouenneExpression(node->m_mChildren[1])));
00379         else
00380             return new exprPow(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00381     case OS_PRODUCT:
00382         switch ( node->inumberOfChildren )
00383         {
00384         case 0:
00385             return new exprConst(1.);
00386         case 1:
00387             return createCouenneExpression(node->m_mChildren[0]);
00388         default:
00389             expression** args = new expression*[node->inumberOfChildren];
00390             for( i = 0; i < node->inumberOfChildren; i++)
00391                 args[i] = createCouenneExpression(node->m_mChildren[i]);
00392             expression* base = new exprMul(args, node->inumberOfChildren);
00393             //delete[] args;
00394             return base;
00395         }
00396     case OS_ABS :
00397         return new exprAbs(createCouenneExpression(node->m_mChildren[0]));
00398     case OS_SQUARE :
00399         return new exprPow(createCouenneExpression(node->m_mChildren[0]), new exprConst(2.));
00400     case OS_SQRT :
00401         return new exprPow(createCouenneExpression(node->m_mChildren[0]), new exprConst(0.5));
00402     case OS_LN :
00403         return new exprLog(createCouenneExpression(node->m_mChildren[0]));
00404     case OS_EXP :
00405         return new exprExp(createCouenneExpression(node->m_mChildren[0]));
00406     case OS_SIN :
00407         return new exprSin(createCouenneExpression(node->m_mChildren[0]));
00408     case OS_COS :
00409         return new exprCos(createCouenneExpression(node->m_mChildren[0]));
00410     case OS_MIN :
00411         switch (node->inumberOfChildren==0)
00412         {
00413         case 0:
00414             return new exprConst(0.);
00415         case 1:
00416             return createCouenneExpression(node->m_mChildren[0]);
00417         default:
00418             expression** args = new expression*[node->inumberOfChildren];
00419             for( i = 0; i <node->inumberOfChildren; i++)
00420                 args[i] = createCouenneExpression(node->m_mChildren[i]);
00421             expression* base = new exprMin(args, node->inumberOfChildren);
00422             //delete[] args;
00423             return base;
00424         }
00425     case OS_MAX :
00426         switch (node->inumberOfChildren==0)
00427         {
00428         case 0:
00429             return new exprConst(0.);
00430         case 1:
00431             return createCouenneExpression(node->m_mChildren[0]);
00432         default:
00433             expression** args = new expression*[node->inumberOfChildren];
00434             for(i = 0; i < node->inumberOfChildren; i++)
00435                 args[i] = createCouenneExpression(node->m_mChildren[i]);
00436             expression* base = new exprMax(args, node->inumberOfChildren);
00437             //delete[] args;
00438             return base;
00439         }
00440     case OS_NUMBER :
00441         return new exprConst(((OSnLNodeNumber*)node)->value);
00442     case OS_PI :
00443         assert(false);
00444         //TODO
00445 //       return new exprConst(PI);
00446     case OS_VARIABLE :
00447     {
00448         OSnLNodeVariable* varnode = (OSnLNodeVariable*)node;
00449         if (varnode->coef == 0.)
00450             return new exprConst(0.);
00451         if (varnode->coef == 1.)
00452             return new exprClone(couenne->Variables()[varnode->idx]);
00453         if (varnode->coef == -1.)
00454             return new exprOpp(new exprClone(couenne->Variables()[varnode->idx]));
00455         return new exprMul(new exprConst(varnode->coef), new exprClone(couenne->Variables()[varnode->idx]));
00456     }
00457     default:
00458         cout << node->getTokenName() << " NOT IMPLEMENTED!!" << endl;
00459         break;
00460     }
00461 
00462     return NULL;
00463 }
00464 
00465 
00466 void CouenneSolver::setSolverOptions() throw (ErrorClass)
00467 {
00468     try
00469     {
00470 
00471         char *pEnd;
00472         bSetSolverOptions = true;
00473         couenneSetup.initializeOptionsAndJournalist();
00474         //turn off a lot of output -- this can be overridden by using OSOptions
00475         couenneSetup.options()->SetIntegerValue("bonmin.bb_log_level", 0);
00476         couenneSetup.options()->SetIntegerValue("bonmin.nlp_log_level", 0 );
00477         if(osoption == NULL && osol.length() > 0)
00478         {
00479             m_osolreader = new OSoLReader();
00480             osoption = m_osolreader->readOSoL( osol);
00481         }
00482 
00483         if(osoption != NULL && osoption->getNumberOfSolverOptions() > 0 )
00484         {
00485 
00486             int i;
00487             std::vector<SolverOption*> optionsVector;
00488             optionsVector = osoption->getSolverOptions( "couenne",true);
00489             int num_bonmin_options = optionsVector.size();
00490             for(i = 0; i < num_bonmin_options; i++)
00491             {
00492                 if(optionsVector[ i]->type == "numeric" )
00493                 {
00494                     //std::cout << "FOUND A  NUMERIC OPTION  "  <<  os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) << std::endl;
00495                     if(optionsVector[ i]->category == "ipopt")
00496                     {
00497                         couenneSetup.options()->SetNumericValue(optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
00498                     }
00499                     else
00500                     {
00501                         if(optionsVector[ i]->category == "bonmin" )
00502                         {
00503                             couenneSetup.options()->SetNumericValue("bonmin."+optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
00504                         }
00505                         else
00506                         {
00507                             couenneSetup.options()->SetNumericValue("couenne."+optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
00508                         }
00509                     }
00510                 }
00511                 else if(optionsVector[ i]->type == "integer" )
00512                 {
00513                     //std::cout << "FOUND AN INTEGER OPTION  "  <<optionsVector[ i]->name << std::endl;
00514                     if(optionsVector[ i]->category == "ipopt")
00515                     {
00516                         couenneSetup.options()->SetIntegerValue(optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ) );
00517                     }
00518                     else
00519                     {
00520                         if(optionsVector[ i]->category == "bonmin" )
00521                         {
00522                             couenneSetup.options()->SetIntegerValue("bonmin."+optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ));
00523                         }
00524                         else
00525                         {
00526                             couenneSetup.options()->SetIntegerValue("couenne."+optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() )  );
00527                         }
00528                     }
00529                 }
00530                 else if(optionsVector[ i]->type == "string" )
00531                 {
00532                     //std::cout << "FOUND A STRING OPTION  "  <<optionsVector[ i]->name << std::endl;
00533                     if(optionsVector[ i]->category == "ipopt")
00534                     {
00535                         couenneSetup.options()->SetStringValue(optionsVector[ i]->name, optionsVector[ i]->value );
00536                     }
00537                     else
00538                     {
00539                         if(optionsVector[ i]->category == "bonmin" )
00540                         {
00541                             couenneSetup.options()->SetStringValue("bonmin."+optionsVector[ i]->name, optionsVector[ i]->value);
00542                         }
00543                         else
00544                         {
00545                             couenneSetup.options()->SetStringValue("couenne."+optionsVector[ i]->name, optionsVector[ i]->value);
00546                         }
00547                     }
00548 
00549                 }
00550             }
00551         }
00552     }
00553 
00554     catch(const ErrorClass& eclass)
00555     {
00556         std::cout << "THERE IS AN ERROR" << std::endl;
00557         osresult->setGeneralMessage( eclass.errormsg);
00558         osresult->setGeneralStatusType( "error");
00559         osrl = osrlwriter->writeOSrL( osresult);
00560         throw ErrorClass( osrl) ;
00561     }
00562 
00563 }//end setSolverOptions()
00564 
00565 
00566 using namespace Ipopt;
00567 
00568 
00569 void CouenneSolver::solve() throw (ErrorClass)
00570 {
00571 #define PRINTED_PRECISION 1e-5
00572     const int infeasible = 1;
00573     //double time_start = CoinCpuTime();
00574     if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00575     if(this->bSetSolverOptions == false) setSolverOptions() ;
00576     try
00577     {
00578 
00579         //couenne->print();
00580 
00581         char **argv = NULL;
00582 
00583         bb.setUsingCouenne (true);
00584 
00585         //using namespace Ipopt;
00586 
00587         if(osoption == NULL  && osol.length() > 0)
00588         {
00589             m_osolreader = new OSoLReader();
00590             osoption = m_osolreader->readOSoL( osol);
00591         }
00592 
00593 
00594         tminlp = new BonminProblem( osinstance, osoption);
00595 
00596         CouenneInterface *ci = NULL;
00597 
00598         ci = new CouenneInterface();
00599         //const std::string  prefix="bonmin.";
00600 
00601         //std::cout << "INITIALIZE COUENNE INTERFACE" << std::endl;
00602 
00603         ci->initialize (couenneSetup.roptions(),//GetRawPtr(roptions),
00604                         couenneSetup.options(),//GetRawPtr( options),
00605                         couenneSetup.journalist(),//GetRawPtr(jnlst),
00606                         GetRawPtr( tminlp) );
00607 
00608         //std::cout << "INITIALIZE IPOPT SOLVER " << std::endl;
00609         app_ = new Bonmin::IpoptSolver(couenneSetup.roptions(),//GetRawPtr(roptions),
00610                                        couenneSetup.options(),//GetRawPtr( options),
00611                                        couenneSetup.journalist()//GetRawPtr(jnlst),
00612                                       );
00613 
00614 
00615 
00616         //std::cout << "INITIALIZE COUENNE MODEL" << std::endl;
00617         ci->setModel( GetRawPtr( tminlp) );
00618         //std::cout << "INITIALIZE COUENNE SOLVER" << std::endl;
00619         ci->setSolver( GetRawPtr( app_) );
00620         // initialize causes lots of memory leaks
00621 
00622 
00623         //std::cout << "INITIALIZE COUENNE " << std::endl;
00624         bool setupInit = false;
00625         setupInit = couenneSetup.InitializeCouenne(argv, couenne, NULL, ci);
00626         //std::cout << "ci -> isProvenOptimal ()" << ci -> isProvenOptimal ()<< std::endl;
00627 
00628 
00629         if(setupInit == false)
00630         {
00631             std::string solutionDescription = "";
00632             std::string message = "Couenne solver finishes to the end.";
00633             int solIdx = 0;
00634             if(osresult->setServiceName( "Couenne solver service") != true)
00635                 throw ErrorClass("OSResult error: setServiceName");
00636             if(osresult->setInstanceName(  osinstance->getInstanceName()) != true)
00637                 throw ErrorClass("OSResult error: setInstanceName");
00638             if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00639                 throw ErrorClass("OSResult error: setVariableNumer");
00640             if(osresult->setObjectiveNumber( 1) != true)
00641                 throw ErrorClass("OSResult error: setObjectiveNumber");
00642             if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00643                 throw ErrorClass("OSResult error: setConstraintNumber");
00644             if(osresult->setSolutionNumber(  1) != true)
00645                 throw ErrorClass("OSResult error: setSolutionNumer");
00646             if(osresult->setGeneralMessage( message) != true)
00647                 throw ErrorClass("OSResult error: setGeneralMessage");
00648             solutionDescription = "COUENNE INITIALIZE PROBLEM: \n There was a problem with Couenne Initialize: \n the problem could be infeasible \n there may be zero decision variables";
00649             osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
00650             osresult->setGeneralStatusType("normal");
00651             osrl = osrlwriter->writeOSrL( osresult);
00652             return;
00653 
00654         }
00655 
00656         std::cout << std::endl << std::endl;
00657         // see if we have an unbounded solution
00658         // if we are not infeasible and not optimal and have no integer variables we are probably unbounded
00659         if(( ci->isProvenPrimalInfeasible() == false) && (ci -> isProvenOptimal () == false)
00660                 && (osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() <= 0) )
00661         {
00662             std::string solutionDescription = "";
00663             std::string message = "Success";
00664             int solIdx = 0;
00665             if(osresult->setServiceName( "Couenne solver service") != true)
00666                 throw ErrorClass("OSResult error: setServiceName");
00667             if(osresult->setInstanceName(  osinstance->getInstanceName()) != true)
00668                 throw ErrorClass("OSResult error: setInstanceName");
00669             if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00670                 throw ErrorClass("OSResult error: setVariableNumer");
00671             if(osresult->setObjectiveNumber( 1) != true)
00672                 throw ErrorClass("OSResult error: setObjectiveNumber");
00673             if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00674                 throw ErrorClass("OSResult error: setConstraintNumber");
00675             if(osresult->setSolutionNumber(  1) != true)
00676                 throw ErrorClass("OSResult error: setSolutionNumer");
00677             if(osresult->setGeneralMessage( message) != true)
00678                 throw ErrorClass("OSResult error: setGeneralMessage");
00679             solutionDescription = "CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
00680             osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
00681             osresult->setGeneralStatusType("normal");
00682             osrl = osrlwriter->writeOSrL( osresult);
00683             return;
00684         }
00685 
00686 
00687         //std::cout << osinstance->printModel() << std::endl;
00688 
00689 
00690         //std::cout << " CALL bb ( couenneSetup) " << std::endl;
00691         bb ( couenneSetup); // do branch and bound
00692         //std::cout << " END bb ( couenneSetup) " << std::endl;
00693 
00694 
00695 
00696 
00697         std::cout.precision (10);
00698 
00699         CouenneCutGenerator *cg = NULL;
00700 
00701         if (bb.model (). cutGenerators ())
00702             cg = dynamic_cast <CouenneCutGenerator *>
00703                  (bb.model (). cutGenerators () [0] -> generator ());
00704 
00705 
00706         double global_opt;
00707         couenneSetup.options () -> GetNumericValue ("couenne_check", global_opt, "couenne.");
00708         //std::cout << "Couenne Global Optimum Check Value = " << global_opt  << std::endl;
00709         //std::cout << "GET BEST POSSIBLE OBJ VALUE =  " << bb.model (). getBestPossibleObjValue ()  << std::endl;
00710         // std::cout << "NUMBER OF NODES  =  " << bb.numNodes()  << std::endl;
00711         //std::cout << "BEST POSSIBLE OBJ VALUE =  " << bb.bestObj()  << std::endl;
00712         double timeLimit = 0;
00713         couenneSetup.options () -> GetNumericValue ("time_limit", timeLimit, "couenne.");
00714         //std::cout << "TIME LIMIT  =  "  <<  timeLimit  << std::endl;
00715         // note model is a CbcModel, bb is a BonCbc object
00716 
00717 
00718 
00719         // now put information in OSResult object
00720         status = tminlp->status;
00721         writeResult();
00722         //if(ci  != NULL)  delete ci;
00723     } //end try
00724 
00725     catch(const ErrorClass& eclass)
00726     {
00727         osresult->setGeneralMessage( eclass.errormsg);
00728         osresult->setGeneralStatusType( "error");
00729         osrl = osrlwriter->writeOSrL( osresult);
00730         throw ErrorClass( osrl) ;
00731     }
00732 
00733     // Pietro's catch
00734 
00735     catch(TNLPSolver::UnsolvedError *E)
00736     {
00737         E->writeDiffFiles();
00738         E->printError(std::cerr);
00739         //There has been a failure to solve a problem with Ipopt.
00740         //And we will output file with information on what has been changed in the problem to make it fail.
00741         //Now depending on what algorithm has been called (B-BB or other) the failed problem may be at different place.
00742         //    const OsiSolverInterface &si1 = (algo > 0) ? nlpSolver : *model.solver();
00743     }
00744 
00745     catch(OsiTMINLPInterface::SimpleError &E)
00746     {
00747         std::cerr<<E.className()<<"::"<<E.methodName()
00748                  <<std::endl
00749                  <<E.message()<<std::endl;
00750     }
00751 
00752     catch(CoinError &E)
00753     {
00754         std::cerr<<E.className()<<"::"<<E.methodName()
00755                  <<std::endl
00756                  <<E.message()<<std::endl;
00757     }
00758 
00759     catch (Ipopt::OPTION_INVALID &E)
00760     {
00761         std::cerr<<"Ipopt exception : "<<E.Message()<<std::endl;
00762     }
00763     catch (int generic_error)
00764     {
00765         if (generic_error == infeasible)
00766             printf ("problem infeasible\n");
00767     }
00768 
00769 }//end solve()
00770 
00771 
00772 void CouenneSolver::writeResult()
00773 {
00774     double *x = NULL;
00775     double *z = NULL;
00776     int i = 0;
00777     int solIdx = 0;
00778     std::string solutionDescription = "";
00779     std::string message = "Couenne solver finishes to the end.";
00780 
00781 
00782     try
00783     {
00784         if(osinstance->getVariableNumber()  > 0) x = new double[osinstance->getVariableNumber() ];
00785         z = new double[1];
00786         // resultHeader information
00787         if(osresult->setSolverInvoked( "COIN-OR Couenne") != true)
00788             throw ErrorClass("OSResult error: setSolverInvoked");
00789         if(osresult->setServiceName( OSgetVersionInfo()) != true)
00790             throw ErrorClass("OSResult error: setServiceName");
00791         if(osresult->setInstanceName(  osinstance->getInstanceName()) != true)
00792             throw ErrorClass("OSResult error: setInstanceName");
00793         //if(osresult->setJobID( osoption->jobID) != true)
00794         //      throw ErrorClass("OSResult error: setJobID");
00795         // set basic problem parameters
00796 
00797         if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00798             throw ErrorClass("OSResult error: setVariableNumer");
00799         if(osresult->setObjectiveNumber( 1) != true)
00800             throw ErrorClass("OSResult error: setObjectiveNumber");
00801         if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00802             throw ErrorClass("OSResult error: setConstraintNumber");
00803         if(osresult->setSolutionNumber(  1) != true)
00804             throw ErrorClass("OSResult error: setSolutionNumer");
00805         if(osresult->setGeneralMessage( message) != true)
00806             throw ErrorClass("OSResult error: setGeneralMessage");
00807 
00808         switch( status)
00809         {
00810         case  TMINLP::SUCCESS:
00811             solutionDescription = "SUCCESS[COUENNE]: Algorithm terminated normally at a locally optimal point, satisfying the convergence tolerances.";
00812             //std::cout << solutionDescription << std::endl;
00813             osresult->setSolutionStatus(solIdx,  "locallyOptimal", solutionDescription);
00814 
00815             if(osinstance->getObjectiveNumber() > 0)
00816             {
00817                 /* Retrieve the solution */
00818                 *(z + 0)  =  osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.bestSolution()), true)[ 0];
00819                 // okay if equal to 9999000000000 we are probably unbounded
00820                 if(fabs(*(z + 0)) == 9.999e+12)
00821                 {
00822                     solutionDescription = "CONTINUOUS_UNBOUNDED [COUENNE]: Continuous relaxation is unbounded, the MINLP may or may not be              unbounded.";
00823                     //std::cout << solutionDescription << std::endl;
00824                     osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
00825                     break;
00826                 }
00827                 osresult->setObjectiveValuesDense(solIdx, z);
00828             }
00829 
00830 
00831             if(osinstance->getVariableNumber() > 0)
00832             {
00833                 for(i=0; i < osinstance->getVariableNumber(); i++)
00834                 {
00835                     *(x + i) = bb.bestSolution()[i];
00836                     //std::cout <<  *(x + i)  << std::endl;
00837                 }
00838                 osresult->setPrimalVariableValuesDense(solIdx, x);
00839             }
00840 
00841 
00842             break;
00843 
00844         case TMINLP::LIMIT_EXCEEDED:
00845             solutionDescription = "LIMIT_EXCEEDED[COUENNE]: A resource limit was exceeded, we provide the current solution.";
00846             //std::cout << solutionDescription << std::endl;
00847             osresult->setSolutionStatus(solIdx,  "other", solutionDescription);
00848             //osresult->setPrimalVariableValuesDense(solIdx, const_cast<double*>(x));
00849             //osresult->setDualVariableValuesDense(solIdx, const_cast<double*>( lambda));
00850             /* Retrieve the solution */
00851             if(osinstance->getObjectiveNumber() > 0)
00852             {
00853                 *(z + 0)  =  osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.model().getColSolution()), true)[ 0];
00854                 osresult->setObjectiveValuesDense(solIdx, z);
00855             }
00856 
00857             if(osinstance->getVariableNumber() > 0)
00858             {
00859                 for(i=0; i < osinstance->getVariableNumber(); i++)
00860                 {
00861                     *(x + i) = bb.model().getColSolution()[i];
00862                     //std::cout <<  *(x + i)  << std::endl;
00863                 }
00864                 osresult->setPrimalVariableValuesDense(solIdx, x);
00865             }
00866             break;
00867 
00868         case TMINLP::MINLP_ERROR:
00869             solutionDescription = "MINLP_ERROR [COUENNE]: Algorithm stopped with unspecified error.";
00870             //std::cout << solutionDescription << std::endl;
00871             osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
00872 
00873             break;
00874 
00875         case TMINLP::CONTINUOUS_UNBOUNDED:
00876             solutionDescription = "CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
00877             //std::cout << solutionDescription << std::endl;
00878             osresult->setSolutionStatus(solIdx,  "error", solutionDescription);
00879 
00880             break;
00881 
00882 
00883         case TMINLP::INFEASIBLE:
00884             solutionDescription = "INFEASIBLE [COUENNE]: Problem may be infeasible.";
00885             //std::cout << solutionDescription << std::endl;
00886             osresult->setSolutionStatus(solIdx,  "infeasible", solutionDescription);
00887             break;
00888 
00889         default:
00890             solutionDescription = "OTHER[COUENNE]: other unknown solution status from Couenne solver";
00891             osresult->setSolutionStatus(solIdx,  "other", solutionDescription);
00892         }//switch end
00893         osresult->setGeneralStatusType("normal");
00894         osrl = osrlwriter->writeOSrL( osresult);
00895         if(osinstance->getVariableNumber()  > 0) delete[] x;
00896         x = NULL;
00897         delete[] z;
00898         z = NULL;
00899     }//end try
00900 
00901 
00902     catch(const ErrorClass& eclass)
00903     {
00904         delete[] x;
00905         x = NULL;
00906         delete[] z;
00907         z = NULL;
00908         osresult->setGeneralMessage( eclass.errormsg);
00909         osresult->setGeneralStatusType( "error");
00910         osrl = osrlwriter->writeOSrL( osresult);
00911         throw ErrorClass( osrl) ;
00912     }
00913 
00914 
00915 }// end writeResult()
00916 
00917 
00918 

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