00001
00020
00021
00022 #include <iostream>
00023
00024
00025 #include "OSBonminSolver.h"
00026 #include "OSDataStructures.h"
00027 #include "OSParameters.h"
00028 #include "OSMathUtil.h"
00029 #include "CoinFinite.hpp"
00030 #include "BonOsiTMINLPInterface.hpp"
00031 #include "BonTMINLP.hpp"
00032
00033
00034 #include "CoinTime.hpp"
00035
00036 using std::cout;
00037 using std::endl;
00038 using std::ostringstream;
00039
00040 BonminSolver::BonminSolver() {
00041 osrlwriter = new OSrLWriter();
00042 osresult = new OSResult();
00043 m_osilreader = NULL;
00044 m_osolreader = NULL;
00045 bonminErrorMsg = "";
00046
00047 }
00048
00049 BonminSolver::~BonminSolver() {
00050 #ifdef DEBUG
00051 cout << "inside BonminSolver destructor" << endl;
00052 #endif
00053 if(m_osilreader != NULL) delete m_osilreader;
00054 m_osilreader = NULL;
00055 if(m_osolreader != NULL) delete m_osolreader;
00056 m_osolreader = NULL;
00057
00058 if(osrlwriter != NULL )delete osrlwriter;
00059 osrlwriter = NULL;
00060 if(osresult != NULL ){
00061 delete osresult;
00062 osresult = NULL;
00063
00064 }
00065 #ifdef DEBUG
00066 cout << "leaving BonminSolver destructor" << endl;
00067 #endif
00068 }
00069
00070
00071
00072
00073
00074
00075 bool BonminProblem::get_variables_types(Index n, VariableType* var_types){
00076 int i = 0;
00077 char *varType;
00078 varType = osinstance->getVariableTypes();
00079 n = osinstance->getVariableNumber();
00080 for(i = 0; i < n; i++){
00081 if( varType[i] == 'B') {
00082 var_types[i] = BINARY;
00083 }
00084 else{
00085 if( varType[i] == 'I') {
00086 var_types[i] = INTEGER;
00087 }
00088 else{
00089 var_types[i] = CONTINUOUS;
00090 }
00091 }
00092 }
00093 return true;
00094 }
00095
00096 bool BonminProblem::get_variables_linearity(Index n, Ipopt::TNLP::LinearityType* var_types){
00097
00098
00099
00100 std::cout << "Initialize Nonlinear Structures" << std::endl;
00101 try{
00102 osinstance->initForAlgDiff( );
00103 }
00104 catch(const ErrorClass& eclass){
00105 bonminErrorMsg = eclass.errormsg;
00106 throw;
00107 }
00113 std::map<int, int> varIndexMap;
00114 std::map<int, int>::iterator posVarIndexMap;
00115 varIndexMap = osinstance->getAllNonlinearVariablesIndexMap( );
00116
00117
00118 int i;
00119
00120 for(i = 0; i < n; i++){
00121 var_types[ i] = Ipopt::TNLP::LINEAR;
00122 }
00127 for(posVarIndexMap = varIndexMap.begin(); posVarIndexMap != varIndexMap.end(); ++posVarIndexMap){
00128 std::cout << "Variable Index = " << posVarIndexMap->first << std::endl ;
00129 var_types[ posVarIndexMap->first] = Ipopt::TNLP::NON_LINEAR;
00130 }
00131 std::cout << "Number of nonlinear variables = " << varIndexMap.size() << std::endl;
00132
00133 return true;
00134 }
00135
00136 bool BonminProblem::get_constraints_linearity(Index m, Ipopt::TNLP::LinearityType* const_types){
00137
00138 int i;
00139
00140 for(i = 0; i < m; i++){
00141 const_types[ i] = Ipopt::TNLP::LINEAR;
00142 }
00143
00144
00145 int mm = osinstance->getNumberOfNonlinearExpressionTreeModIndexes();
00146
00147
00148
00149 for(i = 0; i < mm; i++){
00150 if(osinstance->getNonlinearExpressionTreeModIndexes()[ i] >= 0){
00151 std::cout << osinstance->getNonlinearExpressionTreeModIndexes()[ i] << std::endl;
00152 const_types[ osinstance->getNonlinearExpressionTreeModIndexes()[ i] ] = Ipopt::TNLP::NON_LINEAR;
00153
00154 }
00155
00156 }
00157
00158 return true;
00159 }
00160
00161
00162 bool BonminProblem::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
00163 Index& nnz_h_lag, TNLP::IndexStyleEnum& index_style)
00164 {
00165
00166
00167 n = osinstance->getVariableNumber();
00168
00169 m = osinstance->getConstraintNumber();
00170 #ifdef DEBUG
00171 cout << "Bonmin number variables !!!!!!!!!!!!!!!!!!!!!!!!!!!" << n << endl;
00172 cout << "Bonmin number constraints !!!!!!!!!!!!!!!!!!!!!!!!!!!" << m << endl;
00173 #endif
00174 try{
00175 osinstance->initForAlgDiff( );
00176 }
00177 catch(const ErrorClass& eclass){
00178 bonminErrorMsg = eclass.errormsg;
00179 throw;
00180 }
00181
00182 osinstance->bUseExpTreeForFunEval = true;
00183
00184 SparseJacobianMatrix *sparseJacobian = NULL;
00185 try{
00186 sparseJacobian = osinstance->getJacobianSparsityPattern();
00187
00188 }
00189 catch(const ErrorClass& eclass){
00190 bonminErrorMsg = eclass.errormsg;
00191 throw;
00192 }
00193
00194 nnz_jac_g = sparseJacobian->valueSize;
00195 #ifdef DEBUG
00196 cout << "nnz_jac_g !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_jac_g << endl;
00197 #endif
00198
00199
00200 if( (osinstance->getNumberOfNonlinearExpressions() == 0) && (osinstance->getNumberOfQuadraticTerms() == 0) ) {
00201 cout << "This is a linear program" << endl;
00202 nnz_h_lag = 0;
00203 }
00204 else{
00205
00206 SparseHessianMatrix *sparseHessian = osinstance->getLagrangianHessianSparsityPattern();
00207
00208 nnz_h_lag = sparseHessian->hessDimension;
00209 }
00210 #ifdef DEBUG
00211 cout << "nnz_h_lag !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_h_lag << endl;
00212 #endif
00213
00214 index_style = TNLP::C_STYLE;
00215
00216 return true;
00217 }
00218
00219
00220 bool BonminProblem::get_bounds_info(Index n, Number* x_l, Number* x_u,
00221 Index m, Number* g_l, Number* g_u){
00222 int i;
00223
00224 double * mdVarLB = osinstance->getVariableLowerBounds();
00225
00226
00227 double * mdVarUB = osinstance->getVariableUpperBounds();
00228
00229 for(i = 0; i < n; i++){
00230 x_l[ i] = mdVarLB[ i];
00231 x_u[ i] = mdVarUB[ i];
00232 #ifdef DEBUG
00233 cout << "x_l !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_l[i] << endl;
00234 cout << "x_u !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_u[i] << endl;
00235 #endif
00236 }
00237
00238
00239
00240
00241
00242
00243 double * mdConLB = osinstance->getConstraintLowerBounds();
00244
00245 double * mdConUB = osinstance->getConstraintUpperBounds();
00246
00247 for(int i = 0; i < m; i++){
00248 g_l[ i] = mdConLB[ i];
00249 g_u[ i] = mdConUB[ i];
00250 #ifdef DEBUG
00251 cout << "lower !!!!!!!!!!!!!!!!!!!!!!!!!!!" << g_l[i] << endl;
00252 cout << "upper !!!!!!!!!!!!!!!!!!!!!!!!!!!" << g_u[i] << endl;
00253 #endif
00254 }
00255 return true;
00256 }
00257
00258
00259
00260 bool BonminProblem::get_starting_point(Index n, bool init_x, Number* x,
00261 bool init_z, Number* z_L, Number* z_U, Index m, bool init_lambda,
00262 Number* lambda) {
00263
00264
00265
00266 assert(init_x == true);
00267 assert(init_z == false);
00268 assert(init_lambda == false);
00269 int i, m1, n1;
00270
00271
00272 #ifdef DEBUG
00273 cout << "get initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
00274 #endif
00275
00276
00277 #ifdef DEBUG
00278 cout << "get number of initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
00279 #endif
00280 int k;
00281 if (osoption != NULL)
00282 m1 = osoption->getNumberOfInitVarValues();
00283 else
00284 m1 = 0;
00285 #ifdef DEBUG
00286 cout << "number of variables initialed: " << m1 << endl;
00287 #endif
00288
00289 n1 = osinstance->getVariableNumber();
00290 bool* initialed;
00291 initialed = new bool[n1];
00292 #ifdef DEBUG
00293 cout << "number of variables in total: " << n1 << endl;
00294 #endif
00295
00296
00297 for(k = 0; k < n1; k++)
00298 initialed[k] = false;
00299
00300 if (m1 > 0)
00301 {
00302 #ifdef DEBUG
00303 cout << "get initial values " << endl;
00304 #endif
00305
00306 InitVarValue** initVarVector = osoption->getInitVarValuesSparse();
00307 #ifdef DEBUG
00308 cout << "done " << endl;
00309 #endif
00310
00311 double initval;
00312 try
00313 {
00314 for(k = 0; k < m1; k++)
00315 {
00316 i = initVarVector[k]->idx;
00317 if (initVarVector[k]->idx > n1)
00318 throw ErrorClass ("Illegal index value in variable initialization");
00319
00320 initval = initVarVector[k]->value;
00321 if (osinstance->instanceData->variables->var[i]->ub == OSDBL_MAX)
00322 { if (osinstance->instanceData->variables->var[i]->lb > initval)
00323 throw ErrorClass ("Initial value outside of bounds");
00324 }
00325 else
00326 if (osinstance->instanceData->variables->var[i]->lb == -OSDBL_MAX)
00327 { if (osinstance->instanceData->variables->var[i]->ub < initval)
00328 throw ErrorClass ("Initial value outside of bounds");
00329 }
00330 else
00331 { if ((osinstance->instanceData->variables->var[i]->lb > initval) ||
00332 (osinstance->instanceData->variables->var[i]->ub < initval))
00333 throw ErrorClass ("Initial value outside of bounds");
00334 }
00335
00336 x[initVarVector[k]->idx] = initval;
00337 initialed[initVarVector[k]->idx] = true;
00338 }
00339 }
00340 catch(const ErrorClass& eclass){
00341 cout << "Error in BonminProblem::get_starting_point (OSBonminSolver.cpp)";
00342 cout << endl << endl << endl;
00343 }
00344 }
00345
00346 double default_initval;
00347 default_initval = 1.7171;
00348
00349
00350 for(k = 0; k < n1; k++)
00351 {
00352 if (!initialed[k])
00353 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00354 if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
00355 x[k] = default_initval;
00356 else
00357 x[k] = osinstance->instanceData->variables->var[k]->lb;
00358 else
00359 if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00360 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
00361 x[k] = default_initval;
00362 else
00363 x[k] = osinstance->instanceData->variables->var[k]->ub;
00364 else
00365 if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
00366 (osinstance->instanceData->variables->var[k]->ub >= default_initval))
00367 x[k] = default_initval;
00368 else
00369 if (osinstance->instanceData->variables->var[k]->lb > default_initval)
00370 x[k] = osinstance->instanceData->variables->var[k]->lb;
00371 else
00372 x[k] = osinstance->instanceData->variables->var[k]->ub;
00373 }
00374 for(i = 0; i < n1; i++){
00375 #ifdef DEBUG
00376 std::cout << "INITIAL VALUE !!!!!!!!!!!!!!!!!!!! " << x[ i] << std::endl;
00377 #endif
00378 }
00379
00380 osinstance->calculateAllObjectiveFunctionValues( x, true);
00381 delete[] initialed;
00382 return true;
00383 }
00384
00385
00386
00387 bool BonminProblem::eval_f(Index n, const Number* x, bool new_x, Number& obj_value){
00388
00389 try{
00390 if(osinstance->getObjectiveNumber() > 0){
00391 if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") == 0){
00392 obj_value = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 )[ 0];
00393 }else{
00394 obj_value = -osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 )[ 0];
00395 }
00396 }
00397 }
00398 catch(const ErrorClass& eclass){
00399 bonminErrorMsg = eclass.errormsg;
00400 throw;
00401 }
00402 if( CoinIsnan( (double)obj_value) ) return false;
00403 return true;
00404 }
00405
00406 bool BonminProblem::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f){
00407 int i;
00408 double *objGrad = NULL;
00409 if(osinstance->getObjectiveNumber() > 0){
00410 try{
00411
00412
00413
00414 objGrad = osinstance->calculateObjectiveFunctionGradient( const_cast<double*>(x), NULL, NULL, -1, new_x, 1);
00415 }
00416 catch(const ErrorClass& eclass){
00417 bonminErrorMsg = eclass.errormsg;
00418 throw;
00419 }
00420
00421 for(i = 0; i < n; i++){
00422 if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") == 0){
00423 grad_f[ i] = objGrad[ i];
00424 }else{
00425 grad_f[ i] = -objGrad[ i];
00426 }
00427
00428 }
00429 }
00430
00431 return true;
00432 }
00433
00434
00435 bool BonminProblem::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g) {
00436 try{
00437 double *conVals = osinstance->calculateAllConstraintFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 );
00438 int i;
00439 for(i = 0; i < m; i++){
00440 if( CoinIsnan( (double)conVals[ i] ) ) return false;
00441 g[i] = conVals[ i] ;
00442 }
00443 return true;
00444 }
00445 catch(const ErrorClass& eclass){
00446 bonminErrorMsg = eclass.errormsg;
00447 throw;
00448 }
00449 }
00450
00451
00452
00453 bool BonminProblem::eval_jac_g(Index n, const Number* x, bool new_x,
00454 Index m, Index nele_jac, Index* iRow, Index *jCol,
00455 Number* values){
00456 SparseJacobianMatrix *sparseJacobian;
00457 if (values == NULL) {
00458
00459
00460
00461
00462
00463 try{
00464 sparseJacobian = osinstance->getJacobianSparsityPattern();
00465 }
00466 catch(const ErrorClass& eclass){
00467 bonminErrorMsg = eclass.errormsg;
00468 throw;
00469 }
00470 int i = 0;
00471 int k, idx;
00472 for(idx = 0; idx < m; idx++){
00473 for(k = *(sparseJacobian->starts + idx); k < *(sparseJacobian->starts + idx + 1); k++){
00474 iRow[i] = idx;
00475 jCol[i] = *(sparseJacobian->indexes + k);
00476
00477
00478 i++;
00479 }
00480 }
00481 }
00482 else {
00483
00484 try{
00485 sparseJacobian = osinstance->calculateAllConstraintFunctionGradients( const_cast<double*>(x), NULL, NULL, new_x, 1);
00486 }
00487 catch(const ErrorClass& eclass){
00488 bonminErrorMsg = eclass.errormsg;
00489 throw;
00490 }
00491
00492 for(int i = 0; i < nele_jac; i++){
00493 values[ i] = sparseJacobian->values[i];
00494
00495
00496
00497 }
00498 }
00499 return true;
00500 }
00501
00502
00503 bool BonminProblem::eval_h(Index n, const Number* x, bool new_x,
00504 Number obj_factor, Index m, const Number* lambda,
00505 bool new_lambda, Index nele_hess, Index* iRow,
00506 Index* jCol, Number* values){
00507
00509 SparseHessianMatrix *sparseHessian;
00510
00511 int i;
00512 if (values == NULL) {
00513
00514
00515 try{
00516 sparseHessian = osinstance->getLagrangianHessianSparsityPattern( );
00517 }
00518 catch(const ErrorClass& eclass){
00519 bonminErrorMsg = eclass.errormsg;
00520 throw;
00521 }
00522
00523 for(i = 0; i < nele_hess; i++){
00524 iRow[i] = *(sparseHessian->hessColIdx + i);
00525 jCol[i] = *(sparseHessian->hessRowIdx + i);
00526
00527
00528 }
00529 }
00530 else {
00531
00532
00533 double* objMultipliers = new double[1];
00534 objMultipliers[0] = obj_factor;
00535 try{
00536 sparseHessian = osinstance->calculateLagrangianHessian( const_cast<double*>(x), objMultipliers, const_cast<double*>(lambda) , new_x, 2);
00537 delete[] objMultipliers;
00538 }
00539 catch(const ErrorClass& eclass){
00540 bonminErrorMsg = eclass.errormsg;
00541 delete[] objMultipliers;
00542 throw;
00543 }
00544 for(i = 0; i < nele_hess; i++){
00545 values[ i] = *(sparseHessian->hessValues + i);
00546 }
00547 }
00549 return true;
00550 }
00551
00552 bool BonminProblem::get_scaling_parameters(Number& obj_scaling,
00553 bool& use_x_scaling, Index n,
00554 Number* x_scaling,
00555 bool& use_g_scaling, Index m,
00556 Number* g_scaling){
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 return true;
00567 }
00568
00569
00570
00571
00572 void BonminProblem::finalize_solution(TMINLP::SolverReturn status_,
00573 Index n, const Number* x, Number obj_value)
00574 {
00575
00576 status = status_;
00577 #ifdef DEBUG
00578 std::cout << "FINALIZE OBJ SOLUTION VALUE = " << obj_value << std::endl;
00579 #endif
00580
00581 }
00582
00583
00584
00585
00586 void BonminSolver::buildSolverInstance() throw (ErrorClass) {
00587 try{
00588
00589 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
00590 if(osinstance == NULL){
00591 m_osilreader = new OSiLReader();
00592 osinstance = m_osilreader->readOSiL( osil);
00593 }
00594
00595 tminlp = new BonminProblem( osinstance, osoption);
00596 this->bCallbuildSolverInstance = true;
00597
00598
00599 }
00600 catch(const ErrorClass& eclass){
00601 std::cout << "THERE IS AN ERROR" << std::endl;
00602 osresult->setGeneralMessage( eclass.errormsg);
00603 osresult->setGeneralStatusType( "error");
00604 osrl = osrlwriter->writeOSrL( osresult);
00605 throw ErrorClass( osrl) ;
00606 }
00607 }
00608
00609
00610
00611 void BonminSolver::setSolverOptions() throw (ErrorClass) {
00612 try{
00613 this->bSetSolverOptions = true;
00614 bonminSetup.initializeOptionsAndJournalist();
00615
00616 bonminSetup.roptions()->AddStringOption2("print_solution","Do we print the solution or not?",
00617 "yes",
00618 "no", "No, we don't.",
00619 "yes", "Yes, we do.",
00620 "A longer comment can be put here");
00621
00622
00623 bonminSetup.options()->SetNumericValue("bonmin.time_limit", 5000);
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 bonminSetup.readOptionsString("bonmin.algorithm B-BB\n");
00642
00643
00644 bonminSetup.options()->SetIntegerValue("bonmin.bb_log_level", 0 );
00645 bonminSetup.options()->SetIntegerValue("bonmin.nlp_log_level", 0 );
00646
00647
00648 int printSolution;
00649 bonminSetup.options()->GetEnumValue("print_solution", printSolution,"");
00650 if(printSolution == 1){
00651 tminlp->printSolutionAtEndOfAlgorithm();
00652 }
00653
00654 if(osoption == NULL && osol.length() > 0)
00655 {
00656 m_osolreader = new OSoLReader();
00657 osoption = m_osolreader->readOSoL( osol);
00658 }
00659
00660 if(osoption != NULL && osoption->getNumberOfSolverOptions() > 0 ){
00661 char *pEnd;
00662 int i;
00663 std::vector<SolverOption*> optionsVector;
00664 optionsVector = osoption->getSolverOptions( "bonmin");
00665 int num_bonmin_options = optionsVector.size();
00666 for(i = 0; i < num_bonmin_options; i++){
00667 if(optionsVector[ i]->type == "numeric" ){
00668 std::cout << "FOUND A NUMERIC OPTION " << os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) << std::endl;
00669 if(optionsVector[ i]->category == "ipopt"){
00670 bonminSetup.options()->SetNumericValue(optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
00671 }else{
00672 if(optionsVector[ i]->category == "cbc" ){
00673 bonminSetup.options()->SetNumericValue("milp_solver."+optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
00674 }
00675 else{
00676 bonminSetup.options()->SetNumericValue("bonmin."+optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
00677 }
00678 }
00679 }
00680 else if(optionsVector[ i]->type == "integer" ){
00681 std::cout << "FOUND AN INTEGER OPTION " <<optionsVector[ i]->name << std::endl;
00682 if(optionsVector[ i]->category == "ipopt"){
00683 bonminSetup.options()->SetIntegerValue(optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ) );
00684 }else{
00685 if(optionsVector[ i]->category == "cbc" ){
00686 std::cout << "SETTING INTEGER CBC OPTION" << std::endl;
00687 bonminSetup.options()->SetIntegerValue("milp_solver."+optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ));
00688 }
00689 else{
00690 bonminSetup.options()->SetIntegerValue("bonmin."+optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ) );
00691 }
00692 }
00693 }
00694 else if(optionsVector[ i]->type == "string" ){
00695 std::cout << "FOUND A STRING OPTION " <<optionsVector[ i]->name << std::endl;
00696 if(optionsVector[ i]->category == "ipopt"){
00697 bonminSetup.options()->SetStringValue(optionsVector[ i]->name, optionsVector[ i]->value );
00698 }else{
00699 if(optionsVector[ i]->category == "cbc" ){
00700 bonminSetup.options()->SetStringValue("milp_solver."+optionsVector[ i]->name, optionsVector[ i]->value);
00701 }
00702 else{
00703 bonminSetup.options()->SetStringValue("bonmin."+optionsVector[ i]->name, optionsVector[ i]->value);
00704 }
00705 }
00706
00707 }
00708 }
00709 }
00710
00711 }
00712
00713 catch(const ErrorClass& eclass){
00714 std::cout << "THERE IS AN ERROR" << std::endl;
00715 osresult->setGeneralMessage( eclass.errormsg);
00716 osresult->setGeneralStatusType( "error");
00717 osrl = osrlwriter->writeOSrL( osresult);
00718 throw ErrorClass( osrl) ;
00719 }
00720 }
00721
00722
00723
00724 void BonminSolver::solve() throw (ErrorClass) {
00725 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00726 if( this->bSetSolverOptions == false) setSolverOptions();
00727 try{
00728
00729
00730
00731
00732
00733
00734
00735
00736 try {
00737 bonminSetup.initialize( GetRawPtr(tminlp) );
00738
00739 bb( bonminSetup);
00740
00741 }
00742 catch(TNLPSolver::UnsolvedError *E) {
00743
00744 std::cerr<<"Ipopt has failed to solve a problem"<<std::endl;
00745 }
00746 catch(OsiTMINLPInterface::SimpleError &E) {
00747 std::cerr<<E.className()<<"::"<<E.methodName()
00748 <<std::endl
00749 <<E.message()<<std::endl;
00750 }
00751 catch(CoinError &E) {
00752 std::cerr<<E.className()<<"::"<<E.methodName()
00753 <<std::endl
00754 <<E.message()<<std::endl;
00755 }
00756
00757 if(( bb.model().isContinuousUnbounded() == true) && (osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() <= 0) ){
00758 std::string solutionDescription = "";
00759 std::string message = "Success";
00760 int solIdx = 0;
00761
00762 if(osresult->setServiceName( "Bonin solver service") != true)
00763 throw ErrorClass("OSResult error: setServiceName");
00764 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00765 throw ErrorClass("OSResult error: setInstanceName");
00766 if(osresult->setVariableNumber( osinstance->getVariableNumber() ) != true)
00767 throw ErrorClass("OSResult error: setVariableNumber");
00768 if(osresult->setObjectiveNumber( 1) != true)
00769 throw ErrorClass("OSResult error: setObjectiveNumber");
00770 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00771 throw ErrorClass("OSResult error: setConstraintNumber");
00772 if(osresult->setSolutionNumber( 1) != true)
00773 throw ErrorClass("OSResult error: setSolutionNumer");
00774 if(osresult->setGeneralMessage( message) != true)
00775 throw ErrorClass("OSResult error: setGeneralMessage");
00776 solutionDescription = "The problem is unbounded";
00777 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00778 osresult->setGeneralStatusType("normal");
00779 if( osinstance->getVariableNumber() == 0) osresult->setSolutionMessage(solIdx, "Warning: this problem has zero decision variables!");
00780 osrl = osrlwriter->writeOSrL( osresult);
00781 return;
00782 }
00783
00784
00785 if(( bb.model().isProvenInfeasible() == true) ){
00786 std::string solutionDescription = "";
00787 std::string message = "Success";
00788 int solIdx = 0;
00789
00790
00791 if(osresult->setServiceName( "Bonin solver service") != true)
00792 throw ErrorClass("OSResult error: setServiceName");
00793 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00794 throw ErrorClass("OSResult error: setInstanceName");
00795 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00796 throw ErrorClass("OSResult error: setVariableNumer");
00797 if(osresult->setObjectiveNumber( 1) != true)
00798 throw ErrorClass("OSResult error: setObjectiveNumber");
00799 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00800 throw ErrorClass("OSResult error: setConstraintNumber");
00801 if(osresult->setSolutionNumber( 1) != true)
00802 throw ErrorClass("OSResult error: setSolutionNumber");
00803 if(osresult->setGeneralMessage( message) != true)
00804 throw ErrorClass("OSResult error: setGeneralMessage");
00805 solutionDescription = "The problem is infeasible";
00806 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00807 osresult->setGeneralStatusType("normal");
00808 if( osinstance->getVariableNumber() == 0) osresult->setSolutionMessage(solIdx, "Warning: this problem has zero decision variables!");
00809 osrl = osrlwriter->writeOSrL( osresult);
00810 return;
00811 }
00812 status = tminlp->status;
00813 writeResult();
00814
00815 }
00816 catch(const ErrorClass& eclass){
00817 osresult->setGeneralMessage( eclass.errormsg);
00818 osresult->setGeneralStatusType( "error");
00819 osrl = osrlwriter->writeOSrL( osresult);
00820 throw ErrorClass( osrl) ;
00821 }
00822 }
00823
00824
00825
00826
00827 void BonminSolver::writeResult(){
00828 double *x = NULL;
00829 double *z = NULL;
00830 int i = 0;
00831 int solIdx = 0;
00832 std::string solutionDescription = "";
00833 std::string message = "Bonmin solver finishes to the end.";
00834 if( osinstance->getVariableNumber() == 0) osresult->setSolutionMessage(0, "Warning: this problem has zero decision variables!");
00835
00836
00837 try{
00838 if(osinstance->getVariableNumber() > 0) x = new double[osinstance->getVariableNumber() ];
00839 z = new double[1];
00840
00841 if(osresult->setServiceName( getVersionInfo()) != true)
00842 throw ErrorClass("OSResult error: setServiceName");
00843 if(osresult->setSolverInvoked( "COIN-OR Bonmin") != true)
00844 throw ErrorClass("OSResult error: setSolverInvoked");
00845 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00846 throw ErrorClass("OSResult error: setInstanceName");
00847
00848
00849
00850
00851 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00852 throw ErrorClass("OSResult error: setVariableNumer");
00853 if(osresult->setObjectiveNumber( 1) != true)
00854 throw ErrorClass("OSResult error: setObjectiveNumber");
00855 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00856 throw ErrorClass("OSResult error: setConstraintNumber");
00857 if(osresult->setSolutionNumber( 1) != true)
00858 throw ErrorClass("OSResult error: setSolutionNumer");
00859 if(osresult->setGeneralMessage( message) != true)
00860 throw ErrorClass("OSResult error: setGeneralMessage");
00861
00862 switch( status){
00863 case TMINLP::SUCCESS:
00864 solutionDescription = "SUCCESS[BONMIN]: Algorithm terminated normally at a locally optimal point, satisfying the convergence tolerances.";
00865
00866 osresult->setSolutionStatus(solIdx, "locallyOptimal", solutionDescription);
00867
00868 if(osinstance->getObjectiveNumber() > 0){
00869 *(z + 0) = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.bestSolution()), true)[ 0];
00870 osresult->setObjectiveValuesDense(solIdx, z);
00871 }
00872 if( osinstance->getVariableNumber() > 0){
00873 for(i=0; i < osinstance->getVariableNumber(); i++){
00874 *(x + i) = bb.bestSolution()[i];
00875
00876 }
00877 osresult->setPrimalVariableValuesDense(solIdx, x);
00878 }
00879 break;
00880
00881 case TMINLP::LIMIT_EXCEEDED:
00882 solutionDescription = "LIMIT_EXCEEDED[BONMIN]: A resource limit was exceeded, we provide the current solution.";
00883
00884 osresult->setSolutionStatus(solIdx, "other", solutionDescription);
00885
00886
00887
00888 if(osinstance->getObjectiveNumber() > 0){
00889 *(z + 0) = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.bestSolution()), true)[ 0];
00890 osresult->setObjectiveValuesDense(solIdx, z);
00891 }
00892 if( osinstance->getVariableNumber() > 0){
00893 for(i=0; i < osinstance->getVariableNumber(); i++){
00894 *(x + i) = bb.bestSolution()[i];
00895
00896 }
00897 osresult->setPrimalVariableValuesDense(solIdx, x);
00898 }
00899 break;
00900
00901 case TMINLP::MINLP_ERROR:
00902 solutionDescription = "MINLP_ERROR [BONMIN]: Algorithm stopped with unspecified error.";
00903
00904 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00905
00906 break;
00907
00908 case TMINLP::CONTINUOUS_UNBOUNDED:
00909 solutionDescription = "CONTINUOUS_UNBOUNDED [BONMIN]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
00910
00911 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
00912
00913 break;
00914
00915
00916 case TMINLP::INFEASIBLE:
00917 solutionDescription = "INFEASIBLE [BONMIN]: Problem may be infeasible.";
00918
00919 osresult->setSolutionStatus(solIdx, "infeasible", solutionDescription);
00920 break;
00921
00922
00923 default:
00924 solutionDescription = "OTHER[BONMIN]: other unknown solution status from Bonmin solver";
00925
00926 osresult->setSolutionStatus(solIdx, "other", solutionDescription);
00927 }
00928 osresult->setGeneralStatusType("normal");
00929 osrl = osrlwriter->writeOSrL( osresult);
00930 if(osinstance->getVariableNumber() > 0 ) delete[] x;
00931 x = NULL;
00932 delete[] z;
00933 z = NULL;
00934 }
00935
00936
00937 catch(const ErrorClass& eclass){
00938 if(osinstance->getVariableNumber() > 0) delete[] x;
00939 x = NULL;
00940 delete[] z;
00941 z = NULL;
00942 osresult->setGeneralMessage( eclass.errormsg);
00943 osresult->setGeneralStatusType( "error");
00944 osrl = osrlwriter->writeOSrL( osresult);
00945 throw ErrorClass( osrl) ;
00946 }
00947
00948
00949 }
00950
00951
00952 void BonminSolver::dataEchoCheck(){
00953
00954 int i;
00955
00956
00957 cout << "This is problem: " << osinstance->getInstanceName() << endl;
00958 cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
00959 cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
00960 cout << "number of variables = " << osinstance->getVariableNumber() << endl;
00961 cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
00962
00963
00964 if(osinstance->getVariableNumber() > 0){
00965 for(i = 0; i < osinstance->getVariableNumber(); i++){
00966 if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
00967 if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
00968 if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
00969 if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
00970 }
00971 }
00972
00973
00974 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0){
00975 if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
00976 else cout << "problem is a maximization" << endl;
00977 for(i = 0; i < osinstance->getVariableNumber(); i++){
00978 cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
00979 }
00980 }
00981
00982 if(osinstance->getConstraintNumber() > 0){
00983 for(i = 0; i < osinstance->getConstraintNumber(); i++){
00984 if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
00985 if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
00986 if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
00987 }
00988 }
00989
00990
00991 cout << endl;
00992 cout << "number of nonzeros = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
00993 for(i = 0; i <= osinstance->getVariableNumber(); i++){
00994 cout << "Start Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts[ i] << endl;
00995 }
00996 cout << endl;
00997 for(i = 0; i < osinstance->getLinearConstraintCoefficientNumber(); i++){
00998 cout << "Index Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes[i] << endl;
00999 cout << "Nonzero Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->values[i] << endl;
01000 }
01001
01002
01003 cout << "number of qterms = " << osinstance->getNumberOfQuadraticTerms() << endl;
01004 for(int i = 0; i < osinstance->getNumberOfQuadraticTerms(); i++){
01005 cout << "Row Index = " << osinstance->getQuadraticTerms()->rowIndexes[i] << endl;
01006 cout << "Var Index 1 = " << osinstance->getQuadraticTerms()->varOneIndexes[ i] << endl;
01007 cout << "Var Index 2 = " << osinstance->getQuadraticTerms()->varTwoIndexes[ i] << endl;
01008 cout << "Coefficient = " << osinstance->getQuadraticTerms()->coefficients[ i] << endl;
01009 }
01010 }
01011
01012
01013 BonminProblem::BonminProblem(OSInstance *osinstance_, OSOption *osoption_) {
01014 osinstance = osinstance_;
01015 osoption = osoption_;
01016 printSol_ = false;
01017 }
01018
01019 BonminProblem::~BonminProblem() {
01020
01021 }
01022
01023
01024