My Project
OSBonminSolver.cpp
Go to the documentation of this file.
1
18#include <iostream>
19
20
21#include "OSBonminSolver.h"
22#include "OSDataStructures.h"
23#include "OSParameters.h"
24#include "OSCommonUtil.h"
25#include "OSMathUtil.h"
26
27#include "BonOsiTMINLPInterface.hpp"
28#include "BonCbc.hpp"
29
30#include "CoinTime.hpp"
31
32using std::cout;
33using std::endl;
34using std::ostringstream;
35
36
38 osrlwriter = new OSrLWriter();
39 osresult = new OSResult();
40 m_osilreader = NULL;
41 m_osolreader = NULL;
42 bonminErrorMsg = "";
43
44}
45
47 #ifdef DEBUG
48 cout << "inside BonminSolver destructor" << endl;
49 #endif
50 if(m_osilreader != NULL) delete m_osilreader;
51 m_osilreader = NULL;
52 if(m_osolreader != NULL) delete m_osolreader;
53 m_osolreader = NULL;
54 delete osresult;
55 osresult = NULL;
56 delete osrlwriter;
57 osrlwriter = NULL;
58 //delete osinstance;
59 //osinstance = NULL;
60 #ifdef DEBUG
61 cout << "leaving BonminSolver destructor" << endl;
62 #endif
63}
64
65
66
67
68
69
70bool BonminProblem::get_variables_types(Index n, VariableType* var_types){
71 int i = 0;
72 char *varType;
73 varType = osinstance->getVariableTypes();
75 for(i = 0; i < n; i++){
76 if( varType[i] == 'B') {
77 var_types[i] = BINARY;
78 }
79 else{
80 if( varType[i] == 'I') {
81 var_types[i] = INTEGER;
82 }
83 else{
84 var_types[i] = CONTINUOUS;
85 }
86 }
87 }
88 return true;
89}
90
91bool BonminProblem::get_variables_linearity(Index n, Ipopt::TNLP::LinearityType* var_types){
92
93
94
95 std::cout << "Initialize Nonlinear Structures" << std::endl;
96 try{
98 }
99 catch(const ErrorClass& eclass){
100 bonminErrorMsg = eclass.errormsg;
101 throw;
102 }
108 std::map<int, int> varIndexMap;
109 std::map<int, int>::iterator posVarIndexMap;
111 /* first make all continuous */
112
113 int i;
114
115 for(i = 0; i < n; i++){
116 var_types[ i] = Ipopt::TNLP::LINEAR;
117 }
122 for(posVarIndexMap = varIndexMap.begin(); posVarIndexMap != varIndexMap.end(); ++posVarIndexMap){
123 std::cout << "Variable Index = " << posVarIndexMap->first << std::endl ;
124 var_types[ posVarIndexMap->first] = Ipopt::TNLP::NON_LINEAR;
125 }
126 std::cout << "Number of nonlinear variables = " << varIndexMap.size() << std::endl;
127
128 return true;
129}
130
131bool BonminProblem::get_constraints_linearity(Index m, Ipopt::TNLP::LinearityType* const_types){
132
133 int i;
134
135 for(i = 0; i < m; i++){
136 const_types[ i] = Ipopt::TNLP::LINEAR;
137 }
138
139
141
142
143
144 for(i = 0; i < mm; i++){
146 std::cout << osinstance->getNonlinearExpressionTreeModIndexes()[ i] << std::endl;
147 const_types[ osinstance->getNonlinearExpressionTreeModIndexes()[ i] ] = Ipopt::TNLP::NON_LINEAR;
148
149 }
150
151 }
152
153 return true;
154}
155
156// returns the size of the problem
157bool BonminProblem::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
158 Index& nnz_h_lag, TNLP::IndexStyleEnum& index_style)
159{
160 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Bonmin NEEDS AN OBJECTIVE FUNCTION");
161 // number of variables
163 // number of constraints
165 cout << "Bonmin number variables !!!!!!!!!!!!!!!!!!!!!!!!!!!" << n << endl;
166 cout << "Bonmin number constraints !!!!!!!!!!!!!!!!!!!!!!!!!!!" << m << endl;
167 try{
169 }
170 catch(const ErrorClass& eclass){
171 bonminErrorMsg = eclass.errormsg;
172 throw;
173 }
174 // use the OS Expression tree for function evaluations instead of CppAD
176 //std::cout << "Call sparse jacobian" << std::endl;
177 SparseJacobianMatrix *sparseJacobian = NULL;
178 try{
179 sparseJacobian = osinstance->getJacobianSparsityPattern();
180 }
181 catch(const ErrorClass& eclass){
182 bonminErrorMsg = eclass.errormsg;
183 throw;
184 }
185 //std::cout << "Done calling sparse jacobian" << std::endl;
186 nnz_jac_g = sparseJacobian->valueSize;
187 cout << "nnz_jac_g !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_jac_g << endl;
188 // nonzeros in upper hessian
189
191 cout << "This is a linear program" << endl;
192 nnz_h_lag = 0;
193 }
194 else{
195 //std::cout << "Get Lagrangian Hessian Sparsity Pattern " << std::endl;
197 //std::cout << "Done Getting Lagrangian Hessian Sparsity Pattern " << std::endl;
198 nnz_h_lag = sparseHessian->hessDimension;
199 }
200 cout << "print nnz_h_lag (OSBonminSolver.cpp)" << endl;
201 cout << "nnz_h_lag !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_h_lag << endl;
202 cout << "set index_style (OSBonminSolver.cpp)" << endl;
203 // use the C style indexing (0-based)
204 index_style = TNLP::C_STYLE;
205 cout << "return from get_nlp_info (OSBonminSolver.cpp)" << endl;
206
208
209 return true;
210}//get_nlp_info
211
212
213bool BonminProblem::get_bounds_info(Index n, Number* x_l, Number* x_u,
214 Index m, Number* g_l, Number* g_u){
215 int i;
216
217 double * mdVarLB = osinstance->getVariableLowerBounds();
218 //std::cout << "GET BOUNDS INFORMATION FOR BONMIN !!!!!!!!!!!!!!!!!" << std::endl;
219 // variables upper bounds
220 double * mdVarUB = osinstance->getVariableUpperBounds();
221
222 for(i = 0; i < n; i++){
223 x_l[ i] = mdVarLB[ i];
224 x_u[ i] = mdVarUB[ i];
225 cout << "x_l !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_l[i] << endl;
226 cout << "x_u !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_u[i] << endl;
227 }
228 // Bonmin interprets any number greater than nlp_upper_bound_inf as
229 // infinity. The default value of nlp_upper_bound_inf and nlp_lower_bound_inf
230 // is 1e19 and can be changed through bonmin options.
231 // e.g. g_u[0] = 2e19;
232
233 //constraint lower bounds
234 double * mdConLB = osinstance->getConstraintLowerBounds();
235 //constraint upper bounds
236 double * mdConUB = osinstance->getConstraintUpperBounds();
237
238 for(int i = 0; i < m; i++){
239 g_l[ i] = mdConLB[ i];
240 g_u[ i] = mdConUB[ i];
241 cout << "lower !!!!!!!!!!!!!!!!!!!!!!!!!!!" << g_l[i] << endl;
242 cout << "upper !!!!!!!!!!!!!!!!!!!!!!!!!!!" << g_u[i] << endl;
243 }
244 return true;
245}//get_bounds_info
246
247
248// returns the initial point for the problem
249bool BonminProblem::get_starting_point(Index n, bool init_x, Number* x,
250 bool init_z, Number* z_L, Number* z_U, Index m, bool init_lambda,
251 Number* lambda) {
252 // Here, we assume we only have starting values for x, if you code
253 // your own NLP, you can provide starting values for the dual variables
254 // if you wish
255 assert(init_x == true);
256 assert(init_z == false);
257 assert(init_lambda == false);
258 int i, m1, n1;
259
260#ifdef DEBUG
261 cout << "get initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
262#endif
263
264 //now set initial values
265#ifdef DEBUG
266 cout << "get number of initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
267 cout << "Is osoption = NULL? " << (osoption == NULL) << endl;
268#endif
269 int k;
270 if (osoption != NULL)
272 else
273 m1 = 0;
274#ifdef DEBUG
275 cout << "number of variables initialed: " << m1 << endl;
276#endif
277
279 bool* initialed;
280 initialed = new bool[n1];
281#ifdef DEBUG
282 cout << "number of variables in total: " << n1 << endl;
283#endif
284
285
286 for(k = 0; k < n1; k++)
287 initialed[k] = false;
288
289 if (m1 > 0)
290 {
291#ifdef DEBUG
292 cout << "get initial values " << endl;
293#endif
294
295 InitVarValue** initVarVector = osoption->getInitVarValuesSparse();
296#ifdef DEBUG
297 cout << "done " << endl;
298#endif
299
300 double initval;
301 try
302 {
303 for(k = 0; k < m1; k++)
304 {
305 i = initVarVector[k]->idx;
306 if (initVarVector[k]->idx > n1)
307 throw ErrorClass ("Illegal index value in variable initialization");
308
309 initval = initVarVector[k]->value;
311 { if (osinstance->instanceData->variables->var[i]->lb > initval)
312 throw ErrorClass ("Initial value outside of bounds");
313 }
314 else
316 { if (osinstance->instanceData->variables->var[i]->ub < initval)
317 throw ErrorClass ("Initial value outside of bounds");
318 }
319 else
320 { if ((osinstance->instanceData->variables->var[i]->lb > initval) ||
321 (osinstance->instanceData->variables->var[i]->ub < initval))
322 throw ErrorClass ("Initial value outside of bounds");
323 }
324
325 x[initVarVector[k]->idx] = initval;
326 initialed[initVarVector[k]->idx] = true;
327 }
328 }
329 catch(const ErrorClass& eclass)
330 { cout << "Error in BonminProblem::get_starting_point (OSBonminSolver.cpp)";
331 cout << endl << endl << endl;
332 }
333 } // end if (m1 > 0)
334
335 double default_initval;
336 default_initval = 1.7171;
337
338 for(k = 0; k < n1; k++)
339 {
340 if (!initialed[k])
342 if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
343 x[k] = default_initval;
344 else
345 x[k] = osinstance->instanceData->variables->var[k]->lb;
346 else
348 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
349 x[k] = default_initval;
350 else
351 x[k] = osinstance->instanceData->variables->var[k]->ub;
352 else
353 if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
354 (osinstance->instanceData->variables->var[k]->ub >= default_initval))
355 x[k] = default_initval;
356 else
357 if (osinstance->instanceData->variables->var[k]->lb > default_initval)
358 x[k] = osinstance->instanceData->variables->var[k]->lb;
359 else
360 x[k] = osinstance->instanceData->variables->var[k]->ub;
361 }
362 for(i = 0; i < n1; i++){
363 std::cout << "INITIAL VALUE !!!!!!!!!!!!!!!!!!!! " << x[ i] << std::endl;
364 }
365
366
367 delete[] initialed;
368
369 return true;
370}//get_starting_point
371
372
373// returns the value of the objective function
374bool BonminProblem::eval_f(Index n, const Number* x, bool new_x, Number& obj_value){
375 try{
376 obj_value = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 )[ 0];
377 }
378 catch(const ErrorClass& eclass){
379 bonminErrorMsg = eclass.errormsg;
380 throw;
381 }
382 if( CommonUtil::ISOSNAN( (double)obj_value) ) return false;
383 return true;
384}
385
386bool BonminProblem::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f){
387 int i;
388 double *objGrad;
389 try{
390 //objGrad = osinstance->calculateAllObjectiveFunctionGradients( const_cast<double*>(x), NULL, NULL, new_x, 1)[ 0];
391 //std::cout << "Calculate Objective function gradient " << std::endl;
392 // we assume we are doing the objective function indexed by -1
393 objGrad = osinstance->calculateObjectiveFunctionGradient( const_cast<double*>(x), NULL, NULL, -1, new_x, 1);
394 }
395 catch(const ErrorClass& eclass){
396 bonminErrorMsg = eclass.errormsg;
397 throw;
398 }
399 for(i = 0; i < n; i++){
400 grad_f[ i] = objGrad[ i];
401 //std::cout << grad_f[ i] << std::endl;
402 }
403 std::cout << "DONE WITH Calculate Objective function gradient " << std::endl;
404 return true;
405}//eval_grad_f
406
407// return the value of the constraints: g(x)
408bool BonminProblem::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g) {
409 try{
410 double *conVals = osinstance->calculateAllConstraintFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 );
411 int i;
412 for(i = 0; i < m; i++){
413 if( CommonUtil::ISOSNAN( (double)conVals[ i] ) ) return false;
414 g[i] = conVals[ i] ;
415 }
416 return true;
417 }
418 catch(const ErrorClass& eclass){
419 bonminErrorMsg = eclass.errormsg;
420 throw;
421 }
422}//eval_g
423
424
425// return the structure or values of the jacobian
426bool BonminProblem::eval_jac_g(Index n, const Number* x, bool new_x,
427 Index m, Index nele_jac, Index* iRow, Index *jCol,
428 Number* values){
429 SparseJacobianMatrix *sparseJacobian;
430 if (values == NULL) {
431 // return the values of the jacobian of the constraints
432 //cout << "n: " << n << endl;
433 //cout << "m: " << m << endl;
434 //cout << "nele_jac: " << nele_jac << endl;
435 // return the structure of the jacobian
436 try{
437 sparseJacobian = osinstance->getJacobianSparsityPattern();
438 }
439 catch(const ErrorClass& eclass){
440 bonminErrorMsg = eclass.errormsg;
441 throw;
442 }
443 int i = 0;
444 int k, idx;
445 for(idx = 0; idx < m; idx++){
446 for(k = *(sparseJacobian->starts + idx); k < *(sparseJacobian->starts + idx + 1); k++){
447 iRow[i] = idx;
448 jCol[i] = *(sparseJacobian->indexes + k);
449 //cout << "ROW IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << iRow[i] << endl;
450 //cout << "COL IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << jCol[i] << endl;
451 i++;
452 }
453 }
454 }
455 else {
456 //std::cout << "EVALUATING JACOBIAN" << std::endl;
457 try{
458 sparseJacobian = osinstance->calculateAllConstraintFunctionGradients( const_cast<double*>(x), NULL, NULL, new_x, 1);
459 }
460 catch(const ErrorClass& eclass){
461 bonminErrorMsg = eclass.errormsg;
462 throw;
463 }
464 //osinstance->getIterateResults( (double*)x, 0.0, NULL, -1, new_x, 1);
465 for(int i = 0; i < nele_jac; i++){
466 values[ i] = sparseJacobian->values[i];
467 //values[ i] = osinstance->m_mdJacValue[ i];
468 //cout << "values[i]:!!!!!!!!!!!! " << values[ i] << endl;
469 //cout << "m_mdJacValue[ i]:!!!!!!!!!!!! " << osinstance->m_mdJacValue[ i] << endl;
470 }
471 }
472 return true;
473}//eval_jac_g
474
475//return the structure or values of the hessian
476bool BonminProblem::eval_h(Index n, const Number* x, bool new_x,
477 Number obj_factor, Index m, const Number* lambda,
478 bool new_lambda, Index nele_hess, Index* iRow,
479 Index* jCol, Number* values){
480
482 SparseHessianMatrix *sparseHessian;
483
484 int i;
485 if (values == NULL) {
486 // return the structure. This is a symmetric matrix, fill the lower left triangle only.
487 //cout << "get structure of HESSIAN !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
488 try{
490 }
491 catch(const ErrorClass& eclass){
492 bonminErrorMsg = eclass.errormsg;
493 throw;
494 }
495 //cout << "got structure of HESSIAN !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
496 for(i = 0; i < nele_hess; i++){
497 iRow[i] = *(sparseHessian->hessColIdx + i);
498 jCol[i] = *(sparseHessian->hessRowIdx + i);
499 //cout << "ROW HESS IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << iRow[i] << endl;
500 //cout << "COL HESS IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << jCol[i] << endl;
501 }
502 }
503 else {
504 //std::cout << "EVALUATING HESSIAN" << std::endl;
505 // return the values. This is a symmetric matrix, fill the lower left triangle only
506 double* objMultipliers = new double[1];
507 objMultipliers[0] = obj_factor;
508 try{
509 sparseHessian = osinstance->calculateLagrangianHessian( const_cast<double*>(x), objMultipliers, const_cast<double*>(lambda) , new_x, 2);
510 delete[] objMultipliers;
511 }
512 catch(const ErrorClass& eclass){
513 bonminErrorMsg = eclass.errormsg;
514 delete[] objMultipliers;
515 throw;
516 }
517 for(i = 0; i < nele_hess; i++){
518 values[ i] = *(sparseHessian->hessValues + i);
519 }
520 }
522 return true;
523}//eval_h
524
525bool BonminProblem::get_scaling_parameters(Number& obj_scaling,
526 bool& use_x_scaling, Index n,
527 Number* x_scaling,
528 bool& use_g_scaling, Index m,
529 Number* g_scaling){
530 /*
531 * Bonmin assumes problems cast as a min
532 * if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") != 0){
533 obj_scaling = -1;
534 }
535 else obj_scaling = 1;
536 use_x_scaling = false;
537 use_g_scaling = false;
538 */
539 return true;
540}//get_scaling_parameters
541
542
543
544
545void
546BonminProblem::finalize_solution(TMINLP::SolverReturn status,
547 Index n, const Number* x, Number obj_value)
548{
549 OSrLWriter *osrlwriter ;
550 osrlwriter = new OSrLWriter();
551 std::cout<<"Problem status: "<<status<<std::endl;
552 std::cout<<"Objective value: "<<obj_value<<std::endl;
553 if(printSol_ && x != NULL){
554 std::cout<<"Solution:"<<std::endl;
555 for(int i = 0 ; i < n ; i++){
556 std::cout<<"x["<<i<<"] = "<<x[i];
557 if(i < n-1) std::cout<<", ";
558 }
559 std::cout<<std::endl;
560 }
561
562 printf("\n\nObjective value\n");
563 printf("f(x*) = %e\n", obj_value);
564 int solIdx = 0;
565 ostringstream outStr;
566 double* mdObjValues = new double[1];
567 std::string message = "Bonmin solver finishes to the end.";
568 std::string solutionDescription = "";
569
570 try{
571
572 // resultHeader information
573 if(osresult->setServiceName( "Bonmin solver service") != true)
574 throw ErrorClass("OSResult error: setServiceName");
576 throw ErrorClass("OSResult error: setInstanceName");
577
578 //if(osresult->setJobID( osoption->jobID) != true)
579 // throw ErrorClass("OSResult error: setJobID");
580
581 // set basic problem parameters
583 throw ErrorClass("OSResult error: setVariableNumer");
584 if(osresult->setObjectiveNumber( 1) != true)
585 throw ErrorClass("OSResult error: setObjectiveNumber");
587 throw ErrorClass("OSResult error: setConstraintNumber");
588 if(osresult->setSolutionNumber( 1) != true)
589 throw ErrorClass("OSResult error: setSolutionNumer");
590
591
592 if(osresult->setGeneralMessage( message) != true)
593 throw ErrorClass("OSResult error: setGeneralMessage");
594
595 switch( status){
596 case SUCCESS:
597 solutionDescription = "SUCCESS[BONMIN]: Algorithm terminated successfully at a locally optimal point, satisfying the convergence tolerances.";
598 osresult->setSolutionStatus(solIdx, "locallyOptimal", solutionDescription);
599 osresult->setPrimalVariableValues(solIdx, const_cast<double*>(x), osinstance->getVariableNumber());
600 //osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda));
601 mdObjValues[0] = obj_value;
602 osresult->setObjectiveValues(solIdx, mdObjValues, 1);
603 break;
604 case MAXITER_EXCEEDED:
605 solutionDescription = "MAXITER_EXCEEDED[BONMIN]: Maximum number of iterations exceeded.";
606 osresult->setSolutionStatus(solIdx, "stoppedByLimit", solutionDescription);
607 osresult->setPrimalVariableValues(solIdx, const_cast<double*>(x), osinstance->getVariableNumber());
608 //osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda));
609 mdObjValues[0] = obj_value;
610 osresult->setObjectiveValues(solIdx, mdObjValues, 1);
611 break;
612 case STOP_AT_TINY_STEP:
613 solutionDescription = "STOP_AT_TINY_STEP[BONMIN]: Algorithm proceeds with very little progress.";
614 osresult->setSolutionStatus(solIdx, "stoppedByLimit", solutionDescription);
615 osresult->setPrimalVariableValues(solIdx, const_cast<double*>( x), osinstance->getVariableNumber());
616 //osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda));
617 mdObjValues[0] = obj_value;
618 osresult->setObjectiveValues(solIdx, mdObjValues, 1);
619 break;
620 case STOP_AT_ACCEPTABLE_POINT:
621 solutionDescription = "STOP_AT_ACCEPTABLE_POINT[BONMIN]: Algorithm stopped at a point that was converged, not to _desired_ tolerances, but to _acceptable_ tolerances";
622 osresult->setSolutionStatus(solIdx, "BonminAccetable", solutionDescription);
623 osresult->setPrimalVariableValues(solIdx, const_cast<double*>(x), osinstance->getVariableNumber());
624 //osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda));
625 mdObjValues[0] = obj_value;
626 osresult->setObjectiveValues(solIdx, mdObjValues, 1);
627 break;
628 case LOCAL_INFEASIBILITY:
629 solutionDescription = "LOCAL_INFEASIBILITY[BONMIN]: Algorithm converged to a point of local infeasibility. Problem may be infeasible.";
630 osresult->setSolutionStatus(solIdx, "infeasible", solutionDescription);
631 break;
632 case USER_REQUESTED_STOP:
633 solutionDescription = "USER_REQUESTED_STOP[BONMIN]: The user call-back function intermediate_callback returned false, i.e., the user code requested a premature termination of the optimization.";
634 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
635 break;
636 case DIVERGING_ITERATES:
637 solutionDescription = "DIVERGING_ITERATES[BONMIN]: It seems that the iterates diverge.";
638 osresult->setSolutionStatus(solIdx, "unbounded", solutionDescription);
639 break;
640 case RESTORATION_FAILURE:
641 solutionDescription = "RESTORATION_FAILURE[BONMIN]: Restoration phase failed, algorithm doesn't know how to proceed.";
642 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
643 break;
644 case ERROR_IN_STEP_COMPUTATION:
645 solutionDescription = "ERROR_IN_STEP_COMPUTATION[BONMIN]: An unrecoverable error occurred while IPOPT tried to compute the search direction.";
646 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
647 break;
648 case INVALID_NUMBER_DETECTED:
649 solutionDescription = "INVALID_NUMcatBER_DETECTED[BONMIN]: Algorithm received an invalid number (such as NaN or Inf) from the NLP; see also option check_derivatives_for_naninf.";
650 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
651 break;
652 case INTERNAL_ERROR:
653 solutionDescription = "INTERNAL_ERROR[BONMIN]: An unknown internal error occurred. Please contact the IPOPT authors through the mailing list.";
654 osresult->setSolutionStatus(solIdx, "error", solutionDescription);
655 break;
656 default:
657 solutionDescription = "OTHER[BONMIN]: other unknown solution status from Bonmin solver";
658 osresult->setSolutionStatus(solIdx, "other", solutionDescription);
659 }
661 delete osrlwriter;
662 delete[] mdObjValues;
663 osrlwriter = NULL;
664
665 }
666
667 catch(const ErrorClass& eclass){
670 std::string osrl = osrlwriter->writeOSrL( osresult);
671 delete osrlwriter;
672 osrlwriter = NULL;
673 throw ErrorClass( osrl) ;
674 delete[] mdObjValues;
675 mdObjValues = NULL;
676 }
677}
678
679
680
681
683 try{
684 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
685 if(osinstance == NULL){
686 m_osilreader = new OSiLReader();
688 }
689 // Create a new instance of your nlp
691 this->bCallbuildSolverInstance = true;
692 //Now initialize from tminlp
693 bonmin.initialize( GetRawPtr(tminlp) );
694 }
695 catch(const ErrorClass& eclass){
696 std::cout << "THERE IS AN ERROR" << std::endl;
700 throw ErrorClass( osrl) ;
701 }
702}//end buildSolverInstance()
703
704
705
707 try{
708
709 this->bSetSolverOptions = true;
710 bonmin.initializeOptionsAndJournalist();
711 //Register an additional option
712 bonmin.roptions()->AddStringOption2("print_solution","Do we print the solution or not?",
713 "yes",
714 "no", "No, we don't.",
715 "yes", "Yes, we do.",
716 "A longer comment can be put here");
717
718 // Here we can change the default value of some Bonmin or Ipopt option
719 bonmin.options()->SetNumericValue("bonmin.time_limit", 1000); //changes bonmin's time limit
720 bonmin.options()->SetStringValue("mu_oracle","loqo");
721
722 //Here we read several option files
723 bonmin.readOptionsFile("Mybonmin.opt");
724 bonmin.readOptionsFile();// This reads the default file "bonmin.opt"
725
726 // Options can also be set by using a string with a format similar to the bonmin.opt file
727 bonmin.readOptionsString("bonmin.algorithm B-BB\n");
728
729 // Now we can obtain the value of the new option
730 int printSolution;
731 bonmin.options()->GetEnumValue("print_solution", printSolution,"");
732 if(printSolution == 1){
733 tminlp->printSolutionAtEndOfAlgorithm();
734 }
735
736 if(osoption == NULL && osol.length() > 0)
737 {
738 m_osolreader = new OSoLReader();
740 }
741
742 if(osoption != NULL){
743 std::cout << "number of solver options " << osoption->getNumberOfSolverOptions() << std::endl;
744 std::vector<SolverOption*> optionsVector;
745 optionsVector = osoption->getSolverOptions( "bonmin");
746 char *pEnd;
747 int i;
748 int num_bonmin_options = optionsVector.size();
749 for(i = 0; i < num_bonmin_options; i++){
750 std::cout << "bonmin solver option " << optionsVector[ i]->name << std::endl;
751 if(optionsVector[ i]->type == "numeric" ){
752 std::cout << "FOUND A NUMERIC OPTION " << os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) << std::endl;
753 bonmin.options()->SetNumericValue(optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
754 }
755 else if(optionsVector[ i]->type == "integer" ){
756 std::cout << "FOUND AN INTEGER OPTION " << atoi( optionsVector[ i]->value.c_str() ) << std::endl;
757 bonmin.options()->SetIntegerValue(optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ) );
758 }
759 else if(optionsVector[ i]->type == "string" ){
760 bonmin.options()->SetStringValue(optionsVector[ i]->name, optionsVector[ i]->value);
761 }
762 }
763 }
764
765 }
766
767 catch(const ErrorClass& eclass){
768 std::cout << "THERE IS AN ERROR" << std::endl;
772 throw ErrorClass( osrl) ;
773 }
774}//end setSolverOptions()
775
776
777//void BonminSolver::solve() throw (ErrorClass) {
778void BonminSolver::solve() throw (ErrorClass) {
779 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
780 std::cout << "set Solver Options for Gus" << std::endl;
781 if( this->bSetSolverOptions == false) setSolverOptions();
782 std::cout << "done setting set Solver Options for Gus" << std::endl;
783
784 try{
785 double start = CoinCpuTime();
786 //OSiLWriter osilwriter;
787 //cout << osilwriter.writeOSiL( osinstance) << endl;
788 if(osinstance->getVariableNumber() <= 0)throw ErrorClass("Bonmin requires decision variables");
789
790// The next line should come out eventually...
791 if(osinstance->getConstraintNumber() <= 0)throw ErrorClass("Bonmin cannot handle unconstrained problems");
792
793 double duration = CoinCpuTime() - start;
794 cout << "Parsing took (seconds): "<< duration << endl;
795
796 try {
797 Bab bb;
798 bb( bonmin); //process parameter file using Ipopt and do branch and bound using Cbc
799
800
801 }
802 catch(TNLPSolver::UnsolvedError *E) {
803 //There has been a failure to solve a problem with Ipopt.
804 std::cerr<<"Ipopt has failed to solve a problem"<<std::endl;
805 }
806 catch(OsiTMINLPInterface::SimpleError &E) {
807 std::cerr<<E.className()<<"::"<<E.methodName()
808 <<std::endl
809 <<E.message()<<std::endl;
810 }
811 catch(CoinError &E) {
812 std::cerr<<E.className()<<"::"<<E.methodName()
813 <<std::endl
814 <<E.message()<<std::endl;
815 }
816
817
818 // see if we have a linear program
819 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Bonmin NEEDS AN OBJECTIVE FUNCTION");
821 //app->Options()->SetStringValue("hessian_approximation", "limited-memory");
822 // if it is a max problem call scaling and set to -1
823 if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") != 0){
824 //app->Options()->SetStringValue("nlp_scaling_method", "user-scaling");
825 }
826
827 std::cout << "Finish Bonmin Optimize" << std::endl;
829 std::cout << "Finish writing the osrl" << std::endl;
830
831
832 }
833 catch(const ErrorClass& eclass){
837 throw ErrorClass( osrl) ;
838 }
839}//solve
840
841
843
844 int i;
845
846 // print out problem parameters
847 cout << "This is problem: " << osinstance->getInstanceName() << endl;
848 cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
849 cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
850 cout << "number of variables = " << osinstance->getVariableNumber() << endl;
851 cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
852
853 // print out the variable information
854 if(osinstance->getVariableNumber() > 0){
855 for(i = 0; i < osinstance->getVariableNumber(); i++){
856 if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
857 if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
858 if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
859 if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
860 }
861 }
862
863 // print out objective function information
865 if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
866 else cout << "problem is a maximization" << endl;
867 for(i = 0; i < osinstance->getVariableNumber(); i++){
868 cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
869 }
870 }
871 // print out constraint information
873 for(i = 0; i < osinstance->getConstraintNumber(); i++){
874 if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
875 if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
876 if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
877 }
878 }
879
880 // print out linear constraint data
881 cout << endl;
882 cout << "number of nonzeros = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
883 for(i = 0; i <= osinstance->getVariableNumber(); i++){
884 cout << "Start Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts[ i] << endl;
885 }
886 cout << endl;
887 for(i = 0; i < osinstance->getLinearConstraintCoefficientNumber(); i++){
888 cout << "Index Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes[i] << endl;
889 cout << "Nonzero Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->values[i] << endl;
890 }
891
892 // print out quadratic data
893 cout << "number of qterms = " << osinstance->getNumberOfQuadraticTerms() << endl;
894 for(int i = 0; i < osinstance->getNumberOfQuadraticTerms(); i++){
895 cout << "Row Index = " << osinstance->getQuadraticTerms()->rowIndexes[i] << endl;
896 cout << "Var Index 1 = " << osinstance->getQuadraticTerms()->varOneIndexes[ i] << endl;
897 cout << "Var Index 2 = " << osinstance->getQuadraticTerms()->varTwoIndexes[ i] << endl;
898 cout << "Coefficient = " << osinstance->getQuadraticTerms()->coefficients[ i] << endl;
899 }
900} // end dataEchoCheck
901
902
903BonminProblem::BonminProblem(OSInstance *osinstance_, OSOption *osoption_, OSResult *osresult_) {
904 osinstance = osinstance_;
905 osoption = osoption_;
906 osresult = osresult_;
907 printSol_ = false;
908}
909
911
912}
913
914
915
#define INTEGER
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
double os_strtod(const char *s00, char **se)
Definition OSdtoa.cpp:2541
bool printSol_
Method called by Ipopt at the end of optimization.
virtual ~BonminProblem()
the BonminProblem class destructor
virtual bool get_constraints_linearity(Ipopt::Index m, Ipopt::TNLP::LinearityType *const_types)
Pass the type of the constraints (LINEAR, NON_LINEAR) to the optimizer.
virtual bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Number *g)
Method to return the constraint residuals.
virtual void finalize_solution(Bonmin::TMINLP::SolverReturn status_, Ipopt::Index n, const Ipopt::Number *x, Ipopt::Number obj_value)
Method called by Ipopt at the end of optimization.
virtual bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g, Ipopt::Index &nnz_h_lag, Ipopt::TNLP::IndexStyleEnum &index_style)
Method to pass the main dimensions of the problem to Ipopt.
OSOption * osoption
virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)
Method to return the gradient of the objective.
OSInstance * osinstance
virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number *x, bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U, Ipopt::Index m, bool init_lambda, Ipopt::Number *lambda)
Method to return the starting point for the algorithm.
virtual bool get_variables_types(Ipopt::Index n, VariableType *var_types)
Pass the type of the variables (INTEGER, BINARY, CONTINUOUS) to the optimizer.
virtual bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number &obj_value)
Method to return the objective value.
virtual bool get_variables_linearity(Ipopt::Index n, Ipopt::TNLP::LinearityType *var_types)
Pass info about linear and nonlinear variables.
virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number *x_l, Ipopt::Number *x_u, Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
Bonmin specific methods for defining the nlp problem.
std::string bonminErrorMsg
Bonmin::TMINLP::SolverReturn status
BonminProblem(OSInstance *osinstance_, OSOption *osoption_)
the BonminProblemclass constructor
virtual bool eval_h(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number *lambda, bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
Method to return: 1) The structure of the hessian of the lagrangian (if "values" is NULL) 2) The valu...
virtual bool get_scaling_parameters(Ipopt::Number &obj_scaling, bool &use_x_scaling, Ipopt::Index n, Ipopt::Number *x_scaling, bool &use_g_scaling, Ipopt::Index m, Ipopt::Number *g_scaling)
Method to pass the main dimensions of the problem to Ipopt.
virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
Method to return: 1) The structure of the jacobian (if "values" is NULL) 2) The values of the jacobia...
std::string bonminErrorMsg
Ipopt::SmartPtr< BonminProblem > tminlp
Bonmin::Bab bb
virtual void setSolverOptions()
The implementation of the virtual functions.
virtual void buildSolverInstance()
buildSolverInstance is a virtual function – the actual solvers will implement their own buildSolverIn...
void dataEchoCheck()
use this for debugging, print out the instance that the solver thinks it has and compare this with th...
OSiLReader * m_osilreader
m_osilreader is an OSiLReader object used to create an osinstance from an osil string if needed
OSoLReader * m_osolreader
m_osolreader is an OSoLReader object used to create an osoption from an osol string if needed
~BonminSolver()
the IpoptSolver class destructor
virtual void solve()
solve results in an instance being read into the Bonmin data structrues and optimized
OSrLWriter * osrlwriter
BonminSolver()
the BonminSolver class constructor
std::string osol
osol holds the options for the solver
bool bSetSolverOptions
bSetSolverOptions is set to true if setSolverOptions has been called, false otherwise
std::string osrl
osrl holds the solution or result of the model
OSInstance * osinstance
osinstance holds the problem instance in-memory as an OSInstance object
bool bCallbuildSolverInstance
bCallbuildSolverInstance is set to true if buildSolverService has been called
std::string osil
osil holds the problem instance as a std::string
OSOption * osoption
osoption holds the solver options in-memory as an OSOption object
OSResult * osresult
osresult holds the solution or result of the model in-memory as an OSResult object
used for throwing exceptions.
std::string errormsg
errormsg is the error that is causing the exception to be thrown
the InitVarValue class.
Definition OSOption.h:1160
double value
initial value
Definition OSOption.h:1170
int idx
variable index
Definition OSOption.h:1164
Variables * variables
variables is a pointer to a Variables object
Objectives * objectives
objectives is a pointer to a Objectives object
The in-memory representation of an OSiL instance..
SparseJacobianMatrix * calculateAllConstraintFunctionGradients(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate the gradient of all constraint functions.
double * getConstraintLowerBounds()
Get constraint lower bounds.
int getNumberOfQuadraticTerms()
Get the number of specified (usually nonzero) qTerms in the quadratic coefficients.
double * getVariableUpperBounds()
Get variable upper bounds.
SparseJacobianMatrix * getJacobianSparsityPattern()
int getNumberOfNonlinearExpressionTreeModIndexes()
Get the number of unique nonlinear expression tree indexes after modifying the expression tree to con...
bool bUseExpTreeForFunEval
bUseExpTreeForFunEval is set to true if you wish to use the OS Expression Tree for function evaluatio...
std::string getInstanceDescription()
Get instance description.
std::string getInstanceSource()
Get instance source.
int getConstraintNumber()
Get number of constraints.
double * calculateAllConstraintFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the constraint function values.
int getLinearConstraintCoefficientNumber()
Get number of specified (usually nonzero) linear constraint coefficient values.
char * getVariableTypes()
Get variable initial values.
double * calculateAllObjectiveFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the objective function values.
SparseMatrix * getLinearConstraintCoefficientsInColumnMajor()
Get linear constraint coefficients in column major.
double * calculateObjectiveFunctionGradient(double *x, double *objLambda, double *conLambda, int objIdx, bool new_x, int highestOrder)
Calculate the gradient of the objective function indexed by objIdx.
int * getNonlinearExpressionTreeModIndexes()
Get all the nonlinear expression tree indexes, i.e., indexes of rows (objectives or constraints) that...
double ** getDenseObjectiveCoefficients()
getDenseObjectiveCoefficients.
bool initForAlgDiff()
This should be called by nonlinear solvers using callback functions.
InstanceData * instanceData
A pointer to an InstanceData object.
int getNumberOfNonlinearExpressions()
Get number of nonlinear expressions.
SparseHessianMatrix * getLagrangianHessianSparsityPattern()
std::map< int, int > getAllNonlinearVariablesIndexMap()
QuadraticTerms * getQuadraticTerms()
Get all the quadratic terms in the instance.
double * getVariableLowerBounds()
Get variable lower bounds.
int getVariableNumber()
Get number of variables.
std::string * getVariableNames()
Get variable names.
std::string getInstanceName()
Get instance name.
SparseHessianMatrix * calculateLagrangianHessian(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate the Hessian of the Lagrangian Expression Tree This method will build the CppAD expression t...
std::string * getConstraintNames()
Get constraint names.
std::string * getObjectiveMaxOrMins()
Get objective maxOrMins.
double * getConstraintUpperBounds()
Get constraint upper bounds.
int getObjectiveNumber()
Get number of objectives.
The Option Class.
Definition OSOption.h:3565
InitVarValue ** getInitVarValuesSparse()
Get the initial values associated with the variables in sparse form.
int getNumberOfInitVarValues()
Get the number of initial variable values.
std::vector< SolverOption * > getSolverOptions(std::string solver_name)
Get the options associated with a given solver.
int getNumberOfSolverOptions()
Get the number of solver options.
The Result Class.
Definition OSResult.h:2549
bool setGeneralMessage(std::string message)
Set the general message.
bool setPrimalVariableValues(int solIdx, double *x, int n)
Set the [i]th optimization solution's primal variable values, where i equals the given solution index...
bool setSolutionNumber(int number)
set the number of solutions.
bool setInstanceName(std::string instanceName)
Set instance name.
bool setGeneralStatusType(std::string type)
Set the general status type, which can be: success, error, warning.
bool setObjectiveNumber(int objectiveNumber)
Set the objective number.
bool setObjectiveValues(int solIdx, double *objectiveValues, int n)
Set the [i]th optimization solution's objective values, where i equals the given solution index.
bool setServiceName(std::string serviceName)
Set service name.
bool setVariableNumber(int variableNumber)
Set the variable number.
bool setSolutionStatus(int solIdx, std::string type, std::string description)
Set the [i]th optimization solution status, where i equals the given solution index.
bool setConstraintNumber(int constraintNumber)
Set the constraint number.
Used to read an OSiL string.
Definition OSiLReader.h:38
OSInstance * readOSiL(const std::string &osil)
parse the OSiL model instance.
Used to read an OSoL string.
Definition OSoLReader.h:38
OSOption * readOSoL(const std::string &osol)
parse the OSoL solver options.
Take an OSResult object and write a string that validates against OSrL.
Definition OSrLWriter.h:31
std::string writeOSrL(OSResult *theosresult)
create an osrl string from an OSResult object
std::string maxOrMin
declare the objective function to be a max or a min
Definition OSInstance.h:157
int numberOfObjectives
numberOfObjectives is the number of objective functions in the instance
Definition OSInstance.h:201
Objective ** obj
coef is pointer to an array of ObjCoef object pointers
Definition OSInstance.h:205
int * varTwoIndexes
varTwoIndexes holds an integer array of the second variable indexes of all the quadratic terms.
Definition OSGeneral.h:450
int * rowIndexes
rowIndexes holds an integer array of row indexes of all the quadratic terms.
Definition OSGeneral.h:440
double * coefficients
coefficients holds a double array all the quadratic term coefficients.
Definition OSGeneral.h:455
int * varOneIndexes
varOneIndexes holds an integer array of the first variable indexes of all the quadratic terms.
Definition OSGeneral.h:445
The in-memory representation of a SparseHessianMatrix..
Definition OSGeneral.h:377
int * hessRowIdx
hessRowIdx is an integer array of row indices in the range 0, ..., n - 1.
Definition OSGeneral.h:394
int hessDimension
hessDimension is the number of nonzeros in each array.
Definition OSGeneral.h:389
double * hessValues
hessValues is a double array of the Hessian values.
Definition OSGeneral.h:404
int * hessColIdx
hessColIdx is an integer array of column indices in the range 0, ..., n - 1.
Definition OSGeneral.h:399
a sparse Jacobian matrix data structure
Definition OSGeneral.h:301
int * indexes
indexes holds an integer array of variable indices.
Definition OSGeneral.h:335
int valueSize
valueSize is the dimension of the values array
Definition OSGeneral.h:318
int * starts
starts holds an integer array of start elements, each start element points to the start of partials f...
Definition OSGeneral.h:324
double * values
values holds a double array of nonzero partial derivatives
Definition OSGeneral.h:340
int * indexes
indexes holds an integer array of rowIdx (or colIdx) elements in coefMatrix (AMatrix).
Definition OSGeneral.h:258
int * starts
starts holds an integer array of start elements in coefMatrix (AMatrix), which points to the start of...
Definition OSGeneral.h:252
double * values
values holds a double array of value elements in coefMatrix (AMatrix), which contains nonzero element...
Definition OSGeneral.h:264
double ub
ub corresponds to the optional attribute that holds the variable upper bound.
Definition OSInstance.h:61
double lb
lb corresponds to the optional attribute that holds the variable lower bound.
Definition OSInstance.h:56
Variable ** var
Here we define a pointer to an array of var pointers.
Definition OSInstance.h:97
#define OSDBL_MAX
OSResult * osresult