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