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