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

Go to the documentation of this file.
00001 /* $Id: OSCouenneSolver.cpp 2836 2009-07-22 05:17:59Z 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 Needs Variables");
00172                 #ifdef DEBUG
00173                 std::cout << "NUMBER OF VARIABLES = " <<  n_allvars <<  std::endl;
00174                 #endif
00175         
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                 // now for the objective function -- assume just one for now
00204                 //just worry about linear coefficients
00205 
00206                 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Couenne NEEDS AN OBJECTIVE FUNCTION");
00207                 SparseVector* sv = osinstance->getObjectiveCoefficients()[ 0];
00208                 
00209                 int nterms = sv->number;
00210                 exprGroup::lincoeff lin( nterms);
00211                 for ( i = 0; i < nterms; ++i){
00212                                 lin[i].first = couenne->Var( sv->indexes[ i] );
00213                                 if( osinstance->getObjectiveMaxOrMins()[0] == "min"){
00214                                         lin[i].second = sv->values[ i];
00215                                 }else{
00216                                         lin[i].second = -sv->values[ i];
00217                                         
00218                                 }
00219                 }
00220                                 
00221                 OSExpressionTree* exptree = osinstance->getNonlinearExpressionTree( -1);
00222                 if (exptree != NULL) {
00223                         expression** nl = new expression*[1];
00224                         if( osinstance->getObjectiveMaxOrMins()[0] == "min"){
00225                                 nl[0] = createCouenneExpression( exptree->m_treeRoot );
00226                         }else{
00227                                 nl[ 0] = new exprOpp(createCouenneExpression( exptree->m_treeRoot) );
00228                                 
00229                         }
00230                         obj_body = new exprGroup(osinstance->getObjectiveConstants()[0], lin, nl, 1);
00231                 } else {
00232                         obj_body = new exprGroup(osinstance->getObjectiveConstants()[0], lin, NULL, 0);         
00233                         //std::cout << "THERE WERE NO NONLINEAR TERMS IN THE OBJECTIVE FUNCTION "  << std::endl;        
00234                 }
00235         
00236                 
00237                 couenne->addObjective(obj_body, "min");
00238 
00239                 // get the constraints in row format
00240                 
00241                 SparseMatrix* sm =  osinstance->getLinearConstraintCoefficientsInRowMajor();
00242                 
00243                 int nconss = osinstance->getConstraintNumber();         
00244                 int row_nonz = 0;
00245                 int kount = 0;
00246                 //int row_nonz_actual = 0;
00247                 double *rowlb = osinstance->getConstraintLowerBounds();
00248                 double *rowub = osinstance->getConstraintUpperBounds();
00249                 
00250                 for (i = 0; i < nconss; ++i) {
00251                 //std::cout << "WE ARE PROCESSING ROW " << i << std::endl;
00252                         row_nonz = 0;
00253                         if( sm) row_nonz = sm->starts[ i +1] - sm->starts[ i];
00254                         exprGroup::lincoeff con_lin( row_nonz);
00255                                 for (j = 0; j  <  row_nonz;  ++j){
00256                                         con_lin[j].first = couenne->Var( sm->indexes[ kount] );
00257                                         con_lin[j].second = sm->values[ kount];
00258                                         kount++;
00259                                 }
00260                         //}
00261                         OSExpressionTree* exptree = osinstance->getNonlinearExpressionTree( i);
00262                         if (exptree != NULL) {
00263                                 expression** nl = new expression*[1];
00264                                 nl[0] = createCouenneExpression(exptree->m_treeRoot);
00265                                 con_body = new exprGroup(0., con_lin, nl, 1);
00266                         } else {
00267                                 con_body = new exprGroup(0., con_lin, NULL, 0);                 
00268                         }
00269                 
00270                         if (rowlb[ i] == rowub[ i])
00271                         {
00272                                 couenne->addEQConstraint(con_body, new exprConst( rowub[ i] ));
00273                         }
00274                         else if (rowlb[ i]  ==  -OSDBL_MAX)
00275                         {
00276                                 assert(rowub[ i]  !=  -OSDBL_MAX);
00277                                 couenne->addLEConstraint(con_body, new exprConst( rowub[ i] ));
00278                         }
00279                         else if (rowub[ i] ==  OSDBL_MAX)
00280                         {
00281                                 assert(rowlb[ i]  != OSDBL_MAX);
00282                                 couenne->addGEConstraint(con_body, new exprConst( rowlb[ i] ));                 
00283                         }
00284                         else
00285                                 couenne->addRNGConstraint(con_body, new exprConst( rowlb[ i]), new
00286                                         exprConst( rowub[ i] ));        
00287                                 
00288                 }
00289         }
00290         catch(const ErrorClass& eclass){
00291                 std::cout << "THERE IS AN ERROR" << std::endl;
00292                 osresult->setGeneralMessage( eclass.errormsg);
00293                 osresult->setGeneralStatusType( "error");
00294                 osrl = osrlwriter->writeOSrL( osresult);
00295                 throw ErrorClass( osrl) ;
00296         }                               
00297 }//end buildSolverInstance() 
00298 
00299 
00300 expression* CouenneSolver::createCouenneExpression(OSnLNode* node) {
00301         //std::cout << "NODE NUMBER =  " << node->inodeInt  << std::endl;
00302         unsigned int i;
00303         switch (node->inodeInt) {
00304                 case OS_PLUS :
00305                         return new exprSum(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00306                 case OS_SUM :
00307                 //std::cout << "I AM INSIDE A SUM NODE  "   << std::endl;
00308                 //std::cout << "I HAVE THE FOLLOWING NUMBER OF CHILDREN  " <<   node->inumberOfChildren << std::endl;
00309          //switch ( node->inumberOfChildren==0 ) { // Stefan's coding
00310                  switch ( node->inumberOfChildren ) {  //kipp modification
00311                  case 0:
00312                                         //std::cout << "I IN SUM CASE 0  "   << std::endl;
00313                          return new exprConst(0.);
00314                  case 1:
00315                                 //std::cout << "I IN SUM CASE 1  "   << std::endl;
00316                          return createCouenneExpression(node->m_mChildren[0]);
00317                  default:
00318                                 //std::cout << "I IN SUM CASE DEFAULT  "   << std::endl;
00319                          expression** sumargs = new expression*[node->inumberOfChildren];
00320            for(i = 0;  i<  node->inumberOfChildren;  i++)
00321                  sumargs[i] = createCouenneExpression(node->m_mChildren[i]);
00322                         //expression* base = new exprSum(args, node->inumberOfChildren);  //Stefan
00323            //delete[] args;  //delete Stefan's code -- causes a seg fault
00324            //return base; stefan
00325                    return new exprSum(sumargs, node->inumberOfChildren);
00326         }
00327      case OS_MINUS :
00328          return new exprSub(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00329      case OS_NEGATE :
00330          return new exprOpp(createCouenneExpression(node->m_mChildren[0]));
00331      case OS_TIMES :
00332          return new exprMul(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00333      case OS_DIVIDE :
00334          // couenne does not like expressions of the form exp1/exp2 with exp1 a constant, so we write them as exp1 * 1/exp2
00335          if (node->m_mChildren[0]->inodeInt == OS_NUMBER)
00336          return new exprMul(createCouenneExpression(node->m_mChildren[0]), new exprInv(createCouenneExpression(node->m_mChildren[1])));
00337          else
00338                  return new exprDiv(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00339      case OS_POWER :
00340          // couenne does not like expressions of the form exp1 ^ exp2 with exp2 not a constant, so we write them as exp(log(exp1)*exp2)
00341          if (node->m_mChildren[1]->inodeInt != OS_NUMBER)
00342                  return new exprExp(new exprMul(new exprLog(createCouenneExpression(node->m_mChildren[0])), createCouenneExpression(node->m_mChildren[1])));
00343          else
00344                  return new exprPow(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
00345      case OS_PRODUCT:
00346          switch ( node->inumberOfChildren ) {
00347                  case 0:
00348                          return new exprConst(1.);
00349                  case 1:
00350                          return createCouenneExpression(node->m_mChildren[0]);
00351                  default:
00352                                 expression** args = new expression*[node->inumberOfChildren];
00353                                 for( i = 0; i < node->inumberOfChildren;i++)
00354                                         args[i] = createCouenneExpression(node->m_mChildren[i]);
00355                                 expression* base = new exprMul(args, node->inumberOfChildren);
00356            //delete[] args;
00357                         return base;
00358         }
00359      case OS_ABS :
00360          return new exprAbs(createCouenneExpression(node->m_mChildren[0]));
00361      case OS_SQUARE :
00362          return new exprPow(createCouenneExpression(node->m_mChildren[0]), new exprConst(2.));
00363      case OS_SQRT :
00364          return new exprPow(createCouenneExpression(node->m_mChildren[0]), new exprConst(0.5));
00365      case OS_LN :
00366          return new exprLog(createCouenneExpression(node->m_mChildren[0]));
00367      case OS_EXP :
00368          return new exprExp(createCouenneExpression(node->m_mChildren[0]));
00369      case OS_SIN :
00370          return new exprSin(createCouenneExpression(node->m_mChildren[0]));
00371      case OS_COS :
00372          return new exprCos(createCouenneExpression(node->m_mChildren[0]));
00373      case OS_MIN :
00374          switch (node->inumberOfChildren==0) {
00375                  case 0:
00376                          return new exprConst(0.);
00377                  case 1:
00378                          return createCouenneExpression(node->m_mChildren[0]);
00379                  default:
00380                          expression** args = new expression*[node->inumberOfChildren];
00381            for( i = 0; i <node->inumberOfChildren;i++)
00382                  args[i] = createCouenneExpression(node->m_mChildren[i]);
00383            expression* base = new exprMin(args, node->inumberOfChildren);
00384            //delete[] args;
00385            return base;
00386         }
00387      case OS_MAX :
00388          switch (node->inumberOfChildren==0) {
00389                  case 0:
00390                          return new exprConst(0.);
00391                  case 1:
00392                          return createCouenneExpression(node->m_mChildren[0]);
00393                  default:
00394                          expression** args = new expression*[node->inumberOfChildren];
00395            for(i = 0; i < node->inumberOfChildren;i++)
00396                  args[i] = createCouenneExpression(node->m_mChildren[i]);
00397            expression* base = new exprMax(args, node->inumberOfChildren);
00398            //delete[] args;
00399            return base;
00400         }
00401      case OS_NUMBER :
00402          return new exprConst(((OSnLNodeNumber*)node)->value);
00403      case OS_PI :
00404          assert(false);
00405          //TODO
00406 //       return new exprConst(PI);
00407      case OS_VARIABLE : {
00408         OSnLNodeVariable* varnode = (OSnLNodeVariable*)node;
00409         if (varnode->coef == 0.)
00410                 return new exprConst(0.);
00411         if (varnode->coef == 1.)
00412                 return new exprClone(couenne->Variables()[varnode->idx]);
00413         if (varnode->coef == -1.)
00414                 return new exprOpp(new exprClone(couenne->Variables()[varnode->idx]));
00415                 return new exprMul(new exprConst(varnode->coef), new exprClone(couenne->Variables()[varnode->idx]));
00416      }
00417      default:
00418         cout << node->snodeName << " NOT IMPLEMENTED!!" << endl;
00419         break;
00420   }
00421         
00422         return NULL;
00423 }
00424 
00425 
00426 void CouenneSolver::setSolverOptions() throw (ErrorClass) {
00427         try{
00428 
00429                 char *pEnd;
00430                 bSetSolverOptions = true;
00431                 couenneSetup.initializeOptionsAndJournalist();
00432                 //turn off a lot of output -- this can be overridden by using OSOptions
00433                 couenneSetup.options()->SetIntegerValue("bonmin.bb_log_level", 0);
00434                 couenneSetup.options()->SetIntegerValue("bonmin.nlp_log_level", 0 );
00435                 if(osoption == NULL && osol.length() > 0)
00436                 {
00437                         m_osolreader = new OSoLReader();
00438                         osoption = m_osolreader->readOSoL( osol);
00439                 }
00440 
00441                 if(osoption != NULL && osoption->getNumberOfSolverOptions() > 0 ){
00442                         
00443                         int i;
00444                         std::vector<SolverOption*> optionsVector;
00445                         optionsVector = osoption->getSolverOptions( "couenne");
00446                         int num_bonmin_options = optionsVector.size();
00447                         for(i = 0; i < num_bonmin_options; i++){
00448                                 if(optionsVector[ i]->type == "numeric" ){
00449                                         //std::cout << "FOUND A  NUMERIC OPTION  "  <<  os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) << std::endl;
00450                                         if(optionsVector[ i]->category == "ipopt"){
00451                                                 couenneSetup.options()->SetNumericValue(optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );        
00452                                         }else{
00453                                                 if(optionsVector[ i]->category == "bonmin" ){
00454                                                         couenneSetup.options()->SetNumericValue("bonmin."+optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
00455                                                 }
00456                                                 else{
00457                                                         couenneSetup.options()->SetNumericValue("couenne."+optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );     
00458                                                 }
00459                                         }
00460                                 }  
00461                                 else if(optionsVector[ i]->type == "integer" ){
00462                                         //std::cout << "FOUND AN INTEGER OPTION  "  <<optionsVector[ i]->name << std::endl;
00463                                         if(optionsVector[ i]->category == "ipopt"){
00464                                                 couenneSetup.options()->SetIntegerValue(optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ) );    
00465                                         }else{
00466                                                 if(optionsVector[ i]->category == "bonmin" ){
00467                                                         couenneSetup.options()->SetIntegerValue("bonmin."+optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ));
00468                                                 }
00469                                                 else{
00470                                                         couenneSetup.options()->SetIntegerValue("couenne."+optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() )  );        
00471                                                 }
00472                                         }                                       
00473                                 }
00474                                 else if(optionsVector[ i]->type == "string" ){
00475                                         //std::cout << "FOUND A STRING OPTION  "  <<optionsVector[ i]->name << std::endl;
00476                                         if(optionsVector[ i]->category == "ipopt"){
00477                                                 couenneSetup.options()->SetStringValue(optionsVector[ i]->name, optionsVector[ i]->value );     
00478                                         }else{
00479                                                 if(optionsVector[ i]->category == "bonmin" ){
00480                                                         couenneSetup.options()->SetStringValue("bonmin."+optionsVector[ i]->name, optionsVector[ i]->value);
00481                                                 }
00482                                                 else{
00483                                                         couenneSetup.options()->SetStringValue("couenne."+optionsVector[ i]->name, optionsVector[ i]->value);   
00484                                                 }
00485                                         }       
00486 
00487                                 }
00488                         }       
00489                 }               
00490         }
00491 
00492         catch(const ErrorClass& eclass){
00493                 std::cout << "THERE IS AN ERROR" << std::endl;
00494                 osresult->setGeneralMessage( eclass.errormsg);
00495                 osresult->setGeneralStatusType( "error");
00496                 osrl = osrlwriter->writeOSrL( osresult);
00497                 throw ErrorClass( osrl) ;
00498         }                               
00499                                 
00500 }//end setSolverOptions() 
00501 
00502 
00503 using namespace Ipopt;
00504         
00505 
00506 void CouenneSolver::solve() throw (ErrorClass) {
00507 #define PRINTED_PRECISION 1e-5
00508         const int infeasible = 1;
00509         //double time_start = CoinCpuTime();
00510         if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00511         if(this->bSetSolverOptions == false) setSolverOptions() ;
00512         try{
00513 
00514                 //couenne->print();
00515                 
00516                 char **argv = NULL;
00517 
00518         bb.setUsingCouenne (true);
00519 
00520                 //using namespace Ipopt;
00521 
00522                 if(osoption == NULL  && osol.length() > 0){
00523                         m_osolreader = new OSoLReader();
00524                         osoption = m_osolreader->readOSoL( osol);
00525                 }       
00526 
00527 
00528                 tminlp = new BonminProblem( osinstance, osoption);
00529                 
00530                 CouenneInterface *ci = NULL;
00531                 
00532                 ci = new CouenneInterface();
00533                 //const std::string  prefix="bonmin.";
00534 
00535                 //std::cout << "INITIALIZE COUENNE INTERFACE" << std::endl;
00536                 
00537                 ci->initialize (couenneSetup.roptions(),//GetRawPtr(roptions),  
00538                                 couenneSetup.options(),//GetRawPtr( options), 
00539                                 couenneSetup.journalist(),//GetRawPtr(jnlst),  
00540                                  GetRawPtr( tminlp) );  
00541                 
00542                 //std::cout << "INITIALIZE IPOPT SOLVER " << std::endl;
00543                 app_ = new Bonmin::IpoptSolver(couenneSetup.roptions(),//GetRawPtr(roptions),  
00544                                                couenneSetup.options(),//GetRawPtr( options),                                           
00545                                                couenneSetup.journalist()//GetRawPtr(jnlst),  
00546                                                );               
00547                                                    
00548                                                    
00549                 
00550                 //std::cout << "INITIALIZE COUENNE MODEL" << std::endl;
00551                 ci->setModel( GetRawPtr( tminlp) );
00552                 //std::cout << "INITIALIZE COUENNE SOLVER" << std::endl;
00553                 ci->setSolver( GetRawPtr( app_) );
00554                 // initialize causes lots of memory leaks
00555                 
00556         
00557                 //std::cout << "INITIALIZE COUENNE " << std::endl;
00558                 bool setupInit = false;
00559                 setupInit = couenneSetup.InitializeCouenne(argv, couenne, ci);
00560                 //std::cout << "ci -> isProvenOptimal ()" << ci -> isProvenOptimal ()<< std::endl;
00561                 
00562 
00563                 if(setupInit == false){
00564                         std::string solutionDescription = "";
00565                         std::string message = "Couenne solver finishes to the end.";
00566                         int solIdx = 0;
00567                         if(osresult->setServiceName( "Couenne solver service") != true)
00568                                 throw ErrorClass("OSResult error: setServiceName");
00569                         if(osresult->setInstanceName(  osinstance->getInstanceName()) != true)
00570                                 throw ErrorClass("OSResult error: setInstanceName");
00571                         if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00572                                 throw ErrorClass("OSResult error: setVariableNumer");
00573                         if(osresult->setObjectiveNumber( 1) != true)
00574                                 throw ErrorClass("OSResult error: setObjectiveNumber");
00575                         if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00576                                 throw ErrorClass("OSResult error: setConstraintNumber");
00577                         if(osresult->setSolutionNumber(  1) != true)
00578                                 throw ErrorClass("OSResult error: setSolutionNumer");           
00579                         if(osresult->setGeneralMessage( message) != true)
00580                                 throw ErrorClass("OSResult error: setGeneralMessage");
00581                         solutionDescription = "COUENNE INITIALIZE PROBLEM: There was a problem with Couenne Initialize -- the problem could be infeasible";
00582                                 osresult->setSolutionStatus(solIdx,  "error", solutionDescription);     
00583                         osresult->setGeneralStatusType("normal");
00584                         osrl = osrlwriter->writeOSrL( osresult);                
00585                         return;
00586 
00587                 }
00588 
00589                 std::cout << std::endl << std::endl;
00590         // see if we have an unbounded solution
00591         // if we are not infeasible and not optimal and have no integer variables we are probably unbounded     
00592         if(( ci->isProvenPrimalInfeasible() == false) && (ci -> isProvenOptimal () == false) 
00593                 && (osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() <= 0) ){
00594                 std::string solutionDescription = "";
00595                 std::string message = "Success";
00596                 int solIdx = 0;
00597                 if(osresult->setServiceName( "Couenne solver service") != true)
00598                         throw ErrorClass("OSResult error: setServiceName");
00599                 if(osresult->setInstanceName(  osinstance->getInstanceName()) != true)
00600                         throw ErrorClass("OSResult error: setInstanceName");
00601                 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00602                         throw ErrorClass("OSResult error: setVariableNumer");
00603                 if(osresult->setObjectiveNumber( 1) != true)
00604                         throw ErrorClass("OSResult error: setObjectiveNumber");
00605                 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00606                         throw ErrorClass("OSResult error: setConstraintNumber");
00607                 if(osresult->setSolutionNumber(  1) != true)
00608                         throw ErrorClass("OSResult error: setSolutionNumer");           
00609                 if(osresult->setGeneralMessage( message) != true)
00610                         throw ErrorClass("OSResult error: setGeneralMessage");
00611                 solutionDescription = "CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
00612                         osresult->setSolutionStatus(solIdx,  "error", solutionDescription);     
00613                 osresult->setGeneralStatusType("normal");
00614                 osrl = osrlwriter->writeOSrL( osresult);                
00615                 return;
00616         }
00617 
00618                 
00619         //std::cout << osinstance->printModel() << std::endl;
00620         
00621 
00622         //std::cout << " CALL bb ( couenneSetup) " << std::endl;
00623                 bb ( couenneSetup); // do branch and bound
00624         //std::cout << " END bb ( couenneSetup) " << std::endl;
00625         
00626         
00627 
00628 
00629     std::cout.precision (10);
00630 
00631     CouenneCutGenerator *cg = NULL;
00632 
00633     if (bb.model (). cutGenerators ())
00634       cg = dynamic_cast <CouenneCutGenerator *> 
00635         (bb.model (). cutGenerators () [0] -> generator ());
00636 
00637 
00638     double global_opt;
00639     couenneSetup.options () -> GetNumericValue ("couenne_check", global_opt, "couenne.");
00640         //std::cout << "Couenne Global Optimum Check Value = " << global_opt  << std::endl; 
00641     //std::cout << "GET BEST POSSIBLE OBJ VALUE =  " << bb.model (). getBestPossibleObjValue ()  << std::endl;
00642    // std::cout << "NUMBER OF NODES  =  " << bb.numNodes()  << std::endl;
00643     //std::cout << "BEST POSSIBLE OBJ VALUE =  " << bb.bestObj()  << std::endl;
00644         double timeLimit = 0;
00645         couenneSetup.options () -> GetNumericValue ("time_limit", timeLimit, "couenne.");
00646         //std::cout << "TIME LIMIT  =  "  <<  timeLimit  << std::endl;
00647     // note model is a CbcModel, bb is a BonCbc object
00648         
00649         
00650 
00651     // now put information in OSResult object
00652     status = tminlp->status;
00653     writeResult();
00654         //if(ci  != NULL)  delete ci;
00655         } //end try
00656         
00657         catch(const ErrorClass& eclass){
00658                 osresult->setGeneralMessage( eclass.errormsg);
00659                 osresult->setGeneralStatusType( "error");
00660                 osrl = osrlwriter->writeOSrL( osresult);
00661                 throw ErrorClass( osrl) ;
00662         }
00663         
00664         // Pietro's catch
00665         
00666           catch(TNLPSolver::UnsolvedError *E) {
00667              E->writeDiffFiles();
00668              E->printError(std::cerr);
00669             //There has been a failure to solve a problem with Ipopt.
00670             //And we will output file with information on what has been changed in the problem to make it fail.
00671             //Now depending on what algorithm has been called (B-BB or other) the failed problem may be at different place.
00672             //    const OsiSolverInterface &si1 = (algo > 0) ? nlpSolver : *model.solver();
00673           }
00674           
00675           catch(OsiTMINLPInterface::SimpleError &E) {
00676             std::cerr<<E.className()<<"::"<<E.methodName()
00677                      <<std::endl
00678                      <<E.message()<<std::endl;
00679           }
00680           
00681           catch(CoinError &E) {
00682             std::cerr<<E.className()<<"::"<<E.methodName()
00683                      <<std::endl
00684                      <<E.message()<<std::endl;
00685           }
00686           
00687           catch (Ipopt::OPTION_INVALID &E)
00688           {
00689            std::cerr<<"Ipopt exception : "<<E.Message()<<std::endl;
00690           }
00691           catch (int generic_error) {
00692             if (generic_error == infeasible)
00693               printf ("problem infeasible\n");
00694           }
00695 
00696 }//end solve()
00697 
00698 
00699 void CouenneSolver::writeResult(){
00700         double *x = NULL;
00701         double *z = NULL;
00702         int i = 0;
00703         int solIdx = 0;
00704         std::string solutionDescription = "";
00705         std::string message = "Couenne solver finishes to the end.";
00706         
00707         
00708         try{
00709                 x = new double[osinstance->getVariableNumber() ];
00710                 z = new double[1];              
00711                 // resultHeader information
00712                 if(osresult->setServiceName( "Couenne solver service") != true)
00713                         throw ErrorClass("OSResult error: setServiceName");
00714                 if(osresult->setInstanceName(  osinstance->getInstanceName()) != true)
00715                         throw ErrorClass("OSResult error: setInstanceName");    
00716                 //if(osresult->setJobID( osoption->jobID) != true)
00717                 //      throw ErrorClass("OSResult error: setJobID");   
00718                 // set basic problem parameters
00719                 
00720                 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00721                         throw ErrorClass("OSResult error: setVariableNumer");
00722                 if(osresult->setObjectiveNumber( 1) != true)
00723                         throw ErrorClass("OSResult error: setObjectiveNumber");
00724                 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00725                         throw ErrorClass("OSResult error: setConstraintNumber");
00726                 if(osresult->setSolutionNumber(  1) != true)
00727                         throw ErrorClass("OSResult error: setSolutionNumer");           
00728                 if(osresult->setGeneralMessage( message) != true)
00729                         throw ErrorClass("OSResult error: setGeneralMessage");
00730         
00731                 switch( status){
00732                         case  TMINLP::SUCCESS:
00733                                 solutionDescription = "SUCCESS[COUENNE]: Algorithm terminated normally at a locally optimal point, satisfying the convergence tolerances.";
00734                                 //std::cout << solutionDescription << std::endl;
00735                                 osresult->setSolutionStatus(solIdx,  "locallyOptimal", solutionDescription);            
00736                                 /* Retrieve the solution */
00737                                 *(z + 0)  =  osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.bestSolution()), true)[ 0];
00738                                 // okay if equal to 9999000000000 we are probably unbounded
00739                                 if(fabs(*(z + 0)) == 9.999e+12){
00740                                         solutionDescription = "CONTINUOUS_UNBOUNDED [COUENNE]: Continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
00741                                         //std::cout << solutionDescription << std::endl;
00742                                         osresult->setSolutionStatus(solIdx,  "error", solutionDescription);     
00743                                         break;
00744                                 }
00745                                 osresult->setObjectiveValuesDense(solIdx, z); 
00746                                 for(i=0; i < osinstance->getVariableNumber(); i++){
00747                                         *(x + i) = bb.bestSolution()[i];
00748                                         //std::cout <<  *(x + i)  << std::endl;
00749                                 }
00750                                 osresult->setPrimalVariableValuesDense(solIdx, x);
00751                         break;
00752                         
00753                         case TMINLP::LIMIT_EXCEEDED:
00754                                 solutionDescription = "LIMIT_EXCEEDED[COUENNE]: A resource limit was exceeded, we provide the current solution.";
00755                                 //std::cout << solutionDescription << std::endl;
00756                                 osresult->setSolutionStatus(solIdx,  "stoppedByLimit", solutionDescription);
00757                                 //osresult->setPrimalVariableValuesDense(solIdx, const_cast<double*>(x));
00758                                 //osresult->setDualVariableValuesDense(solIdx, const_cast<double*>( lambda));   
00759                                 /* Retrieve the solution */
00760                                 *(z + 0)  =  osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.model().getColSolution()), true)[ 0];
00761                                 osresult->setObjectiveValuesDense(solIdx, z); 
00762                                 for(i=0; i < osinstance->getVariableNumber(); i++){
00763                                         *(x + i) = bb.model().getColSolution()[i];
00764                                         //std::cout <<  *(x + i)  << std::endl;
00765                                 }
00766                                 osresult->setPrimalVariableValuesDense(solIdx, x); 
00767                         break;
00768                         
00769                         case TMINLP::MINLP_ERROR:
00770                                 solutionDescription = "MINLP_ERROR [COUENNE]: Algorithm stopped with unspecified error.";
00771                                 //std::cout << solutionDescription << std::endl;
00772                                 osresult->setSolutionStatus(solIdx,  "error", solutionDescription);     
00773 
00774                         break;
00775                         
00776                         case TMINLP::CONTINUOUS_UNBOUNDED:
00777                                 solutionDescription = "CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
00778                                 //std::cout << solutionDescription << std::endl;
00779                                 osresult->setSolutionStatus(solIdx,  "error", solutionDescription);     
00780 
00781                         break;
00782                         
00783                 
00784                         case TMINLP::INFEASIBLE:
00785                                 solutionDescription = "INFEASIBLE [COUENNE]: Problem may be infeasible.";
00786                                 //std::cout << solutionDescription << std::endl;
00787                                 osresult->setSolutionStatus(solIdx,  "infeasible", solutionDescription);
00788                         break;
00789                         
00790                         default:
00791                                 solutionDescription = "OTHER[COUENNE]: other unknown solution status from Couenne solver";
00792                                 osresult->setSolutionStatus(solIdx,  "other", solutionDescription);
00793                 }//switch end   
00794                 osresult->setGeneralStatusType("normal");
00795                 osrl = osrlwriter->writeOSrL( osresult);
00796                 delete[] x;
00797                 x = NULL;
00798                 delete[] z;     
00799                 z = NULL;
00800         }//end try
00801         
00802         
00803         catch(const ErrorClass& eclass){
00804                 delete[] x;
00805                 x = NULL;
00806                 delete[] z;     
00807                 z = NULL;
00808                 osresult->setGeneralMessage( eclass.errormsg);
00809                 osresult->setGeneralStatusType( "error");
00810                 osrl = osrlwriter->writeOSrL( osresult);
00811                 throw ErrorClass( osrl) ;
00812         }       
00813         
00814         
00815 }// end writeResult()
00816 
00817 
00818 

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