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

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

Generated on Thu Aug 5 03:03:04 2010 by  doxygen 1.4.7