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

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

Generated on Thu Mar 31 03:13:19 2011 by  doxygen 1.4.7