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