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