00001
00019 #include <iostream>
00020
00021
00022
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
00030
00031
00032
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
00077
00078
00079
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
00138
00139 }
00140 if(con_body != NULL){
00141
00142 }
00143 if(obj_body != NULL){
00144
00145 }
00146 if(m_osilreader != NULL) {
00147
00148 delete m_osilreader;
00149
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
00159
00160 #ifdef DEBUG
00161 cout << "leaving CouenneSolver destructor" << endl;
00162 #endif
00163
00164 }
00165
00166
00167 void CouenneSolver::buildSolverInstance() throw (ErrorClass) {
00168
00169 try{
00170 this->bCallbuildSolverInstance = true;
00171
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
00187 osinstance->initForAlgDiff( );
00188
00189
00190
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
00199 CouNumber *x_ = (CouNumber *) malloc ((n_allvars) * sizeof (CouNumber));
00200 CouNumber *lb = NULL, *ub = NULL;
00201
00202
00203 ub = osinstance->getVariableUpperBounds();
00204 lb = osinstance->getVariableLowerBounds();
00205
00206
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.;
00220 }
00221
00222 couenne->domain()->push(n_allvars, x_, lb, ub);
00223 free(x_);
00224 }
00225
00226
00227
00228
00229 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Couenne NEEDS AN OBJECTIVE FUNCTION");
00230
00231
00232
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
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 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 }
00325
00326
00327 expression* CouenneSolver::createCouenneExpression(OSnLNode* node) {
00328
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
00335
00336
00337 switch ( node->inumberOfChildren ) {
00338 case 0:
00339
00340 return new exprConst(0.);
00341 case 1:
00342
00343 return createCouenneExpression(node->m_mChildren[0]);
00344 default:
00345
00346 expression** sumargs = new expression*[node->inumberOfChildren];
00347 for(i = 0; i< node->inumberOfChildren; i++)
00348 sumargs[i] = createCouenneExpression(node->m_mChildren[i]);
00349
00350
00351
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
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
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
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
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
00426 return base;
00427 }
00428 case OS_NUMBER :
00429 return new exprConst(((OSnLNodeNumber*)node)->value);
00430 case OS_PI :
00431 assert(false);
00432
00433
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
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
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
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
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 }
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
00537 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00538 if(this->bSetSolverOptions == false) setSolverOptions() ;
00539 try{
00540
00541
00542
00543 char **argv = NULL;
00544
00545 bb.setUsingCouenne (true);
00546
00547
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
00561
00562
00563
00564 ci->initialize (couenneSetup.roptions(),
00565 couenneSetup.options(),
00566 couenneSetup.journalist(),
00567 GetRawPtr( tminlp) );
00568
00569
00570 app_ = new Bonmin::IpoptSolver(couenneSetup.roptions(),
00571 couenneSetup.options(),
00572 couenneSetup.journalist()
00573 );
00574
00575
00576
00577
00578 ci->setModel( GetRawPtr( tminlp) );
00579
00580 ci->setSolver( GetRawPtr( app_) );
00581
00582
00583
00584
00585 bool setupInit = false;
00586 setupInit = couenneSetup.InitializeCouenne(argv, couenne, NULL, ci);
00587
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
00618
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
00647
00648
00649
00650 bb ( couenneSetup);
00651
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
00668
00669
00670
00671 double timeLimit = 0;
00672 couenneSetup.options () -> GetNumericValue ("time_limit", timeLimit, "couenne.");
00673
00674
00675
00676
00677
00678
00679 status = tminlp->status;
00680 writeResult();
00681
00682 }
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
00692
00693 catch(TNLPSolver::UnsolvedError *E) {
00694 E->writeDiffFiles();
00695 E->printError(std::cerr);
00696
00697
00698
00699
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 }
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
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
00746
00747
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
00764 osresult->setSolutionStatus(solIdx, "locallyOptimal", solutionDescription);
00765
00766 if(osinstance->getObjectiveNumber() > 0){
00767
00768 *(z + 0) = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.bestSolution()), true)[ 0];
00769
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
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
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
00794 osresult->setSolutionStatus(solIdx, "other", solutionDescription);
00795
00796
00797
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
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
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
00822 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00823
00824 break;
00825
00826
00827 case TMINLP::INFEASIBLE:
00828 solutionDescription = "INFEASIBLE [COUENNE]: Problem may be infeasible.";
00829
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 }
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 }
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 }
00859
00860
00861